diff --git a/package/network/services/hostapd/Makefile b/package/network/services/hostapd/Makefile
index 235f178bc9..5f0e548742 100644
--- a/package/network/services/hostapd/Makefile
+++ b/package/network/services/hostapd/Makefile
@@ -11,9 +11,9 @@ PKG_RELEASE:=6
 
 PKG_SOURCE_URL:=http://w1.fi/hostap.git
 PKG_SOURCE_PROTO:=git
-PKG_SOURCE_DATE:=2018-12-02
-PKG_SOURCE_VERSION:=c2c6c01bb8b6fafc2074b46a53c4eab2c145ac6f
-PKG_MIRROR_HASH:=d381123fe42059b553d96122a03c35e7d1709153c3aaf10fa4e74fe59be243dd
+PKG_SOURCE_DATE:=2.8
+PKG_SOURCE_VERSION:=63962824309bb428e5f73d9caae08fcb949fbe36
+PKG_MIRROR_HASH:=c3d789b822428c92bd47b3c85d9dc36cced38f7affe885cc2bb15e54248a4566
 
 PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
 PKG_LICENSE:=BSD-3-Clause
diff --git a/package/network/services/hostapd/files/hostapd-basic.config b/package/network/services/hostapd/files/hostapd-basic.config
index b15116fbbe..9bf3928b0d 100644
--- a/package/network/services/hostapd/files/hostapd-basic.config
+++ b/package/network/services/hostapd/files/hostapd-basic.config
@@ -50,13 +50,12 @@ CONFIG_DRIVER_NL80211=y
 # WPA2/IEEE 802.11i RSN pre-authentication
 CONFIG_RSN_PREAUTH=y
 
-# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
-CONFIG_PEERKEY=y
-
 # IEEE 802.11w (management frame protection)
-# Driver support is also needed for IEEE 802.11w.
 #CONFIG_IEEE80211W=y
 
+# Support Operating Channel Validation
+#CONFIG_OCV=y
+
 # Integrated EAP server
 #CONFIG_EAP=y
 
@@ -253,6 +252,11 @@ CONFIG_NO_DUMP_STATE=y
 # requirements described above.
 CONFIG_NO_RANDOM_POOL=y
 
+# Should we attempt to use the getrandom(2) call that provides more reliable
+# yet secure randomness source than /dev/random on Linux 3.17 and newer.
+# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
+#CONFIG_GETRANDOM=y
+
 # Should we use poll instead of select? Select is used by default.
 #CONFIG_ELOOP_POLL=y
 
@@ -360,8 +364,6 @@ CONFIG_TLS=internal
 #CONFIG_TAXONOMY=y
 
 # Fast Initial Link Setup (FILS) (IEEE 802.11ai)
-# Note: This is an experimental and not yet complete implementation. This
-# should not be enabled for production use.
 #CONFIG_FILS=y
 # FILS shared key authentication with PFS
 #CONFIG_FILS_SK_PFS=y
@@ -374,6 +376,10 @@ CONFIG_TLS=internal
 # Experimental implementation of draft-harkins-owe-07.txt
 #CONFIG_OWE=y
 
+# Override default value for the wpa_disable_eapol_key_retries configuration
+# parameter. See that parameter in hostapd.conf for more details.
+#CFLAGS += -DDEFAULT_WPA_DISABLE_EAPOL_KEY_RETRIES=1
+
 # uBus IPC/RPC System
 # Services can connect to the bus and provide methods
 # that can be called by other services or clients.
diff --git a/package/network/services/hostapd/files/hostapd-full.config b/package/network/services/hostapd/files/hostapd-full.config
index b4159c2d28..f2e220004f 100644
--- a/package/network/services/hostapd/files/hostapd-full.config
+++ b/package/network/services/hostapd/files/hostapd-full.config
@@ -53,6 +53,9 @@ CONFIG_RSN_PREAUTH=y
 # IEEE 802.11w (management frame protection)
 #CONFIG_IEEE80211W=y
 
+# Support Operating Channel Validation
+#CONFIG_OCV=y
+
 # Integrated EAP server
 CONFIG_EAP=y
 
@@ -249,6 +252,11 @@ CONFIG_NO_DUMP_STATE=y
 # requirements described above.
 CONFIG_NO_RANDOM_POOL=y
 
+# Should we attempt to use the getrandom(2) call that provides more reliable
+# yet secure randomness source than /dev/random on Linux 3.17 and newer.
+# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
+#CONFIG_GETRANDOM=y
+
 # Should we use poll instead of select? Select is used by default.
 #CONFIG_ELOOP_POLL=y
 
@@ -356,8 +364,6 @@ CONFIG_INTERNAL_LIBTOMMATH=y
 CONFIG_TAXONOMY=y
 
 # Fast Initial Link Setup (FILS) (IEEE 802.11ai)
-# Note: This is an experimental and not yet complete implementation. This
-# should not be enabled for production use.
 #CONFIG_FILS=y
 # FILS shared key authentication with PFS
 #CONFIG_FILS_SK_PFS=y
diff --git a/package/network/services/hostapd/files/hostapd-mini.config b/package/network/services/hostapd/files/hostapd-mini.config
index 9057658c16..b8dd53d52b 100644
--- a/package/network/services/hostapd/files/hostapd-mini.config
+++ b/package/network/services/hostapd/files/hostapd-mini.config
@@ -53,6 +53,9 @@ CONFIG_RSN_PREAUTH=y
 # IEEE 802.11w (management frame protection)
 #CONFIG_IEEE80211W=y
 
+# Support Operating Channel Validation
+#CONFIG_OCV=y
+
 # Integrated EAP server
 #CONFIG_EAP=y
 
@@ -249,6 +252,11 @@ CONFIG_NO_DUMP_STATE=y
 # requirements described above.
 CONFIG_NO_RANDOM_POOL=y
 
+# Should we attempt to use the getrandom(2) call that provides more reliable
+# yet secure randomness source than /dev/random on Linux 3.17 and newer.
+# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
+#CONFIG_GETRANDOM=y
+
 # Should we use poll instead of select? Select is used by default.
 #CONFIG_ELOOP_POLL=y
 
@@ -356,8 +364,6 @@ CONFIG_TLS=internal
 #CONFIG_TAXONOMY=y
 
 # Fast Initial Link Setup (FILS) (IEEE 802.11ai)
-# Note: This is an experimental and not yet complete implementation. This
-# should not be enabled for production use.
 #CONFIG_FILS=y
 # FILS shared key authentication with PFS
 #CONFIG_FILS_SK_PFS=y
diff --git a/package/network/services/hostapd/files/wpa_supplicant-basic.config b/package/network/services/hostapd/files/wpa_supplicant-basic.config
index bd02562b74..c93cf783a3 100644
--- a/package/network/services/hostapd/files/wpa_supplicant-basic.config
+++ b/package/network/services/hostapd/files/wpa_supplicant-basic.config
@@ -73,6 +73,12 @@ CONFIG_DRIVER_NL80211=y
 # Driver interface for wired Ethernet drivers
 CONFIG_DRIVER_WIRED=y
 
+# Driver interface for MACsec capable Qualcomm Atheros drivers
+#CONFIG_DRIVER_MACSEC_QCA=y
+
+# Driver interface for Linux MACsec drivers
+#CONFIG_DRIVER_MACSEC_LINUX=y
+
 # Driver interface for the Broadcom RoboSwitch family
 #CONFIG_DRIVER_ROBOSWITCH=y
 
@@ -83,8 +89,8 @@ CONFIG_DRIVER_WIRED=y
 #LIBS += -lsocket -ldlpi -lnsl
 #LIBS_c += -lsocket
 
-# Enable IEEE 802.1X Supplicant (automatically included if any EAP method is
-# included)
+# Enable IEEE 802.1X Supplicant (automatically included if any EAP method or
+# MACsec is included)
 #CONFIG_IEEE8021X_EAPOL=y
 
 # EAP-MD5
@@ -103,9 +109,6 @@ CONFIG_DRIVER_WIRED=y
 #CONFIG_EAP_TTLS=y
 
 # EAP-FAST
-# Note: If OpenSSL is used as the TLS library, OpenSSL 1.0 or newer is needed
-# for EAP-FAST support. Older OpenSSL releases would need to be patched, e.g.,
-# with openssl-0.9.8x-tls-extensions.patch, to add the needed functions.
 #CONFIG_EAP_FAST=y
 
 # EAP-GTC
@@ -166,6 +169,9 @@ CONFIG_DRIVER_WIRED=y
 # EAP-EKE
 #CONFIG_EAP_EKE=y
 
+# MACsec
+#CONFIG_MACSEC=y
+
 # PKCS#12 (PFX) support (used to read private key and certificate file from
 # a file that usually has extension .p12 or .pfx)
 #CONFIG_PKCS12=y
@@ -226,6 +232,9 @@ CONFIG_CTRL_IFACE=y
 # wpa_passphrase). This saves about 0.5 kB in code size.
 #CONFIG_NO_WPA_PASSPHRASE=y
 
+# Simultaneous Authentication of Equals (SAE), WPA3-Personal
+#CONFIG_SAE=y
+
 # Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
 # This can be used if ap_scan=1 mode is never enabled.
 #CONFIG_NO_SCAN_PROCESSING=y
@@ -288,13 +297,13 @@ CONFIG_BACKEND=file
 # bridge interfaces (commit 'bridge: respect RFC2863 operational state')').
 #CONFIG_NO_LINUX_PACKET_SOCKET_WAR=y
 
-# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
-#CONFIG_PEERKEY=y
-
 # IEEE 802.11w (management frame protection), also known as PMF
 # Driver support is also needed for IEEE 802.11w.
 #CONFIG_IEEE80211W=y
 
+# Support Operating Channel Validation
+#CONFIG_OCV=y
+
 # Select TLS implementation
 # openssl = OpenSSL (default)
 # gnutls = GnuTLS
@@ -343,10 +352,6 @@ CONFIG_TLS=internal
 #CONFIG_NDIS_EVENTS_INTEGRATED=y
 #PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
 
-# Add support for old DBus control interface
-# (fi.epitest.hostap.WPASupplicant)
-#CONFIG_CTRL_IFACE_DBUS=y
-
 # Add support for new DBus control interface
 # (fi.w1.hostap.wpa_supplicant1)
 #CONFIG_CTRL_IFACE_DBUS_NEW=y
@@ -378,10 +383,6 @@ CONFIG_TLS=internal
 # IEEE Std 802.11r-2008 (Fast BSS Transition) for station mode
 CONFIG_IEEE80211R=y
 
-# IEEE Std 802.11r-2008 (Fast BSS Transition) for AP mode (implies
-# CONFIG_IEEE80211R).
-#CONFIG_IEEE80211R_AP=y
-
 # Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt)
 #CONFIG_DEBUG_FILE=y
 
@@ -456,6 +457,11 @@ CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON
 # that meet the requirements described above.
 CONFIG_NO_RANDOM_POOL=y
 
+# Should we attempt to use the getrandom(2) call that provides more reliable
+# yet secure randomness source than /dev/random on Linux 3.17 and newer.
+# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
+#CONFIG_GETRANDOM=y
+
 # IEEE 802.11n (High Throughput) support (mainly for AP mode)
 #CONFIG_IEEE80211N=y
 
@@ -497,8 +503,8 @@ CONFIG_NO_RANDOM_POOL=y
 # Enable TDLS support
 #CONFIG_TDLS=y
 
-# Wi-Fi Direct
-# This can be used to enable Wi-Fi Direct extensions for P2P using an external
+# Wi-Fi Display
+# This can be used to enable Wi-Fi Display extensions for P2P using an external
 # program to control the additional information exchanges in the messages.
 #CONFIG_WIFI_DISPLAY=y
 
@@ -559,8 +565,6 @@ CONFIG_NO_RANDOM_POOL=y
 #CONFIG_MBO=y
 
 # Fast Initial Link Setup (FILS) (IEEE 802.11ai)
-# Note: This is an experimental and not yet complete implementation. This
-# should not be enabled for production use.
 #CONFIG_FILS=y
 # FILS shared key authentication with PFS
 #CONFIG_FILS_SK_PFS=y
@@ -592,6 +596,11 @@ CONFIG_NO_RANDOM_POOL=y
 # Experimental implementation of draft-harkins-owe-07.txt
 #CONFIG_OWE=y
 
+# Device Provisioning Protocol (DPP)
+# This requires CONFIG_IEEE80211W=y to be enabled, too. (see
+# wpa_supplicant/README-DPP for details)
+#CONFIG_DPP=y
+
 # uBus IPC/RPC System
 # Services can connect to the bus and provide methods
 # that can be called by other services or clients.
diff --git a/package/network/services/hostapd/files/wpa_supplicant-full.config b/package/network/services/hostapd/files/wpa_supplicant-full.config
index 5f6e82f7b6..10b4d15ea2 100644
--- a/package/network/services/hostapd/files/wpa_supplicant-full.config
+++ b/package/network/services/hostapd/files/wpa_supplicant-full.config
@@ -109,9 +109,6 @@ CONFIG_EAP_PEAP=y
 CONFIG_EAP_TTLS=y
 
 # EAP-FAST
-# Note: If OpenSSL is used as the TLS library, OpenSSL 1.0 or newer is needed
-# for EAP-FAST support. Older OpenSSL releases would need to be patched, e.g.,
-# with openssl-0.9.8x-tls-extensions.patch, to add the needed functions.
 CONFIG_EAP_FAST=y
 
 # EAP-GTC
@@ -235,6 +232,9 @@ CONFIG_CTRL_IFACE=y
 # wpa_passphrase). This saves about 0.5 kB in code size.
 #CONFIG_NO_WPA_PASSPHRASE=y
 
+# Simultaneous Authentication of Equals (SAE), WPA3-Personal
+#CONFIG_SAE=y
+
 # Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
 # This can be used if ap_scan=1 mode is never enabled.
 #CONFIG_NO_SCAN_PROCESSING=y
@@ -301,6 +301,9 @@ CONFIG_BACKEND=file
 # Driver support is also needed for IEEE 802.11w.
 #CONFIG_IEEE80211W=y
 
+# Support Operating Channel Validation
+#CONFIG_OCV=y
+
 # Select TLS implementation
 # openssl = OpenSSL (default)
 # gnutls = GnuTLS
@@ -349,10 +352,6 @@ CONFIG_INTERNAL_LIBTOMMATH_FAST=y
 #CONFIG_NDIS_EVENTS_INTEGRATED=y
 #PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
 
-# Add support for old DBus control interface
-# (fi.epitest.hostap.WPASupplicant)
-#CONFIG_CTRL_IFACE_DBUS=y
-
 # Add support for new DBus control interface
 # (fi.w1.hostap.wpa_supplicant1)
 #CONFIG_CTRL_IFACE_DBUS_NEW=y
@@ -458,6 +457,11 @@ CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON
 # that meet the requirements described above.
 CONFIG_NO_RANDOM_POOL=y
 
+# Should we attempt to use the getrandom(2) call that provides more reliable
+# yet secure randomness source than /dev/random on Linux 3.17 and newer.
+# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
+#CONFIG_GETRANDOM=y
+
 # IEEE 802.11n (High Throughput) support (mainly for AP mode)
 #CONFIG_IEEE80211N=y
 
@@ -499,8 +503,8 @@ CONFIG_WNM=y
 # Enable TDLS support
 #CONFIG_TDLS=y
 
-# Wi-Fi Direct
-# This can be used to enable Wi-Fi Direct extensions for P2P using an external
+# Wi-Fi Display
+# This can be used to enable Wi-Fi Display extensions for P2P using an external
 # program to control the additional information exchanges in the messages.
 #CONFIG_WIFI_DISPLAY=y
 
@@ -561,8 +565,6 @@ CONFIG_WNM=y
 #CONFIG_MBO=y
 
 # Fast Initial Link Setup (FILS) (IEEE 802.11ai)
-# Note: This is an experimental and not yet complete implementation. This
-# should not be enabled for production use.
 #CONFIG_FILS=y
 # FILS shared key authentication with PFS
 #CONFIG_FILS_SK_PFS=y
@@ -594,6 +596,11 @@ CONFIG_IBSS_RSN=y
 # Experimental implementation of draft-harkins-owe-07.txt
 #CONFIG_OWE=y
 
+# Device Provisioning Protocol (DPP)
+# This requires CONFIG_IEEE80211W=y to be enabled, too. (see
+# wpa_supplicant/README-DPP for details)
+#CONFIG_DPP=y
+
 # uBus IPC/RPC System
 # Services can connect to the bus and provide methods
 # that can be called by other services or clients.
diff --git a/package/network/services/hostapd/files/wpa_supplicant-mini.config b/package/network/services/hostapd/files/wpa_supplicant-mini.config
index 5e6f154105..9ffcf7e2e4 100644
--- a/package/network/services/hostapd/files/wpa_supplicant-mini.config
+++ b/package/network/services/hostapd/files/wpa_supplicant-mini.config
@@ -109,9 +109,6 @@ CONFIG_DRIVER_WIRED=y
 #CONFIG_EAP_TTLS=y
 
 # EAP-FAST
-# Note: If OpenSSL is used as the TLS library, OpenSSL 1.0 or newer is needed
-# for EAP-FAST support. Older OpenSSL releases would need to be patched, e.g.,
-# with openssl-0.9.8x-tls-extensions.patch, to add the needed functions.
 #CONFIG_EAP_FAST=y
 
 # EAP-GTC
@@ -235,6 +232,9 @@ CONFIG_CTRL_IFACE=y
 # wpa_passphrase). This saves about 0.5 kB in code size.
 #CONFIG_NO_WPA_PASSPHRASE=y
 
+# Simultaneous Authentication of Equals (SAE), WPA3-Personal
+#CONFIG_SAE=y
+
 # Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
 # This can be used if ap_scan=1 mode is never enabled.
 #CONFIG_NO_SCAN_PROCESSING=y
@@ -301,6 +301,9 @@ CONFIG_BACKEND=file
 # Driver support is also needed for IEEE 802.11w.
 #CONFIG_IEEE80211W=y
 
+# Support Operating Channel Validation
+#CONFIG_OCV=y
+
 # Select TLS implementation
 # openssl = OpenSSL (default)
 # gnutls = GnuTLS
@@ -349,10 +352,6 @@ CONFIG_TLS=internal
 #CONFIG_NDIS_EVENTS_INTEGRATED=y
 #PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
 
-# Add support for old DBus control interface
-# (fi.epitest.hostap.WPASupplicant)
-#CONFIG_CTRL_IFACE_DBUS=y
-
 # Add support for new DBus control interface
 # (fi.w1.hostap.wpa_supplicant1)
 #CONFIG_CTRL_IFACE_DBUS_NEW=y
@@ -458,6 +457,11 @@ CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON
 # that meet the requirements described above.
 CONFIG_NO_RANDOM_POOL=y
 
+# Should we attempt to use the getrandom(2) call that provides more reliable
+# yet secure randomness source than /dev/random on Linux 3.17 and newer.
+# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
+#CONFIG_GETRANDOM=y
+
 # IEEE 802.11n (High Throughput) support (mainly for AP mode)
 #CONFIG_IEEE80211N=y
 
@@ -499,8 +503,8 @@ CONFIG_NO_RANDOM_POOL=y
 # Enable TDLS support
 #CONFIG_TDLS=y
 
-# Wi-Fi Direct
-# This can be used to enable Wi-Fi Direct extensions for P2P using an external
+# Wi-Fi Display
+# This can be used to enable Wi-Fi Display extensions for P2P using an external
 # program to control the additional information exchanges in the messages.
 #CONFIG_WIFI_DISPLAY=y
 
@@ -561,8 +565,6 @@ CONFIG_NO_RANDOM_POOL=y
 #CONFIG_MBO=y
 
 # Fast Initial Link Setup (FILS) (IEEE 802.11ai)
-# Note: This is an experimental and not yet complete implementation. This
-# should not be enabled for production use.
 #CONFIG_FILS=y
 # FILS shared key authentication with PFS
 #CONFIG_FILS_SK_PFS=y
@@ -594,6 +596,11 @@ CONFIG_NO_RANDOM_POOL=y
 # Experimental implementation of draft-harkins-owe-07.txt
 #CONFIG_OWE=y
 
+# Device Provisioning Protocol (DPP)
+# This requires CONFIG_IEEE80211W=y to be enabled, too. (see
+# wpa_supplicant/README-DPP for details)
+#CONFIG_DPP=y
+
 # uBus IPC/RPC System
 # Services can connect to the bus and provide methods
 # that can be called by other services or clients.
diff --git a/package/network/services/hostapd/files/wpa_supplicant-p2p.config b/package/network/services/hostapd/files/wpa_supplicant-p2p.config
index bbbb8e6e30..e2eb57bb38 100644
--- a/package/network/services/hostapd/files/wpa_supplicant-p2p.config
+++ b/package/network/services/hostapd/files/wpa_supplicant-p2p.config
@@ -109,9 +109,6 @@ CONFIG_EAP_PEAP=y
 CONFIG_EAP_TTLS=y
 
 # EAP-FAST
-# Note: If OpenSSL is used as the TLS library, OpenSSL 1.0 or newer is needed
-# for EAP-FAST support. Older OpenSSL releases would need to be patched, e.g.,
-# with openssl-0.9.8x-tls-extensions.patch, to add the needed functions.
 CONFIG_EAP_FAST=y
 
 # EAP-GTC
@@ -235,6 +232,9 @@ CONFIG_CTRL_IFACE=y
 # wpa_passphrase). This saves about 0.5 kB in code size.
 #CONFIG_NO_WPA_PASSPHRASE=y
 
+# Simultaneous Authentication of Equals (SAE), WPA3-Personal
+#CONFIG_SAE=y
+
 # Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
 # This can be used if ap_scan=1 mode is never enabled.
 #CONFIG_NO_SCAN_PROCESSING=y
@@ -301,6 +301,9 @@ CONFIG_BACKEND=file
 # Driver support is also needed for IEEE 802.11w.
 CONFIG_IEEE80211W=y
 
+# Support Operating Channel Validation
+#CONFIG_OCV=y
+
 # Select TLS implementation
 # openssl = OpenSSL (default)
 # gnutls = GnuTLS
@@ -349,10 +352,6 @@ CONFIG_INTERNAL_LIBTOMMATH_FAST=y
 #CONFIG_NDIS_EVENTS_INTEGRATED=y
 #PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
 
-# Add support for old DBus control interface
-# (fi.epitest.hostap.WPASupplicant)
-#CONFIG_CTRL_IFACE_DBUS=y
-
 # Add support for new DBus control interface
 # (fi.w1.hostap.wpa_supplicant1)
 #CONFIG_CTRL_IFACE_DBUS_NEW=y
@@ -458,6 +457,11 @@ CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON
 # that meet the requirements described above.
 CONFIG_NO_RANDOM_POOL=y
 
+# Should we attempt to use the getrandom(2) call that provides more reliable
+# yet secure randomness source than /dev/random on Linux 3.17 and newer.
+# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
+#CONFIG_GETRANDOM=y
+
 # IEEE 802.11n (High Throughput) support (mainly for AP mode)
 #CONFIG_IEEE80211N=y
 
@@ -499,8 +503,8 @@ CONFIG_P2P=y
 # Enable TDLS support
 #CONFIG_TDLS=y
 
-# Wi-Fi Direct
-# This can be used to enable Wi-Fi Direct extensions for P2P using an external
+# Wi-Fi Display
+# This can be used to enable Wi-Fi Display extensions for P2P using an external
 # program to control the additional information exchanges in the messages.
 #CONFIG_WIFI_DISPLAY=y
 
@@ -561,8 +565,6 @@ CONFIG_P2P=y
 #CONFIG_MBO=y
 
 # Fast Initial Link Setup (FILS) (IEEE 802.11ai)
-# Note: This is an experimental and not yet complete implementation. This
-# should not be enabled for production use.
 #CONFIG_FILS=y
 # FILS shared key authentication with PFS
 #CONFIG_FILS_SK_PFS=y
@@ -594,6 +596,11 @@ CONFIG_IBSS_RSN=y
 # Experimental implementation of draft-harkins-owe-07.txt
 #CONFIG_OWE=y
 
+# Device Provisioning Protocol (DPP)
+# This requires CONFIG_IEEE80211W=y to be enabled, too. (see
+# wpa_supplicant/README-DPP for details)
+#CONFIG_DPP=y
+
 # uBus IPC/RPC System
 # Services can connect to the bus and provide methods
 # that can be called by other services or clients.
diff --git a/package/network/services/hostapd/patches/001-mesh-factor-out-mesh-join-function.patch b/package/network/services/hostapd/patches/001-mesh-factor-out-mesh-join-function.patch
deleted file mode 100644
index de8d65b982..0000000000
--- a/package/network/services/hostapd/patches/001-mesh-factor-out-mesh-join-function.patch
+++ /dev/null
@@ -1,211 +0,0 @@
-From 02ae4382f45f772e3630460459eb4e5af64e71b4 Mon Sep 17 00:00:00 2001
-From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:05 -0700
-Subject: [PATCH 01/18] mesh: factor out mesh join function
-
-mesh join function consitss of 2 parts which are preparing
-configurations and sending join event to driver.
-Since physical mesh join event could happen either right
-after mesh configuration is done or after CAC is done
-in case of DFS channel is used, factor out the function
-into 2 parts to reduce redundant calls.
-
-Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
----
- wpa_supplicant/mesh.c             | 119 ++++++++++++++++--------------
- wpa_supplicant/mesh.h             |   1 +
- wpa_supplicant/wpa_supplicant_i.h |   1 +
- 3 files changed, 67 insertions(+), 54 deletions(-)
-
---- a/wpa_supplicant/mesh.c
-+++ b/wpa_supplicant/mesh.c
-@@ -364,13 +364,48 @@ void wpa_supplicant_mesh_add_scan_ie(str
- }
- 
- 
-+void wpas_join_mesh(struct wpa_supplicant *wpa_s)
-+{
-+	struct wpa_driver_mesh_join_params *params = wpa_s->mesh_params;
-+	struct wpa_ssid *ssid = wpa_s->current_ssid;
-+	int ret = 0;
-+
-+	if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
-+		wpa_s->pairwise_cipher = wpa_s->mesh_rsn->pairwise_cipher;
-+		wpa_s->group_cipher = wpa_s->mesh_rsn->group_cipher;
-+		wpa_s->mgmt_group_cipher = wpa_s->mesh_rsn->mgmt_group_cipher;
-+	}
-+
-+	if (wpa_s->ifmsh) {
-+		params->ies = wpa_s->ifmsh->mconf->rsn_ie;
-+		params->ie_len = wpa_s->ifmsh->mconf->rsn_ie_len;
-+		params->basic_rates = wpa_s->ifmsh->basic_rates;
-+		params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_HT_OP_MODE;
-+		params->conf.ht_opmode = wpa_s->ifmsh->bss[0]->iface->ht_op_mode;
-+	}
-+
-+	ret = wpa_drv_join_mesh(wpa_s, params);
-+	if (ret)
-+		wpa_msg(wpa_s, MSG_ERROR, "mesh join error=%d\n", ret);
-+
-+	/* hostapd sets the interface down until we associate */
-+	wpa_drv_set_operstate(wpa_s, 1);
-+
-+	if (!ret)
-+		wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
-+
-+	return;
-+}
-+
-+
- int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s,
- 			     struct wpa_ssid *ssid)
- {
--	struct wpa_driver_mesh_join_params params;
-+	struct wpa_driver_mesh_join_params *params =
-+		os_zalloc(sizeof(struct wpa_driver_mesh_join_params));
- 	int ret = 0;
- 
--	if (!ssid || !ssid->ssid || !ssid->ssid_len || !ssid->frequency) {
-+	if (!ssid || !ssid->ssid || !ssid->ssid_len || !ssid->frequency || !params) {
- 		ret = -ENOENT;
- 		goto out;
- 	}
-@@ -381,22 +416,22 @@ int wpa_supplicant_join_mesh(struct wpa_
- 	wpa_s->group_cipher = WPA_CIPHER_NONE;
- 	wpa_s->mgmt_group_cipher = 0;
- 
--	os_memset(&params, 0, sizeof(params));
--	params.meshid = ssid->ssid;
--	params.meshid_len = ssid->ssid_len;
--	ibss_mesh_setup_freq(wpa_s, ssid, &params.freq);
--	wpa_s->mesh_ht_enabled = !!params.freq.ht_enabled;
--	wpa_s->mesh_vht_enabled = !!params.freq.vht_enabled;
--	if (params.freq.ht_enabled && params.freq.sec_channel_offset)
--		ssid->ht40 = params.freq.sec_channel_offset;
-+	params->meshid = ssid->ssid;
-+	params->meshid_len = ssid->ssid_len;
-+	ibss_mesh_setup_freq(wpa_s, ssid, &params->freq);
-+	wpa_s->mesh_ht_enabled = !!params->freq.ht_enabled;
-+	wpa_s->mesh_vht_enabled = !!params->freq.vht_enabled;
-+	if (params->freq.ht_enabled && params->freq.sec_channel_offset)
-+		ssid->ht40 = params->freq.sec_channel_offset;
-+
- 	if (wpa_s->mesh_vht_enabled) {
- 		ssid->vht = 1;
--		switch (params.freq.bandwidth) {
-+		switch (params->freq.bandwidth) {
- 		case 80:
--			if (params.freq.center_freq2) {
-+			if (params->freq.center_freq2) {
- 				ssid->max_oper_chwidth = VHT_CHANWIDTH_80P80MHZ;
- 				ssid->vht_center_freq2 =
--					params.freq.center_freq2;
-+					params->freq.center_freq2;
- 			} else {
- 				ssid->max_oper_chwidth = VHT_CHANWIDTH_80MHZ;
- 			}
-@@ -410,67 +445,43 @@ int wpa_supplicant_join_mesh(struct wpa_
- 		}
- 	}
- 	if (ssid->beacon_int > 0)
--		params.beacon_int = ssid->beacon_int;
-+		params->beacon_int = ssid->beacon_int;
- 	else if (wpa_s->conf->beacon_int > 0)
--		params.beacon_int = wpa_s->conf->beacon_int;
-+		params->beacon_int = wpa_s->conf->beacon_int;
- 	if (ssid->dtim_period > 0)
--		params.dtim_period = ssid->dtim_period;
-+		params->dtim_period = ssid->dtim_period;
- 	else if (wpa_s->conf->dtim_period > 0)
--		params.dtim_period = wpa_s->conf->dtim_period;
--	params.conf.max_peer_links = wpa_s->conf->max_peer_links;
-+		params->dtim_period = wpa_s->conf->dtim_period;
-+	params->conf.max_peer_links = wpa_s->conf->max_peer_links;
- 	if (ssid->mesh_rssi_threshold < DEFAULT_MESH_RSSI_THRESHOLD) {
--		params.conf.rssi_threshold = ssid->mesh_rssi_threshold;
--		params.conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_RSSI_THRESHOLD;
-+		params->conf.rssi_threshold = ssid->mesh_rssi_threshold;
-+		params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_RSSI_THRESHOLD;
- 	}
- 
- 	if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
--		params.flags |= WPA_DRIVER_MESH_FLAG_SAE_AUTH;
--		params.flags |= WPA_DRIVER_MESH_FLAG_AMPE;
-+		params->flags |= WPA_DRIVER_MESH_FLAG_SAE_AUTH;
-+		params->flags |= WPA_DRIVER_MESH_FLAG_AMPE;
- 		wpa_s->conf->user_mpm = 1;
- 	}
- 
- 	if (wpa_s->conf->user_mpm) {
--		params.flags |= WPA_DRIVER_MESH_FLAG_USER_MPM;
--		params.conf.auto_plinks = 0;
-+		params->flags |= WPA_DRIVER_MESH_FLAG_USER_MPM;
-+		params->conf.auto_plinks = 0;
- 	} else {
--		params.flags |= WPA_DRIVER_MESH_FLAG_DRIVER_MPM;
--		params.conf.auto_plinks = 1;
-+		params->flags |= WPA_DRIVER_MESH_FLAG_DRIVER_MPM;
-+		params->conf.auto_plinks = 1;
- 	}
--	params.conf.peer_link_timeout = wpa_s->conf->mesh_max_inactivity;
-+	params->conf.peer_link_timeout = wpa_s->conf->mesh_max_inactivity;
- 
--	if (wpa_supplicant_mesh_init(wpa_s, ssid, &params.freq)) {
-+	wpa_s->mesh_params = params;
-+	if (wpa_supplicant_mesh_init(wpa_s, ssid, &params->freq)) {
- 		wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh");
- 		wpa_drv_leave_mesh(wpa_s);
- 		ret = -1;
- 		goto out;
- 	}
- 
--	if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
--		wpa_s->pairwise_cipher = wpa_s->mesh_rsn->pairwise_cipher;
--		wpa_s->group_cipher = wpa_s->mesh_rsn->group_cipher;
--		wpa_s->mgmt_group_cipher = wpa_s->mesh_rsn->mgmt_group_cipher;
--	}
--
--	if (wpa_s->ifmsh) {
--		params.ies = wpa_s->ifmsh->mconf->rsn_ie;
--		params.ie_len = wpa_s->ifmsh->mconf->rsn_ie_len;
--		params.basic_rates = wpa_s->ifmsh->basic_rates;
--		params.conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_HT_OP_MODE;
--		params.conf.ht_opmode = wpa_s->ifmsh->bss[0]->iface->ht_op_mode;
--	}
--
--	wpa_msg(wpa_s, MSG_INFO, "joining mesh %s",
--		wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
--	ret = wpa_drv_join_mesh(wpa_s, &params);
--	if (ret)
--		wpa_msg(wpa_s, MSG_ERROR, "mesh join error=%d", ret);
--
--	/* hostapd sets the interface down until we associate */
--	wpa_drv_set_operstate(wpa_s, 1);
--
--	if (!ret)
--		wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
--
-+	wpas_join_mesh(wpa_s);
- out:
- 	return ret;
- }
---- a/wpa_supplicant/mesh.h
-+++ b/wpa_supplicant/mesh.h
-@@ -21,6 +21,7 @@ int wpas_mesh_add_interface(struct wpa_s
- int wpas_mesh_peer_remove(struct wpa_supplicant *wpa_s, const u8 *addr);
- int wpas_mesh_peer_add(struct wpa_supplicant *wpa_s, const u8 *addr,
- 		       int duration);
-+void wpas_join_mesh(struct wpa_supplicant *wpa_s);
- 
- #ifdef CONFIG_MESH
- 
---- a/wpa_supplicant/wpa_supplicant_i.h
-+++ b/wpa_supplicant/wpa_supplicant_i.h
-@@ -814,6 +814,7 @@ struct wpa_supplicant {
- 	unsigned int mesh_if_created:1;
- 	unsigned int mesh_ht_enabled:1;
- 	unsigned int mesh_vht_enabled:1;
-+	struct wpa_driver_mesh_join_params *mesh_params;
- #ifdef CONFIG_PMKSA_CACHE_EXTERNAL
- 	/* struct external_pmksa_cache::list */
- 	struct dl_list mesh_external_pmksa_cache;
diff --git a/package/network/services/hostapd/patches/002-mesh-factor-out-rsn-initialization.patch b/package/network/services/hostapd/patches/002-mesh-factor-out-rsn-initialization.patch
deleted file mode 100644
index 26e872d765..0000000000
--- a/package/network/services/hostapd/patches/002-mesh-factor-out-rsn-initialization.patch
+++ /dev/null
@@ -1,133 +0,0 @@
-From 89db76eeff6502dfa39b011962ec9d560ed4c2ee Mon Sep 17 00:00:00 2001
-From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:06 -0700
-Subject: [PATCH 02/18] mesh: factor out rsn initialization
-
-RSN initialization can be used in different phases
-if mesh initialization and mesh join don't happen
-in sequence such as DFS CAC is done in between,
-hence factor it out to help convering the case.
-
-Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
----
- wpa_supplicant/mesh.c | 84 +++++++++++++++++++++++++------------------
- wpa_supplicant/mesh.h |  1 +
- 2 files changed, 50 insertions(+), 35 deletions(-)
-
---- a/wpa_supplicant/mesh.c
-+++ b/wpa_supplicant/mesh.c
-@@ -147,6 +147,53 @@ static void wpas_mesh_copy_groups(struct
- }
- 
- 
-+int wpas_mesh_init_rsn(struct wpa_supplicant *wpa_s)
-+{
-+	struct hostapd_iface *ifmsh = wpa_s->ifmsh;
-+	struct mesh_conf *mconf = wpa_s->ifmsh->mconf;
-+	struct wpa_ssid *ssid = wpa_s->current_ssid;
-+	struct hostapd_data *bss = ifmsh->bss[0];
-+	static int default_groups[] = { 19, 20, 21, 25, 26, -1 };
-+	const char *password;
-+	size_t len;
-+
-+	if (mconf->security != MESH_CONF_SEC_NONE) {
-+		password = ssid->sae_password;
-+		if (!password)
-+			password = ssid->passphrase;
-+		if (!password) {
-+			wpa_printf(MSG_ERROR,
-+				   "mesh: Passphrase for SAE not configured");
-+			return -1;
-+		}
-+
-+		bss->conf->wpa = ssid->proto;
-+		bss->conf->wpa_key_mgmt = ssid->key_mgmt;
-+
-+		if (wpa_s->conf->sae_groups &&
-+		    wpa_s->conf->sae_groups[0] > 0) {
-+			wpas_mesh_copy_groups(bss, wpa_s);
-+		} else {
-+			bss->conf->sae_groups =
-+				os_memdup(default_groups,
-+					  sizeof(default_groups));
-+			if (!bss->conf->sae_groups)
-+				return -1;
-+		}
-+
-+		len = os_strlen(password);
-+		bss->conf->ssid.wpa_passphrase =
-+			dup_binstr(password, len);
-+
-+		wpa_s->mesh_rsn = mesh_rsn_auth_init(wpa_s, mconf);
-+		if (!wpa_s->mesh_rsn)
-+			return -1;
-+	}
-+
-+	return 0;
-+}
-+
-+
- static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
- 				    struct wpa_ssid *ssid,
- 				    struct hostapd_freq_params *freq)
-@@ -156,9 +203,6 @@ static int wpa_supplicant_mesh_init(stru
- 	struct hostapd_config *conf;
- 	struct mesh_conf *mconf;
- 	int basic_rates_erp[] = { 10, 20, 55, 60, 110, 120, 240, -1 };
--	static int default_groups[] = { 19, 20, 21, 25, 26, -1 };
--	const char *password;
--	size_t len;
- 	int rate_len;
- 	int frequency;
- 
-@@ -292,38 +336,8 @@ static int wpa_supplicant_mesh_init(stru
- 		return -1;
- 	}
- 
--	if (mconf->security != MESH_CONF_SEC_NONE) {
--		password = ssid->sae_password;
--		if (!password)
--			password = ssid->passphrase;
--		if (!password) {
--			wpa_printf(MSG_ERROR,
--				   "mesh: Passphrase for SAE not configured");
--			goto out_free;
--		}
--
--		bss->conf->wpa = ssid->proto;
--		bss->conf->wpa_key_mgmt = ssid->key_mgmt;
--
--		if (wpa_s->conf->sae_groups &&
--		    wpa_s->conf->sae_groups[0] > 0) {
--			wpas_mesh_copy_groups(bss, wpa_s);
--		} else {
--			bss->conf->sae_groups =
--				os_memdup(default_groups,
--					  sizeof(default_groups));
--			if (!bss->conf->sae_groups)
--				goto out_free;
--		}
--
--		len = os_strlen(password);
--		bss->conf->ssid.wpa_passphrase =
--			dup_binstr(password, len);
--
--		wpa_s->mesh_rsn = mesh_rsn_auth_init(wpa_s, mconf);
--		if (!wpa_s->mesh_rsn)
--			goto out_free;
--	}
-+	if (wpas_mesh_init_rsn(wpa_s))
-+		goto out_free;
- 
- 	wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf);
- 
---- a/wpa_supplicant/mesh.h
-+++ b/wpa_supplicant/mesh.h
-@@ -22,6 +22,7 @@ int wpas_mesh_peer_remove(struct wpa_sup
- int wpas_mesh_peer_add(struct wpa_supplicant *wpa_s, const u8 *addr,
- 		       int duration);
- void wpas_join_mesh(struct wpa_supplicant *wpa_s);
-+int wpas_mesh_init_rsn(struct wpa_supplicant *wpa_s);
- 
- #ifdef CONFIG_MESH
- 
diff --git a/package/network/services/hostapd/patches/003-mesh-relocate-RSN-init-function.patch b/package/network/services/hostapd/patches/003-mesh-relocate-RSN-init-function.patch
deleted file mode 100644
index c96e810769..0000000000
--- a/package/network/services/hostapd/patches/003-mesh-relocate-RSN-init-function.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 07bad5f256cbe8a4b45d32c5b43b870ee815fb42 Mon Sep 17 00:00:00 2001
-From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:07 -0700
-Subject: [PATCH 03/18] mesh: relocate RSN init function
-
-RSN init function should work together with mesh join
-when it's used. Since mesh join could be called at different stage
-if DFS channel is used, relocate the function to mesh join.
-It is still the same call flows of mesh join before this changes
-if non-DFS channels are used, hence no side effect will occur.
-
-Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
----
- wpa_supplicant/mesh.c | 9 ++++++---
- 1 file changed, 6 insertions(+), 3 deletions(-)
-
---- a/wpa_supplicant/mesh.c
-+++ b/wpa_supplicant/mesh.c
-@@ -336,9 +336,6 @@ static int wpa_supplicant_mesh_init(stru
- 		return -1;
- 	}
- 
--	if (wpas_mesh_init_rsn(wpa_s))
--		goto out_free;
--
- 	wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf);
- 
- 	return 0;
-@@ -384,6 +381,12 @@ void wpas_join_mesh(struct wpa_supplican
- 	struct wpa_ssid *ssid = wpa_s->current_ssid;
- 	int ret = 0;
- 
-+	if (wpas_mesh_init_rsn(wpa_s)) {
-+		wpa_printf(MSG_ERROR, "Init RSN failed. Deinit mesh...");
-+		wpa_supplicant_mesh_deinit(wpa_s);
-+		return;
-+	}
-+
- 	if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
- 		wpa_s->pairwise_cipher = wpa_s->mesh_rsn->pairwise_cipher;
- 		wpa_s->group_cipher = wpa_s->mesh_rsn->group_cipher;
diff --git a/package/network/services/hostapd/patches/004-mesh-use-setup-completion-callback-to-complete-mesh-.patch b/package/network/services/hostapd/patches/004-mesh-use-setup-completion-callback-to-complete-mesh-.patch
index 3ce2848d02..ead1bcac90 100644
--- a/package/network/services/hostapd/patches/004-mesh-use-setup-completion-callback-to-complete-mesh-.patch
+++ b/package/network/services/hostapd/patches/004-mesh-use-setup-completion-callback-to-complete-mesh-.patch
@@ -1,30 +1,103 @@
-From bd05de484bfa61def530d717c7234381f6b33cf7 Mon Sep 17 00:00:00 2001
+From c05ace7510ead96e72b97ce47b33f7b5865d6d36 Mon Sep 17 00:00:00 2001
 From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:08 -0700
-Subject: [PATCH 04/18] mesh: use setup completion callback to complete mesh
- join
+Date: Mon, 27 Aug 2018 14:28:38 -0700
+Subject: [PATCH 1/7] mesh: use setup completion callback to complete mesh join
 
 mesh join function is the last function to be called during
 mesh join process, but it's been called a bit earlier than
 it's supposed to be, so that some mesh parameter values
 such as VHT capabilities not applied correct when mesh join
-is in process. Moreover current design of mesh join that is called
-directly after mesh initialization is not suitable for DFS channels
-to use, since mesh join process should be paused until DFS CAC is
-done and resumed once it's done.
-Using setup completion callback is how AP mode is using for DFS channels
-and mesh can use the same way.
+is in process.
+Moreover current design of mesh join that is called directly
+after mesh initialization isn't suitable for DFS channels to use,
+since mesh join process should be paused until DFS CAC is
+done and resumed after it's done.
 The callback will be called by hostapd_setup_interface_complete_sync.
+There is possiblity that completing mesh init fails, so add error
+handle codes.
 
+Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
 Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
 ---
- wpa_supplicant/mesh.c | 7 +++++--
- wpa_supplicant/mesh.h | 2 +-
- 2 files changed, 6 insertions(+), 3 deletions(-)
+ src/ap/hostapd.c      | 11 ++++++++++-
+ wpa_supplicant/mesh.c | 13 +++++++------
+ 2 files changed, 17 insertions(+), 7 deletions(-)
 
+--- a/src/ap/hostapd.c
++++ b/src/ap/hostapd.c
+@@ -414,6 +414,8 @@ static void hostapd_free_hapd_data(struc
+ #ifdef CONFIG_MESH
+ 	wpabuf_free(hapd->mesh_pending_auth);
+ 	hapd->mesh_pending_auth = NULL;
++	/* handling setup failure is already done */
++	hapd->setup_complete_cb = NULL;
+ #endif /* CONFIG_MESH */
+ 
+ 	hostapd_clean_rrm(hapd);
+@@ -1980,6 +1982,13 @@ dfs_offload:
+ 	if (hapd->setup_complete_cb)
+ 		hapd->setup_complete_cb(hapd->setup_complete_cb_ctx);
+ 
++#ifdef CONFIG_MESH
++	if (delay_apply_cfg && !iface->mconf) {
++		wpa_printf(MSG_ERROR, "Error while completing mesh init");
++		goto fail;
++	}
++#endif /* CONFIG_MESH */
++
+ 	wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
+ 		   iface->bss[0]->conf->iface);
+ 	if (iface->interfaces && iface->interfaces->terminate_on_error > 0)
+@@ -2123,7 +2132,7 @@ int hostapd_setup_interface(struct hosta
+ 	ret = setup_interface(iface);
+ 	if (ret) {
+ 		wpa_printf(MSG_ERROR, "%s: Unable to setup interface.",
+-			   iface->bss[0]->conf->iface);
++			   iface->conf ? iface->conf->bss[0]->iface : "N/A");
+ 		return -1;
+ 	}
+ 
 --- a/wpa_supplicant/mesh.c
 +++ b/wpa_supplicant/mesh.c
-@@ -217,6 +217,7 @@ static int wpa_supplicant_mesh_init(stru
+@@ -190,8 +190,9 @@ static int wpas_mesh_init_rsn(struct wpa
+ }
+ 
+ 
+-static int wpas_mesh_complete(struct wpa_supplicant *wpa_s)
++static void wpas_mesh_complete_cb(void *ctx)
+ {
++	struct wpa_supplicant *wpa_s = ctx;
+ 	struct hostapd_iface *ifmsh = wpa_s->ifmsh;
+ 	struct wpa_driver_mesh_join_params *params = wpa_s->mesh_params;
+ 	struct wpa_ssid *ssid = wpa_s->current_ssid;
+@@ -200,7 +201,7 @@ static int wpas_mesh_complete(struct wpa
+ 	if (!params || !ssid || !ifmsh) {
+ 		wpa_printf(MSG_ERROR, "mesh: %s called without active mesh",
+ 			   __func__);
+-		return -1;
++		return;
+ 	}
+ 
+ 	if (ifmsh->mconf->security != MESH_CONF_SEC_NONE &&
+@@ -208,7 +209,7 @@ static int wpas_mesh_complete(struct wpa
+ 		wpa_printf(MSG_ERROR,
+ 			   "mesh: RSN initialization failed - deinit mesh");
+ 		wpa_supplicant_mesh_deinit(wpa_s);
+-		return -1;
++		return;
+ 	}
+ 
+ 	if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
+@@ -234,8 +235,6 @@ static int wpas_mesh_complete(struct wpa
+ 
+ 	if (!ret)
+ 		wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
+-
+-	return ret;
+ }
+ 
+ 
+@@ -262,6 +261,7 @@ static int wpa_supplicant_mesh_init(stru
  	if (!ifmsh)
  		return -ENOMEM;
  
@@ -32,7 +105,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
  	ifmsh->drv_flags = wpa_s->drv_flags;
  	ifmsh->num_bss = 1;
  	ifmsh->bss = os_calloc(wpa_s->ifmsh->num_bss,
-@@ -234,6 +235,8 @@ static int wpa_supplicant_mesh_init(stru
+@@ -279,6 +279,8 @@ static int wpa_supplicant_mesh_init(stru
  	bss->drv_priv = wpa_s->drv_priv;
  	bss->iface = ifmsh;
  	bss->mesh_sta_free_cb = mesh_mpm_free_sta;
@@ -41,33 +114,11 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
  	frequency = ssid->frequency;
  	if (frequency != freq->freq &&
  	    frequency == freq->freq + freq->sec_channel_offset * 20) {
-@@ -375,8 +378,9 @@ void wpa_supplicant_mesh_add_scan_ie(str
- }
- 
- 
--void wpas_join_mesh(struct wpa_supplicant *wpa_s)
-+void wpas_mesh_complete_cb(void *ctx)
- {
-+	struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)ctx;
- 	struct wpa_driver_mesh_join_params *params = wpa_s->mesh_params;
- 	struct wpa_ssid *ssid = wpa_s->current_ssid;
- 	int ret = 0;
-@@ -498,7 +502,6 @@ int wpa_supplicant_join_mesh(struct wpa_
+@@ -517,7 +519,6 @@ int wpa_supplicant_join_mesh(struct wpa_
  		goto out;
  	}
  
--	wpas_join_mesh(wpa_s);
+-	ret = wpas_mesh_complete(wpa_s);
  out:
  	return ret;
  }
---- a/wpa_supplicant/mesh.h
-+++ b/wpa_supplicant/mesh.h
-@@ -21,7 +21,7 @@ int wpas_mesh_add_interface(struct wpa_s
- int wpas_mesh_peer_remove(struct wpa_supplicant *wpa_s, const u8 *addr);
- int wpas_mesh_peer_add(struct wpa_supplicant *wpa_s, const u8 *addr,
- 		       int duration);
--void wpas_join_mesh(struct wpa_supplicant *wpa_s);
-+void wpas_mesh_complete_cb(void *ctx);
- int wpas_mesh_init_rsn(struct wpa_supplicant *wpa_s);
- 
- #ifdef CONFIG_MESH
diff --git a/package/network/services/hostapd/patches/005-mesh-reflect-country-setting-to-mesh-configuration.patch b/package/network/services/hostapd/patches/005-mesh-reflect-country-setting-to-mesh-configuration.patch
deleted file mode 100644
index a372230d07..0000000000
--- a/package/network/services/hostapd/patches/005-mesh-reflect-country-setting-to-mesh-configuration.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From dbe9afab3b2dceb35d478ac43dfcf8fdc5e23a22 Mon Sep 17 00:00:00 2001
-From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:09 -0700
-Subject: [PATCH 05/18] mesh: reflect country setting to mesh configuration
-
-wpa_supplicant configuration has country parameter that is
-supposed to be used in AP mode to indicate supporting 802.11h
-and 802.11d. Reflect this configuration to Mesh also since Mesh
-is required to support 802.11h and 802.11d to use DFS channels.
-
-Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-[daniel@makrotopia.org: adapted to changed ieee80211_is_dfs prototype]
----
- wpa_supplicant/mesh.c | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
---- a/wpa_supplicant/mesh.c
-+++ b/wpa_supplicant/mesh.c
-@@ -255,6 +255,15 @@ static int wpa_supplicant_mesh_init(stru
- 	bss->conf->start_disabled = 1;
- 	bss->conf->mesh = MESH_ENABLED;
- 	bss->conf->ap_max_inactivity = wpa_s->conf->mesh_max_inactivity;
-+
-+	if (ieee80211_is_dfs(ssid->frequency, wpa_s->hw.modes,
-+			     wpa_s->hw.num_modes) && wpa_s->conf->country[0]) {
-+		conf->ieee80211h = 1;
-+		conf->ieee80211d = 1;
-+		conf->country[0] = wpa_s->conf->country[0];
-+		conf->country[1] = wpa_s->conf->country[1];
-+	}
-+
- 	bss->iconf = conf;
- 	ifmsh->conf = conf;
- 
diff --git a/package/network/services/hostapd/patches/005-mesh-update-ssid-frequency-as-pri-sec-channel-switch.patch b/package/network/services/hostapd/patches/005-mesh-update-ssid-frequency-as-pri-sec-channel-switch.patch
new file mode 100644
index 0000000000..703c81d04c
--- /dev/null
+++ b/package/network/services/hostapd/patches/005-mesh-update-ssid-frequency-as-pri-sec-channel-switch.patch
@@ -0,0 +1,26 @@
+From c56f18380d1d404a2abc0ea5373d294508ef1e54 Mon Sep 17 00:00:00 2001
+From: Peter Oh <peter.oh@bowerswilkins.com>
+Date: Mon, 27 Aug 2018 14:28:41 -0700
+Subject: [PATCH 2/7] mesh: update ssid->frequency as pri/sec channel switch
+
+ssid->frequency is one of variables used to gets channel
+number from given frequency. Leave it as unchanged when
+pri/sec channel switched will cause picking up wrong
+channel number after applying secondary channel offset
+for HT40 and leads failing interface bring-up.
+
+Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
+---
+ wpa_supplicant/mesh.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/wpa_supplicant/mesh.c
++++ b/wpa_supplicant/mesh.c
+@@ -286,6 +286,7 @@ static int wpa_supplicant_mesh_init(stru
+ 	    frequency == freq->freq + freq->sec_channel_offset * 20) {
+ 		wpa_printf(MSG_DEBUG, "mesh: pri/sec channels switched");
+ 		frequency = freq->freq;
++		ssid->frequency = frequency;
+ 	}
+ 	wpa_s->assoc_freq = frequency;
+ 	wpa_s->current_ssid = ssid;
diff --git a/package/network/services/hostapd/patches/006-mesh-inform-kernel-driver-DFS-handler-in-userspace.patch b/package/network/services/hostapd/patches/006-mesh-inform-kernel-driver-DFS-handler-in-userspace.patch
index 5ec7aa0837..fb7772d481 100644
--- a/package/network/services/hostapd/patches/006-mesh-inform-kernel-driver-DFS-handler-in-userspace.patch
+++ b/package/network/services/hostapd/patches/006-mesh-inform-kernel-driver-DFS-handler-in-userspace.patch
@@ -1,7 +1,7 @@
-From 51e759da5026b3e64f801135b5d53f2198bbd2f0 Mon Sep 17 00:00:00 2001
+From 593602b7f14be5c2695979639764b1c50f01bbec Mon Sep 17 00:00:00 2001
 From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:10 -0700
-Subject: [PATCH 06/18] mesh: inform kernel driver DFS handler in userspace
+Date: Mon, 27 Aug 2018 14:28:49 -0700
+Subject: [PATCH 7/7] mesh: inform kernel driver DFS handler in userspace
 
 NL80211_ATTR_HANDLE_DFS is required by kerenel space
 to enable DFS channels that indicates DFS handler
@@ -16,7 +16,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
 
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -1402,6 +1402,7 @@ struct wpa_driver_mesh_join_params {
+@@ -1436,6 +1436,7 @@ struct wpa_driver_mesh_join_params {
  #define WPA_DRIVER_MESH_FLAG_SAE_AUTH	0x00000004
  #define WPA_DRIVER_MESH_FLAG_AMPE	0x00000008
  	unsigned int flags;
@@ -26,7 +26,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
  /**
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -9375,6 +9375,9 @@ static int nl80211_join_mesh(struct i802
+@@ -9544,6 +9544,9 @@ static int nl80211_join_mesh(struct i802
  
  	wpa_printf(MSG_DEBUG, "  * flags=%08X", params->flags);
  
@@ -38,10 +38,10 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
  		goto fail;
 --- a/wpa_supplicant/mesh.c
 +++ b/wpa_supplicant/mesh.c
-@@ -262,6 +262,7 @@ static int wpa_supplicant_mesh_init(stru
- 		conf->ieee80211d = 1;
+@@ -308,6 +308,7 @@ static int wpa_supplicant_mesh_init(stru
  		conf->country[0] = wpa_s->conf->country[0];
  		conf->country[1] = wpa_s->conf->country[1];
+ 		conf->country[2] = ' ';
 +		wpa_s->mesh_params->handle_dfs = 1;
  	}
  
diff --git a/package/network/services/hostapd/patches/007-mesh-apply-channel-attributes-before-running-Mesh.patch b/package/network/services/hostapd/patches/007-mesh-apply-channel-attributes-before-running-Mesh.patch
deleted file mode 100644
index de11495388..0000000000
--- a/package/network/services/hostapd/patches/007-mesh-apply-channel-attributes-before-running-Mesh.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From bdc77efe681d5b88f3256e2bb6e706d4eaf09518 Mon Sep 17 00:00:00 2001
-From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:11 -0700
-Subject: [PATCH 07/18] mesh: apply channel attributes before running Mesh
-
-This helps mesh interface initializes with correct
-channel parameters.
-
-Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
----
- wpa_supplicant/mesh.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/wpa_supplicant/mesh.c
-+++ b/wpa_supplicant/mesh.c
-@@ -338,6 +338,8 @@ static int wpa_supplicant_mesh_init(stru
- 		conf->basic_rates[rate_len] = -1;
- 	}
- 
-+	wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf);
-+
- 	if (hostapd_setup_interface(ifmsh)) {
- 		wpa_printf(MSG_ERROR,
- 			   "Failed to initialize hostapd interface for mesh");
-@@ -349,8 +351,6 @@ static int wpa_supplicant_mesh_init(stru
- 		return -1;
- 	}
- 
--	wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf);
--
- 	return 0;
- out_free:
- 	wpa_supplicant_mesh_deinit(wpa_s);
diff --git a/package/network/services/hostapd/patches/008-mesh-set-interface-type-to-mesh-before-setting-inter.patch b/package/network/services/hostapd/patches/008-mesh-set-interface-type-to-mesh-before-setting-inter.patch
deleted file mode 100644
index 5b97691eb9..0000000000
--- a/package/network/services/hostapd/patches/008-mesh-set-interface-type-to-mesh-before-setting-inter.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From eb9888ba41faaeb8fd07392ad46808b7d894cc14 Mon Sep 17 00:00:00 2001
-From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:12 -0700
-Subject: [PATCH 08/18] mesh: set interface type to mesh before setting
- interface
-
-Correct interface type is required to start DFS CAC that can be
-triggered during interface setup.
-
-Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
----
- wpa_supplicant/mesh.c | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
---- a/wpa_supplicant/mesh.c
-+++ b/wpa_supplicant/mesh.c
-@@ -340,14 +340,14 @@ static int wpa_supplicant_mesh_init(stru
- 
- 	wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf);
- 
--	if (hostapd_setup_interface(ifmsh)) {
--		wpa_printf(MSG_ERROR,
--			   "Failed to initialize hostapd interface for mesh");
-+	if (wpa_drv_init_mesh(wpa_s)) {
-+		wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh in driver");
- 		return -1;
- 	}
- 
--	if (wpa_drv_init_mesh(wpa_s)) {
--		wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh in driver");
-+	if (hostapd_setup_interface(ifmsh)) {
-+		wpa_printf(MSG_ERROR,
-+			   "Failed to initialize hostapd interface for mesh");
- 		return -1;
- 	}
- 
diff --git a/package/network/services/hostapd/patches/009-mesh-set-mesh-center-frequency.patch b/package/network/services/hostapd/patches/009-mesh-set-mesh-center-frequency.patch
deleted file mode 100644
index 1fca7452b0..0000000000
--- a/package/network/services/hostapd/patches/009-mesh-set-mesh-center-frequency.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From fa3af966032267e618b19bbf06a536ddb81ddbdf Mon Sep 17 00:00:00 2001
-From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:13 -0700
-Subject: [PATCH 09/18] mesh: set mesh center frequency
-
-vht center frequency value is required to compose the correct channel info.
-
-Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
----
- wpa_supplicant/mesh.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/wpa_supplicant/mesh.c
-+++ b/wpa_supplicant/mesh.c
-@@ -457,6 +457,7 @@ int wpa_supplicant_join_mesh(struct wpa_
- 
- 	if (wpa_s->mesh_vht_enabled) {
- 		ssid->vht = 1;
-+		ssid->vht_center_freq1 = params->freq.center_freq1;
- 		switch (params->freq.bandwidth) {
- 		case 80:
- 			if (params->freq.center_freq2) {
diff --git a/package/network/services/hostapd/patches/010-mesh-consider-mesh-interface-on-dfs-event-handler.patch b/package/network/services/hostapd/patches/010-mesh-consider-mesh-interface-on-dfs-event-handler.patch
deleted file mode 100644
index 0c82d84d6b..0000000000
--- a/package/network/services/hostapd/patches/010-mesh-consider-mesh-interface-on-dfs-event-handler.patch
+++ /dev/null
@@ -1,176 +0,0 @@
-From 9a8ca54a264a2820af614043e7af853166b320b0 Mon Sep 17 00:00:00 2001
-From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:14 -0700
-Subject: [PATCH 10/18] mesh: consider mesh interface on dfs event handler
-
-Once mesh starts supporting DFS channels, it has to handle DFS related events
-from drivers, hence add mesh interface to the check list.
-
-Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
-Signed-off-by: Masashi Honma <masashi.honma@gmail.com>
----
- wpa_supplicant/ap.c     | 71 ++++++++++++++++++++++++++++++-----------
- wpa_supplicant/events.c |  7 ++--
- 2 files changed, 57 insertions(+), 21 deletions(-)
-
---- a/wpa_supplicant/ap.c
-+++ b/wpa_supplicant/ap.c
-@@ -1379,13 +1379,18 @@ int ap_ctrl_iface_chanswitch(struct wpa_
- void wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int ht,
- 		       int offset, int width, int cf1, int cf2)
- {
--	if (!wpa_s->ap_iface)
--		return;
-+	struct hostapd_iface *iface = wpa_s->ap_iface;
- 
-+	if (!wpa_s->ap_iface) {
-+		if (!wpa_s->ifmsh)
-+			return;
-+		else
-+			iface = wpa_s->ifmsh;
-+	}
- 	wpa_s->assoc_freq = freq;
- 	if (wpa_s->current_ssid)
- 		wpa_s->current_ssid->frequency = freq;
--	hostapd_event_ch_switch(wpa_s->ap_iface->bss[0], freq, ht,
-+	hostapd_event_ch_switch(iface->bss[0], freq, ht,
- 				offset, width, cf1, cf2);
- }
- 
-@@ -1582,10 +1587,16 @@ int wpas_ap_pmksa_cache_add_external(str
- void wpas_ap_event_dfs_radar_detected(struct wpa_supplicant *wpa_s,
- 				      struct dfs_event *radar)
- {
--	if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
--		return;
-+	struct hostapd_iface *iface = wpa_s->ap_iface;
-+
-+	if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) {
-+		if (!wpa_s->ifmsh || !wpa_s->ifmsh->bss[0])
-+			return;
-+		else
-+			iface = wpa_s->ifmsh;
-+	}
- 	wpa_printf(MSG_DEBUG, "DFS radar detected on %d MHz", radar->freq);
--	hostapd_dfs_radar_detected(wpa_s->ap_iface, radar->freq,
-+	hostapd_dfs_radar_detected(iface, radar->freq,
- 				   radar->ht_enabled, radar->chan_offset,
- 				   radar->chan_width,
- 				   radar->cf1, radar->cf2);
-@@ -1595,10 +1606,16 @@ void wpas_ap_event_dfs_radar_detected(st
- void wpas_ap_event_dfs_cac_started(struct wpa_supplicant *wpa_s,
- 				   struct dfs_event *radar)
- {
--	if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
--		return;
-+	struct hostapd_iface *iface = wpa_s->ap_iface;
-+
-+	if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) {
-+		if (!wpa_s->ifmsh || !wpa_s->ifmsh->bss[0])
-+			return;
-+		else
-+			iface = wpa_s->ifmsh;
-+	}
- 	wpa_printf(MSG_DEBUG, "DFS CAC started on %d MHz", radar->freq);
--	hostapd_dfs_start_cac(wpa_s->ap_iface, radar->freq,
-+	hostapd_dfs_start_cac(iface, radar->freq,
- 			      radar->ht_enabled, radar->chan_offset,
- 			      radar->chan_width, radar->cf1, radar->cf2);
- }
-@@ -1607,10 +1624,16 @@ void wpas_ap_event_dfs_cac_started(struc
- void wpas_ap_event_dfs_cac_finished(struct wpa_supplicant *wpa_s,
- 				    struct dfs_event *radar)
- {
--	if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
--		return;
-+	struct hostapd_iface *iface = wpa_s->ap_iface;
-+
-+	if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) {
-+		if (!wpa_s->ifmsh || !wpa_s->ifmsh->bss[0])
-+			return;
-+		else
-+			iface = wpa_s->ifmsh;
-+	}
- 	wpa_printf(MSG_DEBUG, "DFS CAC finished on %d MHz", radar->freq);
--	hostapd_dfs_complete_cac(wpa_s->ap_iface, 1, radar->freq,
-+	hostapd_dfs_complete_cac(iface, 1, radar->freq,
- 				 radar->ht_enabled, radar->chan_offset,
- 				 radar->chan_width, radar->cf1, radar->cf2);
- }
-@@ -1619,10 +1642,16 @@ void wpas_ap_event_dfs_cac_finished(stru
- void wpas_ap_event_dfs_cac_aborted(struct wpa_supplicant *wpa_s,
- 				   struct dfs_event *radar)
- {
--	if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
--		return;
-+	struct hostapd_iface *iface = wpa_s->ap_iface;
-+
-+	if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) {
-+		if (!wpa_s->ifmsh || !wpa_s->ifmsh->bss[0])
-+			return;
-+		else
-+			iface = wpa_s->ifmsh;
-+	}
- 	wpa_printf(MSG_DEBUG, "DFS CAC aborted on %d MHz", radar->freq);
--	hostapd_dfs_complete_cac(wpa_s->ap_iface, 0, radar->freq,
-+	hostapd_dfs_complete_cac(iface, 0, radar->freq,
- 				 radar->ht_enabled, radar->chan_offset,
- 				 radar->chan_width, radar->cf1, radar->cf2);
- }
-@@ -1631,10 +1660,16 @@ void wpas_ap_event_dfs_cac_aborted(struc
- void wpas_ap_event_dfs_cac_nop_finished(struct wpa_supplicant *wpa_s,
- 					struct dfs_event *radar)
- {
--	if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
--		return;
-+	struct hostapd_iface *iface = wpa_s->ap_iface;
-+
-+	if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) {
-+		if (!wpa_s->ifmsh || !wpa_s->ifmsh->bss[0])
-+			return;
-+		else
-+			iface = wpa_s->ifmsh;
-+	}
- 	wpa_printf(MSG_DEBUG, "DFS NOP finished on %d MHz", radar->freq);
--	hostapd_dfs_nop_finished(wpa_s->ap_iface, radar->freq,
-+	hostapd_dfs_nop_finished(iface, radar->freq,
- 				 radar->ht_enabled, radar->chan_offset,
- 				 radar->chan_width, radar->cf1, radar->cf2);
- }
---- a/wpa_supplicant/events.c
-+++ b/wpa_supplicant/events.c
-@@ -3840,7 +3840,7 @@ static void wpas_event_dfs_cac_started(s
- 				       struct dfs_event *radar)
- {
- #if defined(NEED_AP_MLME) && defined(CONFIG_AP)
--	if (wpa_s->ap_iface) {
-+	if (wpa_s->ap_iface || wpa_s->ifmsh) {
- 		wpas_ap_event_dfs_cac_started(wpa_s, radar);
- 	} else
- #endif /* NEED_AP_MLME && CONFIG_AP */
-@@ -3861,7 +3861,7 @@ static void wpas_event_dfs_cac_finished(
- 					struct dfs_event *radar)
- {
- #if defined(NEED_AP_MLME) && defined(CONFIG_AP)
--	if (wpa_s->ap_iface) {
-+	if (wpa_s->ap_iface || wpa_s->ifmsh) {
- 		wpas_ap_event_dfs_cac_finished(wpa_s, radar);
- 	} else
- #endif /* NEED_AP_MLME && CONFIG_AP */
-@@ -3877,7 +3877,7 @@ static void wpas_event_dfs_cac_aborted(s
- 				       struct dfs_event *radar)
- {
- #if defined(NEED_AP_MLME) && defined(CONFIG_AP)
--	if (wpa_s->ap_iface) {
-+	if (wpa_s->ap_iface || wpa_s->ifmsh) {
- 		wpas_ap_event_dfs_cac_aborted(wpa_s, radar);
- 	} else
- #endif /* NEED_AP_MLME && CONFIG_AP */
-@@ -4328,6 +4328,7 @@ void wpa_supplicant_event(void *ctx, enu
- #ifdef CONFIG_AP
- 		if (wpa_s->current_ssid->mode == WPAS_MODE_AP ||
- 		    wpa_s->current_ssid->mode == WPAS_MODE_P2P_GO ||
-+		    wpa_s->current_ssid->mode == WPAS_MODE_MESH ||
- 		    wpa_s->current_ssid->mode ==
- 		    WPAS_MODE_P2P_GROUP_FORMATION) {
- 			wpas_ap_ch_switch(wpa_s, data->ch_switch.freq,
diff --git a/package/network/services/hostapd/patches/011-mesh-Allow-DFS-channels-to-be-selected-if-dfs-is-ena.patch b/package/network/services/hostapd/patches/011-mesh-Allow-DFS-channels-to-be-selected-if-dfs-is-ena.patch
index 184b6e9e9d..e3afc97f82 100644
--- a/package/network/services/hostapd/patches/011-mesh-Allow-DFS-channels-to-be-selected-if-dfs-is-ena.patch
+++ b/package/network/services/hostapd/patches/011-mesh-Allow-DFS-channels-to-be-selected-if-dfs-is-ena.patch
@@ -1,8 +1,7 @@
-From bbaa6142eadf229334436fdbf51aa65bb819f771 Mon Sep 17 00:00:00 2001
+From 89fa0d75fb1be82330258082ed3d7fd452eb6076 Mon Sep 17 00:00:00 2001
 From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:15 -0700
-Subject: [PATCH 11/18] mesh: Allow DFS channels to be selected if dfs is
- enabled
+Date: Mon, 27 Aug 2018 14:28:45 -0700
+Subject: [PATCH 3/7] mesh: Allow DFS channels to be selected if dfs is enabled
 
 Note: DFS is assumed to be usable if a country code has been set
 
@@ -14,7 +13,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
 
 --- a/wpa_supplicant/wpa_supplicant.c
 +++ b/wpa_supplicant/wpa_supplicant.c
-@@ -2090,6 +2090,8 @@ void ibss_mesh_setup_freq(struct wpa_sup
+@@ -2148,6 +2148,8 @@ void ibss_mesh_setup_freq(struct wpa_sup
  	struct hostapd_freq_params vht_freq;
  	int chwidth, seg0, seg1;
  	u32 vht_caps = 0;
@@ -23,7 +22,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
  
  	freq->freq = ssid->frequency;
  
-@@ -2166,8 +2168,11 @@ void ibss_mesh_setup_freq(struct wpa_sup
+@@ -2224,8 +2226,11 @@ void ibss_mesh_setup_freq(struct wpa_sup
  		return;
  
  	/* Check primary channel flags */
@@ -34,9 +33,9 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
 +		if (!dfs_enabled)
 +			return;
  
- #ifdef CONFIG_HT_OVERRIDES
- 	if (ssid->disable_ht40)
-@@ -2193,8 +2198,11 @@ void ibss_mesh_setup_freq(struct wpa_sup
+ 	freq->channel = pri_chan->chan;
+ 
+@@ -2256,8 +2261,11 @@ void ibss_mesh_setup_freq(struct wpa_sup
  		return;
  
  	/* Check secondary channel flags */
@@ -47,9 +46,9 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
 +		if (!dfs_enabled)
 +			return;
  
- 	freq->channel = pri_chan->chan;
- 
-@@ -2284,8 +2292,11 @@ void ibss_mesh_setup_freq(struct wpa_sup
+ 	if (ht40 == -1) {
+ 		if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS))
+@@ -2348,8 +2356,11 @@ skip_ht40:
  			return;
  
  		/* Back to HT configuration if channel not usable */
@@ -62,7 +61,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
  	}
  
  	chwidth = VHT_CHANWIDTH_80MHZ;
-@@ -2305,10 +2316,11 @@ void ibss_mesh_setup_freq(struct wpa_sup
+@@ -2369,10 +2380,11 @@ skip_ht40:
  				if (!chan)
  					continue;
  
diff --git a/package/network/services/hostapd/patches/013-mesh-do-not-allow-pri-sec-channel-switch.patch b/package/network/services/hostapd/patches/013-mesh-do-not-allow-pri-sec-channel-switch.patch
index 2d818b0835..db0aa77975 100644
--- a/package/network/services/hostapd/patches/013-mesh-do-not-allow-pri-sec-channel-switch.patch
+++ b/package/network/services/hostapd/patches/013-mesh-do-not-allow-pri-sec-channel-switch.patch
@@ -1,27 +1,29 @@
-From 267395271c1a36b54ef21070acff2cadce241035 Mon Sep 17 00:00:00 2001
+From 4f4a9b9e2e61fba334a21dadea749e4b440f42e6 Mon Sep 17 00:00:00 2001
 From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:17 -0700
-Subject: [PATCH 13/18] mesh: do not allow pri/sec channel switch
+Date: Mon, 27 Aug 2018 14:28:48 -0700
+Subject: [PATCH 6/7] mesh: don't allow pri/sec channel switch
 
-We don't want mesh to switch the channel from primary to secondary,
-since mesh points are not able to join each other in that case.
+This limitation isn't backed by standard, but it is known that
+mesh doesn't have capability to handle 20/40 coex change in
+current implementation and it will not able to establish
+PLINK when channel switch between primary and secondary happens.
+
+Since it's unknown when we will have the implementation of handling
+20/40 coex change for mesh, it'd better to avoid them from happening
+until standard based implementation is introduced.
 
 Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
 ---
- wpa_supplicant/mesh.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
+ wpa_supplicant/mesh.c | 1 +
+ 1 file changed, 1 insertion(+)
 
 --- a/wpa_supplicant/mesh.c
 +++ b/wpa_supplicant/mesh.c
-@@ -337,7 +337,10 @@ static int wpa_supplicant_mesh_init(stru
- 			  rate_len * sizeof(int));
- 		conf->basic_rates[rate_len] = -1;
+@@ -396,6 +396,7 @@ static int wpa_supplicant_mesh_init(stru
+ 		return -1;
  	}
--
-+	/* Do not allow primary/secondary channel switch in mesh mode,
-+	  * since mesh is not able to establish a physical link for it
-+	  */
+ 
 +	conf->no_pri_sec_switch = 1;
  	wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf);
  
- 	if (wpa_drv_init_mesh(wpa_s)) {
+ 	return 0;
diff --git a/package/network/services/hostapd/patches/014-mesh-do-not-allow-scan-result-to-swap-pri-sec.patch b/package/network/services/hostapd/patches/014-mesh-do-not-allow-scan-result-to-swap-pri-sec.patch
deleted file mode 100644
index afcbcbb0ad..0000000000
--- a/package/network/services/hostapd/patches/014-mesh-do-not-allow-scan-result-to-swap-pri-sec.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From f95897cef614fff710c31d9e478eacc85d6312d5 Mon Sep 17 00:00:00 2001
-From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:18 -0700
-Subject: [PATCH 14/18] mesh: do not allow scan result to swap pri/sec
-
-Swapping between primary and secondary channel will break
-mesh from joining, hence don't allow it.
-
-Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
----
- wpa_supplicant/wpa_supplicant.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/wpa_supplicant/wpa_supplicant.c
-+++ b/wpa_supplicant/wpa_supplicant.c
-@@ -2215,7 +2215,7 @@ void ibss_mesh_setup_freq(struct wpa_sup
- 	}
- 	freq->sec_channel_offset = ht40;
- 
--	if (obss_scan) {
-+	if (ssid->mode != WPAS_MODE_MESH && obss_scan) {
- 		struct wpa_scan_results *scan_res;
- 
- 		scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0);
diff --git a/package/network/services/hostapd/patches/015-mesh-do-not-use-offchan-mgmt-tx-on-DFS.patch b/package/network/services/hostapd/patches/015-mesh-do-not-use-offchan-mgmt-tx-on-DFS.patch
index c921436925..f1922552f6 100644
--- a/package/network/services/hostapd/patches/015-mesh-do-not-use-offchan-mgmt-tx-on-DFS.patch
+++ b/package/network/services/hostapd/patches/015-mesh-do-not-use-offchan-mgmt-tx-on-DFS.patch
@@ -1,44 +1,56 @@
-From 9423e8be0393e82c8622806a0529e47fd5583c0b Mon Sep 17 00:00:00 2001
+From 71e9c65a7c8af90a5fd11072062b596421316452 Mon Sep 17 00:00:00 2001
 From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:19 -0700
-Subject: [PATCH 15/18] mesh: do not use offchan mgmt tx on DFS
+Date: Mon, 27 Aug 2018 14:28:46 -0700
+Subject: [PATCH 4/7] mesh: do not set offchanok on DFS channels in non-ETSI
 
-Drivers don't allow mesh to use offchannel on management Tx.
+mac80211 does not allow mgmt tx to use off channel on
+DFS channels in non-ETSI domain, because it will invalidate
+CAC result on current operating channel.
+(mac80211 commit: 34373d12f3cbb74960a73431138ef619d857996f)
+Hence don't set offchanok for mgmt tx in case of DFS channels
+in non-ETSI.
 
 Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-[daniel@makrotopia.org: adapted to changed ieee80211_is_dfs prototype]
 ---
- src/drivers/driver_nl80211.c | 12 ++++++++++--
- 1 file changed, 10 insertions(+), 2 deletions(-)
+ src/drivers/driver_nl80211.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
 
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -7268,6 +7268,10 @@ static int wpa_driver_nl80211_send_actio
- 	struct wpa_driver_nl80211_data *drv = bss->drv;
+@@ -7411,6 +7411,10 @@ static int wpa_driver_nl80211_send_actio
  	int ret = -1;
  	u8 *buf;
-+	int offchanok = 1;
-+	u16 num_modes, flags;
+ 	struct ieee80211_hdr *hdr;
 +	struct hostapd_hw_modes *modes;
++	int i, offchanok = 1;
++	u16 num_modes, flags;
 +	u8 dfs_domain;
- 	struct ieee80211_hdr *hdr;
  
  	wpa_printf(MSG_DEBUG, "nl80211: Send Action frame (ifindex=%d, "
-@@ -7292,7 +7296,11 @@ static int wpa_driver_nl80211_send_actio
- 	} else {
+ 		   "freq=%u MHz wait=%d ms no_cck=%d)",
+@@ -7435,6 +7439,21 @@ static int wpa_driver_nl80211_send_actio
  		os_memset(bss->rand_addr, 0, ETH_ALEN);
  	}
--
-+	if (is_mesh_interface(drv->nlmode) &&
-+	    (modes = nl80211_get_hw_feature_data(bss, &num_modes, &flags,
-+						 &dfs_domain)) &&
-+	    ieee80211_is_dfs(freq, modes, num_modes))
-+		offchanok = 0;
+ 
++	if (is_mesh_interface(drv->nlmode)) {
++		modes = nl80211_get_hw_feature_data(bss, &num_modes,
++						    &flags, &dfs_domain);
++		if (dfs_domain != HOSTAPD_DFS_REGION_ETSI &&
++		    ieee80211_is_dfs(bss->freq, modes, num_modes))
++			offchanok = 0;
++		if (modes) {
++			for (i = 0; i < num_modes; i++) {
++				os_free(modes[i].channels);
++				os_free(modes[i].rates);
++			}
++			os_free(modes);
++		}
++	}
++
  	if (is_ap_interface(drv->nlmode) &&
  	    (!(drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) ||
  	     (int) freq == bss->freq || drv->device_ap_sme ||
-@@ -7304,7 +7312,7 @@ static int wpa_driver_nl80211_send_actio
+@@ -7446,7 +7465,7 @@ static int wpa_driver_nl80211_send_actio
  		ret = nl80211_send_frame_cmd(bss, freq, wait_time, buf,
  					     24 + data_len,
  					     &drv->send_action_cookie,
diff --git a/package/network/services/hostapd/patches/016-mesh-fix-channel-switch-error-during-CAC.patch b/package/network/services/hostapd/patches/016-mesh-fix-channel-switch-error-during-CAC.patch
index 5071ae5151..1a8b291949 100644
--- a/package/network/services/hostapd/patches/016-mesh-fix-channel-switch-error-during-CAC.patch
+++ b/package/network/services/hostapd/patches/016-mesh-fix-channel-switch-error-during-CAC.patch
@@ -1,7 +1,7 @@
-From fa9d565fe8841b288f29137c23a7ab2584dd9510 Mon Sep 17 00:00:00 2001
+From 5913d6e2a741683e7c747c046f72ca790bbe1337 Mon Sep 17 00:00:00 2001
 From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:20 -0700
-Subject: [PATCH 16/18] mesh: fix channel switch error during CAC
+Date: Mon, 27 Aug 2018 14:28:47 -0700
+Subject: [PATCH 5/7] mesh: fix channel switch error during CAC
 
 Mesh interface has used its channel parameters that configured
 during its initialization even after channel switched due to
@@ -10,30 +10,23 @@ This change fixes the error by updating its channel parameters
 when channel's been changed from initial one.
 
 Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-[daniel@makrotopia.org: added hw_features_common.h include]
 ---
  wpa_supplicant/mesh.c | 25 +++++++++++++++++++++++++
  1 file changed, 25 insertions(+)
 
 --- a/wpa_supplicant/mesh.c
 +++ b/wpa_supplicant/mesh.c
-@@ -11,6 +11,7 @@
- #include "utils/common.h"
- #include "utils/eloop.h"
+@@ -13,6 +13,7 @@
  #include "utils/uuid.h"
-+#include "common/hw_features_common.h"
  #include "common/ieee802_11_defs.h"
  #include "common/wpa_ctrl.h"
++#include "common/hw_features_common.h"
  #include "ap/sta_info.h"
-@@ -394,10 +395,35 @@ void wpa_supplicant_mesh_add_scan_ie(str
- void wpas_mesh_complete_cb(void *ctx)
- {
- 	struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)ctx;
-+	struct hostapd_iface *ifmsh = wpa_s->ifmsh;
- 	struct wpa_driver_mesh_join_params *params = wpa_s->mesh_params;
- 	struct wpa_ssid *ssid = wpa_s->current_ssid;
- 	int ret = 0;
+ #include "ap/hostapd.h"
+ #include "ap/ieee802_11.h"
+@@ -204,6 +205,30 @@ static void wpas_mesh_complete_cb(void *
+ 		return;
+ 	}
  
 +	/*
 +	 * inspect if channel's been changed since initialized.
@@ -59,6 +52,6 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 +		}
 +	}
 +
- 	if (wpas_mesh_init_rsn(wpa_s)) {
- 		wpa_printf(MSG_ERROR, "Init RSN failed. Deinit mesh...");
- 		wpa_supplicant_mesh_deinit(wpa_s);
+ 	if (ifmsh->mconf->security != MESH_CONF_SEC_NONE &&
+ 	    wpas_mesh_init_rsn(wpa_s)) {
+ 		wpa_printf(MSG_ERROR,
diff --git a/package/network/services/hostapd/patches/017-mesh-use-right-interface-context-to-send-DFS-event-m.patch b/package/network/services/hostapd/patches/017-mesh-use-right-interface-context-to-send-DFS-event-m.patch
deleted file mode 100644
index a4073bb9fd..0000000000
--- a/package/network/services/hostapd/patches/017-mesh-use-right-interface-context-to-send-DFS-event-m.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-From d3201adfe7d2219217a07ef16ef365ad59c1a89b Mon Sep 17 00:00:00 2001
-From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:21 -0700
-Subject: [PATCH 17/18] mesh: use right interface context to send DFS event
- messages
-
-use mesh interface context to send DFS event messages when
-DFS events are on mesh interface.
-
-Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
-Signed-off-by: Masashi Honma <masashi.honma@gmail.com>
----
- src/ap/dfs.c | 27 +++++++++++++++++++--------
- 1 file changed, 19 insertions(+), 8 deletions(-)
-
---- a/src/ap/dfs.c
-+++ b/src/ap/dfs.c
-@@ -637,6 +637,17 @@ static unsigned int dfs_get_cac_time(str
- }
- 
- 
-+static void *get_message_ctx(struct hostapd_iface *iface)
-+{
-+#ifdef CONFIG_MESH
-+       if (iface->mconf)
-+               return iface->owner;
-+#endif /* CONFIG_MESH */
-+
-+       return iface->bss[0]->msg_ctx;
-+}
-+
-+
- /*
-  * Main DFS handler
-  * 1 - continue channel/ap setup
-@@ -719,7 +730,7 @@ int hostapd_handle_dfs(struct hostapd_if
- 	/* Finally start CAC */
- 	hostapd_set_state(iface, HAPD_IFACE_DFS);
- 	wpa_printf(MSG_DEBUG, "DFS start CAC on %d MHz", iface->freq);
--	wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_START
-+	wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_CAC_START
- 		"freq=%d chan=%d sec_chan=%d, width=%d, seg0=%d, seg1=%d, cac_time=%ds",
- 		iface->freq,
- 		iface->conf->channel, iface->conf->secondary_channel,
-@@ -768,7 +779,7 @@ int hostapd_dfs_complete_cac(struct host
- 			     int ht_enabled, int chan_offset, int chan_width,
- 			     int cf1, int cf2)
- {
--	wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_COMPLETED
-+	wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_CAC_COMPLETED
- 		"success=%d freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d",
- 		success, freq, ht_enabled, chan_offset, chan_width, cf1, cf2);
- 
-@@ -810,7 +821,7 @@ int hostapd_dfs_pre_cac_expired(struct h
- 				int ht_enabled, int chan_offset, int chan_width,
- 				int cf1, int cf2)
- {
--	wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_PRE_CAC_EXPIRED
-+	wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_PRE_CAC_EXPIRED
- 		"freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d",
- 		freq, ht_enabled, chan_offset, chan_width, cf1, cf2);
- 
-@@ -848,7 +859,7 @@ static int hostapd_dfs_start_channel_swi
- 
- 	wpa_printf(MSG_DEBUG, "DFS will switch to a new channel %d",
- 		   channel->chan);
--	wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NEW_CHANNEL
-+	wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_NEW_CHANNEL
- 		"freq=%d chan=%d sec_chan=%d", channel->freq,
- 		channel->chan, secondary_channel);
- 
-@@ -935,7 +946,7 @@ static int hostapd_dfs_start_channel_swi
- 
- 	wpa_printf(MSG_DEBUG, "DFS will switch to a new channel %d",
- 		   channel->chan);
--	wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NEW_CHANNEL
-+	wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_NEW_CHANNEL
- 		"freq=%d chan=%d sec_chan=%d", channel->freq,
- 		channel->chan, secondary_channel);
- 
-@@ -997,7 +1008,7 @@ int hostapd_dfs_radar_detected(struct ho
- {
- 	int res;
- 
--	wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_RADAR_DETECTED
-+	wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_RADAR_DETECTED
- 		"freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d",
- 		freq, ht_enabled, chan_offset, chan_width, cf1, cf2);
- 
-@@ -1028,7 +1039,7 @@ int hostapd_dfs_nop_finished(struct host
- 			     int ht_enabled, int chan_offset, int chan_width,
- 			     int cf1, int cf2)
- {
--	wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NOP_FINISHED
-+	wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_NOP_FINISHED
- 		"freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d",
- 		freq, ht_enabled, chan_offset, chan_width, cf1, cf2);
- 
-@@ -1078,7 +1089,7 @@ int hostapd_dfs_start_cac(struct hostapd
- 			  int ht_enabled, int chan_offset, int chan_width,
- 			  int cf1, int cf2)
- {
--	wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_START
-+	wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_CAC_START
- 		"freq=%d chan=%d chan_offset=%d width=%d seg0=%d "
- 		"seg1=%d cac_time=%ds",
- 		freq, (freq - 5000) / 5, chan_offset, chan_width, cf1, cf2, 60);
diff --git a/package/network/services/hostapd/patches/018-mesh-make-forwarding-configurable.patch b/package/network/services/hostapd/patches/018-mesh-make-forwarding-configurable.patch
index 2eb2d7de07..72e47e2914 100644
--- a/package/network/services/hostapd/patches/018-mesh-make-forwarding-configurable.patch
+++ b/package/network/services/hostapd/patches/018-mesh-make-forwarding-configurable.patch
@@ -23,7 +23,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
-@@ -49,6 +49,7 @@ struct mesh_conf {
+@@ -50,6 +50,7 @@ struct mesh_conf {
  	int dot11MeshRetryTimeout; /* msec */
  	int dot11MeshConfirmTimeout; /* msec */
  	int dot11MeshHoldingTimeout; /* msec */
@@ -31,7 +31,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  };
  
  #define MAX_STA_COUNT 2007
-@@ -628,6 +629,7 @@ struct hostapd_bss_config {
+@@ -645,6 +646,7 @@ struct hostapd_bss_config {
  
  #define MESH_ENABLED BIT(0)
  	int mesh;
@@ -41,7 +41,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -1375,6 +1375,7 @@ struct wpa_driver_mesh_bss_params {
+@@ -1409,6 +1409,7 @@ struct wpa_driver_mesh_bss_params {
  #define WPA_DRIVER_MESH_CONF_FLAG_MAX_PEER_LINKS	0x00000004
  #define WPA_DRIVER_MESH_CONF_FLAG_HT_OP_MODE		0x00000008
  #define WPA_DRIVER_MESH_CONF_FLAG_RSSI_THRESHOLD	0x00000010
@@ -49,7 +49,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  	/*
  	 * TODO: Other mesh configuration parameters would go here.
  	 * See NL80211_MESHCONF_* for all the mesh config parameters.
-@@ -1384,6 +1385,7 @@ struct wpa_driver_mesh_bss_params {
+@@ -1418,6 +1419,7 @@ struct wpa_driver_mesh_bss_params {
  	int peer_link_timeout;
  	int max_peer_links;
  	int rssi_threshold;
@@ -59,7 +59,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -9332,6 +9332,9 @@ static int nl80211_put_mesh_config(struc
+@@ -9512,6 +9512,9 @@ static int nl80211_put_mesh_config(struc
  	if (((params->flags & WPA_DRIVER_MESH_CONF_FLAG_AUTO_PLINKS) &&
  	     nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
  			params->auto_plinks)) ||
@@ -71,7 +71,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  			 params->max_peer_links)) ||
 --- a/wpa_supplicant/config.c
 +++ b/wpa_supplicant/config.c
-@@ -2228,6 +2228,7 @@ static const struct parse_data ssid_fiel
+@@ -2307,6 +2307,7 @@ static const struct parse_data ssid_fiel
  #ifdef CONFIG_MESH
  	{ INT_RANGE(mode, 0, 5) },
  	{ INT_RANGE(no_auto_peer, 0, 1) },
@@ -79,7 +79,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  	{ INT_RANGE(mesh_rssi_threshold, -255, 1) },
  #else /* CONFIG_MESH */
  	{ INT_RANGE(mode, 0, 4) },
-@@ -2779,6 +2780,7 @@ void wpa_config_set_network_defaults(str
+@@ -2868,6 +2869,7 @@ void wpa_config_set_network_defaults(str
  	ssid->dot11MeshRetryTimeout = DEFAULT_MESH_RETRY_TIMEOUT;
  	ssid->dot11MeshConfirmTimeout = DEFAULT_MESH_CONFIRM_TIMEOUT;
  	ssid->dot11MeshHoldingTimeout = DEFAULT_MESH_HOLDING_TIMEOUT;
@@ -87,7 +87,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  	ssid->mesh_rssi_threshold = DEFAULT_MESH_RSSI_THRESHOLD;
  #endif /* CONFIG_MESH */
  #ifdef CONFIG_HT_OVERRIDES
-@@ -3996,6 +3998,7 @@ struct wpa_config * wpa_config_alloc_emp
+@@ -4088,6 +4090,7 @@ struct wpa_config * wpa_config_alloc_emp
  	config->user_mpm = DEFAULT_USER_MPM;
  	config->max_peer_links = DEFAULT_MAX_PEER_LINKS;
  	config->mesh_max_inactivity = DEFAULT_MESH_MAX_INACTIVITY;
@@ -95,7 +95,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  	config->dot11RSNASAERetransPeriod =
  		DEFAULT_DOT11_RSNA_SAE_RETRANS_PERIOD;
  	config->fast_reauth = DEFAULT_FAST_REAUTH;
-@@ -4618,6 +4621,7 @@ static const struct global_parse_data gl
+@@ -4725,6 +4728,7 @@ static const struct global_parse_data gl
  	{ INT(user_mpm), 0 },
  	{ INT_RANGE(max_peer_links, 0, 255), 0 },
  	{ INT(mesh_max_inactivity), 0 },
@@ -113,7 +113,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  /*
   * The default dot11RSNASAERetransPeriod is defined as 40 ms in the standard,
   * but use 1000 ms in practice to avoid issues on low power CPUs.
-@@ -1306,6 +1307,14 @@ struct wpa_config {
+@@ -1326,6 +1327,14 @@ struct wpa_config {
  	int mesh_max_inactivity;
  
  	/**
@@ -130,7 +130,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  	 * This timeout value is used in mesh STA to retransmit
 --- a/wpa_supplicant/config_file.c
 +++ b/wpa_supplicant/config_file.c
-@@ -818,6 +818,7 @@ static void wpa_config_write_network(FIL
+@@ -829,6 +829,7 @@ static void wpa_config_write_network(FIL
  #endif /* IEEE8021X_EAPOL */
  	INT(mode);
  	INT(no_auto_peer);
@@ -138,7 +138,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  	INT(frequency);
  	INT(fixed_freq);
  #ifdef CONFIG_ACS
-@@ -1450,6 +1451,9 @@ static void wpa_config_write_global(FILE
+@@ -1471,6 +1472,9 @@ static void wpa_config_write_global(FILE
  		fprintf(f, "mesh_max_inactivity=%d\n",
  			config->mesh_max_inactivity);
  
@@ -150,7 +150,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  		fprintf(f, "dot11RSNASAERetransPeriod=%d\n",
 --- a/wpa_supplicant/config_ssid.h
 +++ b/wpa_supplicant/config_ssid.h
-@@ -500,6 +500,11 @@ struct wpa_ssid {
+@@ -514,6 +514,11 @@ struct wpa_ssid {
  	int dot11MeshConfirmTimeout; /* msec */
  	int dot11MeshHoldingTimeout; /* msec */
  
@@ -164,7 +164,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  
 --- a/wpa_supplicant/mesh.c
 +++ b/wpa_supplicant/mesh.c
-@@ -121,6 +121,7 @@ static struct mesh_conf * mesh_config_cr
+@@ -126,6 +126,7 @@ static struct mesh_conf * mesh_config_cr
  	conf->mesh_cc_id = 0;
  	conf->mesh_sp_id = MESH_SYNC_METHOD_NEIGHBOR_OFFSET;
  	conf->mesh_auth_id = (conf->security & MESH_CONF_SEC_AUTH) ? 1 : 0;
@@ -172,7 +172,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  	conf->dot11MeshMaxRetries = ssid->dot11MeshMaxRetries;
  	conf->dot11MeshRetryTimeout = ssid->dot11MeshRetryTimeout;
  	conf->dot11MeshConfirmTimeout = ssid->dot11MeshConfirmTimeout;
-@@ -256,6 +257,7 @@ static int wpa_supplicant_mesh_init(stru
+@@ -325,6 +326,7 @@ static int wpa_supplicant_mesh_init(stru
  	bss->conf->start_disabled = 1;
  	bss->conf->mesh = MESH_ENABLED;
  	bss->conf->ap_max_inactivity = wpa_s->conf->mesh_max_inactivity;
@@ -180,7 +180,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  
  	if (ieee80211_is_dfs(ssid->frequency, wpa_s->hw.modes,
  			     wpa_s->hw.num_modes) && wpa_s->conf->country[0]) {
-@@ -534,6 +536,10 @@ int wpa_supplicant_join_mesh(struct wpa_
+@@ -538,6 +540,10 @@ int wpa_supplicant_join_mesh(struct wpa_
  	}
  	params->conf.peer_link_timeout = wpa_s->conf->mesh_max_inactivity;
  
@@ -188,12 +188,12 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 +	params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_FORWARDING;
 +	params->conf.forwarding = ssid->mesh_fwding;
 +
+ 	os_free(wpa_s->mesh_params);
  	wpa_s->mesh_params = params;
  	if (wpa_supplicant_mesh_init(wpa_s, ssid, &params->freq)) {
- 		wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh");
 --- a/wpa_supplicant/mesh_mpm.c
 +++ b/wpa_supplicant/mesh_mpm.c
-@@ -289,9 +289,9 @@ static void mesh_mpm_send_plink_action(s
+@@ -295,9 +295,9 @@ static void mesh_mpm_send_plink_action(s
  		info = (bss->num_plinks > 63 ? 63 : bss->num_plinks) << 1;
  		/* TODO: Add Connected to Mesh Gate/AS subfields */
  		wpabuf_put_u8(buf, info);
diff --git a/package/network/services/hostapd/patches/031-mesh-add-VHT_CHANWIDTH_USE_HT-to-max_oper_chwidth.patch b/package/network/services/hostapd/patches/031-mesh-add-VHT_CHANWIDTH_USE_HT-to-max_oper_chwidth.patch
deleted file mode 100644
index de64a59372..0000000000
--- a/package/network/services/hostapd/patches/031-mesh-add-VHT_CHANWIDTH_USE_HT-to-max_oper_chwidth.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 838225f2319348e430b553fd9bb3680bd7434ae3 Mon Sep 17 00:00:00 2001
-From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Wed, 18 Apr 2018 14:14:18 -0700
-Subject: [PATCH 1/2] mesh: add VHT_CHANWIDTH_USE_HT to max_oper_chwidth
-
-Channel width in VHT mode refers HT capability when
-the width goes down to below 80MHz, hence add checking
-HT channel width to its max operation channel width.
-So that mesh has capable to select bandwidth below 80Mhz.
-
-Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
----
- wpa_supplicant/config.c         | 1 +
- wpa_supplicant/config_ssid.h    | 1 +
- wpa_supplicant/wpa_supplicant.c | 3 +++
- 3 files changed, 5 insertions(+)
-
---- a/wpa_supplicant/config.c
-+++ b/wpa_supplicant/config.c
-@@ -2818,6 +2818,7 @@ void wpa_config_set_network_defaults(str
- 	ssid->mka_priority = DEFAULT_PRIO_NOT_KEY_SERVER;
- #endif /* CONFIG_MACSEC */
- 	ssid->mac_addr = -1;
-+	ssid->max_oper_chwidth = (u8)DEFAULT_MAX_OPER_CHWIDTH;
- }
- 
- 
---- a/wpa_supplicant/config_ssid.h
-+++ b/wpa_supplicant/config_ssid.h
-@@ -37,6 +37,7 @@
- #define DEFAULT_AMPDU_FACTOR -1 /* no change */
- #define DEFAULT_AMPDU_DENSITY -1 /* no change */
- #define DEFAULT_USER_SELECTED_SIM 1
-+#define DEFAULT_MAX_OPER_CHWIDTH -1
- 
- struct psk_list_entry {
- 	struct dl_list list;
---- a/wpa_supplicant/wpa_supplicant.c
-+++ b/wpa_supplicant/wpa_supplicant.c
-@@ -2342,6 +2342,9 @@ void ibss_mesh_setup_freq(struct wpa_sup
- 			vht_caps |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
- 			seg0 = 114;
- 		}
-+	} else if (ssid->max_oper_chwidth == VHT_CHANWIDTH_USE_HT) {
-+		chwidth = VHT_CHANWIDTH_USE_HT;
-+		seg0 = vht80[j] + 2;
- 	}
- 
- 	if (hostapd_set_freq_params(&vht_freq, mode->mode, freq->freq,
diff --git a/package/network/services/hostapd/patches/032-mesh-implement-use-of-VHT20-config-in-mesh-mode.patch b/package/network/services/hostapd/patches/032-mesh-implement-use-of-VHT20-config-in-mesh-mode.patch
deleted file mode 100644
index 4691a79404..0000000000
--- a/package/network/services/hostapd/patches/032-mesh-implement-use-of-VHT20-config-in-mesh-mode.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-From 24fc73b2470ff79cd8c92e029ca785c8e95a204c Mon Sep 17 00:00:00 2001
-From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Wed, 18 Apr 2018 14:14:19 -0700
-Subject: [PATCH 2/2] mesh: implement use of VHT20 config in mesh mode
-
-mesh in VHT mode is supposed to be able to use any bandwidth
-that 11ac supports, but we don't have a way to set VHT20
-although there are parameters that are supposed to be used.
-This patch along with the patch of
-"mesh: add VHT_CHANWIDTH_USE_HT to max_oper_chwidth" makes mesh
-available to use of any bandwidth using combination of
-existing parameters like below shown.
-
-VHT80:
-  default
-  do not set any parameters
-VHT40:
-  max_oper_chwidth = 0
-VHT20:
-  max_oper_chwidth=0
-  disable_ht40=1
-HT40:
-  disable_vht = 1
-HT20:
-  disable_ht40 = 1
-disable HT:
-  disable_ht = 1
-
-Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
----
- wpa_supplicant/wpa_supplicant.c | 18 +++++++++++++-----
- 1 file changed, 13 insertions(+), 5 deletions(-)
-
---- a/wpa_supplicant/wpa_supplicant.c
-+++ b/wpa_supplicant/wpa_supplicant.c
-@@ -2174,9 +2174,15 @@ void ibss_mesh_setup_freq(struct wpa_sup
- 		if (!dfs_enabled)
- 			return;
- 
-+	freq->channel = pri_chan->chan;
-+
- #ifdef CONFIG_HT_OVERRIDES
--	if (ssid->disable_ht40)
--		return;
-+	if (ssid->disable_ht40) {
-+		if (ssid->disable_vht)
-+			return;
-+		else
-+			goto skip_ht40;
-+	}
- #endif /* CONFIG_HT_OVERRIDES */
- 
- 	/* Check/setup HT40+/HT40- */
-@@ -2204,8 +2210,6 @@ void ibss_mesh_setup_freq(struct wpa_sup
- 		if (!dfs_enabled)
- 			return;
- 
--	freq->channel = pri_chan->chan;
--
- 	if (ht40 == -1) {
- 		if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS))
- 			return;
-@@ -2249,6 +2253,7 @@ void ibss_mesh_setup_freq(struct wpa_sup
- 		wpa_scan_results_free(scan_res);
- 	}
- 
-+skip_ht40:
- 	wpa_printf(MSG_DEBUG,
- 		   "IBSS/mesh: setup freq channel %d, sec_channel_offset %d",
- 		   freq->channel, freq->sec_channel_offset);
-@@ -2344,7 +2349,10 @@ void ibss_mesh_setup_freq(struct wpa_sup
- 		}
- 	} else if (ssid->max_oper_chwidth == VHT_CHANWIDTH_USE_HT) {
- 		chwidth = VHT_CHANWIDTH_USE_HT;
--		seg0 = vht80[j] + 2;
-+		if (ssid->disable_ht40)
-+			seg0 = 0;
-+		else
-+			seg0 = vht80[j] + 2;
- 	}
- 
- 	if (hostapd_set_freq_params(&vht_freq, mode->mode, freq->freq,
diff --git a/package/network/services/hostapd/patches/040-FT-Fix-CONFIG_IEEE80211X-y-build-without-CONFIG_FILS.patch b/package/network/services/hostapd/patches/040-FT-Fix-CONFIG_IEEE80211X-y-build-without-CONFIG_FILS.patch
deleted file mode 100644
index 66ffd9e48b..0000000000
--- a/package/network/services/hostapd/patches/040-FT-Fix-CONFIG_IEEE80211X-y-build-without-CONFIG_FILS.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From f2973fa39d6109f0f34969e91551a98dc340d537 Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <j@w1.fi>
-Date: Mon, 3 Dec 2018 12:00:26 +0200
-Subject: FT: Fix CONFIG_IEEE80211X=y build without CONFIG_FILS=y
-
-remove_ie() was defined within an ifdef CONFIG_FILS block while it is
-now needed even without CONFIG_FILS=y. Remove the CONFIG_FILS condition
-there.
-
-Fixes 8c41734e5de1 ("FT: Fix Reassociation Request IEs during FT protocol")
-Signed-off-by: Jouni Malinen <j@w1.fi>
----
- wpa_supplicant/sme.c | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/wpa_supplicant/sme.c
-+++ b/wpa_supplicant/sme.c
-@@ -1386,7 +1386,6 @@ void sme_event_auth(struct wpa_supplican
- }
- 
- 
--#ifdef CONFIG_FILS
- #ifdef CONFIG_IEEE80211R
- static void remove_ie(u8 *buf, size_t *len, u8 eid)
- {
-@@ -1401,7 +1400,6 @@ static void remove_ie(u8 *buf, size_t *l
- 	}
- }
- #endif /* CONFIG_IEEE80211R */
--#endif /* CONFIG_FILS */
- 
- 
- void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
diff --git a/package/network/services/hostapd/patches/051-wpa_supplicant-fix-race-condition-in-mesh-mpm-new-pe.patch b/package/network/services/hostapd/patches/051-wpa_supplicant-fix-race-condition-in-mesh-mpm-new-pe.patch
index 26842c97d5..46bd1dc2ff 100644
--- a/package/network/services/hostapd/patches/051-wpa_supplicant-fix-race-condition-in-mesh-mpm-new-pe.patch
+++ b/package/network/services/hostapd/patches/051-wpa_supplicant-fix-race-condition-in-mesh-mpm-new-pe.patch
@@ -14,7 +14,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/wpa_supplicant/mesh_mpm.c
 +++ b/wpa_supplicant/mesh_mpm.c
-@@ -663,11 +663,12 @@ static struct sta_info * mesh_mpm_add_pe
+@@ -685,11 +685,12 @@ static struct sta_info * mesh_mpm_add_pe
  	}
  
  	sta = ap_get_sta(data, addr);
diff --git a/package/network/services/hostapd/patches/061-0001-OpenSSL-Use-constant-time-operations-for-private-big.patch b/package/network/services/hostapd/patches/061-0001-OpenSSL-Use-constant-time-operations-for-private-big.patch
deleted file mode 100644
index 7a73b09ff9..0000000000
--- a/package/network/services/hostapd/patches/061-0001-OpenSSL-Use-constant-time-operations-for-private-big.patch
+++ /dev/null
@@ -1,88 +0,0 @@
-From d42c477cc794163a3757956bbffca5cea000923c Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Tue, 26 Feb 2019 11:43:03 +0200
-Subject: [PATCH 01/14] OpenSSL: Use constant time operations for private
- bignums
-
-This helps in reducing measurable timing differences in operations
-involving private information. BoringSSL has removed BN_FLG_CONSTTIME
-and expects specific constant time functions to be called instead, so a
-bit different approach is needed depending on which library is used.
-
-The main operation that needs protection against side channel attacks is
-BN_mod_exp() that depends on private keys (the public key validation
-step in crypto_dh_derive_secret() is an exception that can use the
-faster version since it does not depend on private keys).
-
-crypto_bignum_div() is currently used only in SAE FFC case with not
-safe-prime groups and only with values that do not depend on private
-keys, so it is not critical to protect it.
-
-crypto_bignum_inverse() is currently used only in SAE FFC PWE
-derivation. The additional protection here is targeting only OpenSSL.
-BoringSSL may need conversion to using BN_mod_inverse_blinded().
-
-This is related to CVE-2019-9494 and CVE-2019-9495.
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- src/crypto/crypto_openssl.c | 20 +++++++++++++++-----
- 1 file changed, 15 insertions(+), 5 deletions(-)
-
---- a/src/crypto/crypto_openssl.c
-+++ b/src/crypto/crypto_openssl.c
-@@ -549,7 +549,8 @@ int crypto_mod_exp(const u8 *base, size_
- 	    bn_result == NULL)
- 		goto error;
- 
--	if (BN_mod_exp(bn_result, bn_base, bn_exp, bn_modulus, ctx) != 1)
-+	if (BN_mod_exp_mont_consttime(bn_result, bn_base, bn_exp, bn_modulus,
-+				      ctx, NULL) != 1)
- 		goto error;
- 
- 	*result_len = BN_bn2bin(bn_result, result);
-@@ -1295,8 +1296,9 @@ int crypto_bignum_exptmod(const struct c
- 	bnctx = BN_CTX_new();
- 	if (bnctx == NULL)
- 		return -1;
--	res = BN_mod_exp((BIGNUM *) d, (const BIGNUM *) a, (const BIGNUM *) b,
--			 (const BIGNUM *) c, bnctx);
-+	res = BN_mod_exp_mont_consttime((BIGNUM *) d, (const BIGNUM *) a,
-+					(const BIGNUM *) b, (const BIGNUM *) c,
-+					bnctx, NULL);
- 	BN_CTX_free(bnctx);
- 
- 	return res ? 0 : -1;
-@@ -1315,6 +1317,11 @@ int crypto_bignum_inverse(const struct c
- 	bnctx = BN_CTX_new();
- 	if (bnctx == NULL)
- 		return -1;
-+#ifdef OPENSSL_IS_BORINGSSL
-+	/* TODO: use BN_mod_inverse_blinded() ? */
-+#else /* OPENSSL_IS_BORINGSSL */
-+	BN_set_flags((BIGNUM *) a, BN_FLG_CONSTTIME);
-+#endif /* OPENSSL_IS_BORINGSSL */
- 	res = BN_mod_inverse((BIGNUM *) c, (const BIGNUM *) a,
- 			     (const BIGNUM *) b, bnctx);
- 	BN_CTX_free(bnctx);
-@@ -1348,6 +1355,9 @@ int crypto_bignum_div(const struct crypt
- 	bnctx = BN_CTX_new();
- 	if (bnctx == NULL)
- 		return -1;
-+#ifndef OPENSSL_IS_BORINGSSL
-+	BN_set_flags((BIGNUM *) a, BN_FLG_CONSTTIME);
-+#endif /* OPENSSL_IS_BORINGSSL */
- 	res = BN_div((BIGNUM *) c, NULL, (const BIGNUM *) a,
- 		     (const BIGNUM *) b, bnctx);
- 	BN_CTX_free(bnctx);
-@@ -1439,8 +1449,8 @@ int crypto_bignum_legendre(const struct
- 	    /* exp = (p-1) / 2 */
- 	    !BN_sub(exp, (const BIGNUM *) p, BN_value_one()) ||
- 	    !BN_rshift1(exp, exp) ||
--	    !BN_mod_exp(tmp, (const BIGNUM *) a, exp, (const BIGNUM *) p,
--			bnctx))
-+	    !BN_mod_exp_mont_consttime(tmp, (const BIGNUM *) a, exp,
-+				       (const BIGNUM *) p, bnctx, NULL))
- 		goto fail;
- 
- 	if (BN_is_word(tmp, 1))
diff --git a/package/network/services/hostapd/patches/061-0002-Add-helper-functions-for-constant-time-operations.patch b/package/network/services/hostapd/patches/061-0002-Add-helper-functions-for-constant-time-operations.patch
deleted file mode 100644
index 87e41aea87..0000000000
--- a/package/network/services/hostapd/patches/061-0002-Add-helper-functions-for-constant-time-operations.patch
+++ /dev/null
@@ -1,212 +0,0 @@
-From 6e34f618d37ddbb5854c42e2ad4fca83492fa7b7 Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Wed, 27 Feb 2019 18:38:30 +0200
-Subject: [PATCH 02/14] Add helper functions for constant time operations
-
-These functions can be used to help implement constant time operations
-for various cryptographic operations that must minimize externally
-observable differences in processing (both in timing and also in
-internal cache use, etc.).
-
-This is related to CVE-2019-9494 and CVE-2019-9495.
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- src/utils/const_time.h | 191 +++++++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 191 insertions(+)
- create mode 100644 src/utils/const_time.h
-
---- /dev/null
-+++ b/src/utils/const_time.h
-@@ -0,0 +1,191 @@
-+/*
-+ * Helper functions for constant time operations
-+ * Copyright (c) 2019, The Linux Foundation
-+ *
-+ * This software may be distributed under the terms of the BSD license.
-+ * See README for more details.
-+ *
-+ * These helper functions can be used to implement logic that needs to minimize
-+ * externally visible differences in execution path by avoiding use of branches,
-+ * avoiding early termination or other time differences, and forcing same memory
-+ * access pattern regardless of values.
-+ */
-+
-+#ifndef CONST_TIME_H
-+#define CONST_TIME_H
-+
-+
-+#if defined(__clang__)
-+#define NO_UBSAN_UINT_OVERFLOW \
-+	__attribute__((no_sanitize("unsigned-integer-overflow")))
-+#else
-+#define NO_UBSAN_UINT_OVERFLOW
-+#endif
-+
-+
-+/**
-+ * const_time_fill_msb - Fill all bits with MSB value
-+ * @val: Input value
-+ * Returns: Value with all the bits set to the MSB of the input val
-+ */
-+static inline unsigned int const_time_fill_msb(unsigned int val)
-+{
-+	/* Move the MSB to LSB and multiple by -1 to fill in all bits. */
-+	return (val >> (sizeof(val) * 8 - 1)) * ~0U;
-+}
-+
-+
-+/* Returns: -1 if val is zero; 0 if val is not zero */
-+static inline unsigned int const_time_is_zero(unsigned int val)
-+	NO_UBSAN_UINT_OVERFLOW
-+{
-+	/* Set MSB to 1 for 0 and fill rest of bits with the MSB value */
-+	return const_time_fill_msb(~val & (val - 1));
-+}
-+
-+
-+/* Returns: -1 if a == b; 0 if a != b */
-+static inline unsigned int const_time_eq(unsigned int a, unsigned int b)
-+{
-+	return const_time_is_zero(a ^ b);
-+}
-+
-+
-+/* Returns: -1 if a == b; 0 if a != b */
-+static inline u8 const_time_eq_u8(unsigned int a, unsigned int b)
-+{
-+	return (u8) const_time_eq(a, b);
-+}
-+
-+
-+/**
-+ * const_time_eq_bin - Constant time memory comparison
-+ * @a: First buffer to compare
-+ * @b: Second buffer to compare
-+ * @len: Number of octets to compare
-+ * Returns: -1 if buffers are equal, 0 if not
-+ *
-+ * This function is meant for comparing passwords or hash values where
-+ * difference in execution time or memory access pattern could provide external
-+ * observer information about the location of the difference in the memory
-+ * buffers. The return value does not behave like memcmp(), i.e.,
-+ * const_time_eq_bin() cannot be used to sort items into a defined order. Unlike
-+ * memcmp(), the execution time of const_time_eq_bin() does not depend on the
-+ * contents of the compared memory buffers, but only on the total compared
-+ * length.
-+ */
-+static inline unsigned int const_time_eq_bin(const void *a, const void *b,
-+					     size_t len)
-+{
-+	const u8 *aa = a;
-+	const u8 *bb = b;
-+	size_t i;
-+	u8 res = 0;
-+
-+	for (i = 0; i < len; i++)
-+		res |= aa[i] ^ bb[i];
-+
-+	return const_time_is_zero(res);
-+}
-+
-+
-+/**
-+ * const_time_select - Constant time unsigned int selection
-+ * @mask: 0 (false) or -1 (true) to identify which value to select
-+ * @true_val: Value to select for the true case
-+ * @false_val: Value to select for the false case
-+ * Returns: true_val if mask == -1, false_val if mask == 0
-+ */
-+static inline unsigned int const_time_select(unsigned int mask,
-+					     unsigned int true_val,
-+					     unsigned int false_val)
-+{
-+	return (mask & true_val) | (~mask & false_val);
-+}
-+
-+
-+/**
-+ * const_time_select_int - Constant time int selection
-+ * @mask: 0 (false) or -1 (true) to identify which value to select
-+ * @true_val: Value to select for the true case
-+ * @false_val: Value to select for the false case
-+ * Returns: true_val if mask == -1, false_val if mask == 0
-+ */
-+static inline int const_time_select_int(unsigned int mask, int true_val,
-+					int false_val)
-+{
-+	return (int) const_time_select(mask, (unsigned int) true_val,
-+				       (unsigned int) false_val);
-+}
-+
-+
-+/**
-+ * const_time_select_u8 - Constant time u8 selection
-+ * @mask: 0 (false) or -1 (true) to identify which value to select
-+ * @true_val: Value to select for the true case
-+ * @false_val: Value to select for the false case
-+ * Returns: true_val if mask == -1, false_val if mask == 0
-+ */
-+static inline u8 const_time_select_u8(u8 mask, u8 true_val, u8 false_val)
-+{
-+	return (u8) const_time_select(mask, true_val, false_val);
-+}
-+
-+
-+/**
-+ * const_time_select_s8 - Constant time s8 selection
-+ * @mask: 0 (false) or -1 (true) to identify which value to select
-+ * @true_val: Value to select for the true case
-+ * @false_val: Value to select for the false case
-+ * Returns: true_val if mask == -1, false_val if mask == 0
-+ */
-+static inline s8 const_time_select_s8(u8 mask, s8 true_val, s8 false_val)
-+{
-+	return (s8) const_time_select(mask, (unsigned int) true_val,
-+				      (unsigned int) false_val);
-+}
-+
-+
-+/**
-+ * const_time_select_bin - Constant time binary buffer selection copy
-+ * @mask: 0 (false) or -1 (true) to identify which value to copy
-+ * @true_val: Buffer to copy for the true case
-+ * @false_val: Buffer to copy for the false case
-+ * @len: Number of octets to copy
-+ * @dst: Destination buffer for the copy
-+ *
-+ * This function copies the specified buffer into the destination buffer using
-+ * operations with identical memory access pattern regardless of which buffer
-+ * is being copied.
-+ */
-+static inline void const_time_select_bin(u8 mask, const u8 *true_val,
-+					 const u8 *false_val, size_t len,
-+					 u8 *dst)
-+{
-+	size_t i;
-+
-+	for (i = 0; i < len; i++)
-+		dst[i] = const_time_select_u8(mask, true_val[i], false_val[i]);
-+}
-+
-+
-+static inline int const_time_memcmp(const void *a, const void *b, size_t len)
-+{
-+	const u8 *aa = a;
-+	const u8 *bb = b;
-+	int diff, res = 0;
-+	unsigned int mask;
-+
-+	if (len == 0)
-+		return 0;
-+	do {
-+		len--;
-+		diff = (int) aa[len] - (int) bb[len];
-+		mask = const_time_is_zero((unsigned int) diff);
-+		res = const_time_select_int(mask, res, diff);
-+	} while (len);
-+
-+	return res;
-+}
-+
-+#endif /* CONST_TIME_H */
diff --git a/package/network/services/hostapd/patches/061-0003-OpenSSL-Use-constant-time-selection-for-crypto_bignu.patch b/package/network/services/hostapd/patches/061-0003-OpenSSL-Use-constant-time-selection-for-crypto_bignu.patch
deleted file mode 100644
index 0d89b46cb3..0000000000
--- a/package/network/services/hostapd/patches/061-0003-OpenSSL-Use-constant-time-selection-for-crypto_bignu.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From c93461c1d98f52681717a088776ab32fd97872b0 Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Fri, 8 Mar 2019 00:24:12 +0200
-Subject: [PATCH 03/14] OpenSSL: Use constant time selection for
- crypto_bignum_legendre()
-
-Get rid of the branches that depend on the result of the Legendre
-operation. This is needed to avoid leaking information about different
-temporary results in blinding mechanisms.
-
-This is related to CVE-2019-9494 and CVE-2019-9495.
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- src/crypto/crypto_openssl.c | 15 +++++++++------
- 1 file changed, 9 insertions(+), 6 deletions(-)
-
---- a/src/crypto/crypto_openssl.c
-+++ b/src/crypto/crypto_openssl.c
-@@ -24,6 +24,7 @@
- #endif /* CONFIG_ECC */
- 
- #include "common.h"
-+#include "utils/const_time.h"
- #include "wpabuf.h"
- #include "dh_group5.h"
- #include "sha1.h"
-@@ -1435,6 +1436,7 @@ int crypto_bignum_legendre(const struct
- 	BN_CTX *bnctx;
- 	BIGNUM *exp = NULL, *tmp = NULL;
- 	int res = -2;
-+	unsigned int mask;
- 
- 	if (TEST_FAIL())
- 		return -2;
-@@ -1453,12 +1455,13 @@ int crypto_bignum_legendre(const struct
- 				       (const BIGNUM *) p, bnctx, NULL))
- 		goto fail;
- 
--	if (BN_is_word(tmp, 1))
--		res = 1;
--	else if (BN_is_zero(tmp))
--		res = 0;
--	else
--		res = -1;
-+	/* Return 1 if tmp == 1, 0 if tmp == 0, or -1 otherwise. Need to use
-+	 * constant time selection to avoid branches here. */
-+	res = -1;
-+	mask = const_time_eq(BN_is_word(tmp, 1), 1);
-+	res = const_time_select_int(mask, 1, res);
-+	mask = const_time_eq(BN_is_zero(tmp), 1);
-+	res = const_time_select_int(mask, 0, res);
- 
- fail:
- 	BN_clear_free(tmp);
diff --git a/package/network/services/hostapd/patches/061-0005-SAE-Minimize-timing-differences-in-PWE-derivation.patch b/package/network/services/hostapd/patches/061-0005-SAE-Minimize-timing-differences-in-PWE-derivation.patch
deleted file mode 100644
index e72a9cbe5a..0000000000
--- a/package/network/services/hostapd/patches/061-0005-SAE-Minimize-timing-differences-in-PWE-derivation.patch
+++ /dev/null
@@ -1,242 +0,0 @@
-From 6513db3e96c43c2e36805cf5ead349765d18eaf7 Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Tue, 26 Feb 2019 13:05:09 +0200
-Subject: [PATCH 05/14] SAE: Minimize timing differences in PWE derivation
-
-The QR test result can provide information about the password to an
-attacker, so try to minimize differences in how the
-sae_test_pwd_seed_ecc() result is used. (CVE-2019-9494)
-
-Use heap memory for the dummy password to allow the same password length
-to be used even with long passwords.
-
-Use constant time selection functions to track the real vs. dummy
-variables so that the exact same operations can be performed for both QR
-test results.
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- src/common/sae.c | 106 ++++++++++++++++++++++++++++++-------------------------
- 1 file changed, 57 insertions(+), 49 deletions(-)
-
---- a/src/common/sae.c
-+++ b/src/common/sae.c
-@@ -9,6 +9,7 @@
- #include "includes.h"
- 
- #include "common.h"
-+#include "utils/const_time.h"
- #include "crypto/crypto.h"
- #include "crypto/sha256.h"
- #include "crypto/random.h"
-@@ -269,15 +270,12 @@ static int sae_test_pwd_seed_ecc(struct
- 				 const u8 *prime,
- 				 const struct crypto_bignum *qr,
- 				 const struct crypto_bignum *qnr,
--				 struct crypto_bignum **ret_x_cand)
-+				 u8 *pwd_value)
- {
--	u8 pwd_value[SAE_MAX_ECC_PRIME_LEN];
- 	struct crypto_bignum *y_sqr, *x_cand;
- 	int res;
- 	size_t bits;
- 
--	*ret_x_cand = NULL;
--
- 	wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-seed", pwd_seed, SHA256_MAC_LEN);
- 
- 	/* pwd-value = KDF-z(pwd-seed, "SAE Hunting and Pecking", p) */
-@@ -286,7 +284,7 @@ static int sae_test_pwd_seed_ecc(struct
- 			    prime, sae->tmp->prime_len, pwd_value, bits) < 0)
- 		return -1;
- 	if (bits % 8)
--		buf_shift_right(pwd_value, sizeof(pwd_value), 8 - bits % 8);
-+		buf_shift_right(pwd_value, sae->tmp->prime_len, 8 - bits % 8);
- 	wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-value",
- 			pwd_value, sae->tmp->prime_len);
- 
-@@ -297,20 +295,13 @@ static int sae_test_pwd_seed_ecc(struct
- 	if (!x_cand)
- 		return -1;
- 	y_sqr = crypto_ec_point_compute_y_sqr(sae->tmp->ec, x_cand);
--	if (!y_sqr) {
--		crypto_bignum_deinit(x_cand, 1);
-+	crypto_bignum_deinit(x_cand, 1);
-+	if (!y_sqr)
- 		return -1;
--	}
- 
- 	res = is_quadratic_residue_blind(sae, prime, bits, qr, qnr, y_sqr);
- 	crypto_bignum_deinit(y_sqr, 1);
--	if (res <= 0) {
--		crypto_bignum_deinit(x_cand, 1);
--		return res;
--	}
--
--	*ret_x_cand = x_cand;
--	return 1;
-+	return res;
- }
- 
- 
-@@ -431,25 +422,30 @@ static int sae_derive_pwe_ecc(struct sae
- 	const u8 *addr[3];
- 	size_t len[3];
- 	size_t num_elem;
--	u8 dummy_password[32];
--	size_t dummy_password_len;
-+	u8 *dummy_password, *tmp_password;
- 	int pwd_seed_odd = 0;
- 	u8 prime[SAE_MAX_ECC_PRIME_LEN];
- 	size_t prime_len;
--	struct crypto_bignum *x = NULL, *qr, *qnr;
-+	struct crypto_bignum *x = NULL, *qr = NULL, *qnr = NULL;
-+	u8 x_bin[SAE_MAX_ECC_PRIME_LEN];
-+	u8 x_cand_bin[SAE_MAX_ECC_PRIME_LEN];
- 	size_t bits;
--	int res;
--
--	dummy_password_len = password_len;
--	if (dummy_password_len > sizeof(dummy_password))
--		dummy_password_len = sizeof(dummy_password);
--	if (random_get_bytes(dummy_password, dummy_password_len) < 0)
--		return -1;
-+	int res = -1;
-+	u8 found = 0; /* 0 (false) or 0xff (true) to be used as const_time_*
-+		       * mask */
-+
-+	os_memset(x_bin, 0, sizeof(x_bin));
-+
-+	dummy_password = os_malloc(password_len);
-+	tmp_password = os_malloc(password_len);
-+	if (!dummy_password || !tmp_password ||
-+	    random_get_bytes(dummy_password, password_len) < 0)
-+		goto fail;
- 
- 	prime_len = sae->tmp->prime_len;
- 	if (crypto_bignum_to_bin(sae->tmp->prime, prime, sizeof(prime),
- 				 prime_len) < 0)
--		return -1;
-+		goto fail;
- 	bits = crypto_ec_prime_len_bits(sae->tmp->ec);
- 
- 	/*
-@@ -458,7 +454,7 @@ static int sae_derive_pwe_ecc(struct sae
- 	 */
- 	if (get_random_qr_qnr(prime, prime_len, sae->tmp->prime, bits,
- 			      &qr, &qnr) < 0)
--		return -1;
-+		goto fail;
- 
- 	wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
- 			      password, password_len);
-@@ -474,7 +470,7 @@ static int sae_derive_pwe_ecc(struct sae
- 	 */
- 	sae_pwd_seed_key(addr1, addr2, addrs);
- 
--	addr[0] = password;
-+	addr[0] = tmp_password;
- 	len[0] = password_len;
- 	num_elem = 1;
- 	if (identifier) {
-@@ -491,9 +487,8 @@ static int sae_derive_pwe_ecc(struct sae
- 	 * attacks that attempt to determine the number of iterations required
- 	 * in the loop.
- 	 */
--	for (counter = 1; counter <= k || !x; counter++) {
-+	for (counter = 1; counter <= k || !found; counter++) {
- 		u8 pwd_seed[SHA256_MAC_LEN];
--		struct crypto_bignum *x_cand;
- 
- 		if (counter > 200) {
- 			/* This should not happen in practice */
-@@ -501,40 +496,49 @@ static int sae_derive_pwe_ecc(struct sae
- 			break;
- 		}
- 
--		wpa_printf(MSG_DEBUG, "SAE: counter = %u", counter);
-+		wpa_printf(MSG_DEBUG, "SAE: counter = %03u", counter);
-+		const_time_select_bin(found, dummy_password, password,
-+				      password_len, tmp_password);
- 		if (hmac_sha256_vector(addrs, sizeof(addrs), num_elem,
- 				       addr, len, pwd_seed) < 0)
- 			break;
- 
- 		res = sae_test_pwd_seed_ecc(sae, pwd_seed,
--					    prime, qr, qnr, &x_cand);
-+					    prime, qr, qnr, x_cand_bin);
-+		const_time_select_bin(found, x_bin, x_cand_bin, prime_len,
-+				      x_bin);
-+		pwd_seed_odd = const_time_select_u8(
-+			found, pwd_seed_odd,
-+			pwd_seed[SHA256_MAC_LEN - 1] & 0x01);
-+		os_memset(pwd_seed, 0, sizeof(pwd_seed));
- 		if (res < 0)
- 			goto fail;
--		if (res > 0 && !x) {
--			wpa_printf(MSG_DEBUG,
--				   "SAE: Selected pwd-seed with counter %u",
--				   counter);
--			x = x_cand;
--			pwd_seed_odd = pwd_seed[SHA256_MAC_LEN - 1] & 0x01;
--			os_memset(pwd_seed, 0, sizeof(pwd_seed));
--
--			/*
--			 * Use a dummy password for the following rounds, if
--			 * any.
--			 */
--			addr[0] = dummy_password;
--			len[0] = dummy_password_len;
--		} else if (res > 0) {
--			crypto_bignum_deinit(x_cand, 1);
--		}
-+		/* Need to minimize differences in handling res == 0 and 1 here
-+		 * to avoid differences in timing and instruction cache access,
-+		 * so use const_time_select_*() to make local copies of the
-+		 * values based on whether this loop iteration was the one that
-+		 * found the pwd-seed/x. */
-+
-+		/* found is 0 or 0xff here and res is 0 or 1. Bitwise OR of them
-+		 * (with res converted to 0/0xff) handles this in constant time.
-+		 */
-+		found |= res * 0xff;
-+		wpa_printf(MSG_DEBUG, "SAE: pwd-seed result %d found=0x%02x",
-+			   res, found);
- 	}
- 
--	if (!x) {
-+	if (!found) {
- 		wpa_printf(MSG_DEBUG, "SAE: Could not generate PWE");
- 		res = -1;
- 		goto fail;
- 	}
- 
-+	x = crypto_bignum_init_set(x_bin, prime_len);
-+	if (!x) {
-+		res = -1;
-+		goto fail;
-+	}
-+
- 	if (!sae->tmp->pwe_ecc)
- 		sae->tmp->pwe_ecc = crypto_ec_point_init(sae->tmp->ec);
- 	if (!sae->tmp->pwe_ecc)
-@@ -543,7 +547,6 @@ static int sae_derive_pwe_ecc(struct sae
- 		res = crypto_ec_point_solve_y_coord(sae->tmp->ec,
- 						    sae->tmp->pwe_ecc, x,
- 						    pwd_seed_odd);
--	crypto_bignum_deinit(x, 1);
- 	if (res < 0) {
- 		/*
- 		 * This should not happen since we already checked that there
-@@ -555,6 +558,11 @@ static int sae_derive_pwe_ecc(struct sae
- fail:
- 	crypto_bignum_deinit(qr, 0);
- 	crypto_bignum_deinit(qnr, 0);
-+	os_free(dummy_password);
-+	bin_clear_free(tmp_password, password_len);
-+	crypto_bignum_deinit(x, 1);
-+	os_memset(x_bin, 0, sizeof(x_bin));
-+	os_memset(x_cand_bin, 0, sizeof(x_cand_bin));
- 
- 	return res;
- }
diff --git a/package/network/services/hostapd/patches/061-0006-SAE-Avoid-branches-in-is_quadratic_residue_blind.patch b/package/network/services/hostapd/patches/061-0006-SAE-Avoid-branches-in-is_quadratic_residue_blind.patch
deleted file mode 100644
index 6d93cb2480..0000000000
--- a/package/network/services/hostapd/patches/061-0006-SAE-Avoid-branches-in-is_quadratic_residue_blind.patch
+++ /dev/null
@@ -1,139 +0,0 @@
-From 362704dda04507e7ebb8035122e83d9f0ae7c320 Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Tue, 26 Feb 2019 19:34:38 +0200
-Subject: [PATCH 06/14] SAE: Avoid branches in is_quadratic_residue_blind()
-
-Make the non-failure path in the function proceed without branches based
-on r_odd and in constant time to minimize risk of observable differences
-in timing or cache use. (CVE-2019-9494)
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- src/common/sae.c | 64 ++++++++++++++++++++++++++++++++------------------------
- 1 file changed, 37 insertions(+), 27 deletions(-)
-
---- a/src/common/sae.c
-+++ b/src/common/sae.c
-@@ -209,12 +209,14 @@ get_rand_1_to_p_1(const u8 *prime, size_
- 
- static int is_quadratic_residue_blind(struct sae_data *sae,
- 				      const u8 *prime, size_t bits,
--				      const struct crypto_bignum *qr,
--				      const struct crypto_bignum *qnr,
-+				      const u8 *qr, const u8 *qnr,
- 				      const struct crypto_bignum *y_sqr)
- {
--	struct crypto_bignum *r, *num;
-+	struct crypto_bignum *r, *num, *qr_or_qnr = NULL;
- 	int r_odd, check, res = -1;
-+	u8 qr_or_qnr_bin[SAE_MAX_ECC_PRIME_LEN];
-+	size_t prime_len = sae->tmp->prime_len;
-+	unsigned int mask;
- 
- 	/*
- 	 * Use the blinding technique to mask y_sqr while determining
-@@ -225,7 +227,7 @@ static int is_quadratic_residue_blind(st
- 	 * r = a random number between 1 and p-1, inclusive
- 	 * num = (v * r * r) modulo p
- 	 */
--	r = get_rand_1_to_p_1(prime, sae->tmp->prime_len, bits, &r_odd);
-+	r = get_rand_1_to_p_1(prime, prime_len, bits, &r_odd);
- 	if (!r)
- 		return -1;
- 
-@@ -235,41 +237,45 @@ static int is_quadratic_residue_blind(st
- 	    crypto_bignum_mulmod(num, r, sae->tmp->prime, num) < 0)
- 		goto fail;
- 
--	if (r_odd) {
--		/*
--		 * num = (num * qr) module p
--		 * LGR(num, p) = 1 ==> quadratic residue
--		 */
--		if (crypto_bignum_mulmod(num, qr, sae->tmp->prime, num) < 0)
--			goto fail;
--		check = 1;
--	} else {
--		/*
--		 * num = (num * qnr) module p
--		 * LGR(num, p) = -1 ==> quadratic residue
--		 */
--		if (crypto_bignum_mulmod(num, qnr, sae->tmp->prime, num) < 0)
--			goto fail;
--		check = -1;
--	}
-+	/*
-+	 * Need to minimize differences in handling different cases, so try to
-+	 * avoid branches and timing differences.
-+	 *
-+	 * If r_odd:
-+	 * num = (num * qr) module p
-+	 * LGR(num, p) = 1 ==> quadratic residue
-+	 * else:
-+	 * num = (num * qnr) module p
-+	 * LGR(num, p) = -1 ==> quadratic residue
-+	 */
-+	mask = const_time_is_zero(r_odd);
-+	const_time_select_bin(mask, qnr, qr, prime_len, qr_or_qnr_bin);
-+	qr_or_qnr = crypto_bignum_init_set(qr_or_qnr_bin, prime_len);
-+	if (!qr_or_qnr ||
-+	    crypto_bignum_mulmod(num, qr_or_qnr, sae->tmp->prime, num) < 0)
-+		goto fail;
-+	/* r_odd is 0 or 1; branchless version of check = r_odd ? 1 : -1, */
-+	check = const_time_select_int(mask, -1, 1);
- 
- 	res = crypto_bignum_legendre(num, sae->tmp->prime);
- 	if (res == -2) {
- 		res = -1;
- 		goto fail;
- 	}
--	res = res == check;
-+	/* branchless version of res = res == check
-+	 * (res is -1, 0, or 1; check is -1 or 1) */
-+	mask = const_time_eq(res, check);
-+	res = const_time_select_int(mask, 1, 0);
- fail:
- 	crypto_bignum_deinit(num, 1);
- 	crypto_bignum_deinit(r, 1);
-+	crypto_bignum_deinit(qr_or_qnr, 1);
- 	return res;
- }
- 
- 
- static int sae_test_pwd_seed_ecc(struct sae_data *sae, const u8 *pwd_seed,
--				 const u8 *prime,
--				 const struct crypto_bignum *qr,
--				 const struct crypto_bignum *qnr,
-+				 const u8 *prime, const u8 *qr, const u8 *qnr,
- 				 u8 *pwd_value)
- {
- 	struct crypto_bignum *y_sqr, *x_cand;
-@@ -429,6 +435,8 @@ static int sae_derive_pwe_ecc(struct sae
- 	struct crypto_bignum *x = NULL, *qr = NULL, *qnr = NULL;
- 	u8 x_bin[SAE_MAX_ECC_PRIME_LEN];
- 	u8 x_cand_bin[SAE_MAX_ECC_PRIME_LEN];
-+	u8 qr_bin[SAE_MAX_ECC_PRIME_LEN];
-+	u8 qnr_bin[SAE_MAX_ECC_PRIME_LEN];
- 	size_t bits;
- 	int res = -1;
- 	u8 found = 0; /* 0 (false) or 0xff (true) to be used as const_time_*
-@@ -453,7 +461,9 @@ static int sae_derive_pwe_ecc(struct sae
- 	 * (qnr) modulo p for blinding purposes during the loop.
- 	 */
- 	if (get_random_qr_qnr(prime, prime_len, sae->tmp->prime, bits,
--			      &qr, &qnr) < 0)
-+			      &qr, &qnr) < 0 ||
-+	    crypto_bignum_to_bin(qr, qr_bin, sizeof(qr_bin), prime_len) < 0 ||
-+	    crypto_bignum_to_bin(qnr, qnr_bin, sizeof(qnr_bin), prime_len) < 0)
- 		goto fail;
- 
- 	wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
-@@ -504,7 +514,7 @@ static int sae_derive_pwe_ecc(struct sae
- 			break;
- 
- 		res = sae_test_pwd_seed_ecc(sae, pwd_seed,
--					    prime, qr, qnr, x_cand_bin);
-+					    prime, qr_bin, qnr_bin, x_cand_bin);
- 		const_time_select_bin(found, x_bin, x_cand_bin, prime_len,
- 				      x_bin);
- 		pwd_seed_odd = const_time_select_u8(
diff --git a/package/network/services/hostapd/patches/061-0007-SAE-Mask-timing-of-MODP-groups-22-23-24.patch b/package/network/services/hostapd/patches/061-0007-SAE-Mask-timing-of-MODP-groups-22-23-24.patch
deleted file mode 100644
index 229d2b1070..0000000000
--- a/package/network/services/hostapd/patches/061-0007-SAE-Mask-timing-of-MODP-groups-22-23-24.patch
+++ /dev/null
@@ -1,113 +0,0 @@
-From 90839597cc4016b33f00055b12d59174c62770a3 Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Sat, 2 Mar 2019 12:24:09 +0200
-Subject: [PATCH 07/14] SAE: Mask timing of MODP groups 22, 23, 24
-
-These groups have significant probability of coming up with pwd-value
-that is equal or greater than the prime and as such, need for going
-through the PWE derivation loop multiple times. This can result in
-sufficient timing different to allow an external observer to determine
-how many rounds are needed and that can leak information about the used
-password.
-
-Force at least 40 loop rounds for these MODP groups similarly to the ECC
-group design to mask timing. This behavior is not described in IEEE Std
-802.11-2016 for SAE, but it does not result in different values (i.e.,
-only different timing), so such implementation specific countermeasures
-can be done without breaking interoperability with other implementation.
-
-Note: These MODP groups 22, 23, and 24 are not considered sufficiently
-strong to be used with SAE (or more or less anything else). As such,
-they should never be enabled in runtime configuration for any production
-use cases. These changes to introduce additional protection to mask
-timing is only for completeness of implementation and not an indication
-that these groups should be used.
-
-This is related to CVE-2019-9494.
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- src/common/sae.c | 38 ++++++++++++++++++++++++++++----------
- 1 file changed, 28 insertions(+), 10 deletions(-)
-
---- a/src/common/sae.c
-+++ b/src/common/sae.c
-@@ -578,22 +578,27 @@ fail:
- }
- 
- 
-+static int sae_modp_group_require_masking(int group)
-+{
-+	/* Groups for which pwd-value is likely to be >= p frequently */
-+	return group == 22 || group == 23 || group == 24;
-+}
-+
-+
- static int sae_derive_pwe_ffc(struct sae_data *sae, const u8 *addr1,
- 			      const u8 *addr2, const u8 *password,
- 			      size_t password_len, const char *identifier)
- {
--	u8 counter;
-+	u8 counter, k;
- 	u8 addrs[2 * ETH_ALEN];
- 	const u8 *addr[3];
- 	size_t len[3];
- 	size_t num_elem;
- 	int found = 0;
-+	struct crypto_bignum *pwe = NULL;
- 
--	if (sae->tmp->pwe_ffc == NULL) {
--		sae->tmp->pwe_ffc = crypto_bignum_init();
--		if (sae->tmp->pwe_ffc == NULL)
--			return -1;
--	}
-+	crypto_bignum_deinit(sae->tmp->pwe_ffc, 1);
-+	sae->tmp->pwe_ffc = NULL;
- 
- 	wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
- 			      password, password_len);
-@@ -617,7 +622,9 @@ static int sae_derive_pwe_ffc(struct sae
- 	len[num_elem] = sizeof(counter);
- 	num_elem++;
- 
--	for (counter = 1; !found; counter++) {
-+	k = sae_modp_group_require_masking(sae->group) ? 40 : 1;
-+
-+	for (counter = 1; counter <= k || !found; counter++) {
- 		u8 pwd_seed[SHA256_MAC_LEN];
- 		int res;
- 
-@@ -627,19 +634,30 @@ static int sae_derive_pwe_ffc(struct sae
- 			break;
- 		}
- 
--		wpa_printf(MSG_DEBUG, "SAE: counter = %u", counter);
-+		wpa_printf(MSG_DEBUG, "SAE: counter = %02u", counter);
- 		if (hmac_sha256_vector(addrs, sizeof(addrs), num_elem,
- 				       addr, len, pwd_seed) < 0)
- 			break;
--		res = sae_test_pwd_seed_ffc(sae, pwd_seed, sae->tmp->pwe_ffc);
-+		if (!pwe) {
-+			pwe = crypto_bignum_init();
-+			if (!pwe)
-+				break;
-+		}
-+		res = sae_test_pwd_seed_ffc(sae, pwd_seed, pwe);
- 		if (res < 0)
- 			break;
- 		if (res > 0) {
--			wpa_printf(MSG_DEBUG, "SAE: Use this PWE");
- 			found = 1;
-+			if (!sae->tmp->pwe_ffc) {
-+				wpa_printf(MSG_DEBUG, "SAE: Use this PWE");
-+				sae->tmp->pwe_ffc = pwe;
-+				pwe = NULL;
-+			}
- 		}
- 	}
- 
-+	crypto_bignum_deinit(pwe, 1);
-+
- 	return found ? 0 : -1;
- }
- 
diff --git a/package/network/services/hostapd/patches/061-0008-SAE-Use-const_time-selection-for-PWE-in-FFC.patch b/package/network/services/hostapd/patches/061-0008-SAE-Use-const_time-selection-for-PWE-in-FFC.patch
deleted file mode 100644
index 47e1b3c68e..0000000000
--- a/package/network/services/hostapd/patches/061-0008-SAE-Use-const_time-selection-for-PWE-in-FFC.patch
+++ /dev/null
@@ -1,100 +0,0 @@
-From f8f20717f87eff1f025f48ed585c7684debacf72 Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Sat, 2 Mar 2019 12:45:33 +0200
-Subject: [PATCH 08/14] SAE: Use const_time selection for PWE in FFC
-
-This is an initial step towards making the FFC case use strictly
-constant time operations similarly to the ECC case.
-sae_test_pwd_seed_ffc() does not yet have constant time behavior,
-though.
-
-This is related to CVE-2019-9494.
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- src/common/sae.c | 53 +++++++++++++++++++++++++++++++++++------------------
- 1 file changed, 35 insertions(+), 18 deletions(-)
-
---- a/src/common/sae.c
-+++ b/src/common/sae.c
-@@ -589,17 +589,28 @@ static int sae_derive_pwe_ffc(struct sae
- 			      const u8 *addr2, const u8 *password,
- 			      size_t password_len, const char *identifier)
- {
--	u8 counter, k;
-+	u8 counter, k, sel_counter = 0;
- 	u8 addrs[2 * ETH_ALEN];
- 	const u8 *addr[3];
- 	size_t len[3];
- 	size_t num_elem;
--	int found = 0;
--	struct crypto_bignum *pwe = NULL;
-+	u8 found = 0; /* 0 (false) or 0xff (true) to be used as const_time_*
-+		       * mask */
-+	u8 mask;
-+	struct crypto_bignum *pwe;
-+	size_t prime_len = sae->tmp->prime_len * 8;
-+	u8 *pwe_buf;
- 
- 	crypto_bignum_deinit(sae->tmp->pwe_ffc, 1);
- 	sae->tmp->pwe_ffc = NULL;
- 
-+	/* Allocate a buffer to maintain selected and candidate PWE for constant
-+	 * time selection. */
-+	pwe_buf = os_zalloc(prime_len * 2);
-+	pwe = crypto_bignum_init();
-+	if (!pwe_buf || !pwe)
-+		goto fail;
-+
- 	wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
- 			      password, password_len);
- 
-@@ -638,27 +649,33 @@ static int sae_derive_pwe_ffc(struct sae
- 		if (hmac_sha256_vector(addrs, sizeof(addrs), num_elem,
- 				       addr, len, pwd_seed) < 0)
- 			break;
--		if (!pwe) {
--			pwe = crypto_bignum_init();
--			if (!pwe)
--				break;
--		}
- 		res = sae_test_pwd_seed_ffc(sae, pwd_seed, pwe);
-+		/* res is -1 for fatal failure, 0 if a valid PWE was not found,
-+		 * or 1 if a valid PWE was found. */
- 		if (res < 0)
- 			break;
--		if (res > 0) {
--			found = 1;
--			if (!sae->tmp->pwe_ffc) {
--				wpa_printf(MSG_DEBUG, "SAE: Use this PWE");
--				sae->tmp->pwe_ffc = pwe;
--				pwe = NULL;
--			}
--		}
-+		/* Store the candidate PWE into the second half of pwe_buf and
-+		 * the selected PWE in the beginning of pwe_buf using constant
-+		 * time selection. */
-+		if (crypto_bignum_to_bin(pwe, pwe_buf + prime_len, prime_len,
-+					 prime_len) < 0)
-+			break;
-+		const_time_select_bin(found, pwe_buf, pwe_buf + prime_len,
-+				      prime_len, pwe_buf);
-+		sel_counter = const_time_select_u8(found, sel_counter, counter);
-+		mask = const_time_eq_u8(res, 1);
-+		found = const_time_select_u8(found, found, mask);
- 	}
- 
--	crypto_bignum_deinit(pwe, 1);
-+	if (!found)
-+		goto fail;
- 
--	return found ? 0 : -1;
-+	wpa_printf(MSG_DEBUG, "SAE: Use PWE from counter = %02u", sel_counter);
-+	sae->tmp->pwe_ffc = crypto_bignum_init_set(pwe_buf, prime_len);
-+fail:
-+	crypto_bignum_deinit(pwe, 1);
-+	bin_clear_free(pwe_buf, prime_len * 2);
-+	return sae->tmp->pwe_ffc ? 0 : -1;
- }
- 
- 
diff --git a/package/network/services/hostapd/patches/061-0009-SAE-Use-constant-time-operations-in-sae_test_pwd_see.patch b/package/network/services/hostapd/patches/061-0009-SAE-Use-constant-time-operations-in-sae_test_pwd_see.patch
deleted file mode 100644
index 150cbeb8ac..0000000000
--- a/package/network/services/hostapd/patches/061-0009-SAE-Use-constant-time-operations-in-sae_test_pwd_see.patch
+++ /dev/null
@@ -1,133 +0,0 @@
-From cff138b0747fa39765cbc641b66cfa5d7f1735d1 Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Sat, 2 Mar 2019 16:05:56 +0200
-Subject: [PATCH 09/14] SAE: Use constant time operations in
- sae_test_pwd_seed_ffc()
-
-Try to avoid showing externally visible timing or memory access
-differences regardless of whether the derived pwd-value is smaller than
-the group prime.
-
-This is related to CVE-2019-9494.
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- src/common/sae.c | 75 ++++++++++++++++++++++++++++++++++----------------------
- 1 file changed, 46 insertions(+), 29 deletions(-)
-
---- a/src/common/sae.c
-+++ b/src/common/sae.c
-@@ -311,14 +311,17 @@ static int sae_test_pwd_seed_ecc(struct
- }
- 
- 
-+/* Returns -1 on fatal failure, 0 if PWE cannot be derived from the provided
-+ * pwd-seed, or 1 if a valid PWE was derived from pwd-seed. */
- static int sae_test_pwd_seed_ffc(struct sae_data *sae, const u8 *pwd_seed,
- 				 struct crypto_bignum *pwe)
- {
- 	u8 pwd_value[SAE_MAX_PRIME_LEN];
- 	size_t bits = sae->tmp->prime_len * 8;
- 	u8 exp[1];
--	struct crypto_bignum *a, *b;
--	int res;
-+	struct crypto_bignum *a, *b = NULL;
-+	int res, is_val;
-+	u8 pwd_value_valid;
- 
- 	wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-seed", pwd_seed, SHA256_MAC_LEN);
- 
-@@ -330,16 +333,29 @@ static int sae_test_pwd_seed_ffc(struct
- 	wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-value", pwd_value,
- 			sae->tmp->prime_len);
- 
--	if (os_memcmp(pwd_value, sae->tmp->dh->prime, sae->tmp->prime_len) >= 0)
--	{
--		wpa_printf(MSG_DEBUG, "SAE: pwd-value >= p");
--		return 0;
--	}
-+	/* Check whether pwd-value < p */
-+	res = const_time_memcmp(pwd_value, sae->tmp->dh->prime,
-+				sae->tmp->prime_len);
-+	/* pwd-value >= p is invalid, so res is < 0 for the valid cases and
-+	 * the negative sign can be used to fill the mask for constant time
-+	 * selection */
-+	pwd_value_valid = const_time_fill_msb(res);
-+
-+	/* If pwd-value >= p, force pwd-value to be < p and perform the
-+	 * calculations anyway to hide timing difference. The derived PWE will
-+	 * be ignored in that case. */
-+	pwd_value[0] = const_time_select_u8(pwd_value_valid, pwd_value[0], 0);
- 
- 	/* PWE = pwd-value^((p-1)/r) modulo p */
- 
-+	res = -1;
- 	a = crypto_bignum_init_set(pwd_value, sae->tmp->prime_len);
-+	if (!a)
-+		goto fail;
- 
-+	/* This is an optimization based on the used group that does not depend
-+	 * on the password in any way, so it is fine to use separate branches
-+	 * for this step without constant time operations. */
- 	if (sae->tmp->dh->safe_prime) {
- 		/*
- 		 * r = (p-1)/2 for the group used here, so this becomes:
-@@ -353,33 +369,34 @@ static int sae_test_pwd_seed_ffc(struct
- 		b = crypto_bignum_init_set(exp, sizeof(exp));
- 		if (b == NULL ||
- 		    crypto_bignum_sub(sae->tmp->prime, b, b) < 0 ||
--		    crypto_bignum_div(b, sae->tmp->order, b) < 0) {
--			crypto_bignum_deinit(b, 0);
--			b = NULL;
--		}
-+		    crypto_bignum_div(b, sae->tmp->order, b) < 0)
-+			goto fail;
- 	}
- 
--	if (a == NULL || b == NULL)
--		res = -1;
--	else
--		res = crypto_bignum_exptmod(a, b, sae->tmp->prime, pwe);
--
--	crypto_bignum_deinit(a, 0);
--	crypto_bignum_deinit(b, 0);
--
--	if (res < 0) {
--		wpa_printf(MSG_DEBUG, "SAE: Failed to calculate PWE");
--		return -1;
--	}
--
--	/* if (PWE > 1) --> found */
--	if (crypto_bignum_is_zero(pwe) || crypto_bignum_is_one(pwe)) {
--		wpa_printf(MSG_DEBUG, "SAE: PWE <= 1");
--		return 0;
--	}
-+	if (!b)
-+		goto fail;
- 
--	wpa_printf(MSG_DEBUG, "SAE: PWE found");
--	return 1;
-+	res = crypto_bignum_exptmod(a, b, sae->tmp->prime, pwe);
-+	if (res < 0)
-+		goto fail;
-+
-+	/* There were no fatal errors in calculations, so determine the return
-+	 * value using constant time operations. We get here for number of
-+	 * invalid cases which are cleared here after having performed all the
-+	 * computation. PWE is valid if pwd-value was less than prime and
-+	 * PWE > 1. Start with pwd-value check first and then use constant time
-+	 * operations to clear res to 0 if PWE is 0 or 1.
-+	 */
-+	res = const_time_select_u8(pwd_value_valid, 1, 0);
-+	is_val = crypto_bignum_is_zero(pwe);
-+	res = const_time_select_u8(const_time_is_zero(is_val), res, 0);
-+	is_val = crypto_bignum_is_one(pwe);
-+	res = const_time_select_u8(const_time_is_zero(is_val), res, 0);
-+
-+fail:
-+	crypto_bignum_deinit(a, 1);
-+	crypto_bignum_deinit(b, 1);
-+	return res;
- }
- 
- 
diff --git a/package/network/services/hostapd/patches/062-0004-EAP-pwd-Use-constant-time-and-memory-access-for-find.patch b/package/network/services/hostapd/patches/062-0004-EAP-pwd-Use-constant-time-and-memory-access-for-find.patch
deleted file mode 100644
index 1870c497c4..0000000000
--- a/package/network/services/hostapd/patches/062-0004-EAP-pwd-Use-constant-time-and-memory-access-for-find.patch
+++ /dev/null
@@ -1,319 +0,0 @@
-From aaf65feac67c3993935634eefe5bc76b9fce03aa Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Tue, 26 Feb 2019 11:59:45 +0200
-Subject: [PATCH 04/14] EAP-pwd: Use constant time and memory access for
- finding the PWE
-
-This algorithm could leak information to external observers in form of
-timing differences or memory access patterns (cache use). While the
-previous implementation had protection against the most visible timing
-differences (looping 40 rounds and masking the legendre operation), it
-did not protect against memory access patterns between the two possible
-code paths in the masking operations. That might be sufficient to allow
-an unprivileged process running on the same device to be able to
-determine which path is being executed through a cache attack and based
-on that, determine information about the used password.
-
-Convert the PWE finding loop to use constant time functions and
-identical memory access path without different branches for the QR/QNR
-cases to minimize possible side-channel information similarly to the
-changes done for SAE authentication. (CVE-2019-9495)
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- src/eap_common/eap_pwd_common.c | 187 +++++++++++++++++++++-------------------
- 1 file changed, 99 insertions(+), 88 deletions(-)
-
---- a/src/eap_common/eap_pwd_common.c
-+++ b/src/eap_common/eap_pwd_common.c
-@@ -8,11 +8,15 @@
- 
- #include "includes.h"
- #include "common.h"
-+#include "utils/const_time.h"
- #include "crypto/sha256.h"
- #include "crypto/crypto.h"
- #include "eap_defs.h"
- #include "eap_pwd_common.h"
- 
-+#define MAX_ECC_PRIME_LEN 66
-+
-+
- /* The random function H(x) = HMAC-SHA256(0^32, x) */
- struct crypto_hash * eap_pwd_h_init(void)
- {
-@@ -102,6 +106,15 @@ EAP_PWD_group * get_eap_pwd_group(u16 nu
- }
- 
- 
-+static void buf_shift_right(u8 *buf, size_t len, size_t bits)
-+{
-+	size_t i;
-+	for (i = len - 1; i > 0; i--)
-+		buf[i] = (buf[i - 1] << (8 - bits)) | (buf[i] >> bits);
-+	buf[0] >>= bits;
-+}
-+
-+
- /*
-  * compute a "random" secret point on an elliptic curve based
-  * on the password and identities.
-@@ -113,17 +126,27 @@ int compute_password_element(EAP_PWD_gro
- 			     const u8 *token)
- {
- 	struct crypto_bignum *qr = NULL, *qnr = NULL, *one = NULL;
-+	struct crypto_bignum *qr_or_qnr = NULL;
-+	u8 qr_bin[MAX_ECC_PRIME_LEN];
-+	u8 qnr_bin[MAX_ECC_PRIME_LEN];
-+	u8 qr_or_qnr_bin[MAX_ECC_PRIME_LEN];
-+	u8 x_bin[MAX_ECC_PRIME_LEN];
- 	struct crypto_bignum *tmp1 = NULL, *tmp2 = NULL, *pm1 = NULL;
- 	struct crypto_hash *hash;
- 	unsigned char pwe_digest[SHA256_MAC_LEN], *prfbuf = NULL, ctr;
--	int is_odd, ret = 0, check, found = 0;
--	size_t primebytelen, primebitlen;
--	struct crypto_bignum *x_candidate = NULL, *rnd = NULL, *cofactor = NULL;
-+	int ret = 0, check, res;
-+	u8 found = 0; /* 0 (false) or 0xff (true) to be used as const_time_*
-+		       * mask */
-+	size_t primebytelen = 0, primebitlen;
-+	struct crypto_bignum *x_candidate = NULL, *cofactor = NULL;
- 	const struct crypto_bignum *prime;
-+	u8 mask, found_ctr = 0, is_odd = 0;
- 
- 	if (grp->pwe)
- 		return -1;
- 
-+	os_memset(x_bin, 0, sizeof(x_bin));
-+
- 	prime = crypto_ec_get_prime(grp->group);
- 	cofactor = crypto_bignum_init();
- 	grp->pwe = crypto_ec_point_init(grp->group);
-@@ -152,8 +175,6 @@ int compute_password_element(EAP_PWD_gro
- 
- 	/* get a random quadratic residue and nonresidue */
- 	while (!qr || !qnr) {
--		int res;
--
- 		if (crypto_bignum_rand(tmp1, prime) < 0)
- 			goto fail;
- 		res = crypto_bignum_legendre(tmp1, prime);
-@@ -167,6 +188,11 @@ int compute_password_element(EAP_PWD_gro
- 		if (!tmp1)
- 			goto fail;
- 	}
-+	if (crypto_bignum_to_bin(qr, qr_bin, sizeof(qr_bin),
-+				 primebytelen) < 0 ||
-+	    crypto_bignum_to_bin(qnr, qnr_bin, sizeof(qnr_bin),
-+				 primebytelen) < 0)
-+		goto fail;
- 
- 	os_memset(prfbuf, 0, primebytelen);
- 	ctr = 0;
-@@ -194,17 +220,16 @@ int compute_password_element(EAP_PWD_gro
- 		eap_pwd_h_update(hash, &ctr, sizeof(ctr));
- 		eap_pwd_h_final(hash, pwe_digest);
- 
--		crypto_bignum_deinit(rnd, 1);
--		rnd = crypto_bignum_init_set(pwe_digest, SHA256_MAC_LEN);
--		if (!rnd) {
--			wpa_printf(MSG_INFO, "EAP-pwd: unable to create rnd");
--			goto fail;
--		}
-+		is_odd = const_time_select_u8(
-+			found, is_odd, pwe_digest[SHA256_MAC_LEN - 1] & 0x01);
- 		if (eap_pwd_kdf(pwe_digest, SHA256_MAC_LEN,
- 				(u8 *) "EAP-pwd Hunting And Pecking",
- 				os_strlen("EAP-pwd Hunting And Pecking"),
- 				prfbuf, primebitlen) < 0)
- 			goto fail;
-+		if (primebitlen % 8)
-+			buf_shift_right(prfbuf, primebytelen,
-+					8 - primebitlen % 8);
- 
- 		crypto_bignum_deinit(x_candidate, 1);
- 		x_candidate = crypto_bignum_init_set(prfbuf, primebytelen);
-@@ -214,24 +239,13 @@ int compute_password_element(EAP_PWD_gro
- 			goto fail;
- 		}
- 
--		/*
--		 * eap_pwd_kdf() returns a string of bits 0..primebitlen but
--		 * BN_bin2bn will treat that string of bits as a big endian
--		 * number. If the primebitlen is not an even multiple of 8
--		 * then excessive bits-- those _after_ primebitlen-- so now
--		 * we have to shift right the amount we masked off.
--		 */
--		if ((primebitlen % 8) &&
--		    crypto_bignum_rshift(x_candidate,
--					 (8 - (primebitlen % 8)),
--					 x_candidate) < 0)
--			goto fail;
--
- 		if (crypto_bignum_cmp(x_candidate, prime) >= 0)
- 			continue;
- 
--		wpa_hexdump(MSG_DEBUG, "EAP-pwd: x_candidate",
--			    prfbuf, primebytelen);
-+		wpa_hexdump_key(MSG_DEBUG, "EAP-pwd: x_candidate",
-+				prfbuf, primebytelen);
-+		const_time_select_bin(found, x_bin, prfbuf, primebytelen,
-+				      x_bin);
- 
- 		/*
- 		 * compute y^2 using the equation of the curve
-@@ -260,13 +274,15 @@ int compute_password_element(EAP_PWD_gro
- 		 * Flip a coin, multiply by the random quadratic residue or the
- 		 * random quadratic nonresidue and record heads or tails.
- 		 */
--		if (crypto_bignum_is_odd(tmp1)) {
--			crypto_bignum_mulmod(tmp2, qr, prime, tmp2);
--			check = 1;
--		} else {
--			crypto_bignum_mulmod(tmp2, qnr, prime, tmp2);
--			check = -1;
--		}
-+		mask = const_time_eq_u8(crypto_bignum_is_odd(tmp1), 1);
-+		check = const_time_select_s8(mask, 1, -1);
-+		const_time_select_bin(mask, qr_bin, qnr_bin, primebytelen,
-+				      qr_or_qnr_bin);
-+		crypto_bignum_deinit(qr_or_qnr, 1);
-+		qr_or_qnr = crypto_bignum_init_set(qr_or_qnr_bin, primebytelen);
-+		if (!qr_or_qnr ||
-+		    crypto_bignum_mulmod(tmp2, qr_or_qnr, prime, tmp2) < 0)
-+			goto fail;
- 
- 		/*
- 		 * Now it's safe to do legendre, if check is 1 then it's
-@@ -274,59 +290,12 @@ int compute_password_element(EAP_PWD_gro
- 		 * change result), if check is -1 then it's the opposite test
- 		 * (multiplying a qr by qnr would make a qnr).
- 		 */
--		if (crypto_bignum_legendre(tmp2, prime) == check) {
--			if (found == 1)
--				continue;
--
--			/* need to unambiguously identify the solution */
--			is_odd = crypto_bignum_is_odd(rnd);
--
--			/*
--			 * We know x_candidate is a quadratic residue so set
--			 * it here.
--			 */
--			if (crypto_ec_point_solve_y_coord(grp->group, grp->pwe,
--							  x_candidate,
--							  is_odd) != 0) {
--				wpa_printf(MSG_INFO,
--					   "EAP-pwd: Could not solve for y");
--				continue;
--			}
--
--			/*
--			 * If there's a solution to the equation then the point
--			 * must be on the curve so why check again explicitly?
--			 * OpenSSL code says this is required by X9.62. We're
--			 * not X9.62 but it can't hurt just to be sure.
--			 */
--			if (!crypto_ec_point_is_on_curve(grp->group,
--							 grp->pwe)) {
--				wpa_printf(MSG_INFO,
--					   "EAP-pwd: point is not on curve");
--				continue;
--			}
--
--			if (!crypto_bignum_is_one(cofactor)) {
--				/* make sure the point is not in a small
--				 * sub-group */
--				if (crypto_ec_point_mul(grp->group, grp->pwe,
--							cofactor,
--							grp->pwe) != 0) {
--					wpa_printf(MSG_INFO,
--						   "EAP-pwd: cannot multiply generator by order");
--					continue;
--				}
--				if (crypto_ec_point_is_at_infinity(grp->group,
--								   grp->pwe)) {
--					wpa_printf(MSG_INFO,
--						   "EAP-pwd: point is at infinity");
--					continue;
--				}
--			}
--			wpa_printf(MSG_DEBUG,
--				   "EAP-pwd: found a PWE in %d tries", ctr);
--			found = 1;
--		}
-+		res = crypto_bignum_legendre(tmp2, prime);
-+		if (res == -2)
-+			goto fail;
-+		mask = const_time_eq(res, check);
-+		found_ctr = const_time_select_u8(found, found_ctr, ctr);
-+		found |= mask;
- 	}
- 	if (found == 0) {
- 		wpa_printf(MSG_INFO,
-@@ -334,6 +303,44 @@ int compute_password_element(EAP_PWD_gro
- 			   num);
- 		goto fail;
- 	}
-+
-+	/*
-+	 * We know x_candidate is a quadratic residue so set it here.
-+	 */
-+	crypto_bignum_deinit(x_candidate, 1);
-+	x_candidate = crypto_bignum_init_set(x_bin, primebytelen);
-+	if (!x_candidate ||
-+	    crypto_ec_point_solve_y_coord(grp->group, grp->pwe, x_candidate,
-+					  is_odd) != 0) {
-+		wpa_printf(MSG_INFO, "EAP-pwd: Could not solve for y");
-+		goto fail;
-+	}
-+
-+	/*
-+	 * If there's a solution to the equation then the point must be on the
-+	 * curve so why check again explicitly? OpenSSL code says this is
-+	 * required by X9.62. We're not X9.62 but it can't hurt just to be sure.
-+	 */
-+	if (!crypto_ec_point_is_on_curve(grp->group, grp->pwe)) {
-+		wpa_printf(MSG_INFO, "EAP-pwd: point is not on curve");
-+		goto fail;
-+	}
-+
-+	if (!crypto_bignum_is_one(cofactor)) {
-+		/* make sure the point is not in a small sub-group */
-+		if (crypto_ec_point_mul(grp->group, grp->pwe, cofactor,
-+					grp->pwe) != 0) {
-+			wpa_printf(MSG_INFO,
-+				   "EAP-pwd: cannot multiply generator by order");
-+			goto fail;
-+		}
-+		if (crypto_ec_point_is_at_infinity(grp->group, grp->pwe)) {
-+			wpa_printf(MSG_INFO, "EAP-pwd: point is at infinity");
-+			goto fail;
-+		}
-+	}
-+	wpa_printf(MSG_DEBUG, "EAP-pwd: found a PWE in %02d tries", found_ctr);
-+
- 	if (0) {
-  fail:
- 		crypto_ec_point_deinit(grp->pwe, 1);
-@@ -343,14 +350,18 @@ int compute_password_element(EAP_PWD_gro
- 	/* cleanliness and order.... */
- 	crypto_bignum_deinit(cofactor, 1);
- 	crypto_bignum_deinit(x_candidate, 1);
--	crypto_bignum_deinit(rnd, 1);
- 	crypto_bignum_deinit(pm1, 0);
- 	crypto_bignum_deinit(tmp1, 1);
- 	crypto_bignum_deinit(tmp2, 1);
- 	crypto_bignum_deinit(qr, 1);
- 	crypto_bignum_deinit(qnr, 1);
-+	crypto_bignum_deinit(qr_or_qnr, 1);
- 	crypto_bignum_deinit(one, 0);
--	os_free(prfbuf);
-+	bin_clear_free(prfbuf, primebytelen);
-+	os_memset(qr_bin, 0, sizeof(qr_bin));
-+	os_memset(qnr_bin, 0, sizeof(qnr_bin));
-+	os_memset(qr_or_qnr_bin, 0, sizeof(qr_or_qnr_bin));
-+	os_memset(pwe_digest, 0, sizeof(pwe_digest));
- 
- 	return ret;
- }
diff --git a/package/network/services/hostapd/patches/063-0010-SAE-Fix-confirm-message-validation-in-error-cases.patch b/package/network/services/hostapd/patches/063-0010-SAE-Fix-confirm-message-validation-in-error-cases.patch
deleted file mode 100644
index 3a3658e640..0000000000
--- a/package/network/services/hostapd/patches/063-0010-SAE-Fix-confirm-message-validation-in-error-cases.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From ac8fa9ef198640086cf2ce7c94673be2b6a018a0 Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Tue, 5 Mar 2019 23:43:25 +0200
-Subject: [PATCH 10/14] SAE: Fix confirm message validation in error cases
-
-Explicitly verify that own and peer commit scalar/element are available
-when trying to check SAE confirm message. It could have been possible to
-hit a NULL pointer dereference if the peer element could not have been
-parsed. (CVE-2019-9496)
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- src/common/sae.c | 14 +++++++++++---
- 1 file changed, 11 insertions(+), 3 deletions(-)
-
---- a/src/common/sae.c
-+++ b/src/common/sae.c
-@@ -1464,23 +1464,31 @@ int sae_check_confirm(struct sae_data *s
- 
- 	wpa_printf(MSG_DEBUG, "SAE: peer-send-confirm %u", WPA_GET_LE16(data));
- 
--	if (sae->tmp == NULL) {
-+	if (!sae->tmp || !sae->peer_commit_scalar ||
-+	    !sae->tmp->own_commit_scalar) {
- 		wpa_printf(MSG_DEBUG, "SAE: Temporary data not yet available");
- 		return -1;
- 	}
- 
--	if (sae->tmp->ec)
-+	if (sae->tmp->ec) {
-+		if (!sae->tmp->peer_commit_element_ecc ||
-+		    !sae->tmp->own_commit_element_ecc)
-+			return -1;
- 		sae_cn_confirm_ecc(sae, data, sae->peer_commit_scalar,
- 				   sae->tmp->peer_commit_element_ecc,
- 				   sae->tmp->own_commit_scalar,
- 				   sae->tmp->own_commit_element_ecc,
- 				   verifier);
--	else
-+	} else {
-+		if (!sae->tmp->peer_commit_element_ffc ||
-+		    !sae->tmp->own_commit_element_ffc)
-+			return -1;
- 		sae_cn_confirm_ffc(sae, data, sae->peer_commit_scalar,
- 				   sae->tmp->peer_commit_element_ffc,
- 				   sae->tmp->own_commit_scalar,
- 				   sae->tmp->own_commit_element_ffc,
- 				   verifier);
-+	}
- 
- 	if (os_memcmp_const(verifier, data + 2, SHA256_MAC_LEN) != 0) {
- 		wpa_printf(MSG_DEBUG, "SAE: Confirm mismatch");
diff --git a/package/network/services/hostapd/patches/064-0011-EAP-pwd-server-Verify-received-scalar-and-element.patch b/package/network/services/hostapd/patches/064-0011-EAP-pwd-server-Verify-received-scalar-and-element.patch
deleted file mode 100644
index 8ecb5fd502..0000000000
--- a/package/network/services/hostapd/patches/064-0011-EAP-pwd-server-Verify-received-scalar-and-element.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 70ff850e89fbc8bc7da515321b4d15b5eef70581 Mon Sep 17 00:00:00 2001
-From: Mathy Vanhoef <mathy.vanhoef@nyu.edu>
-Date: Sun, 31 Mar 2019 17:13:06 +0200
-Subject: [PATCH 11/14] EAP-pwd server: Verify received scalar and element
-
-When processing an EAP-pwd Commit frame, the peer's scalar and element
-(elliptic curve point) were not validated. This allowed an adversary to
-bypass authentication, and impersonate any user if the crypto
-implementation did not verify the validity of the EC point.
-
-Fix this vulnerability by assuring the received scalar lies within the
-valid range, and by checking that the received element is not the point
-at infinity and lies on the elliptic curve being used. (CVE-2019-9498)
-
-The vulnerability is only exploitable if OpenSSL version 1.0.2 or lower
-is used, or if LibreSSL or wolfssl is used. Newer versions of OpenSSL
-(and also BoringSSL) implicitly validate the elliptic curve point in
-EC_POINT_set_affine_coordinates_GFp(), preventing the attack.
-
-Signed-off-by: Mathy Vanhoef <mathy.vanhoef@nyu.edu>
----
- src/eap_server/eap_server_pwd.c | 20 ++++++++++++++++++++
- 1 file changed, 20 insertions(+)
-
---- a/src/eap_server/eap_server_pwd.c
-+++ b/src/eap_server/eap_server_pwd.c
-@@ -718,6 +718,26 @@ eap_pwd_process_commit_resp(struct eap_s
- 		goto fin;
- 	}
- 
-+	/* verify received scalar */
-+	if (crypto_bignum_is_zero(data->peer_scalar) ||
-+	    crypto_bignum_is_one(data->peer_scalar) ||
-+	    crypto_bignum_cmp(data->peer_scalar,
-+			      crypto_ec_get_order(data->grp->group)) >= 0) {
-+		wpa_printf(MSG_INFO,
-+			   "EAP-PWD (server): received scalar is invalid");
-+		goto fin;
-+	}
-+
-+	/* verify received element */
-+	if (!crypto_ec_point_is_on_curve(data->grp->group,
-+					 data->peer_element) ||
-+	    crypto_ec_point_is_at_infinity(data->grp->group,
-+					   data->peer_element)) {
-+		wpa_printf(MSG_INFO,
-+			   "EAP-PWD (server): received element is invalid");
-+		goto fin;
-+	}
-+
- 	/* check to ensure peer's element is not in a small sub-group */
- 	if (!crypto_bignum_is_one(cofactor)) {
- 		if (crypto_ec_point_mul(data->grp->group, data->peer_element,
diff --git a/package/network/services/hostapd/patches/064-0012-EAP-pwd-server-Detect-reflection-attacks.patch b/package/network/services/hostapd/patches/064-0012-EAP-pwd-server-Detect-reflection-attacks.patch
deleted file mode 100644
index 44949cb24d..0000000000
--- a/package/network/services/hostapd/patches/064-0012-EAP-pwd-server-Detect-reflection-attacks.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From d63edfa90243e9a7de6ae5c275032f2cc79fef95 Mon Sep 17 00:00:00 2001
-From: Mathy Vanhoef <mathy.vanhoef@nyu.edu>
-Date: Sun, 31 Mar 2019 17:26:01 +0200
-Subject: [PATCH 12/14] EAP-pwd server: Detect reflection attacks
-
-When processing an EAP-pwd Commit frame, verify that the peer's scalar
-and elliptic curve element differ from the one sent by the server. This
-prevents reflection attacks where the adversary reflects the scalar and
-element sent by the server. (CVE-2019-9497)
-
-The vulnerability allows an adversary to complete the EAP-pwd handshake
-as any user. However, the adversary does not learn the negotiated
-session key, meaning the subsequent 4-way handshake would fail. As a
-result, this cannot be abused to bypass authentication unless EAP-pwd is
-used in non-WLAN cases without any following key exchange that would
-require the attacker to learn the MSK.
-
-Signed-off-by: Mathy Vanhoef <mathy.vanhoef@nyu.edu>
----
- src/eap_server/eap_server_pwd.c | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
---- a/src/eap_server/eap_server_pwd.c
-+++ b/src/eap_server/eap_server_pwd.c
-@@ -753,6 +753,15 @@ eap_pwd_process_commit_resp(struct eap_s
- 		}
- 	}
- 
-+	/* detect reflection attacks */
-+	if (crypto_bignum_cmp(data->my_scalar, data->peer_scalar) == 0 ||
-+	    crypto_ec_point_cmp(data->grp->group, data->my_element,
-+				data->peer_element) == 0) {
-+		wpa_printf(MSG_INFO,
-+			   "EAP-PWD (server): detected reflection attack!");
-+		goto fin;
-+	}
-+
- 	/* compute the shared key, k */
- 	if ((crypto_ec_point_mul(data->grp->group, data->grp->pwe,
- 				 data->peer_scalar, K) < 0) ||
diff --git a/package/network/services/hostapd/patches/064-0013-EAP-pwd-client-Verify-received-scalar-and-element.patch b/package/network/services/hostapd/patches/064-0013-EAP-pwd-client-Verify-received-scalar-and-element.patch
deleted file mode 100644
index 9c7707ae3f..0000000000
--- a/package/network/services/hostapd/patches/064-0013-EAP-pwd-client-Verify-received-scalar-and-element.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 8ad8585f91823ddcc3728155e288e0f9f872e31a Mon Sep 17 00:00:00 2001
-From: Mathy Vanhoef <mathy.vanhoef@nyu.edu>
-Date: Sun, 31 Mar 2019 17:43:44 +0200
-Subject: [PATCH 13/14] EAP-pwd client: Verify received scalar and element
-
-When processing an EAP-pwd Commit frame, the server's scalar and element
-(elliptic curve point) were not validated. This allowed an adversary to
-bypass authentication, and act as a rogue Access Point (AP) if the
-crypto implementation did not verify the validity of the EC point.
-
-Fix this vulnerability by assuring the received scalar lies within the
-valid range, and by checking that the received element is not the point
-at infinity and lies on the elliptic curve being used. (CVE-2019-9499)
-
-The vulnerability is only exploitable if OpenSSL version 1.0.2 or lower
-is used, or if LibreSSL or wolfssl is used. Newer versions of OpenSSL
-(and also BoringSSL) implicitly validate the elliptic curve point in
-EC_POINT_set_affine_coordinates_GFp(), preventing the attack.
-
-Signed-off-by: Mathy Vanhoef <mathy.vanhoef@nyu.edu>
----
- src/eap_peer/eap_pwd.c | 20 ++++++++++++++++++++
- 1 file changed, 20 insertions(+)
-
---- a/src/eap_peer/eap_pwd.c
-+++ b/src/eap_peer/eap_pwd.c
-@@ -594,6 +594,26 @@ eap_pwd_perform_commit_exchange(struct e
- 		goto fin;
- 	}
- 
-+	/* verify received scalar */
-+	if (crypto_bignum_is_zero(data->server_scalar) ||
-+	    crypto_bignum_is_one(data->server_scalar) ||
-+	    crypto_bignum_cmp(data->server_scalar,
-+			      crypto_ec_get_order(data->grp->group)) >= 0) {
-+		wpa_printf(MSG_INFO,
-+			   "EAP-PWD (peer): received scalar is invalid");
-+		goto fin;
-+	}
-+
-+	/* verify received element */
-+	if (!crypto_ec_point_is_on_curve(data->grp->group,
-+					 data->server_element) ||
-+	    crypto_ec_point_is_at_infinity(data->grp->group,
-+					   data->server_element)) {
-+		wpa_printf(MSG_INFO,
-+			   "EAP-PWD (peer): received element is invalid");
-+		goto fin;
-+	}
-+
- 	/* check to ensure server's element is not in a small sub-group */
- 	if (!crypto_bignum_is_one(cofactor)) {
- 		if (crypto_ec_point_mul(data->grp->group, data->server_element,
diff --git a/package/network/services/hostapd/patches/064-0014-EAP-pwd-Check-element-x-y-coordinates-explicitly.patch b/package/network/services/hostapd/patches/064-0014-EAP-pwd-Check-element-x-y-coordinates-explicitly.patch
deleted file mode 100644
index ab1edfaffc..0000000000
--- a/package/network/services/hostapd/patches/064-0014-EAP-pwd-Check-element-x-y-coordinates-explicitly.patch
+++ /dev/null
@@ -1,320 +0,0 @@
-From 16d4f1069118aa19bfce013493e1ac5783f92f1d Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Fri, 5 Apr 2019 02:12:50 +0300
-Subject: [PATCH 14/14] EAP-pwd: Check element x,y coordinates explicitly
-
-This adds an explicit check for 0 < x,y < prime based on RFC 5931,
-2.8.5.2.2 requirement. The earlier checks might have covered this
-implicitly, but it is safer to avoid any dependency on implicit checks
-and specific crypto library behavior. (CVE-2019-9498 and CVE-2019-9499)
-
-Furthermore, this moves the EAP-pwd element and scalar parsing and
-validation steps into shared helper functions so that there is no need
-to maintain two separate copies of this common functionality between the
-server and peer implementations.
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- src/eap_common/eap_pwd_common.c | 106 ++++++++++++++++++++++++++++++++++++++++
- src/eap_common/eap_pwd_common.h |   3 ++
- src/eap_peer/eap_pwd.c          |  45 ++---------------
- src/eap_server/eap_server_pwd.c |  45 ++---------------
- 4 files changed, 117 insertions(+), 82 deletions(-)
-
---- a/src/eap_common/eap_pwd_common.c
-+++ b/src/eap_common/eap_pwd_common.c
-@@ -427,3 +427,109 @@ int compute_keys(EAP_PWD_group *grp, con
- 
- 	return 1;
- }
-+
-+
-+static int eap_pwd_element_coord_ok(const struct crypto_bignum *prime,
-+				    const u8 *buf, size_t len)
-+{
-+	struct crypto_bignum *val;
-+	int ok = 1;
-+
-+	val = crypto_bignum_init_set(buf, len);
-+	if (!val || crypto_bignum_is_zero(val) ||
-+	    crypto_bignum_cmp(val, prime) >= 0)
-+		ok = 0;
-+	crypto_bignum_deinit(val, 0);
-+	return ok;
-+}
-+
-+
-+struct crypto_ec_point * eap_pwd_get_element(EAP_PWD_group *group,
-+					     const u8 *buf)
-+{
-+	struct crypto_ec_point *element;
-+	const struct crypto_bignum *prime;
-+	size_t prime_len;
-+	struct crypto_bignum *cofactor = NULL;
-+
-+	prime = crypto_ec_get_prime(group->group);
-+	prime_len = crypto_ec_prime_len(group->group);
-+
-+	/* RFC 5931, 2.8.5.2.2: 0 < x,y < p */
-+	if (!eap_pwd_element_coord_ok(prime, buf, prime_len) ||
-+	    !eap_pwd_element_coord_ok(prime, buf + prime_len, prime_len)) {
-+		wpa_printf(MSG_INFO, "EAP-pwd: Invalid coordinate in element");
-+		return NULL;
-+	}
-+
-+	element = crypto_ec_point_from_bin(group->group, buf);
-+	if (!element) {
-+		wpa_printf(MSG_INFO, "EAP-pwd: EC point from element failed");
-+		return NULL;
-+	}
-+
-+	/* RFC 5931, 2.8.5.2.2: on curve and not the point at infinity */
-+	if (!crypto_ec_point_is_on_curve(group->group, element) ||
-+	    crypto_ec_point_is_at_infinity(group->group, element)) {
-+		wpa_printf(MSG_INFO, "EAP-pwd: Invalid element");
-+		goto fail;
-+	}
-+
-+	cofactor = crypto_bignum_init();
-+	if (!cofactor || crypto_ec_cofactor(group->group, cofactor) < 0) {
-+		wpa_printf(MSG_INFO,
-+			   "EAP-pwd: Unable to get cofactor for curve");
-+		goto fail;
-+	}
-+
-+	if (!crypto_bignum_is_one(cofactor)) {
-+		struct crypto_ec_point *point;
-+		int ok = 1;
-+
-+		/* check to ensure peer's element is not in a small sub-group */
-+		point = crypto_ec_point_init(group->group);
-+		if (!point ||
-+		    crypto_ec_point_mul(group->group, element,
-+					cofactor, point) != 0 ||
-+		    crypto_ec_point_is_at_infinity(group->group, point))
-+			ok = 0;
-+		crypto_ec_point_deinit(point, 0);
-+
-+		if (!ok) {
-+			wpa_printf(MSG_INFO,
-+				   "EAP-pwd: Small sub-group check on peer element failed");
-+			goto fail;
-+		}
-+	}
-+
-+out:
-+	crypto_bignum_deinit(cofactor, 0);
-+	return element;
-+fail:
-+	crypto_ec_point_deinit(element, 0);
-+	element = NULL;
-+	goto out;
-+}
-+
-+
-+struct crypto_bignum * eap_pwd_get_scalar(EAP_PWD_group *group, const u8 *buf)
-+{
-+	struct crypto_bignum *scalar;
-+	const struct crypto_bignum *order;
-+	size_t order_len;
-+
-+	order = crypto_ec_get_order(group->group);
-+	order_len = crypto_ec_order_len(group->group);
-+
-+	/* RFC 5931, 2.8.5.2: 1 < scalar < r */
-+	scalar = crypto_bignum_init_set(buf, order_len);
-+	if (!scalar || crypto_bignum_is_zero(scalar) ||
-+	    crypto_bignum_is_one(scalar) ||
-+	    crypto_bignum_cmp(scalar, order) >= 0) {
-+		wpa_printf(MSG_INFO, "EAP-pwd: received scalar is invalid");
-+		crypto_bignum_deinit(scalar, 0);
-+		scalar = NULL;
-+	}
-+
-+	return scalar;
-+}
---- a/src/eap_common/eap_pwd_common.h
-+++ b/src/eap_common/eap_pwd_common.h
-@@ -67,5 +67,8 @@ int compute_keys(EAP_PWD_group *grp, con
- struct crypto_hash * eap_pwd_h_init(void);
- void eap_pwd_h_update(struct crypto_hash *hash, const u8 *data, size_t len);
- void eap_pwd_h_final(struct crypto_hash *hash, u8 *digest);
-+struct crypto_ec_point * eap_pwd_get_element(EAP_PWD_group *group,
-+					     const u8 *buf);
-+struct crypto_bignum * eap_pwd_get_scalar(EAP_PWD_group *group, const u8 *buf);
- 
- #endif  /* EAP_PWD_COMMON_H */
---- a/src/eap_peer/eap_pwd.c
-+++ b/src/eap_peer/eap_pwd.c
-@@ -308,7 +308,7 @@ eap_pwd_perform_commit_exchange(struct e
- 				const struct wpabuf *reqData,
- 				const u8 *payload, size_t payload_len)
- {
--	struct crypto_ec_point *K = NULL, *point = NULL;
-+	struct crypto_ec_point *K = NULL;
- 	struct crypto_bignum *mask = NULL, *cofactor = NULL;
- 	const u8 *ptr = payload;
- 	u8 *scalar = NULL, *element = NULL;
-@@ -572,63 +572,27 @@ eap_pwd_perform_commit_exchange(struct e
- 	/* process the request */
- 	data->k = crypto_bignum_init();
- 	K = crypto_ec_point_init(data->grp->group);
--	point = crypto_ec_point_init(data->grp->group);
--	if (!data->k || !K || !point) {
-+	if (!data->k || !K) {
- 		wpa_printf(MSG_INFO, "EAP-PWD (peer): peer data allocation "
- 			   "fail");
- 		goto fin;
- 	}
- 
- 	/* element, x then y, followed by scalar */
--	data->server_element = crypto_ec_point_from_bin(data->grp->group, ptr);
-+	data->server_element = eap_pwd_get_element(data->grp, ptr);
- 	if (!data->server_element) {
- 		wpa_printf(MSG_INFO, "EAP-PWD (peer): setting peer element "
- 			   "fail");
- 		goto fin;
- 	}
- 	ptr += prime_len * 2;
--	data->server_scalar = crypto_bignum_init_set(ptr, order_len);
-+	data->server_scalar = eap_pwd_get_scalar(data->grp, ptr);
- 	if (!data->server_scalar) {
- 		wpa_printf(MSG_INFO,
- 			   "EAP-PWD (peer): setting peer scalar fail");
- 		goto fin;
- 	}
- 
--	/* verify received scalar */
--	if (crypto_bignum_is_zero(data->server_scalar) ||
--	    crypto_bignum_is_one(data->server_scalar) ||
--	    crypto_bignum_cmp(data->server_scalar,
--			      crypto_ec_get_order(data->grp->group)) >= 0) {
--		wpa_printf(MSG_INFO,
--			   "EAP-PWD (peer): received scalar is invalid");
--		goto fin;
--	}
--
--	/* verify received element */
--	if (!crypto_ec_point_is_on_curve(data->grp->group,
--					 data->server_element) ||
--	    crypto_ec_point_is_at_infinity(data->grp->group,
--					   data->server_element)) {
--		wpa_printf(MSG_INFO,
--			   "EAP-PWD (peer): received element is invalid");
--		goto fin;
--	}
--
--	/* check to ensure server's element is not in a small sub-group */
--	if (!crypto_bignum_is_one(cofactor)) {
--		if (crypto_ec_point_mul(data->grp->group, data->server_element,
--					cofactor, point) < 0) {
--			wpa_printf(MSG_INFO, "EAP-PWD (peer): cannot multiply "
--				   "server element by order!\n");
--			goto fin;
--		}
--		if (crypto_ec_point_is_at_infinity(data->grp->group, point)) {
--			wpa_printf(MSG_INFO, "EAP-PWD (peer): server element "
--				   "is at infinity!\n");
--			goto fin;
--		}
--	}
--
- 	/* compute the shared key, k */
- 	if (crypto_ec_point_mul(data->grp->group, data->grp->pwe,
- 				data->server_scalar, K) < 0 ||
-@@ -702,7 +666,6 @@ fin:
- 	crypto_bignum_deinit(mask, 1);
- 	crypto_bignum_deinit(cofactor, 1);
- 	crypto_ec_point_deinit(K, 1);
--	crypto_ec_point_deinit(point, 1);
- 	if (data->outbuf == NULL)
- 		eap_pwd_state(data, FAILURE);
- 	else
---- a/src/eap_server/eap_server_pwd.c
-+++ b/src/eap_server/eap_server_pwd.c
-@@ -669,7 +669,7 @@ eap_pwd_process_commit_resp(struct eap_s
- {
- 	const u8 *ptr;
- 	struct crypto_bignum *cofactor = NULL;
--	struct crypto_ec_point *K = NULL, *point = NULL;
-+	struct crypto_ec_point *K = NULL;
- 	int res = 0;
- 	size_t prime_len, order_len;
- 
-@@ -688,9 +688,8 @@ eap_pwd_process_commit_resp(struct eap_s
- 
- 	data->k = crypto_bignum_init();
- 	cofactor = crypto_bignum_init();
--	point = crypto_ec_point_init(data->grp->group);
- 	K = crypto_ec_point_init(data->grp->group);
--	if (!data->k || !cofactor || !point || !K) {
-+	if (!data->k || !cofactor || !K) {
- 		wpa_printf(MSG_INFO, "EAP-PWD (server): peer data allocation "
- 			   "fail");
- 		goto fin;
-@@ -704,55 +703,20 @@ eap_pwd_process_commit_resp(struct eap_s
- 
- 	/* element, x then y, followed by scalar */
- 	ptr = payload;
--	data->peer_element = crypto_ec_point_from_bin(data->grp->group, ptr);
-+	data->peer_element = eap_pwd_get_element(data->grp, ptr);
- 	if (!data->peer_element) {
- 		wpa_printf(MSG_INFO, "EAP-PWD (server): setting peer element "
- 			   "fail");
- 		goto fin;
- 	}
- 	ptr += prime_len * 2;
--	data->peer_scalar = crypto_bignum_init_set(ptr, order_len);
-+	data->peer_scalar = eap_pwd_get_scalar(data->grp, ptr);
- 	if (!data->peer_scalar) {
- 		wpa_printf(MSG_INFO, "EAP-PWD (server): peer data allocation "
- 			   "fail");
- 		goto fin;
- 	}
- 
--	/* verify received scalar */
--	if (crypto_bignum_is_zero(data->peer_scalar) ||
--	    crypto_bignum_is_one(data->peer_scalar) ||
--	    crypto_bignum_cmp(data->peer_scalar,
--			      crypto_ec_get_order(data->grp->group)) >= 0) {
--		wpa_printf(MSG_INFO,
--			   "EAP-PWD (server): received scalar is invalid");
--		goto fin;
--	}
--
--	/* verify received element */
--	if (!crypto_ec_point_is_on_curve(data->grp->group,
--					 data->peer_element) ||
--	    crypto_ec_point_is_at_infinity(data->grp->group,
--					   data->peer_element)) {
--		wpa_printf(MSG_INFO,
--			   "EAP-PWD (server): received element is invalid");
--		goto fin;
--	}
--
--	/* check to ensure peer's element is not in a small sub-group */
--	if (!crypto_bignum_is_one(cofactor)) {
--		if (crypto_ec_point_mul(data->grp->group, data->peer_element,
--					cofactor, point) != 0) {
--			wpa_printf(MSG_INFO, "EAP-PWD (server): cannot "
--				   "multiply peer element by order");
--			goto fin;
--		}
--		if (crypto_ec_point_is_at_infinity(data->grp->group, point)) {
--			wpa_printf(MSG_INFO, "EAP-PWD (server): peer element "
--				   "is at infinity!\n");
--			goto fin;
--		}
--	}
--
- 	/* detect reflection attacks */
- 	if (crypto_bignum_cmp(data->my_scalar, data->peer_scalar) == 0 ||
- 	    crypto_ec_point_cmp(data->grp->group, data->my_element,
-@@ -804,7 +768,6 @@ eap_pwd_process_commit_resp(struct eap_s
- 
- fin:
- 	crypto_ec_point_deinit(K, 1);
--	crypto_ec_point_deinit(point, 1);
- 	crypto_bignum_deinit(cofactor, 1);
- 
- 	if (res)
diff --git a/package/network/services/hostapd/patches/110-no_eapol_fix.patch b/package/network/services/hostapd/patches/110-no_eapol_fix.patch
index 2a9c5ec807..81b66f8ada 100644
--- a/package/network/services/hostapd/patches/110-no_eapol_fix.patch
+++ b/package/network/services/hostapd/patches/110-no_eapol_fix.patch
@@ -1,6 +1,6 @@
 --- a/wpa_supplicant/wpa_supplicant.c
 +++ b/wpa_supplicant/wpa_supplicant.c
-@@ -295,9 +295,10 @@ void wpa_supplicant_cancel_auth_timeout(
+@@ -296,9 +296,10 @@ void wpa_supplicant_cancel_auth_timeout(
   */
  void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s)
  {
diff --git a/package/network/services/hostapd/patches/200-multicall.patch b/package/network/services/hostapd/patches/200-multicall.patch
index 9c7936695a..7a3a10b895 100644
--- a/package/network/services/hostapd/patches/200-multicall.patch
+++ b/package/network/services/hostapd/patches/200-multicall.patch
@@ -18,7 +18,7 @@
  OBJS += ../src/ap/vlan_init.o
  OBJS += ../src/ap/vlan_ifconfig.o
  OBJS += ../src/ap/vlan.o
-@@ -354,10 +356,14 @@ CFLAGS += -DCONFIG_MBO
+@@ -360,10 +362,14 @@ CFLAGS += -DCONFIG_MBO
  OBJS += ../src/ap/mbo_ap.o
  endif
  
@@ -36,7 +36,7 @@
  LIBS += $(DRV_AP_LIBS)
  
  ifdef CONFIG_L2_PACKET
-@@ -1274,6 +1280,12 @@ install: $(addprefix $(DESTDIR)$(BINDIR)
+@@ -1286,6 +1292,12 @@ install: $(addprefix $(DESTDIR)$(BINDIR)
  
  BCHECK=../src/drivers/build.hostapd
  
@@ -49,7 +49,7 @@
  hostapd: $(BCHECK) $(OBJS)
  	$(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS)
  	@$(E) "  LD " $@
-@@ -1316,6 +1328,12 @@ ifeq ($(CONFIG_TLS), linux)
+@@ -1328,6 +1340,12 @@ ifeq ($(CONFIG_TLS), linux)
  HOBJS += ../src/crypto/crypto_linux.o
  endif
  
@@ -72,7 +72,7 @@
  
  ifndef CONFIG_NO_GITVER
  # Add VERSION_STR postfix for builds from a git repository
-@@ -354,7 +355,9 @@ endif
+@@ -362,7 +363,9 @@ endif
  ifdef CONFIG_IBSS_RSN
  NEED_RSN_AUTHENTICATOR=y
  CFLAGS += -DCONFIG_IBSS_RSN
@@ -82,7 +82,7 @@
  OBJS += ibss_rsn.o
  endif
  
-@@ -862,6 +865,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS
+@@ -870,6 +873,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS
  CFLAGS += -DCONFIG_DYNAMIC_EAP_METHODS
  LIBS += -ldl -rdynamic
  endif
@@ -93,7 +93,7 @@
  endif
  
  ifdef CONFIG_AP
-@@ -869,9 +876,11 @@ NEED_EAP_COMMON=y
+@@ -877,9 +884,11 @@ NEED_EAP_COMMON=y
  NEED_RSN_AUTHENTICATOR=y
  CFLAGS += -DCONFIG_AP
  OBJS += ap.o
@@ -105,7 +105,7 @@
  OBJS += ../src/ap/hostapd.o
  OBJS += ../src/ap/wpa_auth_glue.o
  OBJS += ../src/ap/utils.o
-@@ -953,6 +962,12 @@ endif
+@@ -961,6 +970,12 @@ endif
  ifdef CONFIG_HS20
  OBJS += ../src/ap/hs20.o
  endif
@@ -118,7 +118,7 @@
  endif
  
  ifdef CONFIG_MBO
-@@ -961,7 +976,9 @@ CFLAGS += -DCONFIG_MBO
+@@ -969,7 +984,9 @@ CFLAGS += -DCONFIG_MBO
  endif
  
  ifdef NEED_RSN_AUTHENTICATOR
@@ -128,7 +128,7 @@
  NEED_AES_WRAP=y
  OBJS += ../src/ap/wpa_auth.o
  OBJS += ../src/ap/wpa_auth_ie.o
-@@ -1888,6 +1905,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv)
+@@ -1872,6 +1889,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv)
  
  $(OBJS_c) $(OBJS_t) $(OBJS_t2) $(OBJS) $(BCHECK) $(EXTRA_progs): .config
  
@@ -141,8 +141,8 @@
  wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs)
  	$(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS)
  	@$(E) "  LD " $@
-@@ -1990,6 +2013,12 @@ endif
- 		-e 's|\@DBUS_INTERFACE\@|$(DBUS_INTERFACE)|g' $< >$@
+@@ -1972,6 +1995,12 @@ endif
+ 	$(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@
  	@$(E) "  sed" $<
  
 +dump_cflags:
@@ -156,7 +156,7 @@
  wpa_cli.exe: wpa_cli
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -5476,8 +5476,8 @@ union wpa_event_data {
+@@ -5551,8 +5551,8 @@ union wpa_event_data {
   * Driver wrapper code should call this function whenever an event is received
   * from the driver.
   */
@@ -167,7 +167,7 @@
  
  /**
   * wpa_supplicant_event_global - Report a driver event for wpa_supplicant
-@@ -5489,7 +5489,7 @@ void wpa_supplicant_event(void *ctx, enu
+@@ -5564,7 +5564,7 @@ void wpa_supplicant_event(void *ctx, enu
   * Same as wpa_supplicant_event(), but we search for the interface in
   * wpa_global.
   */
@@ -178,7 +178,7 @@
  /*
 --- a/src/ap/drv_callbacks.c
 +++ b/src/ap/drv_callbacks.c
-@@ -1527,8 +1527,8 @@ static void hostapd_event_wds_sta_interf
+@@ -1568,8 +1568,8 @@ static void hostapd_event_wds_sta_interf
  }
  
  
@@ -189,7 +189,7 @@
  {
  	struct hostapd_data *hapd = ctx;
  #ifndef CONFIG_NO_STDOUT_DEBUG
-@@ -1757,7 +1757,7 @@ void wpa_supplicant_event(void *ctx, enu
+@@ -1803,7 +1803,7 @@ void wpa_supplicant_event(void *ctx, enu
  }
  
  
@@ -231,7 +231,7 @@
  	os_memset(&global, 0, sizeof(global));
 --- a/wpa_supplicant/events.c
 +++ b/wpa_supplicant/events.c
-@@ -4026,8 +4026,8 @@ static void wpas_event_assoc_reject(stru
+@@ -4176,8 +4176,8 @@ static void wpas_event_assoc_reject(stru
  }
  
  
@@ -242,7 +242,7 @@
  {
  	struct wpa_supplicant *wpa_s = ctx;
  	int resched;
-@@ -4796,7 +4796,7 @@ void wpa_supplicant_event(void *ctx, enu
+@@ -4951,7 +4951,7 @@ void wpa_supplicant_event(void *ctx, enu
  }
  
  
@@ -253,7 +253,7 @@
  	struct wpa_supplicant *wpa_s;
 --- a/wpa_supplicant/wpa_supplicant.c
 +++ b/wpa_supplicant/wpa_supplicant.c
-@@ -5861,7 +5861,6 @@ struct wpa_interface * wpa_supplicant_ma
+@@ -6087,7 +6087,6 @@ struct wpa_interface * wpa_supplicant_ma
  	return NULL;
  }
  
@@ -261,7 +261,7 @@
  /**
   * wpa_supplicant_match_existing - Match existing interfaces
   * @global: Pointer to global data from wpa_supplicant_init()
-@@ -5898,6 +5897,11 @@ static int wpa_supplicant_match_existing
+@@ -6124,6 +6123,11 @@ static int wpa_supplicant_match_existing
  
  #endif /* CONFIG_MATCH_IFACE */
  
@@ -273,7 +273,7 @@
  
  /**
   * wpa_supplicant_add_iface - Add a new network interface
-@@ -6154,6 +6158,8 @@ struct wpa_global * wpa_supplicant_init(
+@@ -6380,6 +6384,8 @@ struct wpa_global * wpa_supplicant_init(
  #ifndef CONFIG_NO_WPA_MSG
  	wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
  #endif /* CONFIG_NO_WPA_MSG */
@@ -284,7 +284,7 @@
  		wpa_debug_open_file(params->wpa_debug_file_path);
 --- a/hostapd/main.c
 +++ b/hostapd/main.c
-@@ -591,6 +591,11 @@ fail:
+@@ -592,6 +592,11 @@ fail:
  	return -1;
  }
  
@@ -296,8 +296,8 @@
  
  #ifdef CONFIG_WPS
  static int gen_uuid(const char *txt_addr)
-@@ -674,6 +679,8 @@ int main(int argc, char *argv[])
- 	hostapd_dpp_init_global(&interfaces);
+@@ -677,6 +682,8 @@ int main(int argc, char *argv[])
+ 		return -1;
  #endif /* CONFIG_DPP */
  
 +	wpa_supplicant_event = hostapd_wpa_event;
@@ -333,7 +333,7 @@
  
  const struct wpa_driver_ops *const wpa_drivers[] = { NULL };
  
-@@ -1295,6 +1300,10 @@ static void usage(void)
+@@ -1296,6 +1301,10 @@ static void usage(void)
  	       "option several times.\n");
  }
  
@@ -344,7 +344,7 @@
  
  int main(int argc, char *argv[])
  {
-@@ -1315,6 +1324,8 @@ int main(int argc, char *argv[])
+@@ -1316,6 +1325,8 @@ int main(int argc, char *argv[])
  	if (os_program_init())
  		return -1;
  
diff --git a/package/network/services/hostapd/patches/300-noscan.patch b/package/network/services/hostapd/patches/300-noscan.patch
index d055422969..73e6a4ede2 100644
--- a/package/network/services/hostapd/patches/300-noscan.patch
+++ b/package/network/services/hostapd/patches/300-noscan.patch
@@ -1,8 +1,8 @@
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
-@@ -3317,6 +3317,10 @@ static int hostapd_config_fill(struct ho
- 		}
- #endif /* CONFIG_IEEE80211W */
+@@ -3390,6 +3390,10 @@ static int hostapd_config_fill(struct ho
+ 			bss->ieee80211w = 1;
+ #endif /* CONFIG_OCV */
  #ifdef CONFIG_IEEE80211N
 +	} else if (os_strcmp(buf, "noscan") == 0) {
 +		conf->noscan = atoi(pos);
@@ -13,7 +13,7 @@
  	} else if (os_strcmp(buf, "ht_capab") == 0) {
 --- a/src/ap/ap_config.h
 +++ b/src/ap/ap_config.h
-@@ -781,6 +781,8 @@ struct hostapd_config {
+@@ -803,6 +803,8 @@ struct hostapd_config {
  
  	int ht_op_mode_fixed;
  	u16 ht_capab;
@@ -24,7 +24,7 @@
  	int no_pri_sec_switch;
 --- a/src/ap/hw_features.c
 +++ b/src/ap/hw_features.c
-@@ -480,7 +480,8 @@ static int ieee80211n_check_40mhz(struct
+@@ -477,7 +477,8 @@ static int ieee80211n_check_40mhz(struct
  	int ret;
  
  	/* Check that HT40 is used and PRI / SEC switch is allowed */
diff --git a/package/network/services/hostapd/patches/301-mesh-noscan.patch b/package/network/services/hostapd/patches/301-mesh-noscan.patch
index ed4e91cae9..7f2374424c 100644
--- a/package/network/services/hostapd/patches/301-mesh-noscan.patch
+++ b/package/network/services/hostapd/patches/301-mesh-noscan.patch
@@ -1,6 +1,6 @@
 --- a/wpa_supplicant/config.c
 +++ b/wpa_supplicant/config.c
-@@ -2233,6 +2233,7 @@ static const struct parse_data ssid_fiel
+@@ -2312,6 +2312,7 @@ static const struct parse_data ssid_fiel
  #else /* CONFIG_MESH */
  	{ INT_RANGE(mode, 0, 4) },
  #endif /* CONFIG_MESH */
@@ -10,7 +10,7 @@
  	{ STR(id_str) },
 --- a/wpa_supplicant/config_file.c
 +++ b/wpa_supplicant/config_file.c
-@@ -818,6 +818,7 @@ static void wpa_config_write_network(FIL
+@@ -829,6 +829,7 @@ static void wpa_config_write_network(FIL
  #endif /* IEEE8021X_EAPOL */
  	INT(mode);
  	INT(no_auto_peer);
@@ -20,7 +20,7 @@
  	INT(fixed_freq);
 --- a/wpa_supplicant/mesh.c
 +++ b/wpa_supplicant/mesh.c
-@@ -288,6 +288,8 @@ static int wpa_supplicant_mesh_init(stru
+@@ -358,6 +358,8 @@ static int wpa_supplicant_mesh_init(stru
  			   frequency);
  		goto out_free;
  	}
@@ -31,7 +31,7 @@
  	if (conf->hw_mode == HOSTAPD_MODE_IEEE80211A && ssid->vht) {
 --- a/wpa_supplicant/wpa_supplicant.c
 +++ b/wpa_supplicant/wpa_supplicant.c
-@@ -2081,12 +2081,12 @@ void ibss_mesh_setup_freq(struct wpa_sup
+@@ -2139,12 +2139,12 @@ void ibss_mesh_setup_freq(struct wpa_sup
  {
  	enum hostapd_hw_mode hw_mode;
  	struct hostapd_hw_modes *mode = NULL;
@@ -46,7 +46,7 @@
  	unsigned int j, k;
  	struct hostapd_freq_params vht_freq;
  	int chwidth, seg0, seg1;
-@@ -2156,7 +2156,7 @@ void ibss_mesh_setup_freq(struct wpa_sup
+@@ -2214,7 +2214,7 @@ void ibss_mesh_setup_freq(struct wpa_sup
  		return;
  
  	/* Setup higher BW only for 5 GHz */
@@ -57,7 +57,7 @@
  	for (chan_idx = 0; chan_idx < mode->num_channels; chan_idx++) {
 --- a/wpa_supplicant/config_ssid.h
 +++ b/wpa_supplicant/config_ssid.h
-@@ -856,6 +856,8 @@ struct wpa_ssid {
+@@ -916,6 +916,8 @@ struct wpa_ssid {
  	 */
  	int no_auto_peer;
  
diff --git a/package/network/services/hostapd/patches/310-rescan_immediately.patch b/package/network/services/hostapd/patches/310-rescan_immediately.patch
index 84eb252319..0bf93a6ec2 100644
--- a/package/network/services/hostapd/patches/310-rescan_immediately.patch
+++ b/package/network/services/hostapd/patches/310-rescan_immediately.patch
@@ -1,6 +1,6 @@
 --- a/wpa_supplicant/wpa_supplicant.c
 +++ b/wpa_supplicant/wpa_supplicant.c
-@@ -4312,7 +4312,7 @@ wpa_supplicant_alloc(struct wpa_supplica
+@@ -4465,7 +4465,7 @@ wpa_supplicant_alloc(struct wpa_supplica
  	if (wpa_s == NULL)
  		return NULL;
  	wpa_s->scan_req = INITIAL_SCAN_REQ;
diff --git a/package/network/services/hostapd/patches/320-optional_rfkill.patch b/package/network/services/hostapd/patches/320-optional_rfkill.patch
index bdc1764578..9a3afad1f8 100644
--- a/package/network/services/hostapd/patches/320-optional_rfkill.patch
+++ b/package/network/services/hostapd/patches/320-optional_rfkill.patch
@@ -1,14 +1,14 @@
 --- a/src/drivers/drivers.mak
 +++ b/src/drivers/drivers.mak
-@@ -49,7 +49,6 @@ NEED_SME=y
+@@ -50,7 +50,6 @@ NEED_SME=y
  NEED_AP_MLME=y
  NEED_NETLINK=y
  NEED_LINUX_IOCTL=y
 -NEED_RFKILL=y
  NEED_RADIOTAP=y
- 
- ifdef CONFIG_LIBNL32
-@@ -136,7 +135,6 @@ DRV_WPA_CFLAGS += -DCONFIG_DRIVER_WEXT
+ NEED_LIBNL=y
+ endif
+@@ -107,7 +106,6 @@ DRV_WPA_CFLAGS += -DCONFIG_DRIVER_WEXT
  CONFIG_WIRELESS_EXTENSION=y
  NEED_NETLINK=y
  NEED_LINUX_IOCTL=y
@@ -16,7 +16,7 @@
  endif
  
  ifdef CONFIG_DRIVER_NDIS
-@@ -162,7 +160,6 @@ endif
+@@ -133,7 +131,6 @@ endif
  ifdef CONFIG_WIRELESS_EXTENSION
  DRV_WPA_CFLAGS += -DCONFIG_WIRELESS_EXTENSION
  DRV_WPA_OBJS += ../src/drivers/driver_wext.o
@@ -24,7 +24,7 @@
  endif
  
  ifdef NEED_NETLINK
-@@ -175,6 +172,7 @@ endif
+@@ -146,6 +143,7 @@ endif
  
  ifdef NEED_RFKILL
  DRV_OBJS += ../src/drivers/rfkill.o
diff --git a/package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch b/package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch
index e175bbc103..0ab114f86f 100644
--- a/package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch
+++ b/package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch
@@ -1,6 +1,6 @@
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -4318,7 +4318,7 @@ static int nl80211_set_channel(struct i8
+@@ -4434,7 +4434,7 @@ static int nl80211_set_channel(struct i8
  		   freq->freq, freq->ht_enabled, freq->vht_enabled,
  		   freq->bandwidth, freq->center_freq1, freq->center_freq2);
  
diff --git a/package/network/services/hostapd/patches/341-mesh-ctrl-iface-channel-switch.patch b/package/network/services/hostapd/patches/341-mesh-ctrl-iface-channel-switch.patch
index b9a0b23a7b..e3b19a3d35 100644
--- a/package/network/services/hostapd/patches/341-mesh-ctrl-iface-channel-switch.patch
+++ b/package/network/services/hostapd/patches/341-mesh-ctrl-iface-channel-switch.patch
@@ -1,6 +1,6 @@
 --- a/wpa_supplicant/ap.c
 +++ b/wpa_supplicant/ap.c
-@@ -1363,15 +1363,35 @@ int ap_switch_channel(struct wpa_supplic
+@@ -1373,15 +1373,35 @@ int ap_switch_channel(struct wpa_supplic
  
  
  #ifdef CONFIG_CTRL_IFACE
diff --git a/package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch b/package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch
index 836339f2e2..8343595ecc 100644
--- a/package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch
+++ b/package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch
@@ -1,6 +1,6 @@
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -2634,10 +2634,15 @@ static int wpa_driver_nl80211_del_beacon
+@@ -2722,10 +2722,15 @@ static int wpa_driver_nl80211_del_beacon
  	struct nl_msg *msg;
  	struct wpa_driver_nl80211_data *drv = bss->drv;
  
@@ -18,7 +18,7 @@
  	return send_and_recv_msgs(drv, msg, NULL, NULL);
  }
  
-@@ -4919,7 +4924,7 @@ static void nl80211_teardown_ap(struct i
+@@ -5036,7 +5041,7 @@ static void nl80211_teardown_ap(struct i
  		nl80211_mgmt_unsubscribe(bss, "AP teardown");
  
  	nl80211_put_wiphy_data_ap(bss);
@@ -27,7 +27,7 @@
  }
  
  
-@@ -7160,8 +7165,6 @@ static int wpa_driver_nl80211_if_remove(
+@@ -7302,8 +7307,6 @@ static int wpa_driver_nl80211_if_remove(
  	} else {
  		wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context");
  		nl80211_teardown_ap(bss);
@@ -36,7 +36,7 @@
  		nl80211_destroy_bss(bss);
  		if (!bss->added_if)
  			i802_set_iface_flags(bss, 0);
-@@ -7540,7 +7543,6 @@ static int wpa_driver_nl80211_deinit_ap(
+@@ -7693,7 +7696,6 @@ static int wpa_driver_nl80211_deinit_ap(
  	if (!is_ap_interface(drv->nlmode))
  		return -1;
  	wpa_driver_nl80211_del_beacon(bss);
@@ -44,7 +44,7 @@
  
  	/*
  	 * If the P2P GO interface was dynamically added, then it is
-@@ -7560,7 +7562,6 @@ static int wpa_driver_nl80211_stop_ap(vo
+@@ -7713,7 +7715,6 @@ static int wpa_driver_nl80211_stop_ap(vo
  	if (!is_ap_interface(drv->nlmode))
  		return -1;
  	wpa_driver_nl80211_del_beacon(bss);
diff --git a/package/network/services/hostapd/patches/360-ctrl_iface_reload.patch b/package/network/services/hostapd/patches/360-ctrl_iface_reload.patch
index 537c0881c4..c0108c7ce0 100644
--- a/package/network/services/hostapd/patches/360-ctrl_iface_reload.patch
+++ b/package/network/services/hostapd/patches/360-ctrl_iface_reload.patch
@@ -78,7 +78,7 @@
  
  #ifdef CONFIG_IEEE80211W
  #ifdef NEED_AP_MLME
-@@ -3084,6 +3141,8 @@ static int hostapd_ctrl_iface_receive_pr
+@@ -3172,6 +3229,8 @@ static int hostapd_ctrl_iface_receive_pr
  	} else if (os_strncmp(buf, "VENDOR ", 7) == 0) {
  		reply_len = hostapd_ctrl_iface_vendor(hapd, buf + 7, reply,
  						      reply_size);
@@ -89,7 +89,7 @@
  #ifdef RADIUS_SERVER
 --- a/src/ap/ctrl_iface_ap.c
 +++ b/src/ap/ctrl_iface_ap.c
-@@ -864,7 +864,13 @@ int hostapd_parse_csa_settings(const cha
+@@ -872,7 +872,13 @@ int hostapd_parse_csa_settings(const cha
  
  int hostapd_ctrl_iface_stop_ap(struct hostapd_data *hapd)
  {
diff --git a/package/network/services/hostapd/patches/370-ap_sta_support.patch b/package/network/services/hostapd/patches/370-ap_sta_support.patch
index d93984a172..79dc3f56e8 100644
--- a/package/network/services/hostapd/patches/370-ap_sta_support.patch
+++ b/package/network/services/hostapd/patches/370-ap_sta_support.patch
@@ -11,7 +11,7 @@
  -include .config
  -include $(if $(MULTICALL),../hostapd/.config)
  
-@@ -117,6 +121,8 @@ OBJS_c += ../src/utils/common.o
+@@ -116,6 +120,8 @@ OBJS_c += ../src/utils/common.o
  OBJS_c += ../src/common/cli.o
  OBJS += wmm_ac.o
  
@@ -110,7 +110,7 @@
  			break;
 --- a/wpa_supplicant/wpa_supplicant.c
 +++ b/wpa_supplicant/wpa_supplicant.c
-@@ -125,6 +125,55 @@ static void wpas_update_fils_connect_par
+@@ -126,6 +126,55 @@ static void wpas_update_fils_connect_par
  #endif /* CONFIG_FILS && IEEE8021X_EAPOL */
  
  
@@ -166,7 +166,7 @@
  /* Configure default/group WEP keys for static WEP */
  int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
  {
-@@ -920,12 +969,16 @@ void wpa_supplicant_set_state(struct wpa
+@@ -940,12 +989,16 @@ void wpa_supplicant_set_state(struct wpa
  
  		sme_sched_obss_scan(wpa_s, 1);
  
@@ -183,7 +183,7 @@
  		wpa_s->new_connection = 1;
  		wpa_drv_set_operstate(wpa_s, 0);
  #ifndef IEEE8021X_EAPOL
-@@ -1977,6 +2030,8 @@ void wpa_supplicant_associate(struct wpa
+@@ -2035,6 +2088,8 @@ void wpa_supplicant_associate(struct wpa
  			wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
  			ssid->id);
  		wpas_notify_mesh_group_started(wpa_s, ssid);
@@ -192,7 +192,7 @@
  #else /* CONFIG_MESH */
  		wpa_msg(wpa_s, MSG_ERROR,
  			"mesh mode support not included in the build");
-@@ -5487,6 +5542,16 @@ static int wpa_supplicant_init_iface(str
+@@ -5707,6 +5762,16 @@ static int wpa_supplicant_init_iface(str
  			   sizeof(wpa_s->bridge_ifname));
  	}
  
@@ -209,7 +209,7 @@
  	/* RSNA Supplicant Key Management - INITIALIZE */
  	eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
  	eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
-@@ -5808,6 +5873,11 @@ static void wpa_supplicant_deinit_iface(
+@@ -6034,6 +6099,11 @@ static void wpa_supplicant_deinit_iface(
  	if (terminate)
  		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
  
@@ -235,7 +235,7 @@
  	 * bridge_ifname - Optional bridge interface name
  	 *
  	 * If the driver interface (ifname) is included in a Linux bridge
-@@ -513,6 +518,8 @@ struct wpa_supplicant {
+@@ -516,6 +521,8 @@ struct wpa_supplicant {
  #endif /* CONFIG_CTRL_IFACE_BINDER */
  	char bridge_ifname[16];
  
@@ -246,7 +246,7 @@
  
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -2328,6 +2328,11 @@ static int hostapd_ctrl_iface_chan_switc
+@@ -2385,6 +2385,11 @@ static int hostapd_ctrl_iface_chan_switc
  	if (ret)
  		return ret;
  
@@ -260,7 +260,7 @@
  		/* Save CHAN_SWITCH VHT config */
 --- a/src/ap/beacon.c
 +++ b/src/ap/beacon.c
-@@ -1381,11 +1381,6 @@ int ieee802_11_set_beacon(struct hostapd
+@@ -1397,11 +1397,6 @@ int ieee802_11_set_beacon(struct hostapd
  	struct wpabuf *beacon, *proberesp, *assocresp;
  	int res, ret = -1;
  
@@ -274,7 +274,7 @@
  	if (ieee802_11_build_ap_params(hapd, &params) < 0)
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -4469,6 +4469,13 @@ enum wpa_event_type {
+@@ -4544,6 +4544,13 @@ enum wpa_event_type {
  	EVENT_CH_SWITCH,
  
  	/**
@@ -288,7 +288,7 @@
  	 * EVENT_WNM - Request WNM operation
  	 *
  	 * This event can be used to request a WNM operation to be performed.
-@@ -5306,6 +5313,7 @@ union wpa_event_data {
+@@ -5381,6 +5388,7 @@ union wpa_event_data {
  
  	/**
  	 * struct ch_switch
@@ -296,7 +296,7 @@
  	 * @freq: Frequency of new channel in MHz
  	 * @ht_enabled: Whether this is an HT channel
  	 * @ch_offset: Secondary channel offset
-@@ -5314,6 +5322,7 @@ union wpa_event_data {
+@@ -5389,6 +5397,7 @@ union wpa_event_data {
  	 * @cf2: Center frequency 2
  	 */
  	struct ch_switch {
@@ -306,7 +306,7 @@
  		int ch_offset;
 --- a/src/drivers/driver_nl80211_event.c
 +++ b/src/drivers/driver_nl80211_event.c
-@@ -526,7 +526,8 @@ static int calculate_chan_offset(int wid
+@@ -534,7 +534,8 @@ static int calculate_chan_offset(int wid
  static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
  				 struct nlattr *ifindex, struct nlattr *freq,
  				 struct nlattr *type, struct nlattr *bw,
@@ -316,7 +316,7 @@
  {
  	struct i802_bss *bss;
  	union wpa_event_data data;
-@@ -584,11 +585,15 @@ static void mlme_event_ch_switch(struct
+@@ -592,11 +593,15 @@ static void mlme_event_ch_switch(struct
  		data.ch_switch.cf1 = nla_get_u32(cf1);
  	if (cf2)
  		data.ch_switch.cf2 = nla_get_u32(cf2);
@@ -333,7 +333,7 @@
  }
  
  
-@@ -2446,6 +2451,7 @@ static void do_process_drv_event(struct
+@@ -2508,6 +2513,7 @@ static void do_process_drv_event(struct
  				   tb[NL80211_ATTR_PMK],
  				   tb[NL80211_ATTR_PMKID]);
  		break;
@@ -341,7 +341,7 @@
  	case NL80211_CMD_CH_SWITCH_NOTIFY:
  		mlme_event_ch_switch(drv,
  				     tb[NL80211_ATTR_IFINDEX],
-@@ -2453,7 +2459,8 @@ static void do_process_drv_event(struct
+@@ -2515,7 +2521,8 @@ static void do_process_drv_event(struct
  				     tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE],
  				     tb[NL80211_ATTR_CHANNEL_WIDTH],
  				     tb[NL80211_ATTR_CENTER_FREQ1],
@@ -353,7 +353,7 @@
  		mlme_event_disconnect(drv, tb[NL80211_ATTR_REASON_CODE],
 --- a/wpa_supplicant/events.c
 +++ b/wpa_supplicant/events.c
-@@ -4026,6 +4026,60 @@ static void wpas_event_assoc_reject(stru
+@@ -4176,6 +4176,60 @@ static void wpas_event_assoc_reject(stru
  }
  
  
@@ -414,7 +414,7 @@
  void supplicant_event(void *ctx, enum wpa_event_type event,
  		      union wpa_event_data *data)
  {
-@@ -4309,6 +4363,10 @@ void supplicant_event(void *ctx, enum wp
+@@ -4461,6 +4515,10 @@ void supplicant_event(void *ctx, enum wp
  				       data->rx_from_unknown.wds);
  		break;
  #endif /* CONFIG_AP */
diff --git a/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch b/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch
index 2fe03340a8..86f8ba48c3 100644
--- a/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch
+++ b/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch
@@ -12,7 +12,7 @@
  else
 --- a/hostapd/ctrl_iface.c
 +++ b/hostapd/ctrl_iface.c
-@@ -2912,6 +2912,7 @@ static int hostapd_ctrl_iface_receive_pr
+@@ -2997,6 +2997,7 @@ static int hostapd_ctrl_iface_receive_pr
  						      reply_size);
  	} else if (os_strcmp(buf, "STATUS-DRIVER") == 0) {
  		reply_len = hostapd_drv_status(hapd, reply, reply_size);
@@ -20,7 +20,7 @@
  	} else if (os_strcmp(buf, "MIB") == 0) {
  		reply_len = ieee802_11_get_mib(hapd, reply, reply_size);
  		if (reply_len >= 0) {
-@@ -2953,6 +2954,7 @@ static int hostapd_ctrl_iface_receive_pr
+@@ -3038,6 +3039,7 @@ static int hostapd_ctrl_iface_receive_pr
  	} else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
  		reply_len = hostapd_ctrl_iface_sta_next(hapd, buf + 9, reply,
  							reply_size);
@@ -30,7 +30,7 @@
  			reply_len = -1;
 --- a/wpa_supplicant/Makefile
 +++ b/wpa_supplicant/Makefile
-@@ -927,6 +927,9 @@ ifdef CONFIG_FILS
+@@ -935,6 +935,9 @@ ifdef CONFIG_FILS
  OBJS += ../src/ap/fils_hlp.o
  endif
  ifdef CONFIG_CTRL_IFACE
@@ -42,7 +42,7 @@
  
 --- a/wpa_supplicant/ctrl_iface.c
 +++ b/wpa_supplicant/ctrl_iface.c
-@@ -2117,7 +2117,7 @@ static int wpa_supplicant_ctrl_iface_sta
+@@ -2144,7 +2144,7 @@ static int wpa_supplicant_ctrl_iface_sta
  			pos += ret;
  		}
  
@@ -51,7 +51,7 @@
  		if (wpa_s->ap_iface) {
  			pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos,
  							    end - pos,
-@@ -9852,6 +9852,7 @@ char * wpa_supplicant_ctrl_iface_process
+@@ -9968,6 +9968,7 @@ char * wpa_supplicant_ctrl_iface_process
  			reply_len = -1;
  	} else if (os_strncmp(buf, "NOTE ", 5) == 0) {
  		wpa_printf(MSG_INFO, "NOTE: %s", buf + 5);
@@ -59,15 +59,15 @@
  	} else if (os_strcmp(buf, "MIB") == 0) {
  		reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size);
  		if (reply_len >= 0) {
-@@ -9859,6 +9860,7 @@ char * wpa_supplicant_ctrl_iface_process
- 						      reply + reply_len,
- 						      reply_size - reply_len);
+@@ -9980,6 +9981,7 @@ char * wpa_supplicant_ctrl_iface_process
+ 				reply_size - reply_len);
+ #endif /* CONFIG_MACSEC */
  		}
 +#endif
  	} else if (os_strncmp(buf, "STATUS", 6) == 0) {
  		reply_len = wpa_supplicant_ctrl_iface_status(
  			wpa_s, buf + 6, reply, reply_size);
-@@ -10340,6 +10342,7 @@ char * wpa_supplicant_ctrl_iface_process
+@@ -10461,6 +10463,7 @@ char * wpa_supplicant_ctrl_iface_process
  		reply_len = wpa_supplicant_ctrl_iface_bss(
  			wpa_s, buf + 4, reply, reply_size);
  #ifdef CONFIG_AP
@@ -75,7 +75,7 @@
  	} else if (os_strcmp(buf, "STA-FIRST") == 0) {
  		reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size);
  	} else if (os_strncmp(buf, "STA ", 4) == 0) {
-@@ -10348,12 +10351,15 @@ char * wpa_supplicant_ctrl_iface_process
+@@ -10469,12 +10472,15 @@ char * wpa_supplicant_ctrl_iface_process
  	} else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
  		reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply,
  						   reply_size);
@@ -101,7 +101,7 @@
  
  static size_t hostapd_write_ht_mcs_bitmask(char *buf, size_t buflen,
  					   size_t curr_len, const u8 *mcs_set)
-@@ -415,6 +416,7 @@ int hostapd_ctrl_iface_sta_next(struct h
+@@ -423,6 +424,7 @@ int hostapd_ctrl_iface_sta_next(struct h
  	return hostapd_ctrl_iface_sta_mib(hapd, sta->next, buf, buflen);
  }
  
@@ -109,7 +109,7 @@
  
  #ifdef CONFIG_P2P_MANAGER
  static int p2p_manager_disconnect(struct hostapd_data *hapd, u16 stype,
-@@ -753,12 +755,12 @@ int hostapd_ctrl_iface_status(struct hos
+@@ -761,12 +763,12 @@ int hostapd_ctrl_iface_status(struct hos
  			return len;
  		len += ret;
  	}
@@ -126,7 +126,7 @@
  		if (os_snprintf_error(buflen - len, ret))
 --- a/src/ap/ieee802_1x.c
 +++ b/src/ap/ieee802_1x.c
-@@ -2581,6 +2581,7 @@ static const char * bool_txt(Boolean val
+@@ -2579,6 +2579,7 @@ static const char * bool_txt(Boolean val
  	return val ? "TRUE" : "FALSE";
  }
  
@@ -134,7 +134,7 @@
  
  int ieee802_1x_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen)
  {
-@@ -2756,6 +2757,7 @@ int ieee802_1x_get_mib_sta(struct hostap
+@@ -2765,6 +2766,7 @@ int ieee802_1x_get_mib_sta(struct hostap
  	return len;
  }
  
@@ -144,7 +144,7 @@
  static void ieee802_1x_wnm_notif_send(void *eloop_ctx, void *timeout_ctx)
 --- a/src/ap/wpa_auth.c
 +++ b/src/ap/wpa_auth.c
-@@ -3798,6 +3798,7 @@ static const char * wpa_bool_txt(int val
+@@ -4112,6 +4112,7 @@ static const char * wpa_bool_txt(int val
  	return val ? "TRUE" : "FALSE";
  }
  
@@ -152,7 +152,7 @@
  
  #define RSN_SUITE "%02x-%02x-%02x-%d"
  #define RSN_SUITE_ARG(s) \
-@@ -3942,7 +3943,7 @@ int wpa_get_mib_sta(struct wpa_state_mac
+@@ -4256,7 +4257,7 @@ int wpa_get_mib_sta(struct wpa_state_mac
  
  	return len;
  }
@@ -163,7 +163,7 @@
  {
 --- a/src/rsn_supp/wpa.c
 +++ b/src/rsn_supp/wpa.c
-@@ -2319,6 +2319,8 @@ static u32 wpa_key_mgmt_suite(struct wpa
+@@ -2481,6 +2481,8 @@ static u32 wpa_key_mgmt_suite(struct wpa
  }
  
  
@@ -172,7 +172,7 @@
  #define RSN_SUITE "%02x-%02x-%02x-%d"
  #define RSN_SUITE_ARG(s) \
  ((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff
-@@ -2402,6 +2404,7 @@ int wpa_sm_get_mib(struct wpa_sm *sm, ch
+@@ -2564,6 +2566,7 @@ int wpa_sm_get_mib(struct wpa_sm *sm, ch
  
  	return (int) len;
  }
@@ -182,7 +182,7 @@
  
 --- a/wpa_supplicant/ap.c
 +++ b/wpa_supplicant/ap.c
-@@ -1221,7 +1221,7 @@ int wpas_ap_wps_nfc_report_handover(stru
+@@ -1231,7 +1231,7 @@ int wpas_ap_wps_nfc_report_handover(stru
  #endif /* CONFIG_WPS */
  
  
diff --git a/package/network/services/hostapd/patches/390-wpa_ie_cap_workaround.patch b/package/network/services/hostapd/patches/390-wpa_ie_cap_workaround.patch
index 855fc808e9..92b3d9b046 100644
--- a/package/network/services/hostapd/patches/390-wpa_ie_cap_workaround.patch
+++ b/package/network/services/hostapd/patches/390-wpa_ie_cap_workaround.patch
@@ -1,6 +1,6 @@
 --- a/src/common/wpa_common.c
 +++ b/src/common/wpa_common.c
-@@ -2042,6 +2042,31 @@ u32 wpa_akm_to_suite(int akm)
+@@ -2079,6 +2079,31 @@ u32 wpa_akm_to_suite(int akm)
  }
  
  
@@ -32,7 +32,7 @@
  int wpa_compare_rsn_ie(int ft_initial_assoc,
  		       const u8 *ie1, size_t ie1len,
  		       const u8 *ie2, size_t ie2len)
-@@ -2049,8 +2074,19 @@ int wpa_compare_rsn_ie(int ft_initial_as
+@@ -2086,8 +2111,19 @@ int wpa_compare_rsn_ie(int ft_initial_as
  	if (ie1 == NULL || ie2 == NULL)
  		return -1;
  
diff --git a/package/network/services/hostapd/patches/400-wps_single_auth_enc_type.patch b/package/network/services/hostapd/patches/400-wps_single_auth_enc_type.patch
index ea144f4def..7f1986ec46 100644
--- a/package/network/services/hostapd/patches/400-wps_single_auth_enc_type.patch
+++ b/package/network/services/hostapd/patches/400-wps_single_auth_enc_type.patch
@@ -10,7 +10,7 @@
  			bss->wpa_pairwise |= WPA_CIPHER_TKIP;
  		bss->rsn_pairwise = bss->wpa_pairwise;
  		bss->wpa_group = wpa_select_ap_group_cipher(bss->wpa,
-@@ -1069,8 +1068,7 @@ int hostapd_init_wps(struct hostapd_data
+@@ -1108,8 +1107,7 @@ int hostapd_init_wps(struct hostapd_data
  					  WPA_CIPHER_GCMP_256)) {
  			wps->encr_types |= WPS_ENCR_AES;
  			wps->encr_types_rsn |= WPS_ENCR_AES;
diff --git a/package/network/services/hostapd/patches/410-limit_debug_messages.patch b/package/network/services/hostapd/patches/410-limit_debug_messages.patch
index d182e8d986..624897cd02 100644
--- a/package/network/services/hostapd/patches/410-limit_debug_messages.patch
+++ b/package/network/services/hostapd/patches/410-limit_debug_messages.patch
@@ -43,7 +43,7 @@
  {
  	size_t i, llen;
  	const u8 *pos = buf;
-@@ -499,20 +487,6 @@ static void _wpa_hexdump_ascii(int level
+@@ -505,20 +493,6 @@ static void _wpa_hexdump_ascii(int level
  }
  
  
@@ -64,7 +64,7 @@
  #ifdef CONFIG_DEBUG_FILE
  static char *last_path = NULL;
  #endif /* CONFIG_DEBUG_FILE */
-@@ -628,7 +602,7 @@ void wpa_msg_register_ifname_cb(wpa_msg_
+@@ -634,7 +608,7 @@ void wpa_msg_register_ifname_cb(wpa_msg_
  }
  
  
@@ -73,7 +73,7 @@
  {
  	va_list ap;
  	char *buf;
-@@ -666,7 +640,7 @@ void wpa_msg(void *ctx, int level, const
+@@ -672,7 +646,7 @@ void wpa_msg(void *ctx, int level, const
  }
  
  
diff --git a/package/network/services/hostapd/patches/420-indicate-features.patch b/package/network/services/hostapd/patches/420-indicate-features.patch
index d582c8574c..fe5e2d89a3 100644
--- a/package/network/services/hostapd/patches/420-indicate-features.patch
+++ b/package/network/services/hostapd/patches/420-indicate-features.patch
@@ -8,7 +8,7 @@
  #include "crypto/random.h"
  #include "crypto/tls.h"
  #include "common/version.h"
-@@ -682,7 +683,7 @@ int main(int argc, char *argv[])
+@@ -685,7 +686,7 @@ int main(int argc, char *argv[])
  	wpa_supplicant_event = hostapd_wpa_event;
  	wpa_supplicant_event_global = hostapd_wpa_event_global;
  	for (;;) {
@@ -17,7 +17,7 @@
  		if (c < 0)
  			break;
  		switch (c) {
-@@ -719,6 +720,8 @@ int main(int argc, char *argv[])
+@@ -722,6 +723,8 @@ int main(int argc, char *argv[])
  			break;
  #endif /* CONFIG_DEBUG_LINUX_TRACING */
  		case 'v':
@@ -47,7 +47,7 @@
  		switch (c) {
 @@ -305,8 +306,12 @@ int main(int argc, char *argv[])
  			break;
- #endif /* CONFIG_DBUS */
+ #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
  		case 'v':
 -			printf("%s\n", wpa_supplicant_version);
 -			exitcode = 0;
diff --git a/package/network/services/hostapd/patches/430-hostapd_cli_ifdef.patch b/package/network/services/hostapd/patches/430-hostapd_cli_ifdef.patch
index 29dc0832ee..3cb07d16d7 100644
--- a/package/network/services/hostapd/patches/430-hostapd_cli_ifdef.patch
+++ b/package/network/services/hostapd/patches/430-hostapd_cli_ifdef.patch
@@ -32,7 +32,7 @@
  
  
  static int hostapd_cli_cmd_disassoc_imminent(struct wpa_ctrl *ctrl, int argc,
-@@ -1510,15 +1506,12 @@ static const struct hostapd_cli_cmd host
+@@ -1531,15 +1527,12 @@ static const struct hostapd_cli_cmd host
  	{ "disassociate", hostapd_cli_cmd_disassociate,
  	  hostapd_complete_stations,
  	  "<addr> = disassociate a station" },
@@ -48,7 +48,7 @@
  	{ "wps_pin", hostapd_cli_cmd_wps_pin, NULL,
  	  "<uuid> <pin> [timeout] [addr] = add WPS Enrollee PIN" },
  	{ "wps_check_pin", hostapd_cli_cmd_wps_check_pin, NULL,
-@@ -1543,7 +1536,6 @@ static const struct hostapd_cli_cmd host
+@@ -1564,7 +1557,6 @@ static const struct hostapd_cli_cmd host
  	  "<SSID> <auth> <encr> <key> = configure AP" },
  	{ "wps_get_status", hostapd_cli_cmd_wps_get_status, NULL,
  	  "= show current WPS status" },
diff --git a/package/network/services/hostapd/patches/450-scan_wait.patch b/package/network/services/hostapd/patches/450-scan_wait.patch
index 9620ecc520..5e080df82f 100644
--- a/package/network/services/hostapd/patches/450-scan_wait.patch
+++ b/package/network/services/hostapd/patches/450-scan_wait.patch
@@ -1,6 +1,6 @@
 --- a/hostapd/main.c
 +++ b/hostapd/main.c
-@@ -38,6 +38,8 @@ struct hapd_global {
+@@ -39,6 +39,8 @@ struct hapd_global {
  };
  
  static struct hapd_global global;
@@ -9,7 +9,7 @@
  
  
  #ifndef CONFIG_NO_HOSTAPD_LOGGER
-@@ -148,6 +150,14 @@ static void hostapd_logger_cb(void *ctx,
+@@ -149,6 +151,14 @@ static void hostapd_logger_cb(void *ctx,
  }
  #endif /* CONFIG_NO_HOSTAPD_LOGGER */
  
@@ -24,7 +24,7 @@
  
  /**
   * hostapd_driver_init - Preparate driver interface
-@@ -166,6 +176,8 @@ static int hostapd_driver_init(struct ho
+@@ -167,6 +177,8 @@ static int hostapd_driver_init(struct ho
  		return -1;
  	}
  
@@ -33,7 +33,7 @@
  	/* Initialize the driver interface */
  	if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5]))
  		b = NULL;
-@@ -406,8 +418,6 @@ static void hostapd_global_deinit(const
+@@ -407,8 +419,6 @@ static void hostapd_global_deinit(const
  #endif /* CONFIG_NATIVE_WINDOWS */
  
  	eap_server_unregister_methods();
@@ -42,7 +42,7 @@
  }
  
  
-@@ -433,18 +443,6 @@ static int hostapd_global_run(struct hap
+@@ -434,18 +444,6 @@ static int hostapd_global_run(struct hap
  	}
  #endif /* EAP_SERVER_TNC */
  
@@ -61,7 +61,7 @@
  	eloop_run();
  
  	return 0;
-@@ -646,8 +644,7 @@ int main(int argc, char *argv[])
+@@ -647,8 +645,7 @@ int main(int argc, char *argv[])
  	struct hapd_interfaces interfaces;
  	int ret = 1;
  	size_t i, j;
diff --git a/package/network/services/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch b/package/network/services/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch
index 1bb5d6e620..a0869e9c1c 100644
--- a/package/network/services/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch
+++ b/package/network/services/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch
@@ -22,7 +22,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
  #include "common/defs.h"
  #include "common/ieee802_11_defs.h"
  #include "common/wpa_common.h"
-@@ -774,6 +775,9 @@ struct wpa_driver_associate_params {
+@@ -791,6 +792,9 @@ struct wpa_driver_associate_params {
  	 * responsible for selecting with which BSS to associate. */
  	const u8 *bssid;
  
@@ -42,7 +42,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
  #include "config.h"
  
  
-@@ -2053,6 +2054,97 @@ static char * wpa_config_write_peerkey(c
+@@ -2130,6 +2131,97 @@ static char * wpa_config_write_peerkey(c
  #endif /* NO_CONFIG_WRITE */
  
  
@@ -140,7 +140,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
  /* Helper macros for network block parser */
  
  #ifdef OFFSET
-@@ -2298,6 +2390,8 @@ static const struct parse_data ssid_fiel
+@@ -2382,6 +2474,8 @@ static const struct parse_data ssid_fiel
  	{ INT(ap_max_inactivity) },
  	{ INT(dtim_period) },
  	{ INT(beacon_int) },
@@ -162,7 +162,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
  
  
  #define DEFAULT_EAP_WORKAROUND ((unsigned int) -1)
-@@ -757,6 +759,9 @@ struct wpa_ssid {
+@@ -788,6 +790,9 @@ struct wpa_ssid {
  	 */
  	void *parent_cred;
  
@@ -174,7 +174,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
  	 * macsec_policy - Determines the policy for MACsec secure session
 --- a/wpa_supplicant/wpa_supplicant.c
 +++ b/wpa_supplicant/wpa_supplicant.c
-@@ -3117,6 +3117,12 @@ static void wpas_start_assoc_cb(struct w
+@@ -3258,6 +3258,12 @@ static void wpas_start_assoc_cb(struct w
  			params.beacon_int = ssid->beacon_int;
  		else
  			params.beacon_int = wpa_s->conf->beacon_int;
diff --git a/package/network/services/hostapd/patches/461-driver_nl80211-use-new-parameters-during-ibss-join.patch b/package/network/services/hostapd/patches/461-driver_nl80211-use-new-parameters-during-ibss-join.patch
index 287cd1dd2e..efae01a40a 100644
--- a/package/network/services/hostapd/patches/461-driver_nl80211-use-new-parameters-during-ibss-join.patch
+++ b/package/network/services/hostapd/patches/461-driver_nl80211-use-new-parameters-during-ibss-join.patch
@@ -10,7 +10,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
 
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -5178,7 +5178,7 @@ static int wpa_driver_nl80211_ibss(struc
+@@ -5295,7 +5295,7 @@ static int wpa_driver_nl80211_ibss(struc
  				   struct wpa_driver_associate_params *params)
  {
  	struct nl_msg *msg;
@@ -19,7 +19,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
  	int count = 0;
  
  	wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex);
-@@ -5205,6 +5205,37 @@ retry:
+@@ -5322,6 +5322,37 @@ retry:
  	    nl80211_put_beacon_int(msg, params->beacon_int))
  		goto fail;
  
diff --git a/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch b/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch
index 55a48b9733..4bc2fdcecc 100644
--- a/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch
+++ b/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch
@@ -19,7 +19,7 @@ Tested-by: Simon Wunderlich <simon.wunderlich@openmesh.com>
 
 --- a/src/drivers/driver.h
 +++ b/src/drivers/driver.h
-@@ -1409,6 +1409,7 @@ struct wpa_driver_mesh_join_params {
+@@ -1443,6 +1443,7 @@ struct wpa_driver_mesh_join_params {
  #define WPA_DRIVER_MESH_FLAG_AMPE	0x00000008
  	unsigned int flags;
  	u8 handle_dfs;
@@ -29,7 +29,7 @@ Tested-by: Simon Wunderlich <simon.wunderlich@openmesh.com>
  /**
 --- a/src/drivers/driver_nl80211.c
 +++ b/src/drivers/driver_nl80211.c
-@@ -9352,6 +9352,18 @@ static int nl80211_put_mesh_id(struct nl
+@@ -9532,6 +9532,18 @@ static int nl80211_put_mesh_id(struct nl
  }
  
  
@@ -48,7 +48,7 @@ Tested-by: Simon Wunderlich <simon.wunderlich@openmesh.com>
  static int nl80211_put_mesh_config(struct nl_msg *msg,
  				   struct wpa_driver_mesh_bss_params *params)
  {
-@@ -9413,6 +9425,7 @@ static int nl80211_join_mesh(struct i802
+@@ -9593,6 +9605,7 @@ static int nl80211_join_mesh(struct i802
  	    nl80211_put_basic_rates(msg, params->basic_rates) ||
  	    nl80211_put_mesh_id(msg, params->meshid, params->meshid_len) ||
  	    nl80211_put_beacon_int(msg, params->beacon_int) ||
@@ -58,7 +58,7 @@ Tested-by: Simon Wunderlich <simon.wunderlich@openmesh.com>
  
 --- a/wpa_supplicant/mesh.c
 +++ b/wpa_supplicant/mesh.c
-@@ -482,6 +482,7 @@ int wpa_supplicant_join_mesh(struct wpa_
+@@ -486,6 +486,7 @@ int wpa_supplicant_join_mesh(struct wpa_
  
  	params->meshid = ssid->ssid;
  	params->meshid_len = ssid->ssid_len;
diff --git a/package/network/services/hostapd/patches/464-fix-mesh-obss-check.patch b/package/network/services/hostapd/patches/464-fix-mesh-obss-check.patch
index 3d4946e0b0..5b7dc391e0 100644
--- a/package/network/services/hostapd/patches/464-fix-mesh-obss-check.patch
+++ b/package/network/services/hostapd/patches/464-fix-mesh-obss-check.patch
@@ -1,6 +1,6 @@
 --- a/wpa_supplicant/wpa_supplicant.c
 +++ b/wpa_supplicant/wpa_supplicant.c
-@@ -2154,11 +2154,13 @@ void ibss_mesh_setup_freq(struct wpa_sup
+@@ -2212,11 +2212,13 @@ void ibss_mesh_setup_freq(struct wpa_sup
  	for (j = 0; j < wpa_s->last_scan_res_used; j++) {
  		struct wpa_bss *bss = wpa_s->last_scan_res[j];
  
diff --git a/package/network/services/hostapd/patches/470-survey_data_fallback.patch b/package/network/services/hostapd/patches/470-survey_data_fallback.patch
index 1c094bed23..a0e5384e3c 100644
--- a/package/network/services/hostapd/patches/470-survey_data_fallback.patch
+++ b/package/network/services/hostapd/patches/470-survey_data_fallback.patch
@@ -1,6 +1,6 @@
 --- a/src/ap/acs.c
 +++ b/src/ap/acs.c
-@@ -292,18 +292,12 @@ static void acs_fail(struct hostapd_ifac
+@@ -293,18 +293,12 @@ static void acs_fail(struct hostapd_ifac
  static long double
  acs_survey_interference_factor(struct freq_survey *survey, s8 min_nf)
  {
@@ -20,7 +20,7 @@
  
  	total = survey->channel_time;
  
-@@ -392,20 +386,19 @@ static int acs_usable_vht80_chan(struct
+@@ -406,20 +400,19 @@ static int acs_usable_vht160_chan(const
  static int acs_survey_is_sufficient(struct freq_survey *survey)
  {
  	if (!(survey->filled & SURVEY_HAS_NF)) {
diff --git a/package/network/services/hostapd/patches/500-lto-jobserver-support.patch b/package/network/services/hostapd/patches/500-lto-jobserver-support.patch
index a65ad9c7f6..31c578537d 100644
--- a/package/network/services/hostapd/patches/500-lto-jobserver-support.patch
+++ b/package/network/services/hostapd/patches/500-lto-jobserver-support.patch
@@ -1,6 +1,6 @@
 --- a/hostapd/Makefile
 +++ b/hostapd/Makefile
-@@ -1290,14 +1290,14 @@ hostapd_multi.a: $(BCHECK) $(OBJS)
+@@ -1302,14 +1302,14 @@ hostapd_multi.a: $(BCHECK) $(OBJS)
  	@$(AR) cr $@ hostapd_multi.o $(OBJS)
  
  hostapd: $(BCHECK) $(OBJS)
@@ -19,7 +19,7 @@
  NOBJS = nt_password_hash.o ../src/crypto/ms_funcs.o $(SHA1OBJS)
 --- a/wpa_supplicant/Makefile
 +++ b/wpa_supplicant/Makefile
-@@ -1921,23 +1921,23 @@ wpa_supplicant_multi.a: .config $(BCHECK
+@@ -1905,23 +1905,23 @@ wpa_supplicant_multi.a: .config $(BCHECK
  	@$(AR) cr $@ wpa_supplicant_multi.o $(OBJS)
  
  wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs)
diff --git a/package/network/services/hostapd/patches/550-hostapd-Add-Multi-AP-protocol-support.patch b/package/network/services/hostapd/patches/550-hostapd-Add-Multi-AP-protocol-support.patch
deleted file mode 100644
index 812f794eda..0000000000
--- a/package/network/services/hostapd/patches/550-hostapd-Add-Multi-AP-protocol-support.patch
+++ /dev/null
@@ -1,306 +0,0 @@
-From 9c06f0f6aed26c1628acaa74df0232dd7b345e9a Mon Sep 17 00:00:00 2001
-From: Venkateswara Naralasetty <vnaralas@codeaurora.org>
-Date: Wed, 5 Dec 2018 11:23:51 +0100
-Subject: [PATCH] hostapd: Add Multi-AP protocol support
-
-The purpose of Multi-AP specification is to enable inter-operability
-across Wi-Fi access points (APs) from different vendors.
-
-This patch introduces one new configuration parameter 'multi_ap' to
-enable Multi-AP functionality and to configure the BSS as a backhaul
-and/or fronthaul BSS.
-
-Advertise vendor specific Multi-AP capabilities in (Re)Association
-Response frame, if Multi-AP functionality is enabled through the
-configuration parameter.
-
-A backhaul AP must support receiving both 3addr and 4addr frames from a
-backhaul STA, so create a VLAN for it just like is done for WDS, i.e.,
-by calling hostapd_set_wds_sta(). Since Multi-AP requires WPA2 (never
-WEP), we can safely call hostapd_set_wds_encryption() as well and we can
-reuse the entire WDS condition.
-
-To parse the Multi-AP Extension subelement, we use get_ie(): even though
-that function is meant for parsing IEs, it works for subelements.
-
-Signed-off-by: Venkateswara Naralasetty <vnaralas@codeaurora.org>
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
-Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
----
- hostapd/config_file.c          | 10 +++++
- hostapd/hostapd.conf           |  7 ++++
- src/ap/ap_config.h             |  4 ++
- src/ap/ieee802_11.c            | 77 +++++++++++++++++++++++++++++++++-
- src/ap/sta_info.c              |  2 +-
- src/ap/sta_info.h              |  1 +
- src/common/ieee802_11_common.c | 24 +++++++++++
- src/common/ieee802_11_common.h |  4 ++
- src/common/ieee802_11_defs.h   |  7 ++++
- 9 files changed, 134 insertions(+), 2 deletions(-)
-
---- a/hostapd/config_file.c
-+++ b/hostapd/config_file.c
-@@ -4115,6 +4115,16 @@ static int hostapd_config_fill(struct ho
- 	} else if (os_strcmp(buf, "coloc_intf_reporting") == 0) {
- 		bss->coloc_intf_reporting = atoi(pos);
- #endif /* CONFIG_OWE */
-+	} else if (os_strcmp(buf, "multi_ap") == 0) {
-+		int val = atoi(pos);
-+
-+		if (val < 0 || val > 3) {
-+			wpa_printf(MSG_ERROR, "Line %d: Invalid multi_ap '%s'",
-+				   line, buf);
-+			return -1;
-+		}
-+
-+		bss->multi_ap = val;
- 	} else {
- 		wpa_printf(MSG_ERROR,
- 			   "Line %d: unknown configuration item '%s'",
---- a/hostapd/hostapd.conf
-+++ b/hostapd/hostapd.conf
-@@ -438,6 +438,13 @@ wmm_ac_vo_txop_limit=47
- wmm_ac_vo_acm=0
- # Note: for IEEE 802.11b mode: cWmin=3 cWmax=4 burst=102
- 
-+# Enable Multi-AP functionality
-+# 0 = disabled (default)
-+# 1 = AP support backhaul BSS
-+# 2 = AP support fronthaul BSS
-+# 3 = AP supports both backhaul BSS and fronthaul BSS
-+#multi_ap=0
-+
- # Static WEP key configuration
- #
- # The key number to use when transmitting.
---- a/src/ap/ap_config.h
-+++ b/src/ap/ap_config.h
-@@ -688,6 +688,10 @@ struct hostapd_bss_config {
- #endif /* CONFIG_OWE */
- 
- 	int coloc_intf_reporting;
-+
-+#define BACKHAUL_BSS 1
-+#define FRONTHAUL_BSS 2
-+	int multi_ap; /* bitmap of BACKHAUL_BSS, FRONTHAUL_BSS */
- };
- 
- /**
---- a/src/ap/ieee802_11.c
-+++ b/src/ap/ieee802_11.c
-@@ -62,6 +62,22 @@ prepare_auth_resp_fils(struct hostapd_da
- 		       int *is_pub);
- #endif /* CONFIG_FILS */
- 
-+
-+u8 * hostapd_eid_multi_ap(struct hostapd_data *hapd, u8 *eid)
-+{
-+	u8 multi_ap_val = 0;
-+
-+	if (!hapd->conf->multi_ap)
-+		return eid;
-+	if (hapd->conf->multi_ap & BACKHAUL_BSS)
-+		multi_ap_val |= MULTI_AP_BACKHAUL_BSS;
-+	if (hapd->conf->multi_ap & FRONTHAUL_BSS)
-+		multi_ap_val |= MULTI_AP_FRONTHAUL_BSS;
-+
-+	return eid + add_multi_ap_ie(eid, 9, multi_ap_val);
-+}
-+
-+
- u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid)
- {
- 	u8 *pos = eid;
-@@ -2210,6 +2226,57 @@ static u16 check_wmm(struct hostapd_data
- 	return WLAN_STATUS_SUCCESS;
- }
- 
-+static u16 check_multi_ap(struct hostapd_data *hapd, struct sta_info *sta,
-+			  const u8 *multi_ap_ie, size_t multi_ap_len)
-+{
-+	u8 multi_ap_value = 0;
-+
-+	sta->flags &= ~WLAN_STA_MULTI_AP;
-+
-+	if (!hapd->conf->multi_ap)
-+		return WLAN_STATUS_SUCCESS;
-+
-+	if (multi_ap_ie) {
-+		const u8 *multi_ap_subelem;
-+
-+		multi_ap_subelem = get_ie(multi_ap_ie + 4,
-+					  multi_ap_len - 4,
-+					  MULTI_AP_SUB_ELEM_TYPE);
-+		if (multi_ap_subelem && multi_ap_subelem[1] == 1) {
-+			multi_ap_value = multi_ap_subelem[2];
-+		} else {
-+			hostapd_logger(hapd, sta->addr,
-+				       HOSTAPD_MODULE_IEEE80211,
-+				       HOSTAPD_LEVEL_INFO,
-+				       "Multi-AP IE has missing or invalid Multi-AP subelement");
-+			return WLAN_STATUS_INVALID_IE;
-+		}
-+	}
-+
-+	if (multi_ap_value == MULTI_AP_BACKHAUL_STA)
-+		sta->flags |= WLAN_STA_MULTI_AP;
-+
-+	if ((hapd->conf->multi_ap & BACKHAUL_BSS) &&
-+	    multi_ap_value == MULTI_AP_BACKHAUL_STA)
-+		return WLAN_STATUS_SUCCESS;
-+
-+	if (hapd->conf->multi_ap & FRONTHAUL_BSS) {
-+		if (multi_ap_value == MULTI_AP_BACKHAUL_STA) {
-+			hostapd_logger(hapd, sta->addr,
-+				       HOSTAPD_MODULE_IEEE80211,
-+				       HOSTAPD_LEVEL_INFO,
-+				       "Backhaul STA tries to associate with fronthaul-only BSS");
-+			return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
-+		}
-+		return WLAN_STATUS_SUCCESS;
-+	}
-+
-+	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
-+		       HOSTAPD_LEVEL_INFO,
-+		       "Non-Multi-AP STA tries to associate with backhaul-only BSS");
-+	return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
-+}
-+
- 
- static u16 copy_supp_rates(struct hostapd_data *hapd, struct sta_info *sta,
- 			   struct ieee802_11_elems *elems)
-@@ -2466,6 +2533,11 @@ static u16 check_assoc_ies(struct hostap
- 	resp = copy_supp_rates(hapd, sta, &elems);
- 	if (resp != WLAN_STATUS_SUCCESS)
- 		return resp;
-+
-+	resp = check_multi_ap(hapd, sta, elems.multi_ap, elems.multi_ap_len);
-+	if (resp != WLAN_STATUS_SUCCESS)
-+		return resp;
-+
- #ifdef CONFIG_IEEE80211N
- 	resp = copy_sta_ht_capab(hapd, sta, elems.ht_capabilities);
- 	if (resp != WLAN_STATUS_SUCCESS)
-@@ -2996,6 +3068,9 @@ static u16 send_assoc_resp(struct hostap
- 	}
- #endif /* CONFIG_WPS */
- 
-+	if (sta && (sta->flags & WLAN_STA_MULTI_AP))
-+		p = hostapd_eid_multi_ap(hapd, p);
-+
- #ifdef CONFIG_P2P
- 	if (sta && sta->p2p_ie && hapd->p2p_group) {
- 		struct wpabuf *p2p_resp_ie;
-@@ -4236,7 +4311,7 @@ static void handle_assoc_cb(struct hosta
- 		sta->flags |= WLAN_STA_WDS;
- 	}
- 
--	if (sta->flags & WLAN_STA_WDS) {
-+	if (sta->flags & (WLAN_STA_WDS | WLAN_STA_MULTI_AP)) {
- 		int ret;
- 		char ifname_wds[IFNAMSIZ + 1];
- 
---- a/src/ap/sta_info.c
-+++ b/src/ap/sta_info.c
-@@ -166,7 +166,7 @@ void ap_free_sta(struct hostapd_data *ha
- 	/* just in case */
- 	ap_sta_set_authorized(hapd, sta, 0);
- 
--	if (sta->flags & WLAN_STA_WDS)
-+	if (sta->flags & (WLAN_STA_WDS | WLAN_STA_MULTI_AP))
- 		hostapd_set_wds_sta(hapd, NULL, sta->addr, sta->aid, 0);
- 
- 	if (sta->ipaddr)
---- a/src/ap/sta_info.h
-+++ b/src/ap/sta_info.h
-@@ -36,6 +36,7 @@
- #define WLAN_STA_VHT_OPMODE_ENABLED BIT(20)
- #define WLAN_STA_VENDOR_VHT BIT(21)
- #define WLAN_STA_PENDING_FILS_ERP BIT(22)
-+#define WLAN_STA_MULTI_AP BIT(23)
- #define WLAN_STA_PENDING_DISASSOC_CB BIT(29)
- #define WLAN_STA_PENDING_DEAUTH_CB BIT(30)
- #define WLAN_STA_NONERP BIT(31)
---- a/src/common/ieee802_11_common.c
-+++ b/src/common/ieee802_11_common.c
-@@ -126,6 +126,10 @@ static int ieee802_11_parse_vendor_speci
- 			elems->roaming_cons_sel = pos;
- 			elems->roaming_cons_sel_len = elen;
- 			break;
-+		case MULTI_AP_OUI_TYPE:
-+			elems->multi_ap = pos;
-+			elems->multi_ap_len = elen;
-+			break;
- 		default:
- 			wpa_printf(MSG_MSGDUMP, "Unknown WFA "
- 				   "information element ignored "
-@@ -1519,6 +1523,26 @@ size_t mbo_add_ie(u8 *buf, size_t len, c
- }
- 
- 
-+size_t add_multi_ap_ie(u8 *buf, size_t len, u8 value)
-+{
-+	u8 *pos = buf;
-+
-+	if (len < 9)
-+		return 0;
-+
-+	*pos++ = WLAN_EID_VENDOR_SPECIFIC;
-+	*pos++ = 7; /* len */
-+	WPA_PUT_BE24(pos, OUI_WFA);
-+	pos += 3;
-+	*pos++ = MULTI_AP_OUI_TYPE;
-+	*pos++ = MULTI_AP_SUB_ELEM_TYPE;
-+	*pos++ = 1; /* len */
-+	*pos++ = value;
-+
-+	return pos - buf;
-+}
-+
-+
- static const struct country_op_class us_op_class[] = {
- 	{ 1, 115 },
- 	{ 2, 118 },
---- a/src/common/ieee802_11_common.h
-+++ b/src/common/ieee802_11_common.h
-@@ -84,6 +84,7 @@ struct ieee802_11_elems {
- 	const u8 *power_capab;
- 	const u8 *roaming_cons_sel;
- 	const u8 *password_id;
-+	const u8 *multi_ap;
- 
- 	u8 ssid_len;
- 	u8 supp_rates_len;
-@@ -130,6 +131,7 @@ struct ieee802_11_elems {
- 	u8 power_capab_len;
- 	u8 roaming_cons_sel_len;
- 	u8 password_id_len;
-+	u8 multi_ap_len;
- 
- 	struct mb_ies_info mb_ies;
- };
-@@ -189,6 +191,8 @@ const u8 * get_ie_ext(const u8 *ies, siz
- 
- size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len);
- 
-+size_t add_multi_ap_ie(u8 *buf, size_t len, u8 value);
-+
- struct country_op_class {
- 	u8 country_op_class;
- 	u8 global_op_class;
---- a/src/common/ieee802_11_defs.h
-+++ b/src/common/ieee802_11_defs.h
-@@ -1210,6 +1210,13 @@ struct ieee80211_ampe_ie {
- #define MBO_OUI_TYPE 22
- #define OWE_IE_VENDOR_TYPE 0x506f9a1c
- #define OWE_OUI_TYPE 28
-+#define MULTI_AP_OUI_TYPE 0x1B
-+
-+#define MULTI_AP_SUB_ELEM_TYPE 0x06
-+#define MULTI_AP_TEAR_DOWN BIT(4)
-+#define MULTI_AP_FRONTHAUL_BSS BIT(5)
-+#define MULTI_AP_BACKHAUL_BSS BIT(6)
-+#define MULTI_AP_BACKHAUL_STA BIT(7)
- 
- #define WMM_OUI_TYPE 2
- #define WMM_OUI_SUBTYPE_INFORMATION_ELEMENT 0
diff --git a/package/network/services/hostapd/patches/551-wpa_supplicant-Add-Multi-AP-protocol-support-to-supp.patch b/package/network/services/hostapd/patches/551-wpa_supplicant-Add-Multi-AP-protocol-support-to-supp.patch
deleted file mode 100644
index 5fc41c20e6..0000000000
--- a/package/network/services/hostapd/patches/551-wpa_supplicant-Add-Multi-AP-protocol-support-to-supp.patch
+++ /dev/null
@@ -1,311 +0,0 @@
-From 5abc7823bd01f69b8afbe1fd19f65fff86137c44 Mon Sep 17 00:00:00 2001
-From: Venkateswara Naralasetty <vnaralas@codeaurora.org>
-Date: Wed, 5 Dec 2018 11:23:53 +0100
-Subject: [PATCH] wpa_supplicant: Add Multi-AP backhaul STA support
-
-Advertise vendor specific Multi-AP IE in (Re)Association Request frames
-and process Multi-AP IE from (Re)Association Response frames if the user
-enables Multi-AP fuctionality. If the (Re)Association Response frame
-does not contain the Multi-AP IE, disassociate.
-
-This adds a new configuration parameter 'multi_ap_backhaul_sta' to
-enable/disable Multi-AP functionality.
-
-Enable 4-address mode after association (if the Association Response
-frame contains the Multi-AP IE). Also enable the bridge in that case.
-This is necessary because wpa_supplicant only enables the bridge in
-wpa_drv_if_add(), which only gets called when an interface is added
-through the control interface, not when it is configured from the
-command line.
-
-Signed-off-by: Venkateswara Naralasetty <vnaralas@codeaurora.org>
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
-Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
----
- src/drivers/driver.h               |  9 ++++++
- src/drivers/driver_nl80211.c       | 44 ++++++++++++++++++++++++++
- wpa_supplicant/config.c            |  1 +
- wpa_supplicant/config_ssid.h       |  7 +++++
- wpa_supplicant/driver_i.h          |  8 +++++
- wpa_supplicant/events.c            | 50 ++++++++++++++++++++++++++++++
- wpa_supplicant/sme.c               | 16 ++++++++++
- wpa_supplicant/wpa_supplicant.c    | 18 +++++++++++
- wpa_supplicant/wpa_supplicant.conf |  7 +++++
- wpa_supplicant/wpa_supplicant_i.h  |  1 +
- 10 files changed, 161 insertions(+)
-
---- a/src/drivers/driver.h
-+++ b/src/drivers/driver.h
-@@ -4100,6 +4100,15 @@ struct wpa_driver_ops {
- 	 */
- 	int (*send_external_auth_status)(void *priv,
- 					 struct external_auth *params);
-+
-+	/**
-+	 * set_4addr_mode - Set 4-address mode
-+	 * @priv: Private driver interface data
-+	 * @bridge_ifname: Bridge interface name
-+	 * @val: 0 - disable 4addr mode, 1 - enable 4addr mode
-+	 * Returns: 0 on success, < 0 on failure
-+	 */
-+	int (*set_4addr_mode)(void *priv, const char *bridge_ifname, int val);
- };
- 
- /**
---- a/src/drivers/driver_nl80211.c
-+++ b/src/drivers/driver_nl80211.c
-@@ -10728,6 +10728,49 @@ fail:
- }
- 
- 
-+static int nl80211_set_4addr_mode(void *priv, const char *bridge_ifname,
-+				  int val)
-+{
-+	struct i802_bss *bss = priv;
-+	struct wpa_driver_nl80211_data *drv = bss->drv;
-+	struct nl_msg *msg;
-+	int ret = -ENOBUFS;
-+
-+	wpa_printf(MSG_DEBUG, "nl80211: %s 4addr mode (bridge_ifname: %s)",
-+		   val ? "Enable" : "Disable", bridge_ifname);
-+
-+	msg = nl80211_cmd_msg(drv->first_bss, 0, NL80211_CMD_SET_INTERFACE);
-+	if (!msg || nla_put_u8(msg, NL80211_ATTR_4ADDR, val))
-+		goto fail;
-+
-+	if (bridge_ifname[0] && bss->added_if_into_bridge && !val) {
-+		if (linux_br_del_if(drv->global->ioctl_sock,
-+				    bridge_ifname, bss->ifname)) {
-+			wpa_printf(MSG_ERROR,
-+				   "nl80211: Failed to remove interface %s from bridge %s",
-+				   bss->ifname, bridge_ifname);
-+			return -1;
-+		}
-+		bss->added_if_into_bridge = 0;
-+	}
-+
-+	ret = send_and_recv_msgs(drv, msg, NULL, NULL);
-+	msg = NULL;
-+	if (!ret) {
-+		if (bridge_ifname[0] && val &&
-+		    i802_check_bridge(drv, bss, bridge_ifname, bss->ifname) < 0)
-+			return -1;
-+		return 0;
-+	}
-+
-+fail:
-+	nlmsg_free(msg);
-+	wpa_printf(MSG_ERROR, "nl80211: Failed to enable/disable 4addr");
-+
-+	return ret;
-+}
-+
-+
- const struct wpa_driver_ops wpa_driver_nl80211_ops = {
- 	.name = "nl80211",
- 	.desc = "Linux nl80211/cfg80211",
-@@ -10856,4 +10899,5 @@ const struct wpa_driver_ops wpa_driver_n
- 	.get_ext_capab = nl80211_get_ext_capab,
- 	.update_connect_params = nl80211_update_connection_params,
- 	.send_external_auth_status = nl80211_send_external_auth_status,
-+	.set_4addr_mode = nl80211_set_4addr_mode,
- };
---- a/wpa_supplicant/config.c
-+++ b/wpa_supplicant/config.c
-@@ -2416,6 +2416,7 @@ static const struct parse_data ssid_fiel
- #endif /* CONFIG_DPP */
- 	{ INT_RANGE(owe_group, 0, 65535) },
- 	{ INT_RANGE(owe_only, 0, 1) },
-+	{ INT_RANGE(multi_ap_backhaul_sta, 0, 1) },
- };
- 
- #undef OFFSET
---- a/wpa_supplicant/config_ssid.h
-+++ b/wpa_supplicant/config_ssid.h
-@@ -950,6 +950,13 @@ struct wpa_ssid {
- 	 * the selection attempts for OWE BSS exceed the configured threshold.
- 	 */
- 	int owe_transition_bss_select_count;
-+
-+	/**
-+	 * multi_ap_backhaul_sta - Multi-AP backhaul STA
-+	 * 0 = normal (non-Multi-AP) station
-+	 * 1 = Multi-AP backhaul station
-+	 */
-+	int multi_ap_backhaul_sta;
- };
- 
- #endif /* CONFIG_SSID_H */
---- a/wpa_supplicant/driver_i.h
-+++ b/wpa_supplicant/driver_i.h
-@@ -1046,4 +1046,12 @@ wpa_drv_send_external_auth_status(struct
- 							params);
- }
- 
-+static inline int wpa_drv_set_4addr_mode(struct wpa_supplicant *wpa_s, int val)
-+{
-+	if (!wpa_s->driver->set_4addr_mode)
-+		return -1;
-+	return wpa_s->driver->set_4addr_mode(wpa_s->drv_priv,
-+					     wpa_s->bridge_ifname, val);
-+}
-+
- #endif /* DRIVER_I_H */
---- a/wpa_supplicant/events.c
-+++ b/wpa_supplicant/events.c
-@@ -324,6 +324,9 @@ void wpa_supplicant_mark_disassoc(struct
- 	os_memset(wpa_s->last_tk, 0, sizeof(wpa_s->last_tk));
- #endif /* CONFIG_TESTING_OPTIONS */
- 	wpa_s->ieee80211ac = 0;
-+
-+	if (wpa_s->enabled_4addr_mode && wpa_drv_set_4addr_mode(wpa_s, 0) == 0)
-+		wpa_s->enabled_4addr_mode = 0;
- }
- 
- 
-@@ -2267,6 +2270,50 @@ static void interworking_process_assoc_r
- #endif /* CONFIG_INTERWORKING */
- 
- 
-+static void multi_ap_process_assoc_resp(struct wpa_supplicant *wpa_s,
-+					const u8 *ies, size_t ies_len)
-+{
-+	struct ieee802_11_elems elems;
-+	const u8 *map_sub_elem, *pos;
-+	size_t len;
-+
-+	if (!wpa_s->current_ssid ||
-+	    !wpa_s->current_ssid->multi_ap_backhaul_sta ||
-+	    !ies ||
-+	    ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed)
-+		return;
-+
-+	if (!elems.multi_ap || elems.multi_ap_len < 7) {
-+		wpa_printf(MSG_INFO, "AP doesn't support Multi-AP protocol");
-+		goto fail;
-+	}
-+
-+	pos = elems.multi_ap + 4;
-+	len = elems.multi_ap_len - 4;
-+
-+	map_sub_elem = get_ie(pos, len, MULTI_AP_SUB_ELEM_TYPE);
-+	if (!map_sub_elem || map_sub_elem[1] < 1) {
-+		wpa_printf(MSG_INFO, "invalid Multi-AP sub elem type");
-+		goto fail;
-+	}
-+
-+	if (!(map_sub_elem[2] & MULTI_AP_BACKHAUL_BSS)) {
-+		wpa_printf(MSG_INFO, "AP doesn't support backhaul BSS");
-+		goto fail;
-+	}
-+
-+	if (wpa_drv_set_4addr_mode(wpa_s, 1) < 0) {
-+		wpa_printf(MSG_ERROR, "Failed to set 4addr mode");
-+		goto fail;
-+	}
-+	wpa_s->enabled_4addr_mode = 1;
-+	return;
-+
-+fail:
-+	wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
-+}
-+
-+
- #ifdef CONFIG_FST
- static int wpas_fst_update_mbie(struct wpa_supplicant *wpa_s,
- 				const u8 *ie, size_t ie_len)
-@@ -2343,6 +2390,9 @@ static int wpa_supplicant_event_associnf
- 		    get_ie(data->assoc_info.resp_ies,
- 			   data->assoc_info.resp_ies_len, WLAN_EID_VHT_CAP))
- 			wpa_s->ieee80211ac = 1;
-+
-+		multi_ap_process_assoc_resp(wpa_s, data->assoc_info.resp_ies,
-+					    data->assoc_info.resp_ies_len);
- 	}
- 	if (data->assoc_info.beacon_ies)
- 		wpa_hexdump(MSG_DEBUG, "beacon_ies",
---- a/wpa_supplicant/sme.c
-+++ b/wpa_supplicant/sme.c
-@@ -1552,6 +1552,22 @@ void sme_associate(struct wpa_supplicant
- 	}
- #endif /* CONFIG_OWE */
- 
-+	if (wpa_s->current_ssid && wpa_s->current_ssid->multi_ap_backhaul_sta) {
-+		size_t multi_ap_ie_len;
-+
-+		multi_ap_ie_len = add_multi_ap_ie(
-+			wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
-+			sizeof(wpa_s->sme.assoc_req_ie) -
-+			wpa_s->sme.assoc_req_ie_len,
-+			MULTI_AP_BACKHAUL_STA);
-+		if (multi_ap_ie_len == 0) {
-+			wpa_printf(MSG_ERROR,
-+				   "Multi-AP: Failed to build Multi-AP IE");
-+			return;
-+		}
-+		wpa_s->sme.assoc_req_ie_len += multi_ap_ie_len;
-+	}
-+
- 	params.bssid = bssid;
- 	params.ssid = wpa_s->sme.ssid;
- 	params.ssid_len = wpa_s->sme.ssid_len;
---- a/wpa_supplicant/wpa_supplicant.c
-+++ b/wpa_supplicant/wpa_supplicant.c
-@@ -2893,6 +2893,21 @@ static u8 * wpas_populate_assoc_ies(
- 	}
- #endif /* CONFIG_IEEE80211R */
- 
-+	if (ssid->multi_ap_backhaul_sta) {
-+		size_t multi_ap_ie_len;
-+
-+		multi_ap_ie_len = add_multi_ap_ie(wpa_ie + wpa_ie_len,
-+						  max_wpa_ie_len - wpa_ie_len,
-+						  MULTI_AP_BACKHAUL_STA);
-+		if (multi_ap_ie_len == 0) {
-+			wpa_printf(MSG_ERROR,
-+				   "Multi-AP: Failed to build Multi-AP IE");
-+			os_free(wpa_ie);
-+			return NULL;
-+		}
-+		wpa_ie_len += multi_ap_ie_len;
-+	}
-+
- 	params->wpa_ie = wpa_ie;
- 	params->wpa_ie_len = wpa_ie_len;
- 	params->auth_alg = algs;
-@@ -3377,6 +3392,9 @@ void wpa_supplicant_deauthenticate(struc
- 		zero_addr = 1;
- 	}
- 
-+	if (wpa_s->enabled_4addr_mode && wpa_drv_set_4addr_mode(wpa_s, 0) == 0)
-+		wpa_s->enabled_4addr_mode = 0;
-+
- #ifdef CONFIG_TDLS
- 	wpa_tdls_teardown_peers(wpa_s->wpa);
- #endif /* CONFIG_TDLS */
---- a/wpa_supplicant/wpa_supplicant.conf
-+++ b/wpa_supplicant/wpa_supplicant.conf
-@@ -1399,6 +1399,13 @@ fast_reauth=1
- #  2: MCS 0-9
- #  3: not supported
- 
-+# multi_ap_backhaul_sta: Multi-AP backhaul STA functionality
-+# 0 = normal STA (default)
-+# 1 = backhaul STA
-+# A backhaul STA sends the Multi-AP IE, fails to associate if the AP does not
-+# support Multi-AP, and sets 4-address mode if it does. Thus, the netdev can be
-+# added to a bridge to allow forwarding frames over this backhaul link.
-+
- ##### Fast Session Transfer (FST) support #####################################
- #
- # The options in this section are only available when the build configuration
---- a/wpa_supplicant/wpa_supplicant_i.h
-+++ b/wpa_supplicant/wpa_supplicant_i.h
-@@ -1242,6 +1242,7 @@ struct wpa_supplicant {
- 	unsigned int disable_fils:1;
- #endif /* CONFIG_FILS */
- 	unsigned int ieee80211ac:1;
-+	unsigned int enabled_4addr_mode:1;
- };
- 
- 
diff --git a/package/network/services/hostapd/patches/552-tests-Multi-AP-association.patch b/package/network/services/hostapd/patches/552-tests-Multi-AP-association.patch
deleted file mode 100644
index 1f3aed92bd..0000000000
--- a/package/network/services/hostapd/patches/552-tests-Multi-AP-association.patch
+++ /dev/null
@@ -1,100 +0,0 @@
-From 7488e0ade6dffb6df4c1fb6526a9f3ede0eb18ef Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Thu, 20 Dec 2018 12:41:00 +0200
-Subject: [PATCH] tests: Multi-AP association
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- tests/hwsim/test_multi_ap.py | 73 ++++++++++++++++++++++++++++++++++++
- tests/hwsim/wpasupplicant.py |  3 +-
- 2 files changed, 75 insertions(+), 1 deletion(-)
- create mode 100644 tests/hwsim/test_multi_ap.py
-
---- /dev/null
-+++ b/tests/hwsim/test_multi_ap.py
-@@ -0,0 +1,73 @@
-+# Test cases for Multi-AP
-+# Copyright (c) 2018, The Linux Foundation
-+#
-+# This software may be distributed under the terms of the BSD license.
-+# See README for more details.
-+
-+import hostapd
-+
-+def test_multi_ap_association(dev, apdev):
-+    """Multi-AP association in backhaul BSS"""
-+    run_multi_ap_association(dev, apdev, 1)
-+    dev[1].connect("multi-ap", psk="12345678", scan_freq="2412",
-+                   wait_connect=False)
-+    ev = dev[1].wait_event([ "CTRL-EVENT-DISCONNECTED",
-+                             "CTRL-EVENT-CONNECTED",
-+                             "CTRL-EVENT-ASSOC-REJECT" ],
-+                           timeout=5)
-+    dev[1].request("DISCONNECT")
-+    if ev is None:
-+        raise Exception("Connection result not reported")
-+    if "CTRL-EVENT-ASSOC-REJECT" not in ev:
-+        raise Exception("Association rejection not reported")
-+    if "status_code=12" not in ev:
-+        raise Exception("Unexpected association status code: " + ev)
-+
-+def test_multi_ap_association_shared_bss(dev, apdev):
-+    """Multi-AP association in backhaul BSS (with fronthaul BSS enabled)"""
-+    run_multi_ap_association(dev, apdev, 3)
-+    dev[1].connect("multi-ap", psk="12345678", scan_freq="2412")
-+
-+def run_multi_ap_association(dev, apdev, multi_ap):
-+    params = hostapd.wpa2_params(ssid="multi-ap", passphrase="12345678")
-+    params["multi_ap"] = str(multi_ap)
-+    hapd = hostapd.add_ap(apdev[0], params)
-+
-+    dev[0].connect("multi-ap", psk="12345678", multi_ap_backhaul_sta="1",
-+                   scan_freq="2412")
-+
-+def test_multi_ap_disabled_on_ap(dev, apdev):
-+    """Multi-AP association attempt when disabled on AP"""
-+    params = hostapd.wpa2_params(ssid="multi-ap", passphrase="12345678")
-+    hapd = hostapd.add_ap(apdev[0], params)
-+
-+    dev[0].connect("multi-ap", psk="12345678", multi_ap_backhaul_sta="1",
-+                   scan_freq="2412", wait_connect=False)
-+    ev = dev[0].wait_event([ "CTRL-EVENT-DISCONNECTED",
-+                             "CTRL-EVENT-CONNECTED" ],
-+                           timeout=5)
-+    dev[0].request("DISCONNECT")
-+    if ev is None:
-+        raise Exception("Connection result not reported")
-+    if "CTRL-EVENT-DISCONNECTED" not in ev:
-+        raise Exception("Unexpected connection result")
-+
-+def test_multi_ap_fronthaul_on_ap(dev, apdev):
-+    """Multi-AP association attempt when only fronthaul BSS on AP"""
-+    params = hostapd.wpa2_params(ssid="multi-ap", passphrase="12345678")
-+    params["multi_ap"] = "2"
-+    hapd = hostapd.add_ap(apdev[0], params)
-+
-+    dev[0].connect("multi-ap", psk="12345678", multi_ap_backhaul_sta="1",
-+                   scan_freq="2412", wait_connect=False)
-+    ev = dev[0].wait_event([ "CTRL-EVENT-DISCONNECTED",
-+                             "CTRL-EVENT-CONNECTED",
-+                             "CTRL-EVENT-ASSOC-REJECT" ],
-+                           timeout=5)
-+    dev[0].request("DISCONNECT")
-+    if ev is None:
-+        raise Exception("Connection result not reported")
-+    if "CTRL-EVENT-ASSOC-REJECT" not in ev:
-+        raise Exception("Association rejection not reported")
-+    if "status_code=12" not in ev:
-+        raise Exception("Unexpected association status code: " + ev)
---- a/tests/hwsim/wpasupplicant.py
-+++ b/tests/hwsim/wpasupplicant.py
-@@ -1031,7 +1031,8 @@ class WpaSupplicant:
-                        "dpp_csign", "dpp_csign_expiry",
-                        "dpp_netaccesskey", "dpp_netaccesskey_expiry",
-                        "group_mgmt", "owe_group",
--                       "roaming_consortium_selection" ]
-+                       "roaming_consortium_selection", "multi_ap_backhaul_sta" ]
-+
-         for field in not_quoted:
-             if field in kwargs and kwargs[field]:
-                 self.set_network(id, field, kwargs[field])
diff --git a/package/network/services/hostapd/patches/553-tests-refactor-test_multi_ap.patch b/package/network/services/hostapd/patches/553-tests-refactor-test_multi_ap.patch
deleted file mode 100644
index 240407fd1c..0000000000
--- a/package/network/services/hostapd/patches/553-tests-refactor-test_multi_ap.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From 0f5029ff41ef286aa7b3e4a3efd3f1a16be925e8 Mon Sep 17 00:00:00 2001
-From: "Arnout Vandecappelle (Essensium/Mind)" <arnout@mind.be>
-Date: Wed, 9 Jan 2019 18:41:08 +0100
-Subject: [PATCH] tests: refactor test_multi_ap
-
-With just one additional argument, the run_multi_ap_association function
-can be used for all tests.
-
-While we're at it, also move it to the top of the file.
-
-Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
----
-v4: new patch
----
- tests/hwsim/test_multi_ap.py | 30 +++++++++++-------------------
- 1 file changed, 11 insertions(+), 19 deletions(-)
-
---- a/tests/hwsim/test_multi_ap.py
-+++ b/tests/hwsim/test_multi_ap.py
-@@ -6,6 +6,15 @@
- 
- import hostapd
- 
-+def run_multi_ap_association(dev, apdev, multi_ap, wait_connect=True):
-+    params = hostapd.wpa2_params(ssid="multi-ap", passphrase="12345678")
-+    if multi_ap:
-+        params["multi_ap"] = str(multi_ap)
-+    hapd = hostapd.add_ap(apdev[0], params)
-+
-+    dev[0].connect("multi-ap", psk="12345678", scan_freq="2412",
-+                   multi_ap_backhaul_sta="1", wait_connect=wait_connect)
-+
- def test_multi_ap_association(dev, apdev):
-     """Multi-AP association in backhaul BSS"""
-     run_multi_ap_association(dev, apdev, 1)
-@@ -28,21 +37,9 @@ def test_multi_ap_association_shared_bss
-     run_multi_ap_association(dev, apdev, 3)
-     dev[1].connect("multi-ap", psk="12345678", scan_freq="2412")
- 
--def run_multi_ap_association(dev, apdev, multi_ap):
--    params = hostapd.wpa2_params(ssid="multi-ap", passphrase="12345678")
--    params["multi_ap"] = str(multi_ap)
--    hapd = hostapd.add_ap(apdev[0], params)
--
--    dev[0].connect("multi-ap", psk="12345678", multi_ap_backhaul_sta="1",
--                   scan_freq="2412")
--
- def test_multi_ap_disabled_on_ap(dev, apdev):
-     """Multi-AP association attempt when disabled on AP"""
--    params = hostapd.wpa2_params(ssid="multi-ap", passphrase="12345678")
--    hapd = hostapd.add_ap(apdev[0], params)
--
--    dev[0].connect("multi-ap", psk="12345678", multi_ap_backhaul_sta="1",
--                   scan_freq="2412", wait_connect=False)
-+    run_multi_ap_association(dev, apdev, 0, wait_connect=False)
-     ev = dev[0].wait_event([ "CTRL-EVENT-DISCONNECTED",
-                              "CTRL-EVENT-CONNECTED" ],
-                            timeout=5)
-@@ -54,12 +51,7 @@ def test_multi_ap_disabled_on_ap(dev, ap
- 
- def test_multi_ap_fronthaul_on_ap(dev, apdev):
-     """Multi-AP association attempt when only fronthaul BSS on AP"""
--    params = hostapd.wpa2_params(ssid="multi-ap", passphrase="12345678")
--    params["multi_ap"] = "2"
--    hapd = hostapd.add_ap(apdev[0], params)
--
--    dev[0].connect("multi-ap", psk="12345678", multi_ap_backhaul_sta="1",
--                   scan_freq="2412", wait_connect=False)
-+    run_multi_ap_association(dev, apdev, 2, wait_connect=False)
-     ev = dev[0].wait_event([ "CTRL-EVENT-DISCONNECTED",
-                              "CTRL-EVENT-CONNECTED",
-                              "CTRL-EVENT-ASSOC-REJECT" ],
diff --git a/package/network/services/hostapd/patches/554-multi_ap-don-t-reject-backhaul-STA-on-fronhaul-BSS.patch b/package/network/services/hostapd/patches/554-multi_ap-don-t-reject-backhaul-STA-on-fronhaul-BSS.patch
deleted file mode 100644
index 6c30a1793e..0000000000
--- a/package/network/services/hostapd/patches/554-multi_ap-don-t-reject-backhaul-STA-on-fronhaul-BSS.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From 71b061b8a13791a1ed858d924e401541c8584030 Mon Sep 17 00:00:00 2001
-From: "Arnout Vandecappelle (Essensium/Mind)" <arnout@mind.be>
-Date: Wed, 9 Jan 2019 19:08:00 +0100
-Subject: [PATCH] multi_ap: don't reject backhaul STA on fronhaul BSS
-
-The Multi-AP specification only specifies that information elements have
-to be added to the association requests and responses; it doesn't
-specify anything about what should be done in case they are missing.
-Currently, we reject non-backhaul associations on a backhaul-only BSS,
-and non-fronthaul associations on a fronthaul-only BSS.
-
-However, this makes WPS fail when fronthaul and backhaul are separate
-SSIDs. Indeed, WPS for the backhaul link is performed on the *fronthaul*
-SSID. Thus, the association request used for WPS *will* contain the
-Multi-AP IE indicating a backhaul STA. Rejecting that association makes
-WPS fail.
-
-Therefore, accept a multi-AP backhaul STA association request on a
-fronthaul-only BSS. Still issue a warning about it, but only at level
-DEBUG intead of INFO. Also change the condition checking to make it
-clearer.
-
-While we're at it, also fix the handling of unexpected bits in the
-Multi-AP IE. 4 bits are reserved in the specification, so these
-certainly have to be ignored. The specification also doesn't say that
-setting one of the other bits is not allowed. Therefore, only report
-unexpected values in the Multi-AP IE, don't reject because of it.
-Note that a malformed IE (containing more than one byte) still triggers
-a rejection.
-
-Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
----
-v4: new patch
-
-Cfr. discussion on http://lists.infradead.org/pipermail/hostap/2019-January/039232.html
-and follow-ups.
----
- src/ap/ieee802_11.c          | 38 +++++++++++++++++++-----------------
- tests/hwsim/test_multi_ap.py |  6 ++----
- 2 files changed, 22 insertions(+), 22 deletions(-)
-
---- a/src/ap/ieee802_11.c
-+++ b/src/ap/ieee802_11.c
-@@ -2253,28 +2253,30 @@ static u16 check_multi_ap(struct hostapd
- 		}
- 	}
- 
--	if (multi_ap_value == MULTI_AP_BACKHAUL_STA)
--		sta->flags |= WLAN_STA_MULTI_AP;
--
--	if ((hapd->conf->multi_ap & BACKHAUL_BSS) &&
--	    multi_ap_value == MULTI_AP_BACKHAUL_STA)
--		return WLAN_STATUS_SUCCESS;
--
--	if (hapd->conf->multi_ap & FRONTHAUL_BSS) {
--		if (multi_ap_value == MULTI_AP_BACKHAUL_STA) {
--			hostapd_logger(hapd, sta->addr,
--				       HOSTAPD_MODULE_IEEE80211,
--				       HOSTAPD_LEVEL_INFO,
--				       "Backhaul STA tries to associate with fronthaul-only BSS");
--			return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
--		}
--		return WLAN_STATUS_SUCCESS;
-+	if (multi_ap_value && multi_ap_value != MULTI_AP_BACKHAUL_STA)
-+		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
-+			       HOSTAPD_LEVEL_INFO,
-+			       "Multi-AP IE with unexpected value 0x%02x",
-+			       multi_ap_value);
-+
-+	if (!(multi_ap_value & MULTI_AP_BACKHAUL_STA)) {
-+		if (hapd->conf->multi_ap & FRONTHAUL_BSS)
-+			return WLAN_STATUS_SUCCESS;
-+
-+		hostapd_logger(hapd, sta->addr,
-+			       HOSTAPD_MODULE_IEEE80211,
-+			       HOSTAPD_LEVEL_INFO,
-+			       "Non-Multi-AP STA tries to associate with backhaul-only BSS");
-+		return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
- 	}
- 
--	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
--		       HOSTAPD_LEVEL_INFO,
--		       "Non-Multi-AP STA tries to associate with backhaul-only BSS");
--	return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
-+	if (!(hapd->conf->multi_ap & BACKHAUL_BSS))
-+		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
-+			       HOSTAPD_LEVEL_DEBUG,
-+			       "Backhaul STA tries to associate with fronthaul-only BSS");
-+
-+	sta->flags |= WLAN_STA_MULTI_AP;
-+	return WLAN_STATUS_SUCCESS;
- }
- 
- 
---- a/tests/hwsim/test_multi_ap.py
-+++ b/tests/hwsim/test_multi_ap.py
-@@ -59,7 +59,5 @@ def test_multi_ap_fronthaul_on_ap(dev, a
-     dev[0].request("DISCONNECT")
-     if ev is None:
-         raise Exception("Connection result not reported")
--    if "CTRL-EVENT-ASSOC-REJECT" not in ev:
--        raise Exception("Association rejection not reported")
--    if "status_code=12" not in ev:
--        raise Exception("Unexpected association status code: " + ev)
-+    if "CTRL-EVENT-DISCONNECTED" not in ev:
-+        raise Exception("Unexpected connection result")
diff --git a/package/network/services/hostapd/patches/555-WPS-wps_build_wfa_ext-add-multi_ap_subelem-parameter.patch b/package/network/services/hostapd/patches/555-WPS-wps_build_wfa_ext-add-multi_ap_subelem-parameter.patch
deleted file mode 100644
index 2a1dc76ac1..0000000000
--- a/package/network/services/hostapd/patches/555-WPS-wps_build_wfa_ext-add-multi_ap_subelem-parameter.patch
+++ /dev/null
@@ -1,342 +0,0 @@
-From ad3c6faca118c23cdafef418dc27b3cee7d0e06e Mon Sep 17 00:00:00 2001
-From: "Arnout Vandecappelle (Essensium/Mind)" <arnout@mind.be>
-Date: Wed, 9 Jan 2019 19:19:26 +0100
-Subject: [PATCH] WPS: wps_build_wfa_ext(): add multi_ap_subelem parameter
-
-The Multi-AP specification adds a new subelement to the WFA extension
-element in the WPS exchange. Add an additional parameter to
-wps_build_wfa_ext() to add this subelement. The subelement is only added
-if the parameter is non-0. Note that we don't reuse the existing
-MULTI_AP_SUB_ELEM_TYPE definition here, but rather define a new
-WFA_ELEM_MULTI_AP, to make sure the enum of WFA subelement types remains
-complete.
-
-For now, all callers set the multi_ap_subelem parameter to 0.
-
-Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
----
-v4: Split off from supplicant WPS patch
-
-Since the original patch from Davina Lyu didn't have this extra
-argument, I kept myself as the author of this patch.
----
- src/p2p/p2p_build.c      |  2 +-
- src/wps/wps.c            |  6 +++---
- src/wps/wps_attr_build.c | 11 ++++++++++-
- src/wps/wps_common.c     | 16 ++++++++--------
- src/wps/wps_defs.h       |  3 ++-
- src/wps/wps_enrollee.c   | 10 +++++-----
- src/wps/wps_er.c         |  4 ++--
- src/wps/wps_i.h          |  3 ++-
- src/wps/wps_registrar.c  | 14 +++++++-------
- src/wps/wps_upnp.c       |  2 +-
- 10 files changed, 41 insertions(+), 30 deletions(-)
-
---- a/src/p2p/p2p_build.c
-+++ b/src/p2p/p2p_build.c
-@@ -802,7 +802,7 @@ int p2p_build_wps_ie(struct p2p_data *p2
- 		wpabuf_put_be16(buf, p2p->cfg->config_methods);
- 	}
- 
--	if (wps_build_wfa_ext(buf, 0, NULL, 0) < 0)
-+	if (wps_build_wfa_ext(buf, 0, NULL, 0, 0) < 0)
- 		return -1;
- 
- 	if (all_attr && p2p->cfg->num_sec_dev_types) {
---- a/src/wps/wps.c
-+++ b/src/wps/wps.c
-@@ -430,7 +430,7 @@ struct wpabuf * wps_build_assoc_req_ie(e
- 
- 	if (wps_build_version(ie) ||
- 	    wps_build_req_type(ie, req_type) ||
--	    wps_build_wfa_ext(ie, 0, NULL, 0)) {
-+	    wps_build_wfa_ext(ie, 0, NULL, 0, 0)) {
- 		wpabuf_free(ie);
- 		return NULL;
- 	}
-@@ -464,7 +464,7 @@ struct wpabuf * wps_build_assoc_resp_ie(
- 
- 	if (wps_build_version(ie) ||
- 	    wps_build_resp_type(ie, WPS_RESP_AP) ||
--	    wps_build_wfa_ext(ie, 0, NULL, 0)) {
-+	    wps_build_wfa_ext(ie, 0, NULL, 0, 0)) {
- 		wpabuf_free(ie);
- 		return NULL;
- 	}
-@@ -516,7 +516,7 @@ struct wpabuf * wps_build_probe_req_ie(u
- 	    wps_build_model_name(dev, ie) ||
- 	    wps_build_model_number(dev, ie) ||
- 	    wps_build_dev_name(dev, ie) ||
--	    wps_build_wfa_ext(ie, req_type == WPS_REQ_ENROLLEE, NULL, 0) ||
-+	    wps_build_wfa_ext(ie, req_type == WPS_REQ_ENROLLEE, NULL, 0, 0) ||
- 	    wps_build_req_dev_type(dev, ie, num_req_dev_types, req_dev_types)
- 	    ||
- 	    wps_build_secondary_dev_type(dev, ie)
---- a/src/wps/wps_attr_build.c
-+++ b/src/wps/wps_attr_build.c
-@@ -203,7 +203,8 @@ int wps_build_version(struct wpabuf *msg
- 
- 
- int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll,
--		      const u8 *auth_macs, size_t auth_macs_count)
-+		      const u8 *auth_macs, size_t auth_macs_count,
-+		      u8 multi_ap_subelem)
- {
- 	u8 *len;
- 
-@@ -244,6 +245,14 @@ int wps_build_wfa_ext(struct wpabuf *msg
- 				   MAC2STR(&auth_macs[i * ETH_ALEN]));
- 	}
- 
-+	if (multi_ap_subelem) {
-+		wpa_printf(MSG_DEBUG, "WPS:  * Multi-AP (0x%x)",
-+			   multi_ap_subelem);
-+		wpabuf_put_u8(msg, WFA_ELEM_MULTI_AP);
-+		wpabuf_put_u8(msg, 1); /* length */
-+		wpabuf_put_u8(msg, multi_ap_subelem);
-+	}
-+
- 	WPA_PUT_BE16(len, (u8 *) wpabuf_put(msg, 0) - len - 2);
- 
- #ifdef CONFIG_WPS_TESTING
---- a/src/wps/wps_common.c
-+++ b/src/wps/wps_common.c
-@@ -374,7 +374,7 @@ struct wpabuf * wps_get_oob_cred(struct
- 	    (rf_band && wps_build_rf_bands_attr(plain, rf_band)) ||
- 	    (channel && wps_build_ap_channel(plain, channel)) ||
- 	    wps_build_mac_addr(plain, wps->dev.mac_addr) ||
--	    wps_build_wfa_ext(plain, 0, NULL, 0)) {
-+	    wps_build_wfa_ext(plain, 0, NULL, 0, 0)) {
- 		os_free(data.new_psk);
- 		wpabuf_clear_free(plain);
- 		return NULL;
-@@ -421,7 +421,7 @@ struct wpabuf * wps_build_nfc_pw_token(u
- 
- 	if (wps_build_oob_dev_pw(data, dev_pw_id, pubkey,
- 				 wpabuf_head(dev_pw), wpabuf_len(dev_pw)) ||
--	    wps_build_wfa_ext(data, 0, NULL, 0)) {
-+	    wps_build_wfa_ext(data, 0, NULL, 0, 0)) {
- 		wpa_printf(MSG_ERROR, "WPS: Failed to build NFC password "
- 			   "token");
- 		wpabuf_clear_free(data);
-@@ -586,7 +586,7 @@ struct wpabuf * wps_build_wsc_ack(struct
- 	    wps_build_msg_type(msg, WPS_WSC_ACK) ||
- 	    wps_build_enrollee_nonce(wps, msg) ||
- 	    wps_build_registrar_nonce(wps, msg) ||
--	    wps_build_wfa_ext(msg, 0, NULL, 0)) {
-+	    wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
- 		wpabuf_free(msg);
- 		return NULL;
- 	}
-@@ -610,7 +610,7 @@ struct wpabuf * wps_build_wsc_nack(struc
- 	    wps_build_enrollee_nonce(wps, msg) ||
- 	    wps_build_registrar_nonce(wps, msg) ||
- 	    wps_build_config_error(msg, wps->config_error) ||
--	    wps_build_wfa_ext(msg, 0, NULL, 0)) {
-+	    wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
- 		wpabuf_free(msg);
- 		return NULL;
- 	}
-@@ -726,7 +726,7 @@ struct wpabuf * wps_build_nfc_handover_r
- 	if (wps_build_oob_dev_pw(msg, DEV_PW_NFC_CONNECTION_HANDOVER,
- 				 nfc_dh_pubkey, NULL, 0) ||
- 	    wps_build_uuid_e(msg, ctx->uuid) ||
--	    wps_build_wfa_ext(msg, 0, NULL, 0)) {
-+	    wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
- 		wpabuf_free(msg);
- 		return NULL;
- 	}
-@@ -809,7 +809,7 @@ struct wpabuf * wps_build_nfc_handover_s
- 	    wps_build_ssid(msg, ctx) ||
- 	    wps_build_ap_freq(msg, freq) ||
- 	    (bssid && wps_build_mac_addr(msg, bssid)) ||
--	    wps_build_wfa_ext(msg, 0, NULL, 0)) {
-+	    wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
- 		wpabuf_free(msg);
- 		return NULL;
- 	}
-@@ -848,7 +848,7 @@ struct wpabuf * wps_build_nfc_handover_r
- 	    wps_build_rf_bands(&ctx->dev, msg, 0) ||
- 	    wps_build_serial_number(&ctx->dev, msg) ||
- 	    wps_build_uuid_e(msg, ctx->uuid) ||
--	    wps_build_wfa_ext(msg, 0, NULL, 0)) {
-+	    wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
- 		wpabuf_free(msg);
- 		return NULL;
- 	}
-@@ -900,7 +900,7 @@ struct wpabuf * wps_build_nfc_handover_s
- 	    wps_build_rf_bands(&ctx->dev, msg, 0) ||
- 	    wps_build_serial_number(&ctx->dev, msg) ||
- 	    wps_build_uuid_e(msg, ctx->uuid) ||
--	    wps_build_wfa_ext(msg, 0, NULL, 0)) {
-+	    wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
- 		wpabuf_free(msg);
- 		return NULL;
- 	}
---- a/src/wps/wps_defs.h
-+++ b/src/wps/wps_defs.h
-@@ -152,7 +152,8 @@ enum {
- 	WFA_ELEM_NETWORK_KEY_SHAREABLE = 0x02,
- 	WFA_ELEM_REQUEST_TO_ENROLL = 0x03,
- 	WFA_ELEM_SETTINGS_DELAY_TIME = 0x04,
--	WFA_ELEM_REGISTRAR_CONFIGURATION_METHODS = 0x05
-+	WFA_ELEM_REGISTRAR_CONFIGURATION_METHODS = 0x05,
-+	WFA_ELEM_MULTI_AP = 0x06
- };
- 
- /* Device Password ID */
---- a/src/wps/wps_enrollee.c
-+++ b/src/wps/wps_enrollee.c
-@@ -152,7 +152,7 @@ static struct wpabuf * wps_build_m1(stru
- 	    wps_build_dev_password_id(msg, wps->dev_pw_id) ||
- 	    wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
- 	    wps_build_os_version(&wps->wps->dev, msg) ||
--	    wps_build_wfa_ext(msg, 0, NULL, 0) ||
-+	    wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
- 	    wps_build_vendor_ext_m1(&wps->wps->dev, msg)) {
- 		wpabuf_free(msg);
- 		return NULL;
-@@ -190,7 +190,7 @@ static struct wpabuf * wps_build_m3(stru
- 	    wps_build_msg_type(msg, WPS_M3) ||
- 	    wps_build_registrar_nonce(wps, msg) ||
- 	    wps_build_e_hash(wps, msg) ||
--	    wps_build_wfa_ext(msg, 0, NULL, 0) ||
-+	    wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
- 	    wps_build_authenticator(wps, msg)) {
- 		wpabuf_free(msg);
- 		return NULL;
-@@ -223,7 +223,7 @@ static struct wpabuf * wps_build_m5(stru
- 	    wps_build_e_snonce1(wps, plain) ||
- 	    wps_build_key_wrap_auth(wps, plain) ||
- 	    wps_build_encr_settings(wps, msg, plain) ||
--	    wps_build_wfa_ext(msg, 0, NULL, 0) ||
-+	    wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
- 	    wps_build_authenticator(wps, msg)) {
- 		wpabuf_clear_free(plain);
- 		wpabuf_free(msg);
-@@ -393,7 +393,7 @@ static struct wpabuf * wps_build_m7(stru
- 	    (wps->wps->ap && wps_build_ap_settings(wps, plain)) ||
- 	    wps_build_key_wrap_auth(wps, plain) ||
- 	    wps_build_encr_settings(wps, msg, plain) ||
--	    wps_build_wfa_ext(msg, 0, NULL, 0) ||
-+	    wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
- 	    wps_build_authenticator(wps, msg)) {
- 		wpabuf_clear_free(plain);
- 		wpabuf_free(msg);
-@@ -430,7 +430,7 @@ static struct wpabuf * wps_build_wsc_don
- 	    wps_build_msg_type(msg, WPS_WSC_DONE) ||
- 	    wps_build_enrollee_nonce(wps, msg) ||
- 	    wps_build_registrar_nonce(wps, msg) ||
--	    wps_build_wfa_ext(msg, 0, NULL, 0)) {
-+	    wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
- 		wpabuf_free(msg);
- 		return NULL;
- 	}
---- a/src/wps/wps_er.c
-+++ b/src/wps/wps_er.c
-@@ -1530,7 +1530,7 @@ void wps_er_set_sel_reg(struct wps_er *e
- 	    wps_er_build_selected_registrar(msg, sel_reg) ||
- 	    wps_er_build_dev_password_id(msg, dev_passwd_id) ||
- 	    wps_er_build_sel_reg_config_methods(msg, sel_reg_config_methods) ||
--	    wps_build_wfa_ext(msg, 0, auth_macs, count) ||
-+	    wps_build_wfa_ext(msg, 0, auth_macs, count, 0) ||
- 	    wps_er_build_uuid_r(msg, er->wps->uuid)) {
- 		wpabuf_free(msg);
- 		return;
-@@ -2048,7 +2048,7 @@ struct wpabuf * wps_er_config_token_from
- 	data.wps = wps;
- 	data.use_cred = cred;
- 	if (wps_build_cred(&data, ret) ||
--	    wps_build_wfa_ext(ret, 0, NULL, 0)) {
-+	    wps_build_wfa_ext(ret, 0, NULL, 0, 0)) {
- 		wpabuf_free(ret);
- 		return NULL;
- 	}
---- a/src/wps/wps_i.h
-+++ b/src/wps/wps_i.h
-@@ -163,7 +163,8 @@ int wps_build_encr_settings(struct wps_d
- 			    struct wpabuf *plain);
- int wps_build_version(struct wpabuf *msg);
- int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll,
--		      const u8 *auth_macs, size_t auth_macs_count);
-+		      const u8 *auth_macs, size_t auth_macs_count,
-+		      u8 multi_ap_subelem);
- int wps_build_msg_type(struct wpabuf *msg, enum wps_msg_type msg_type);
- int wps_build_enrollee_nonce(struct wps_data *wps, struct wpabuf *msg);
- int wps_build_registrar_nonce(struct wps_data *wps, struct wpabuf *msg);
---- a/src/wps/wps_registrar.c
-+++ b/src/wps/wps_registrar.c
-@@ -1281,7 +1281,7 @@ static int wps_set_ie(struct wps_registr
- 	    wps_build_sel_reg_config_methods(reg, beacon) ||
- 	    wps_build_sel_pbc_reg_uuid_e(reg, beacon) ||
- 	    (reg->dualband && wps_build_rf_bands(&reg->wps->dev, beacon, 0)) ||
--	    wps_build_wfa_ext(beacon, 0, auth_macs, count) ||
-+	    wps_build_wfa_ext(beacon, 0, auth_macs, count, 0) ||
- 	    wps_build_vendor_ext(&reg->wps->dev, beacon)) {
- 		wpabuf_free(beacon);
- 		wpabuf_free(probe);
-@@ -1311,7 +1311,7 @@ static int wps_set_ie(struct wps_registr
- 	    wps_build_device_attrs(&reg->wps->dev, probe) ||
- 	    wps_build_probe_config_methods(reg, probe) ||
- 	    (reg->dualband && wps_build_rf_bands(&reg->wps->dev, probe, 0)) ||
--	    wps_build_wfa_ext(probe, 0, auth_macs, count) ||
-+	    wps_build_wfa_ext(probe, 0, auth_macs, count, 0) ||
- 	    wps_build_vendor_ext(&reg->wps->dev, probe)) {
- 		wpabuf_free(beacon);
- 		wpabuf_free(probe);
-@@ -1845,7 +1845,7 @@ static struct wpabuf * wps_build_m2(stru
- 	    wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
- 	    wps_build_dev_password_id(msg, wps->dev_pw_id) ||
- 	    wps_build_os_version(&wps->wps->dev, msg) ||
--	    wps_build_wfa_ext(msg, 0, NULL, 0)) {
-+	    wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
- 		wpabuf_free(msg);
- 		return NULL;
- 	}
-@@ -1913,7 +1913,7 @@ static struct wpabuf * wps_build_m2d(str
- 	    wps_build_assoc_state(wps, msg) ||
- 	    wps_build_config_error(msg, err) ||
- 	    wps_build_os_version(&wps->wps->dev, msg) ||
--	    wps_build_wfa_ext(msg, 0, NULL, 0)) {
-+	    wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
- 		wpabuf_free(msg);
- 		return NULL;
- 	}
-@@ -1949,7 +1949,7 @@ static struct wpabuf * wps_build_m4(stru
- 	    wps_build_r_snonce1(wps, plain) ||
- 	    wps_build_key_wrap_auth(wps, plain) ||
- 	    wps_build_encr_settings(wps, msg, plain) ||
--	    wps_build_wfa_ext(msg, 0, NULL, 0) ||
-+	    wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
- 	    wps_build_authenticator(wps, msg)) {
- 		wpabuf_clear_free(plain);
- 		wpabuf_free(msg);
-@@ -1984,7 +1984,7 @@ static struct wpabuf * wps_build_m6(stru
- 	    wps_build_r_snonce2(wps, plain) ||
- 	    wps_build_key_wrap_auth(wps, plain) ||
- 	    wps_build_encr_settings(wps, msg, plain) ||
--	    wps_build_wfa_ext(msg, 0, NULL, 0) ||
-+	    wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
- 	    wps_build_authenticator(wps, msg)) {
- 		wpabuf_clear_free(plain);
- 		wpabuf_free(msg);
-@@ -2021,7 +2021,7 @@ static struct wpabuf * wps_build_m8(stru
- 	    (!wps->wps->ap && !wps->er && wps_build_ap_settings(wps, plain)) ||
- 	    wps_build_key_wrap_auth(wps, plain) ||
- 	    wps_build_encr_settings(wps, msg, plain) ||
--	    wps_build_wfa_ext(msg, 0, NULL, 0) ||
-+	    wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
- 	    wps_build_authenticator(wps, msg)) {
- 		wpabuf_clear_free(plain);
- 		wpabuf_clear_free(msg);
---- a/src/wps/wps_upnp.c
-+++ b/src/wps/wps_upnp.c
-@@ -599,7 +599,7 @@ static struct wpabuf * build_fake_wsc_ac
- 	wpabuf_put_be16(msg, ATTR_REGISTRAR_NONCE);
- 	wpabuf_put_be16(msg, WPS_NONCE_LEN);
- 	wpabuf_put(msg, WPS_NONCE_LEN);
--	if (wps_build_wfa_ext(msg, 0, NULL, 0)) {
-+	if (wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
- 		wpabuf_free(msg);
- 		return NULL;
- 	}
diff --git a/package/network/services/hostapd/patches/556-wpa_supplicant-support-Multi-AP-backhaul-STA-onboard.patch b/package/network/services/hostapd/patches/556-wpa_supplicant-support-Multi-AP-backhaul-STA-onboard.patch
deleted file mode 100644
index 11c65c71a0..0000000000
--- a/package/network/services/hostapd/patches/556-wpa_supplicant-support-Multi-AP-backhaul-STA-onboard.patch
+++ /dev/null
@@ -1,217 +0,0 @@
-From 6c4c98db9420a3321bbf091cfc254de5eba4b404 Mon Sep 17 00:00:00 2001
-From: Davina Lu <ylu@quantenna.com>
-Date: Tue, 15 Jan 2019 19:17:51 +0100
-Subject: [PATCH] wpa_supplicant: support Multi-AP backhaul STA onboarding
-
-The Wi-Fi Alliance Multi-AP Specification v1.0 allows onboarding of a
-backhaul STA through WPS. To enable this, the backhaul STA needs to add
-a Multi-AP IE to the WFA vendor extension element in the WSC M1 message
-that indicates it supports the Multi-AP backhaul STA role. The registrar
-(if it support Multi-AP onboarding) will respond to that with a WSC M8
-message that also contains the Multi-AP IE, and that contains the
-credentials for the backhaul SSID (which may be different from the SSID
-on which WPS is performed).
-
-Introduce a new parameter to wpas_wps_start_pbc() and allow it to be
-set via control interface's new multi_ap=1 parameter of WPS_PBC call.
-multi_ap_backhaul_sta is set to 1 in the automatically created SSID.
-Thus, if the AP does not support Multi-AP, association will fail and
-WPS will be terminated.
-
-Only wps_pbc is supported.
-
-The multi_ap argument is only added to the socket interface, not to the
-dbus interface.
-
-Signed-off-by: Davina Lu <ylu@quantenna.com>
-Signed-off-by: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
-Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
-v4: use argument to wps_pbc instead of a global configuration option
- (requested by Jouni)
----
- src/eap_peer/eap_wsc.c                      | 3 +++
- src/wps/wps.h                               | 6 ++++++
- src/wps/wps_enrollee.c                      | 6 +++++-
- wpa_supplicant/ctrl_iface.c                 | 5 ++++-
- wpa_supplicant/dbus/dbus_new_handlers_wps.c | 2 +-
- wpa_supplicant/dbus/dbus_old_handlers_wps.c | 4 ++--
- wpa_supplicant/events.c                     | 2 +-
- wpa_supplicant/p2p_supplicant.c             | 2 +-
- wpa_supplicant/wps_supplicant.c             | 9 +++++++--
- wpa_supplicant/wps_supplicant.h             | 2 +-
- 10 files changed, 31 insertions(+), 10 deletions(-)
-
---- a/src/eap_peer/eap_wsc.c
-+++ b/src/eap_peer/eap_wsc.c
-@@ -274,6 +274,9 @@ static void * eap_wsc_init(struct eap_sm
- 				      cfg.pin, cfg.pin_len, 0);
- 	}
- 
-+	if (os_strstr(phase1, "multi_ap=1"))
-+		wps->multi_ap_backhaul_sta = 1;
-+
- 	/* Use reduced client timeout for WPS to avoid long wait */
- 	if (sm->ClientTimeout > 30)
- 		sm->ClientTimeout = 30;
---- a/src/wps/wps.h
-+++ b/src/wps/wps.h
-@@ -613,6 +613,12 @@ struct wps_context {
- 	int ap_setup_locked;
- 
- 	/**
-+	 * multi_ap_backhaul_sta - Whether this is a Multi-AP backhaul STA
-+	 * enrollee
-+	 */
-+	int multi_ap_backhaul_sta;
-+
-+	/**
- 	 * uuid - Own UUID
- 	 */
- 	u8 uuid[16];
---- a/src/wps/wps_enrollee.c
-+++ b/src/wps/wps_enrollee.c
-@@ -105,6 +105,7 @@ static struct wpabuf * wps_build_m1(stru
- {
- 	struct wpabuf *msg;
- 	u16 config_methods;
-+	u8 multi_ap_backhaul_sta = 0;
- 
- 	if (random_get_bytes(wps->nonce_e, WPS_NONCE_LEN) < 0)
- 		return NULL;
-@@ -134,6 +135,9 @@ static struct wpabuf * wps_build_m1(stru
- 				    WPS_CONFIG_PHY_PUSHBUTTON);
- 	}
- 
-+	if (wps->wps->multi_ap_backhaul_sta)
-+		multi_ap_backhaul_sta = MULTI_AP_BACKHAUL_STA;
-+
- 	if (wps_build_version(msg) ||
- 	    wps_build_msg_type(msg, WPS_M1) ||
- 	    wps_build_uuid_e(msg, wps->uuid_e) ||
-@@ -152,7 +156,7 @@ static struct wpabuf * wps_build_m1(stru
- 	    wps_build_dev_password_id(msg, wps->dev_pw_id) ||
- 	    wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
- 	    wps_build_os_version(&wps->wps->dev, msg) ||
--	    wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
-+	    wps_build_wfa_ext(msg, 0, NULL, 0, multi_ap_backhaul_sta) ||
- 	    wps_build_vendor_ext_m1(&wps->wps->dev, msg)) {
- 		wpabuf_free(msg);
- 		return NULL;
---- a/wpa_supplicant/ctrl_iface.c
-+++ b/wpa_supplicant/ctrl_iface.c
-@@ -1167,6 +1167,7 @@ static int wpa_supplicant_ctrl_iface_wps
- #ifdef CONFIG_AP
- 	u8 *_p2p_dev_addr = NULL;
- #endif /* CONFIG_AP */
-+	int multi_ap = 0;
- 
- 	if (cmd == NULL || os_strcmp(cmd, "any") == 0) {
- 		_bssid = NULL;
-@@ -1184,6 +1185,8 @@ static int wpa_supplicant_ctrl_iface_wps
- 		wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
- 			   cmd);
- 		return -1;
-+	} else if (os_strncmp(cmd, "multi_ap=", 9) == 0) {
-+		multi_ap = atoi(cmd + 9);
- 	}
- 
- #ifdef CONFIG_AP
-@@ -1191,7 +1194,7 @@ static int wpa_supplicant_ctrl_iface_wps
- 		return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid, _p2p_dev_addr);
- #endif /* CONFIG_AP */
- 
--	return wpas_wps_start_pbc(wpa_s, _bssid, 0);
-+	return wpas_wps_start_pbc(wpa_s, _bssid, 0, multi_ap);
- }
- 
- 
---- a/wpa_supplicant/dbus/dbus_new_handlers_wps.c
-+++ b/wpa_supplicant/dbus/dbus_new_handlers_wps.c
-@@ -289,7 +289,7 @@ DBusMessage * wpas_dbus_handler_wps_star
- 		if (ret > 0)
- 			os_snprintf(npin, sizeof(npin), "%08d", ret);
- 	} else {
--		ret = wpas_wps_start_pbc(wpa_s, params.bssid, 0);
-+		ret = wpas_wps_start_pbc(wpa_s, params.bssid, 0, 0);
- 	}
- 
- 	if (ret < 0) {
---- a/wpa_supplicant/dbus/dbus_old_handlers_wps.c
-+++ b/wpa_supplicant/dbus/dbus_old_handlers_wps.c
-@@ -37,9 +37,9 @@ DBusMessage * wpas_dbus_iface_wps_pbc(DB
- 		return wpas_dbus_new_invalid_opts_error(message, NULL);
- 
- 	if (os_strcmp(arg_bssid, "any") == 0)
--		ret = wpas_wps_start_pbc(wpa_s, NULL, 0);
-+		ret = wpas_wps_start_pbc(wpa_s, NULL, 0, 0);
- 	else if (!hwaddr_aton(arg_bssid, bssid))
--		ret = wpas_wps_start_pbc(wpa_s, bssid, 0);
-+		ret = wpas_wps_start_pbc(wpa_s, bssid, 0, 0);
- 	else {
- 		return wpas_dbus_new_invalid_opts_error(message,
- 							"Invalid BSSID");
---- a/wpa_supplicant/events.c
-+++ b/wpa_supplicant/events.c
-@@ -4816,7 +4816,7 @@ void supplicant_event(void *ctx, enum wp
- 		break;
- 	case EVENT_WPS_BUTTON_PUSHED:
- #ifdef CONFIG_WPS
--		wpas_wps_start_pbc(wpa_s, NULL, 0);
-+		wpas_wps_start_pbc(wpa_s, NULL, 0, 0);
- #endif /* CONFIG_WPS */
- 		break;
- 	case EVENT_AVOID_FREQUENCIES:
---- a/wpa_supplicant/p2p_supplicant.c
-+++ b/wpa_supplicant/p2p_supplicant.c
-@@ -1649,7 +1649,7 @@ static void wpas_start_wps_enrollee(stru
- 	wpa_supplicant_ap_deinit(wpa_s);
- 	wpas_copy_go_neg_results(wpa_s, res);
- 	if (res->wps_method == WPS_PBC) {
--		wpas_wps_start_pbc(wpa_s, res->peer_interface_addr, 1);
-+		wpas_wps_start_pbc(wpa_s, res->peer_interface_addr, 1, 0);
- #ifdef CONFIG_WPS_NFC
- 	} else if (res->wps_method == WPS_NFC) {
- 		wpas_wps_start_nfc(wpa_s, res->peer_device_addr,
---- a/wpa_supplicant/wps_supplicant.c
-+++ b/wpa_supplicant/wps_supplicant.c
-@@ -1137,9 +1137,10 @@ static void wpas_wps_reassoc(struct wpa_
- 
- 
- int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
--		       int p2p_group)
-+		       int p2p_group, int multi_ap_backhaul_sta)
- {
- 	struct wpa_ssid *ssid;
-+	char phase1[32];
- 
- #ifdef CONFIG_AP
- 	if (wpa_s->ap_iface) {
-@@ -1177,10 +1178,14 @@ int wpas_wps_start_pbc(struct wpa_suppli
- 		}
- 	}
- #endif /* CONFIG_P2P */
--	if (wpa_config_set(ssid, "phase1", "\"pbc=1\"", 0) < 0)
-+	if (os_snprintf(phase1, sizeof(phase1), "pbc=1%s",
-+			multi_ap_backhaul_sta ? " multi_ap=1" : "") ||
-+	    wpa_config_set_quoted(ssid, "phase1", phase1) < 0)
- 		return -1;
- 	if (wpa_s->wps_fragment_size)
- 		ssid->eap.fragment_size = wpa_s->wps_fragment_size;
-+	if (multi_ap_backhaul_sta)
-+		ssid->multi_ap_backhaul_sta = 1;
- 	wpa_supplicant_wps_event(wpa_s, WPS_EV_PBC_ACTIVE, NULL);
- 	eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout,
- 			       wpa_s, NULL);
---- a/wpa_supplicant/wps_supplicant.h
-+++ b/wpa_supplicant/wps_supplicant.h
-@@ -30,7 +30,7 @@ void wpas_wps_deinit(struct wpa_supplica
- int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s);
- enum wps_request_type wpas_wps_get_req_type(struct wpa_ssid *ssid);
- int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
--		       int p2p_group);
-+		       int p2p_group, int multi_ap_backhaul_sta);
- int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
- 		       const char *pin, int p2p_group, u16 dev_pw_id);
- void wpas_wps_pbc_overlap(struct wpa_supplicant *wpa_s);
diff --git a/package/network/services/hostapd/patches/557-hostapd-support-Multi-AP-backhaul-STA-onboarding.patch b/package/network/services/hostapd/patches/557-hostapd-support-Multi-AP-backhaul-STA-onboarding.patch
deleted file mode 100644
index c5785e50c3..0000000000
--- a/package/network/services/hostapd/patches/557-hostapd-support-Multi-AP-backhaul-STA-onboarding.patch
+++ /dev/null
@@ -1,339 +0,0 @@
-From 8b04a4cddbd6dbadb24279713af7ac677e80d342 Mon Sep 17 00:00:00 2001
-From: Davina Lu <ylu@quantenna.com>
-Date: Tue, 2 Oct 2018 18:34:14 -0700
-Subject: [PATCH] hostapd: support Multi-AP backhaul STA onboarding
-
-The Wi-Fi Alliance Multi-AP Specification v1.0 allows onboarding of a
-backhaul STA through WPS. To enable this, the WPS registrar offers a
-different set of credentials (backhaul credentials instead of fronthaul
-credentials) when the Multi-AP subelement is present in the WFA vendor
-extension element of the WSC M1 message.
-
-Add 3 new configuration options to specify the backhaul credentials for
-the hostapd internal registrar: multi_ap_backhaul_ssid,
-multi_ap_backhaul_wpa_psk, multi_ap_backhaul_wpa_passphrase. These are
-only relevant for a fronthaul SSID, i.e. where multi_ap is set to 2 or
-3. When these options are set, pass the backhaul credentials instead of
-the normal credentials when the Multi-AP subelement is present.
-
-Ignore the Multi-AP subelement if the backhaul config options are not
-set. Note that for an SSID which is fronthaul and backhaul at the same
-time (i.e., multi_ap == 3), this results in the correct credentials
-being sent anyway.
-
-The security to be used for the backaul BSS is fixed to WPA2PSK. The
-Multi-AP Specification only allows Open and WPA2PSK networks to be
-configured. Although not stated explicitly, the backhaul link is
-intended to be always encrypted, hence WPA2PSK.
-
-To build the credentials, the credential-building code is essentially
-copied and simplified. Indeed, the backhaul credentials are always
-WPA2PSK and never use per-device PSK. All the options set for the
-fronthaul BSS WPS are simply ignored.
-
-Signed-off-by: Davina Lu <ylu@quantenna.com>
-Signed-off-by: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
-Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
----
-v4: no change
----
- hostapd/config_file.c    | 47 ++++++++++++++++++++++++++++++++++++++++
- hostapd/hostapd.conf     |  9 ++++++++
- src/ap/ap_config.c       |  2 ++
- src/ap/ap_config.h       |  1 +
- src/ap/wps_hostapd.c     | 26 ++++++++++++++++++++++
- src/wps/wps.h            | 32 +++++++++++++++++++++++++++
- src/wps/wps_attr_parse.c | 11 ++++++++++
- src/wps/wps_attr_parse.h |  1 +
- src/wps/wps_dev_attr.c   |  5 +++++
- src/wps/wps_dev_attr.h   |  1 +
- src/wps/wps_registrar.c  | 25 ++++++++++++++++++++-
- 11 files changed, 159 insertions(+), 1 deletion(-)
-
---- a/hostapd/config_file.c
-+++ b/hostapd/config_file.c
-@@ -3479,6 +3479,53 @@ static int hostapd_config_fill(struct ho
- 				   line, pos);
- 			return 1;
- 		}
-+	} else if (os_strcmp(buf, "multi_ap_backhaul_ssid") == 0) {
-+		size_t slen;
-+		char *str = wpa_config_parse_string(pos, &slen);
-+
-+		if (str == NULL || slen < 1 || slen > SSID_MAX_LEN) {
-+			wpa_printf(MSG_ERROR, "Line %d: invalid SSID '%s'",
-+				   line, pos);
-+			os_free(str);
-+			return 1;
-+		}
-+		os_memcpy(bss->multi_ap_backhaul_ssid.ssid, str, slen);
-+		bss->multi_ap_backhaul_ssid.ssid_len = slen;
-+		bss->multi_ap_backhaul_ssid.ssid_set = 1;
-+		os_free(str);
-+	} else if (os_strcmp(buf, "multi_ap_backhaul_wpa_passphrase") == 0) {
-+		int len = os_strlen(pos);
-+
-+		if (len < 8 || len > 63) {
-+			wpa_printf(MSG_ERROR,
-+				   "Line %d: invalid WPA passphrase length %d (expected 8..63)",
-+				   line, len);
-+			return 1;
-+		}
-+		os_free(bss->multi_ap_backhaul_ssid.wpa_passphrase);
-+		bss->multi_ap_backhaul_ssid.wpa_passphrase = os_strdup(pos);
-+		if (bss->multi_ap_backhaul_ssid.wpa_passphrase) {
-+			hostapd_config_clear_wpa_psk(&bss->multi_ap_backhaul_ssid.wpa_psk);
-+			bss->multi_ap_backhaul_ssid.wpa_passphrase_set = 1;
-+		}
-+	} else if (os_strcmp(buf, "multi_ap_backhaul_wpa_psk") == 0) {
-+		hostapd_config_clear_wpa_psk(&bss->multi_ap_backhaul_ssid.wpa_psk);
-+		bss->multi_ap_backhaul_ssid.wpa_psk =
-+			os_zalloc(sizeof(struct hostapd_wpa_psk));
-+		if (bss->multi_ap_backhaul_ssid.wpa_psk == NULL)
-+			return 1;
-+		if (hexstr2bin(pos, bss->multi_ap_backhaul_ssid.wpa_psk->psk,
-+			       PMK_LEN) ||
-+		    pos[PMK_LEN * 2] != '\0') {
-+			wpa_printf(MSG_ERROR, "Line %d: Invalid PSK '%s'.",
-+				   line, pos);
-+			hostapd_config_clear_wpa_psk(&bss->multi_ap_backhaul_ssid.wpa_psk);
-+			return 1;
-+		}
-+		bss->multi_ap_backhaul_ssid.wpa_psk->group = 1;
-+		os_free(bss->multi_ap_backhaul_ssid.wpa_passphrase);
-+		bss->multi_ap_backhaul_ssid.wpa_passphrase = NULL;
-+		bss->multi_ap_backhaul_ssid.wpa_psk_set = 1;
- 	} else if (os_strcmp(buf, "upnp_iface") == 0) {
- 		os_free(bss->upnp_iface);
- 		bss->upnp_iface = os_strdup(pos);
---- a/hostapd/hostapd.conf
-+++ b/hostapd/hostapd.conf
-@@ -1852,6 +1852,15 @@ own_ip_addr=127.0.0.1
- # attribute.
- #ap_settings=hostapd.ap_settings
- 
-+# Multi-AP backhaul BSS config
-+# Used in WPS when multi_ap=2 or 3. Defines "backhaul BSS" credentials.
-+# These are passed in WPS M8 instead of the normal (fronthaul) credentials
-+# if the enrollee has the Multi-AP subelement set. Backhaul SSID is formatted
-+# like ssid2. The key is set like wpa_psk or wpa_passphrase.
-+#multi_ap_backhaul_ssid="backhaul"
-+#multi_ap_backhaul_wpa_psk=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
-+#multi_ap_backhaul_wpa_passphrase=secret passphrase
-+
- # WPS UPnP interface
- # If set, support for external Registrars is enabled.
- #upnp_iface=br0
---- a/src/ap/ap_config.c
-+++ b/src/ap/ap_config.c
-@@ -582,6 +582,8 @@ void hostapd_config_free_bss(struct host
- 	os_free(conf->ap_pin);
- 	os_free(conf->extra_cred);
- 	os_free(conf->ap_settings);
-+	hostapd_config_clear_wpa_psk(&conf->multi_ap_backhaul_ssid.wpa_psk);
-+	str_clear_free(conf->multi_ap_backhaul_ssid.wpa_passphrase);
- 	os_free(conf->upnp_iface);
- 	os_free(conf->friendly_name);
- 	os_free(conf->manufacturer_url);
---- a/src/ap/ap_config.h
-+++ b/src/ap/ap_config.h
-@@ -456,6 +456,7 @@ struct hostapd_bss_config {
- 	int force_per_enrollee_psk;
- 	u8 *ap_settings;
- 	size_t ap_settings_len;
-+	struct hostapd_ssid multi_ap_backhaul_ssid;
- 	char *upnp_iface;
- 	char *friendly_name;
- 	char *manufacturer_url;
---- a/src/ap/wps_hostapd.c
-+++ b/src/ap/wps_hostapd.c
-@@ -962,6 +962,7 @@ static void hostapd_free_wps(struct wps_
- 		wpabuf_free(wps->dev.vendor_ext[i]);
- 	wps_device_data_free(&wps->dev);
- 	os_free(wps->network_key);
-+	os_free(wps->multi_ap_backhaul_network_key);
- 	hostapd_wps_nfc_clear(wps);
- 	wpabuf_free(wps->dh_pubkey);
- 	wpabuf_free(wps->dh_privkey);
-@@ -1131,6 +1132,31 @@ int hostapd_init_wps(struct hostapd_data
- 		wps->encr_types_wpa = WPS_ENCR_AES | WPS_ENCR_TKIP;
- 	}
- 
-+	if (hapd->conf->multi_ap & FRONTHAUL_BSS &&
-+	    hapd->conf->multi_ap_backhaul_ssid.ssid_len) {
-+		wps->multi_ap_backhaul_ssid_len =
-+			hapd->conf->multi_ap_backhaul_ssid.ssid_len;
-+		os_memcpy(wps->multi_ap_backhaul_ssid,
-+			  hapd->conf->multi_ap_backhaul_ssid.ssid,
-+			  wps->multi_ap_backhaul_ssid_len);
-+		if (conf->multi_ap_backhaul_ssid.wpa_passphrase) {
-+			wps->multi_ap_backhaul_network_key =
-+				(u8 *) os_strdup(conf->multi_ap_backhaul_ssid.wpa_passphrase);
-+			wps->multi_ap_backhaul_network_key_len =
-+				os_strlen(conf->multi_ap_backhaul_ssid.wpa_passphrase);
-+		} else if (conf->multi_ap_backhaul_ssid.wpa_psk) {
-+			wps->multi_ap_backhaul_network_key =
-+				os_malloc(2 * PMK_LEN + 1);
-+			if (wps->multi_ap_backhaul_network_key == NULL)
-+				goto fail;
-+			wpa_snprintf_hex((char *) wps->multi_ap_backhaul_network_key,
-+					 2 * PMK_LEN + 1,
-+					 conf->multi_ap_backhaul_ssid.wpa_psk->psk,
-+					 PMK_LEN);
-+			wps->multi_ap_backhaul_network_key_len = 2 * PMK_LEN;
-+		}
-+	}
-+
- 	wps->ap_settings = conf->ap_settings;
- 	wps->ap_settings_len = conf->ap_settings_len;
- 
---- a/src/wps/wps.h
-+++ b/src/wps/wps.h
-@@ -100,6 +100,7 @@ struct wps_device_data {
- 	struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
- 
- 	int p2p;
-+	u8 multi_ap_ext;
- };
- 
- /**
-@@ -730,6 +731,37 @@ struct wps_context {
- 	int psk_set;
- 
- 	/**
-+	 * multi_ap_backhaul_ssid - SSID to supply to a Multi-AP backhaul
-+	 * enrollee
-+	 *
-+	 * This SSID is used by the Registrar to fill in information for
-+	 * Credentials when the enrollee advertises it is a Multi-AP backhaul
-+	 * STA.
-+	 */
-+	u8 multi_ap_backhaul_ssid[SSID_MAX_LEN];
-+
-+	/**
-+	 * multi_ap_backhaul_ssid_len - Length of multi_ap_backhaul_ssid in
-+	 * octets
-+	 */
-+	size_t multi_ap_backhaul_ssid_len;
-+
-+	/**
-+	 * multi_ap_backhaul_network_key - The Network Key (PSK) for the
-+	 * Multi-AP backhaul enrollee.
-+	 *
-+	 * This key can be either the ASCII passphrase (8..63 characters) or the
-+	 * 32-octet PSK (64 hex characters).
-+	 */
-+	u8 *multi_ap_backhaul_network_key;
-+
-+	/**
-+	 * multi_ap_backhaul_network_key_len - Length of
-+	 * multi_ap_backhaul_network_key in octets
-+	 */
-+	size_t multi_ap_backhaul_network_key_len;
-+
-+	/**
- 	 * ap_settings - AP Settings override for M7 (only used at AP)
- 	 *
- 	 * If %NULL, AP Settings attributes will be generated based on the
---- a/src/wps/wps_attr_parse.c
-+++ b/src/wps/wps_attr_parse.c
-@@ -67,6 +67,17 @@ static int wps_set_vendor_ext_wfa_subele
- 		}
- 		attr->registrar_configuration_methods = pos;
- 		break;
-+	case WFA_ELEM_MULTI_AP:
-+		if (len != 1) {
-+			wpa_printf(MSG_DEBUG,
-+				   "WPS: Invalid Multi-AP Extension length %u",
-+				   len);
-+			return -1;
-+		}
-+		attr->multi_ap_ext = *pos;
-+		wpa_printf(MSG_DEBUG, "WPS: Multi-AP Extension 0x%02x",
-+			   attr->multi_ap_ext);
-+		break;
- 	default:
- 		wpa_printf(MSG_MSGDUMP, "WPS: Skipped unknown WFA Vendor "
- 			   "Extension subelement %u", id);
---- a/src/wps/wps_attr_parse.h
-+++ b/src/wps/wps_attr_parse.h
-@@ -97,6 +97,7 @@ struct wps_parse_attr {
- 	const u8 *cred[MAX_CRED_COUNT];
- 	const u8 *req_dev_type[MAX_REQ_DEV_TYPE_COUNT];
- 	const u8 *vendor_ext[MAX_WPS_PARSE_VENDOR_EXT];
-+	u8 multi_ap_ext;
- };
- 
- int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr);
---- a/src/wps/wps_dev_attr.c
-+++ b/src/wps/wps_dev_attr.c
-@@ -389,6 +389,11 @@ int wps_process_os_version(struct wps_de
- 	return 0;
- }
- 
-+void wps_process_vendor_ext_m1(struct wps_device_data *dev, const u8 ext)
-+{
-+	dev->multi_ap_ext = ext;
-+	wpa_printf(MSG_DEBUG, "WPS: Multi-AP extension value %02x", dev->multi_ap_ext);
-+}
- 
- int wps_process_rf_bands(struct wps_device_data *dev, const u8 *bands)
- {
---- a/src/wps/wps_dev_attr.h
-+++ b/src/wps/wps_dev_attr.h
-@@ -29,6 +29,7 @@ int wps_build_dev_name(struct wps_device
- int wps_process_device_attrs(struct wps_device_data *dev,
- 			     struct wps_parse_attr *attr);
- int wps_process_os_version(struct wps_device_data *dev, const u8 *ver);
-+void wps_process_vendor_ext_m1(struct wps_device_data *dev, const u8 ext);
- int wps_process_rf_bands(struct wps_device_data *dev, const u8 *bands);
- void wps_device_data_free(struct wps_device_data *dev);
- int wps_build_vendor_ext(struct wps_device_data *dev, struct wpabuf *msg);
---- a/src/wps/wps_registrar.c
-+++ b/src/wps/wps_registrar.c
-@@ -1588,7 +1588,6 @@ int wps_build_credential_wrap(struct wpa
- 	return 0;
- }
- 
--
- int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
- {
- 	struct wpabuf *cred;
-@@ -1603,6 +1602,29 @@ int wps_build_cred(struct wps_data *wps,
- 	}
- 	os_memset(&wps->cred, 0, sizeof(wps->cred));
- 
-+	if (wps->peer_dev.multi_ap_ext == MULTI_AP_BACKHAUL_STA &&
-+	    wps->wps->multi_ap_backhaul_ssid_len) {
-+		wpa_printf(MSG_DEBUG, "WPS: Use backhaul STA credentials");
-+		os_memcpy(wps->cred.ssid, wps->wps->multi_ap_backhaul_ssid,
-+			  wps->wps->multi_ap_backhaul_ssid_len);
-+		wps->cred.ssid_len = wps->wps->multi_ap_backhaul_ssid_len;
-+		/* Backhaul is always WPA2PSK */
-+		wps->cred.auth_type = WPS_AUTH_WPA2PSK;
-+		wps->cred.encr_type = WPS_ENCR_AES;
-+		/* Set MAC address in the Credential to be the Enrollee's MAC
-+		 * address
-+		 */
-+		os_memcpy(wps->cred.mac_addr, wps->mac_addr_e, ETH_ALEN);
-+		if (wps->wps->multi_ap_backhaul_network_key) {
-+			os_memcpy(wps->cred.key,
-+				  wps->wps->multi_ap_backhaul_network_key,
-+				  wps->wps->multi_ap_backhaul_network_key_len);
-+			wps->cred.key_len =
-+				wps->wps->multi_ap_backhaul_network_key_len;
-+		}
-+		goto use_provided;
-+	}
-+
- 	os_memcpy(wps->cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
- 	wps->cred.ssid_len = wps->wps->ssid_len;
- 
-@@ -2705,6 +2727,7 @@ static enum wps_process_res wps_process_
- 		wps->use_psk_key = 1;
- 	}
- #endif /* WPS_WORKAROUNDS */
-+	wps_process_vendor_ext_m1(&wps->peer_dev, attr->multi_ap_ext);
- 
- 	wps->state = SEND_M2;
- 	return WPS_CONTINUE;
diff --git a/package/network/services/hostapd/patches/558-hostapd-add-README-MULTI-AP.patch b/package/network/services/hostapd/patches/558-hostapd-add-README-MULTI-AP.patch
deleted file mode 100644
index b8526b8b71..0000000000
--- a/package/network/services/hostapd/patches/558-hostapd-add-README-MULTI-AP.patch
+++ /dev/null
@@ -1,181 +0,0 @@
-From bd733055a22c8ca3bcd7648bf716da2713b3d9f1 Mon Sep 17 00:00:00 2001
-From: "Arnout Vandecappelle (Essensium/Mind)" <arnout@mind.be>
-Date: Mon, 21 Jan 2019 16:44:06 +0100
-Subject: [PATCH] hostapd: add README-MULTI-AP
-
-Document what hostapd and wpa_supplicant do for Multi-AP.
-
-This is only included in hostapd, since a Multi-AP device is always an
-access point so it should have hostapd.
-
-Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
----
-v4: wps_pbc has multi_ap as a parameter instead of config option.
----
- hostapd/README-MULTI-AP | 160 ++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 160 insertions(+)
- create mode 100644 hostapd/README-MULTI-AP
-
---- /dev/null
-+++ b/hostapd/README-MULTI-AP
-@@ -0,0 +1,160 @@
-+hostapd, wpa_supplicant and the Multi-AP Specification
-+======================================================
-+
-+This document describes how hostapd and wpa_supplicant can be configured to
-+support the Multi-AP Specification.
-+
-+Introduction to Multi-AP
-+------------------------
-+
-+The Wi-Fi Alliance Multi-AP Specification is the technical specification for
-+Wi-Fi CERTIFIED EasyMesh(TM) [1], the Wi-Fi Alliance® certification program for
-+Multi-AP. It defines control protocols between Wi-Fi® access points (APs) to
-+join them into a network with centralized control and operation. It is targeted
-+only at routers (repeaters, gateways, ...), not at clients. Clients are not
-+involved at all in the protocols.
-+
-+Most of the Multi-AP specification falls outside of the scope of
-+hostapd/wpa_supplicant. hostapd/wpa_supplicant is only involved for the items
-+summarized below. The rest of the protocol must be implemented by a separate
-+daemon, e.g. prplMesh [2]. That daemon also needs to communicate with hostapd,
-+e.g. to get a list of associated clients, but this can be done using the normal
-+hostapd interfaces.
-+
-+hostapd/wpa_supplicant needs to be configured specifically to support:
-+- the WPS onboarding process;
-+- configuring backhaul links.
-+
-+The text below refers to "Multi-AP Specification v1.0" [3].
-+
-+
-+Fronthaul and backhaul links
-+----------------------------
-+
-+In a Multi-AP network, the central controller can configure the SSIDs on the
-+devices that are joined into the network. These are called fronthaul SSIDs.
-+From the point of view of hostapd, there is nothing special about these
-+fronthaul SSIDs.
-+
-+In addition to fronthaul SSIDs, the controller can also configure backhaul
-+links. A backhaul link is a link between two access point devices, giving
-+internet access to access point devices that don't have a wired link. The
-+Multi-AP specification doesn't dictate this, but typically the backhaul link
-+will be bridged into a LAN together with (one of) the fronthaul SSID(s) and the
-+wired Ethernet ports.
-+
-+A backhaul link must be treated specially by hostapd and wpa_supplicant. One
-+side of the backhaul link is configured through the Multi-AP protocol as the
-+"backhaul STA", i.e. the client side of the link. A backhaul STA is like any
-+station and is handled appropriately by wpa_supplicant, but two additional
-+features are required. It must send an additional information element in each
-+(Re-)Association Request ([3], section 5.2, paragraph 4). In addition, it must
-+use 4-address mode for all frames sent over this link ([3], section 14).
-+Therefore, wpa_supplicant must be configured explicitly as the backhaul STA
-+role, by setting 'multi_ap_backhaul_sta=1' in the network configuration block
-+or when configuring the SSID through the client socket. When
-+'multi_ap_backhaul_sta=1', wpa_supplicant includes the Multi-AP IE in
-+(Re-)Association Request messages and verifies that it is included in the
-+(Re-)Association Response. If it is not, association fails. If it is,
-+wpa_supplicant sets 4-address mode for this interface through a driver
-+callback.
-+
-+The AP side of the backhaul link is called a "backhaul SSID". Such an SSID must
-+be handled specially by hostapd, because it must add an additional information
-+element in each (Re-)Association Response, but only to stations that have
-+identified themselves as backhaul stations ([3], section 5.2, paragraph 5-6).
-+This is important because it is possible to use the same BSS and SSID for
-+fronthaul and backhaul at the same time. The additional information element must
-+only be used for frames sent to a backhaul STA, not to a normal STA. Also,
-+frames sent to a backhaul STA must use 4-address mode, while frames sent to a
-+normal STA (fronthaul, when it's a fronthaul and backhaul SSID) must use
-+3-address mode.
-+
-+An SSID is configured in Multi-AP mode in hostapd by setting the 'multi_ap'
-+configuration option to 1 (backhaul SSID), 2 (fronthaul SSID) or 3
-+(simultaneous backhaul and fronthaul SSID). If this option is set, hostapd
-+parses the Multi-AP information element in the Association Request. If the
-+station is a backhaul STA and the SSID is configured as a backhaul SSID,
-+hostapd sets up 4-address mode. Since there may be multiple stations connected
-+simultaneously, and each of them has a different RA (receiver address), a VLAN
-+is created for each backhaul STA and it is automatically added to a bridge.
-+This is the same behavior as for WDS, and the relevant option ('bridge' or
-+'wds_bridge') applies here as well.
-+
-+If 'multi_ap' is 1 (backhaul SSID only), any station that tries to associate
-+without the Multi-AP information element will be denied.
-+
-+If 'multi_ap' is 2 (fronthaul SSID only), any station that tries to associate
-+with the Multi-AP information element will be denied. That is also the only
-+difference with 'multi_ap' set to 0: in the latter case, the Multi-AP
-+information element is simply ignored.
-+
-+In summary, this is the end-to-end behaviour for a backhaul BSS (i.e.,
-+multi_ap_backhaul_sta=1 in wpa_supplicant on STA, and multi_ap=1 or 3 in
-+hostapd on AP). Note that point 1 means that hostapd must not be configured
-+with WPS support on the backhaul BSS (multi_ap=1). hostapd does not check for
-+that.
-+
-+1. Backhaul BSS beacons do not advertise WPS support (other than that, nothing
-+   multi-ap specific).
-+2. STA sends authentication req (nothing multi-ap specific).
-+3. AP sends authentication resp (nothing multi-ap specific).
-+4. STA sends association req with Multi-AP IE.
-+5. AP send association resp with Multi-AP IE.
-+6. STA and AP both use 4-address mode for data.
-+
-+
-+WPS support
-+-----------
-+
-+WPS requires more special handling. WPS must only be advertised on fronthaul
-+SSIDs, not on backhaul SSIDs, so WPS should not be enabled on a backhaul-only
-+SSID in hostapd.conf. The WPS configuration purely works on the fronthaul SSID.
-+When a WPS M1 message has an additional subelement that indicates a request for
-+a multi-AP backhaul link, hostapd must not respond with the normal fronthaul
-+SSID credentials; instead, it should respond with the (potentially different)
-+backhaul SSID credentials.
-+
-+To support this, hostapd has the 'multi_ap_backhaul_ssid',
-+'multi_ap_backhaul_wpa_psk' and 'multi_ap_backhaul_wpa_passphrase' options.
-+When these are set on an SSID with WPS, they are used instead of the normal
-+credentials when hostapd receives a WPS M1 message with the Multi-AP IE. Only
-+WPA2 Personal is supported in the Multi-AP specification, so there is no need
-+to specify authentication or encryption options. For the backhaul credentials,
-+per-device PSK is not supported.
-+
-+If the SSID is a simultaneous backhaul and fronthaul SSID, there is no need to
-+specify the backhaul credentials, since the backhaul and fronthaul credentials
-+are identical.
-+
-+To enable the Multi-AP backhaul STA feature when it performs WPS, a new
-+parameter has been introduced to the WPS_PBC control interface call.
-+When this option is set, it adds the multi-AP backhaul subelement to
-+the association and M1 messages. It then configures the new SSID with
-+'multi_ap_backhaul_sta=1'. Note that this means that if the AP does not
-+follow the Multi-AP specification, wpa_supplicant will fail to
-+associate.
-+
-+In summary, this is the end-to-end behaviour for WPS of a backhaul link (i.e.,
-+multi_ap=1 option is given in the wps_pbc call on the STA side, and multi_ap=2
-+and multi_ap_backhaul_ssid and either multi_ap_backhaul_wpa_psk or
-+multi_ap_backhaul_wpa_passphrase are set to the credentials of a backhaul SSID
-+in hostapd on registrar AP).
-+
-+1. Fronthaul BSS beacons advertise WPS support (nothing multi-ap specific).
-+2. Enrollee sends authentication req (nothing multi-ap specific).
-+3. AP sends authentication resp (nothing multi-ap specific).
-+4. Enrollee sends association req with Multi-AP IE.
-+5. AP send association resp with Multi-AP IE.
-+6. Enrollee sends M1 with additional Multi-AP subelement
-+7. AP sends M8 with backhaul instead of fronthaul credentials.
-+8. Enrollee sends Deauth.
-+
-+
-+References
-+----------
-+
-+[1] https://www.wi-fi.org/discover-wi-fi/wi-fi-easymesh
-+[2] https://github.com/prplfoundation/prplMesh
-+[3] https://www.wi-fi.org/file/multi-ap-specification-v10
-+    (requires registration)
diff --git a/package/network/services/hostapd/patches/559-tests-add-WPS-tests-to-multi_ap-hwsim-tests.patch b/package/network/services/hostapd/patches/559-tests-add-WPS-tests-to-multi_ap-hwsim-tests.patch
deleted file mode 100644
index 3a121ba911..0000000000
--- a/package/network/services/hostapd/patches/559-tests-add-WPS-tests-to-multi_ap-hwsim-tests.patch
+++ /dev/null
@@ -1,182 +0,0 @@
-From 0729e01f5830ebf4701f0b1b7ff1bd2a2eedae40 Mon Sep 17 00:00:00 2001
-From: "Arnout Vandecappelle (Essensium/Mind)" <arnout@mind.be>
-Date: Tue, 12 Feb 2019 11:02:42 +0100
-Subject: [PATCH] tests: add WPS tests to multi_ap hwsim tests
-
-Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
----
-v4: new patch
----
- tests/hwsim/test_multi_ap.py | 164 +++++++++++++++++++++++++++++++++++
- 1 file changed, 164 insertions(+)
-
---- a/tests/hwsim/test_multi_ap.py
-+++ b/tests/hwsim/test_multi_ap.py
-@@ -61,3 +61,167 @@ def test_multi_ap_fronthaul_on_ap(dev, a
-         raise Exception("Connection result not reported")
-     if "CTRL-EVENT-DISCONNECTED" not in ev:
-         raise Exception("Unexpected connection result")
-+
-+def run_multi_ap_wps(dev, apdev, params, multi_ap_bssid = None):
-+    """Helper for running Multi-AP WPS tests
-+
-+    dev[0] does multi_ap WPS, dev[1] does normal WPS. apdev[0] is the fronthaul
-+    BSS. If there is a separate backhaul BSS, it must have been set up by the
-+    caller. params are the normal SSID parameters, they will be extended with
-+    the WPS parameters. multi_ap_bssid must be given if it is not equal to the
-+    fronthaul BSSID."""
-+
-+    if multi_ap_bssid is None:
-+        multi_ap_bssid = apdev[0]['bssid']
-+    params.update({"wps_state": "2", "eap_server": "1"})
-+
-+    # WPS with multi-ap station dev[0]
-+    hapd = hostapd.add_ap(apdev[0], params)
-+    hapd.request("WPS_PBC")
-+    if "PBC Status: Active" not in hapd.request("WPS_GET_STATUS"):
-+        raise Exception("PBC status not shown correctly")
-+
-+    dev[0].request("WPS_PBC multi_ap=1")
-+    dev[0].wait_connected(timeout=20)
-+    status = dev[0].get_status()
-+    if status['wpa_state'] != 'COMPLETED' or status['bssid'] != multi_ap_bssid:
-+        raise Exception("Not fully connected")
-+    if status['ssid'] != params['multi_ap_backhaul_ssid'].strip('"'):
-+        raise Exception("Unexpected SSID %s != %s" % (status['ssid'], params["multi_ap_backhaul_ssid"]))
-+    if status['pairwise_cipher'] != 'CCMP':
-+        raise Exception("Unexpected encryption configuration %s" % status['pairwise_cipher'])
-+    if status['key_mgmt'] != 'WPA2-PSK':
-+        raise Exception("Unexpected key_mgmt")
-+
-+    status = hapd.request("WPS_GET_STATUS")
-+    if "PBC Status: Disabled" not in status:
-+        raise Exception("PBC status not shown correctly")
-+    if "Last WPS result: Success" not in status:
-+        raise Exception("Last WPS result not shown correctly")
-+    if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
-+        raise Exception("Peer address not shown correctly")
-+
-+    if len(dev[0].list_networks()) != 1:
-+        raise Exception("Unexpected number of network blocks")
-+
-+    # WPS with non-multi-ap station dev[1]
-+    hapd.request("WPS_PBC")
-+    if "PBC Status: Active" not in hapd.request("WPS_GET_STATUS"):
-+        raise Exception("PBC status not shown correctly")
-+
-+    dev[1].request("WPS_PBC")
-+    dev[1].wait_connected(timeout=20)
-+    status = dev[1].get_status()
-+    if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
-+        raise Exception("Not fully connected")
-+    if status['ssid'] != params["ssid"]:
-+        raise Exception("Unexpected SSID")
-+    # Fronthaul may be something else than WPA2-PSK so don't test it.
-+
-+    status = hapd.request("WPS_GET_STATUS")
-+    if "PBC Status: Disabled" not in status:
-+        raise Exception("PBC status not shown correctly")
-+    if "Last WPS result: Success" not in status:
-+        raise Exception("Last WPS result not shown correctly")
-+    if "Peer Address: " + dev[1].p2p_interface_addr() not in status:
-+        raise Exception("Peer address not shown correctly")
-+
-+    if len(dev[1].list_networks()) != 1:
-+        raise Exception("Unexpected number of network blocks")
-+
-+
-+def test_multi_ap_wps_shared(dev, apdev):
-+    """WPS on shared fronthaul/backhaul AP"""
-+    ssid = "multi-ap-wps"
-+    passphrase = "12345678"
-+    params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
-+    params.update({"multi_ap": "3",
-+                   "multi_ap_backhaul_ssid": '"%s"' % ssid,
-+                   "multi_ap_backhaul_wpa_passphrase": passphrase})
-+    run_multi_ap_wps(dev, apdev, params)
-+
-+def test_multi_ap_wps_shared_psk(dev, apdev):
-+    """WPS on shared fronthaul/backhaul AP using PSK"""
-+    ssid = "multi-ap-wps"
-+    psk = "1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
-+    params = hostapd.wpa2_params(ssid=ssid)
-+    params.update({"wpa_psk": psk, "multi_ap": "3",
-+                   "multi_ap_backhaul_ssid": '"%s"' % ssid,
-+                   "multi_ap_backhaul_wpa_psk": psk})
-+    run_multi_ap_wps(dev, apdev, params)
-+
-+def test_multi_ap_wps_split(dev, apdev):
-+    """WPS on split fronthaul and backhaul AP"""
-+    backhaul_ssid = "multi-ap-backhaul-wps"
-+    backhaul_passphrase = "87654321"
-+    params = hostapd.wpa2_params(ssid="multi-ap-fronthaul-wps", passphrase="12345678")
-+    params.update({"multi_ap": "2",
-+                   "multi_ap_backhaul_ssid": '"%s"' % backhaul_ssid,
-+                   "multi_ap_backhaul_wpa_passphrase": backhaul_passphrase})
-+    params_backhaul = hostapd.wpa2_params(ssid=backhaul_ssid, passphrase=backhaul_passphrase)
-+    params_backhaul.update({"multi_ap": "1"})
-+    hapd_backhaul = hostapd.add_ap(apdev[1], params_backhaul)
-+
-+    run_multi_ap_wps(dev, apdev, params, hapd_backhaul.own_addr())
-+
-+def test_multi_ap_wps_split_psk(dev, apdev):
-+    """WPS on split fronthaul and backhaul AP"""
-+    backhaul_ssid = "multi-ap-backhaul-wps"
-+    backhaul_psk = "1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
-+    params = hostapd.wpa2_params(ssid="multi-ap-fronthaul-wps", passphrase="12345678")
-+    params.update({"multi_ap": "2",
-+                   "multi_ap_backhaul_ssid": '"%s"' % backhaul_ssid,
-+                   "multi_ap_backhaul_wpa_psk": backhaul_psk})
-+    params_backhaul = hostapd.wpa2_params(ssid=backhaul_ssid)
-+    params_backhaul.update({"multi_ap": "1", "wpa_psk": backhaul_psk})
-+    hapd_backhaul = hostapd.add_ap(apdev[1], params_backhaul)
-+
-+    run_multi_ap_wps(dev, apdev, params, hapd_backhaul.own_addr())
-+
-+def test_multi_ap_wps_split_mixed(dev, apdev):
-+    """WPS on split fronthaul and backhaul AP with mixed-mode fronthaul"""
-+    backhaul_ssid = "multi-ap-backhaul-wps"
-+    backhaul_passphrase = "87654321"
-+    params = hostapd.wpa_mixed_params(ssid="multi-ap-fronthaul-wps", passphrase="12345678")
-+    params.update({"multi_ap": "2",
-+                   "multi_ap_backhaul_ssid": '"%s"' % backhaul_ssid,
-+                   "multi_ap_backhaul_wpa_passphrase": backhaul_passphrase})
-+    params_backhaul = hostapd.wpa2_params(ssid=backhaul_ssid, passphrase=backhaul_passphrase)
-+    params_backhaul.update({"multi_ap": "1"})
-+    hapd_backhaul = hostapd.add_ap(apdev[1], params_backhaul)
-+
-+    run_multi_ap_wps(dev, apdev, params, hapd_backhaul.own_addr())
-+
-+def test_multi_ap_wps_split_open(dev, apdev):
-+    """WPS on split fronthaul and backhaul AP with open fronthaul"""
-+    backhaul_ssid = "multi-ap-backhaul-wps"
-+    backhaul_passphrase = "87654321"
-+    params = {"ssid": "multi-ap-wps-fronthaul", "multi_ap": "2",
-+              "multi_ap_backhaul_ssid": '"%s"' % backhaul_ssid,
-+              "multi_ap_backhaul_wpa_passphrase": backhaul_passphrase}
-+    params_backhaul = hostapd.wpa2_params(ssid=backhaul_ssid, passphrase=backhaul_passphrase)
-+    params_backhaul.update({"multi_ap": "1"})
-+    hapd_backhaul = hostapd.add_ap(apdev[1], params_backhaul)
-+
-+    run_multi_ap_wps(dev, apdev, params, hapd_backhaul.own_addr())
-+
-+def test_multi_ap_wps_fail_non_multi_ap(dev, apdev):
-+    """Multi-AP WPS on non-WPS AP fails"""
-+
-+    params = hostapd.wpa2_params(ssid="non-multi-ap-wps", passphrase="12345678")
-+    params.update({"wps_state": "2", "eap_server": "1"})
-+
-+    hapd = hostapd.add_ap(apdev[0], params)
-+    hapd.request("WPS_PBC")
-+    if "PBC Status: Active" not in hapd.request("WPS_GET_STATUS"):
-+        raise Exception("PBC status not shown correctly")
-+
-+    dev[0].request("WPS_PBC multi_ap=1")
-+    # Since we will fail to associate and WPS doesn't even get started, there
-+    # isn't much we can do except wait for timeout. For PBC, it is not possible
-+    # to change the timeout from 2 minutes. Instead of waiting for the timeout,
-+    # just check that WPS doesn't finish within reasonable time.
-+    ev = dev[0].wait_event(["WPS-SUCCESS", "WPS-FAIL"], timeout=20)
-+    if ev:
-+        raise Exception("WPS operation completed: " + ev)
-+    dev[0].request("WPS_CANCEL")
diff --git a/package/network/services/hostapd/patches/600-ubus_support.patch b/package/network/services/hostapd/patches/600-ubus_support.patch
index db037c6491..d5b1e33e48 100644
--- a/package/network/services/hostapd/patches/600-ubus_support.patch
+++ b/package/network/services/hostapd/patches/600-ubus_support.patch
@@ -22,7 +22,7 @@
  
  #define OCE_STA_CFON_ENABLED(hapd) \
  	((hapd->conf->oce & OCE_STA_CFON) && \
-@@ -136,6 +137,7 @@ struct hostapd_data {
+@@ -141,6 +142,7 @@ struct hostapd_data {
  	struct hostapd_iface *iface;
  	struct hostapd_config *iconf;
  	struct hostapd_bss_config *conf;
@@ -30,25 +30,17 @@
  	int interface_added; /* virtual interface added for this BSS */
  	unsigned int started:1;
  	unsigned int disabled:1;
-@@ -547,6 +549,7 @@ hostapd_alloc_bss_data(struct hostapd_if
- 		       struct hostapd_bss_config *bss);
- int hostapd_setup_interface(struct hostapd_iface *iface);
- int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err);
-+void hostapd_set_own_neighbor_report(struct hostapd_data *hapd);
- void hostapd_interface_deinit(struct hostapd_iface *iface);
- void hostapd_interface_free(struct hostapd_iface *iface);
- struct hostapd_iface * hostapd_alloc_iface(void);
 --- a/src/ap/hostapd.c
 +++ b/src/ap/hostapd.c
-@@ -373,6 +373,7 @@ static void hostapd_free_hapd_data(struc
- 	hapd->started = 0;
+@@ -374,6 +374,7 @@ static void hostapd_free_hapd_data(struc
+ 	hapd->beacon_set_done = 0;
  
  	wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface);
 +	hostapd_ubus_free_bss(hapd);
  	iapp_deinit(hapd->iapp);
  	hapd->iapp = NULL;
  	accounting_deinit(hapd);
-@@ -1295,6 +1296,8 @@ static int hostapd_setup_bss(struct host
+@@ -1314,6 +1315,8 @@ static int hostapd_setup_bss(struct host
  	if (hapd->driver && hapd->driver->set_operstate)
  		hapd->driver->set_operstate(hapd->drv_priv, 1);
  
@@ -57,16 +49,7 @@
  	return 0;
  }
  
-@@ -1709,7 +1712,7 @@ static enum nr_chan_width hostapd_get_nr
- #endif /* NEED_AP_MLME */
- 
- 
--static void hostapd_set_own_neighbor_report(struct hostapd_data *hapd)
-+void hostapd_set_own_neighbor_report(struct hostapd_data *hapd)
- {
- #ifdef NEED_AP_MLME
- 	u16 capab = hostapd_own_capab_info(hapd);
-@@ -1930,6 +1933,7 @@ static int hostapd_setup_interface_compl
+@@ -1828,6 +1831,7 @@ static int hostapd_setup_interface_compl
  	if (err)
  		goto fail;
  
@@ -74,7 +57,7 @@
  	wpa_printf(MSG_DEBUG, "Completing interface initialization");
  	if (iface->conf->channel) {
  #ifdef NEED_AP_MLME
-@@ -2110,6 +2114,7 @@ dfs_offload:
+@@ -2020,6 +2024,7 @@ dfs_offload:
  
  fail:
  	wpa_printf(MSG_ERROR, "Interface initialization failed");
@@ -82,7 +65,7 @@
  	hostapd_set_state(iface, HAPD_IFACE_DISABLED);
  	wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
  #ifdef CONFIG_FST
-@@ -2576,6 +2581,7 @@ void hostapd_interface_deinit_free(struc
+@@ -2489,6 +2494,7 @@ void hostapd_interface_deinit_free(struc
  		   (unsigned int) iface->conf->num_bss);
  	driver = iface->bss[0]->driver;
  	drv_priv = iface->bss[0]->drv_priv;
@@ -92,14 +75,7 @@
  		   __func__, driver, drv_priv);
 --- a/src/ap/ieee802_11.c
 +++ b/src/ap/ieee802_11.c
-@@ -1759,12 +1759,13 @@ ieee802_11_set_radius_info(struct hostap
- 
- 
- static void handle_auth(struct hostapd_data *hapd,
--			const struct ieee80211_mgmt *mgmt, size_t len)
-+			const struct ieee80211_mgmt *mgmt, size_t len,
-+			struct hostapd_frame_info *fi)
- {
+@@ -2029,7 +2029,7 @@ static void handle_auth(struct hostapd_d
  	u16 auth_alg, auth_transaction, status_code;
  	u16 resp = WLAN_STATUS_SUCCESS;
  	struct sta_info *sta = NULL;
@@ -108,19 +84,19 @@
  	u16 fc;
  	const u8 *challenge = NULL;
  	u32 session_timeout, acct_interim_interval;
-@@ -1775,6 +1776,11 @@ static void handle_auth(struct hostapd_d
+@@ -2040,6 +2040,11 @@ static void handle_auth(struct hostapd_d
  	char *identity = NULL;
  	char *radius_cui = NULL;
  	u16 seq_ctrl;
 +	struct hostapd_ubus_request req = {
 +		.type = HOSTAPD_UBUS_AUTH_REQ,
 +		.mgmt_frame = mgmt,
-+		.frame_info = fi,
++		.ssi_signal = rssi,
 +	};
  
  	if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
  		wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)",
-@@ -1935,6 +1941,13 @@ static void handle_auth(struct hostapd_d
+@@ -2201,6 +2206,13 @@ static void handle_auth(struct hostapd_d
  		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
  		goto fail;
  	}
@@ -134,13 +110,7 @@
  	if (res == HOSTAPD_ACL_PENDING)
  		return;
  
-@@ -3287,12 +3300,12 @@ void fils_hlp_timeout(void *eloop_ctx, v
- 
- static void handle_assoc(struct hostapd_data *hapd,
- 			 const struct ieee80211_mgmt *mgmt, size_t len,
--			 int reassoc)
-+			 int reassoc, struct hostapd_frame_info *fi)
- {
+@@ -3699,7 +3711,7 @@ static void handle_assoc(struct hostapd_
  	u16 capab_info, listen_interval, seq_ctrl, fc;
  	u16 resp = WLAN_STATUS_SUCCESS, reply_res;
  	const u8 *pos;
@@ -149,19 +119,19 @@
  	struct sta_info *sta;
  	u8 *tmp = NULL;
  	struct hostapd_sta_wpa_psk_short *psk = NULL;
-@@ -3301,6 +3314,11 @@ static void handle_assoc(struct hostapd_
+@@ -3708,6 +3720,11 @@ static void handle_assoc(struct hostapd_
  #ifdef CONFIG_FILS
  	int delay_assoc = 0;
  #endif /* CONFIG_FILS */
 +	struct hostapd_ubus_request req = {
 +		.type = HOSTAPD_UBUS_ASSOC_REQ,
 +		.mgmt_frame = mgmt,
-+		.frame_info = fi,
++		.ssi_signal = rssi,
 +	};
  
  	if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) :
  				      sizeof(mgmt->u.assoc_req))) {
-@@ -3472,6 +3490,14 @@ static void handle_assoc(struct hostapd_
+@@ -3887,6 +3904,14 @@ static void handle_assoc(struct hostapd_
  	}
  #endif /* CONFIG_MBO */
  
@@ -176,7 +146,7 @@
  	/*
  	 * sta->capability is used in check_assoc_ies() for RRM enabled
  	 * capability element.
-@@ -3685,6 +3711,7 @@ static void handle_disassoc(struct hosta
+@@ -4114,6 +4139,7 @@ static void handle_disassoc(struct hosta
  	wpa_printf(MSG_DEBUG, "disassocation: STA=" MACSTR " reason_code=%d",
  		   MAC2STR(mgmt->sa),
  		   le_to_host16(mgmt->u.disassoc.reason_code));
@@ -184,7 +154,7 @@
  
  	sta = ap_get_sta(hapd, mgmt->sa);
  	if (sta == NULL) {
-@@ -3750,6 +3777,8 @@ static void handle_deauth(struct hostapd
+@@ -4179,6 +4205,8 @@ static void handle_deauth(struct hostapd
  		" reason_code=%d",
  		MAC2STR(mgmt->sa), le_to_host16(mgmt->u.deauth.reason_code));
  
@@ -193,69 +163,22 @@
  	sta = ap_get_sta(hapd, mgmt->sa);
  	if (sta == NULL) {
  		wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " trying "
-@@ -4077,7 +4106,7 @@ int ieee802_11_mgmt(struct hostapd_data
- 
- 
- 	if (stype == WLAN_FC_STYPE_PROBE_REQ) {
--		handle_probe_req(hapd, mgmt, len, ssi_signal);
-+		handle_probe_req(hapd, mgmt, len, fi);
- 		return 1;
- 	}
- 
-@@ -4097,17 +4126,17 @@ int ieee802_11_mgmt(struct hostapd_data
- 	switch (stype) {
- 	case WLAN_FC_STYPE_AUTH:
- 		wpa_printf(MSG_DEBUG, "mgmt::auth");
--		handle_auth(hapd, mgmt, len);
-+		handle_auth(hapd, mgmt, len, fi);
- 		ret = 1;
- 		break;
- 	case WLAN_FC_STYPE_ASSOC_REQ:
- 		wpa_printf(MSG_DEBUG, "mgmt::assoc_req");
--		handle_assoc(hapd, mgmt, len, 0);
-+		handle_assoc(hapd, mgmt, len, 0, fi);
- 		ret = 1;
- 		break;
- 	case WLAN_FC_STYPE_REASSOC_REQ:
- 		wpa_printf(MSG_DEBUG, "mgmt::reassoc_req");
--		handle_assoc(hapd, mgmt, len, 1);
-+		handle_assoc(hapd, mgmt, len, 1, fi);
- 		ret = 1;
- 		break;
- 	case WLAN_FC_STYPE_DISASSOC:
 --- a/src/ap/beacon.c
 +++ b/src/ap/beacon.c
-@@ -725,7 +725,7 @@ void sta_track_claim_taxonomy_info(struc
- 
- void handle_probe_req(struct hostapd_data *hapd,
- 		      const struct ieee80211_mgmt *mgmt, size_t len,
--		      int ssi_signal)
-+		      struct hostapd_frame_info *fi)
- {
- 	u8 *resp;
- 	struct ieee802_11_elems elems;
-@@ -734,6 +734,7 @@ void handle_probe_req(struct hostapd_dat
- 	size_t i, resp_len;
- 	int noack;
- 	enum ssid_match_result res;
-+	int ssi_signal = fi->ssi_signal;
- 	int ret;
- 	u16 csa_offs[2];
- 	size_t csa_offs_len;
-@@ -742,6 +743,12 @@ void handle_probe_req(struct hostapd_dat
+@@ -744,6 +744,12 @@ void handle_probe_req(struct hostapd_dat
  	struct hostapd_sta_wpa_psk_short *psk = NULL;
  	char *identity = NULL;
  	char *radius_cui = NULL;
 +	struct hostapd_ubus_request req = {
 +		.type = HOSTAPD_UBUS_PROBE_REQ,
 +		.mgmt_frame = mgmt,
-+		.frame_info = fi,
++		.ssi_signal = ssi_signal,
 +		.elems = &elems,
 +	};
  
  	if (len < IEEE80211_HDRLEN)
  		return;
-@@ -919,6 +926,12 @@ void handle_probe_req(struct hostapd_dat
+@@ -921,6 +927,12 @@ void handle_probe_req(struct hostapd_dat
  	}
  #endif /* CONFIG_P2P */
  
@@ -268,20 +191,9 @@
  	/* TODO: verify that supp_rates contains at least one matching rate
  	 * with AP configuration */
  
---- a/src/ap/beacon.h
-+++ b/src/ap/beacon.h
-@@ -14,7 +14,7 @@ struct ieee80211_mgmt;
- 
- void handle_probe_req(struct hostapd_data *hapd,
- 		      const struct ieee80211_mgmt *mgmt, size_t len,
--		      int ssi_signal);
-+		      struct hostapd_frame_info *fi);
- int ieee802_11_set_beacon(struct hostapd_data *hapd);
- int ieee802_11_set_beacons(struct hostapd_iface *iface);
- int ieee802_11_update_beacons(struct hostapd_iface *iface);
 --- a/src/ap/drv_callbacks.c
 +++ b/src/ap/drv_callbacks.c
-@@ -116,6 +116,10 @@ int hostapd_notif_assoc(struct hostapd_d
+@@ -118,6 +118,10 @@ int hostapd_notif_assoc(struct hostapd_d
  	u16 reason = WLAN_REASON_UNSPECIFIED;
  	u16 status = WLAN_STATUS_SUCCESS;
  	const u8 *p2p_dev_addr = NULL;
@@ -292,7 +204,7 @@
  
  	if (addr == NULL) {
  		/*
-@@ -195,6 +199,12 @@ int hostapd_notif_assoc(struct hostapd_d
+@@ -197,6 +201,12 @@ int hostapd_notif_assoc(struct hostapd_d
  		goto fail;
  	}
  
@@ -307,7 +219,7 @@
  		wpabuf_free(sta->p2p_ie);
 --- a/src/ap/sta_info.c
 +++ b/src/ap/sta_info.c
-@@ -416,6 +416,7 @@ void ap_handle_timer(void *eloop_ctx, vo
+@@ -423,6 +423,7 @@ void ap_handle_timer(void *eloop_ctx, vo
  			       HOSTAPD_LEVEL_INFO, "deauthenticated due to "
  			       "local deauth request");
  		ap_free_sta(hapd, sta);
@@ -315,7 +227,7 @@
  		return;
  	}
  
-@@ -563,6 +564,7 @@ skip_poll:
+@@ -577,6 +578,7 @@ skip_poll:
  			hapd, sta,
  			WLAN_REASON_PREV_AUTH_NOT_VALID);
  		ap_free_sta(hapd, sta);
@@ -323,8 +235,8 @@
  		break;
  	}
  }
-@@ -1224,6 +1226,7 @@ void ap_sta_set_authorized(struct hostap
- 					  buf, ip_addr);
+@@ -1273,6 +1275,7 @@ void ap_sta_set_authorized(struct hostap
+ 					  buf, ip_addr, keyid_buf);
  	} else {
  		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED "%s", buf);
 +		hostapd_ubus_notify(hapd, "disassoc", sta->addr);
@@ -333,7 +245,7 @@
  		    hapd->msg_ctx_parent != hapd->msg_ctx)
 --- a/src/ap/wpa_auth_glue.c
 +++ b/src/ap/wpa_auth_glue.c
-@@ -177,6 +177,7 @@ static void hostapd_wpa_auth_psk_failure
+@@ -181,6 +181,7 @@ static void hostapd_wpa_auth_psk_failure
  	struct hostapd_data *hapd = ctx;
  	wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POSSIBLE_PSK_MISMATCH MACSTR,
  		MAC2STR(addr));
@@ -343,7 +255,7 @@
  
 --- a/wpa_supplicant/Makefile
 +++ b/wpa_supplicant/Makefile
-@@ -189,6 +189,12 @@ ifdef CONFIG_EAPOL_TEST
+@@ -188,6 +188,12 @@ ifdef CONFIG_EAPOL_TEST
  CFLAGS += -Werror -DEAPOL_TEST
  endif
  
@@ -356,7 +268,7 @@
  ifdef CONFIG_CODE_COVERAGE
  CFLAGS += -O0 -fprofile-arcs -ftest-coverage
  LIBS += -lgcov
-@@ -915,6 +921,9 @@ endif
+@@ -923,6 +929,9 @@ endif
  ifdef CONFIG_IEEE80211AX
  OBJS += ../src/ap/ieee802_11_he.o
  endif
@@ -368,7 +280,7 @@
  CFLAGS += -DCONFIG_WNM_AP
 --- a/wpa_supplicant/wpa_supplicant.c
 +++ b/wpa_supplicant/wpa_supplicant.c
-@@ -6080,6 +6080,8 @@ struct wpa_supplicant * wpa_supplicant_a
+@@ -6288,6 +6288,8 @@ struct wpa_supplicant * wpa_supplicant_a
  	}
  #endif /* CONFIG_P2P */
  
@@ -377,7 +289,7 @@
  	return wpa_s;
  }
  
-@@ -6106,6 +6108,8 @@ int wpa_supplicant_remove_iface(struct w
+@@ -6314,6 +6316,8 @@ int wpa_supplicant_remove_iface(struct w
  	struct wpa_supplicant *parent = wpa_s->parent;
  #endif /* CONFIG_MESH */
  
@@ -396,7 +308,7 @@
  
  extern const char *const wpa_supplicant_version;
  extern const char *const wpa_supplicant_license;
-@@ -500,6 +501,7 @@ struct wpa_supplicant {
+@@ -506,6 +507,7 @@ struct wpa_supplicant {
  	unsigned char own_addr[ETH_ALEN];
  	unsigned char perm_addr[ETH_ALEN];
  	char ifname[100];
diff --git a/package/network/services/hostapd/src/src/ap/ubus.c b/package/network/services/hostapd/src/src/ap/ubus.c
index 3375ac49f7..3b768d0e8c 100644
--- a/package/network/services/hostapd/src/src/ap/ubus.c
+++ b/package/network/services/hostapd/src/src/ap/ubus.c
@@ -546,7 +546,7 @@ __hostapd_bss_mgmt_enable_f(struct hostapd_data *hapd, int flag)
 
 		bss->radio_measurements[0] |=
 			WLAN_RRM_CAPS_NEIGHBOR_REPORT;
-		hostapd_set_own_neighbor_report(hapd);
+		hostapd_neighbor_set_own_report(hapd);
 		return true;
 	case BSS_MGMT_EN_BEACON:
 		flags = WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE |
@@ -1065,8 +1065,8 @@ int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_req
 	blobmsg_add_macaddr(&b, "address", addr);
 	if (req->mgmt_frame)
 		blobmsg_add_macaddr(&b, "target", req->mgmt_frame->da);
-	if (req->frame_info)
-		blobmsg_add_u32(&b, "signal", req->frame_info->ssi_signal);
+	if (req->ssi_signal)
+		blobmsg_add_u32(&b, "signal", req->ssi_signal);
 	blobmsg_add_u32(&b, "freq", hapd->iface->freq);
 
 	if (req->elems) {
diff --git a/package/network/services/hostapd/src/src/ap/ubus.h b/package/network/services/hostapd/src/src/ap/ubus.h
index 185af5a7f4..58ebe0e65b 100644
--- a/package/network/services/hostapd/src/src/ap/ubus.h
+++ b/package/network/services/hostapd/src/src/ap/ubus.h
@@ -19,7 +19,7 @@ struct hostapd_ubus_request {
 	enum hostapd_ubus_event_type type;
 	const struct ieee80211_mgmt *mgmt_frame;
 	const struct ieee802_11_elems *elems;
-	const struct hostapd_frame_info *frame_info;
+	int ssi_signal; /* dBm */
 	const u8 *addr;
 };
 
