Merge "[Feature][ZXW-4][SIM/SMS]Add liblynq-qser-sms and liblynq-qser-sim" into MR3.0-merge
diff --git a/meta-sdk/meta/meta-lynqSDK-T800/recipes-core/images/mtk-image-2735.bb b/meta-sdk/meta/meta-lynqSDK-T800/recipes-core/images/mtk-image-2735.bb
index e68822b..313bc5d 100755
--- a/meta-sdk/meta/meta-lynqSDK-T800/recipes-core/images/mtk-image-2735.bb
+++ b/meta-sdk/meta/meta-lynqSDK-T800/recipes-core/images/mtk-image-2735.bb
@@ -161,6 +161,8 @@
 mk_oem_init_part_rootfs_post() {
     if [ "${MOBILETEK_OEMAPP_CFG}" = "GSW" ]; then
         cp ${STAGING_DIR_HOST}/${datadir}/init/* ${IMAGE_ROOTFS}/${datadir}/init/
+        mkdir -p ${IMAGE_ROOTFS}/${datadir}/wg870/
+        cp ${STAGING_DIR_HOST}/${datadir}/wg870/wifi_network ${IMAGE_ROOTFS}/${datadir}/wg870/
     fi
 }
 
diff --git a/meta-sdk/meta/meta-lynqSDK-T800/recipes-core/initial/init-oem_1.0.0.bb b/meta-sdk/meta/meta-lynqSDK-T800/recipes-core/initial/init-oem_1.0.0.bb
index 0d4276d..7026696 100755
--- a/meta-sdk/meta/meta-lynqSDK-T800/recipes-core/initial/init-oem_1.0.0.bb
+++ b/meta-sdk/meta/meta-lynqSDK-T800/recipes-core/initial/init-oem_1.0.0.bb
@@ -15,14 +15,14 @@
 INSANE_SKIP_${PN} += "already-stripped"
 
 FILES_${PN} = "${datadir}/init/init_mount \
-               /etc/config/wifi_network \
+               ${datadir}/wg870/wifi_network \
                ${@bb.utils.contains('BOOTDEV_TYPE', 'nand',  ' ${datadir}/init/init_mmc', ' ', d)} \
                "
 
 do_install_append() {
     install -d ${D}${datadir}/init
-    install -d ${D}/etc/config
-    install -m 0644 wifi_network ${D}/etc/config/wifi_network 
+    install -d ${D}${datadir}/wg870
+    install -m 0644 wifi_network ${D}${datadir}/wg870/wifi_network 
     if [ "${BOOTDEV_TYPE}" = "nand" ]; then
         install -m 0755 init_mount_nand_gsw ${D}${datadir}/init/init_mount
     	install -m 0755 init_mmc ${D}${datadir}/init/init_mmc
diff --git a/meta/meta-mediatek-mt2735/recipes-connectivity/connman/connman/lynq_wifi_netmask.patch b/meta/meta-mediatek-mt2735/recipes-connectivity/connman/connman/lynq_wifi_netmask.patch
index a3bc18d..fad275d 100755
--- a/meta/meta-mediatek-mt2735/recipes-connectivity/connman/connman/lynq_wifi_netmask.patch
+++ b/meta/meta-mediatek-mt2735/recipes-connectivity/connman/connman/lynq_wifi_netmask.patch
@@ -19,7 +19,7 @@
 +
 +	DBG("");
 +
-+    fp = fopen("/etc/config/wifi_network", "rb");
++    fp = fopen("/usr/share/wg870/wifi_network", "rb");
 +    if (NULL == fp) {
 +        return NULL;
 +    }
diff --git a/meta/meta-mediatek-mt2735/recipes-kernel/modules/files/wifi/wg870/0926.clm_blob b/meta/meta-mediatek-mt2735/recipes-kernel/modules/files/wifi/wg870/0926.clm_blob
index 8b9b2e0..0f3fc7f 100755
--- a/meta/meta-mediatek-mt2735/recipes-kernel/modules/files/wifi/wg870/0926.clm_blob
+++ b/meta/meta-mediatek-mt2735/recipes-kernel/modules/files/wifi/wg870/0926.clm_blob
Binary files differ
diff --git a/meta/meta-mediatek-mt2735/recipes-kernel/modules/files/wifi/wg870/config_pcie.trxse b/meta/meta-mediatek-mt2735/recipes-kernel/modules/files/wifi/wg870/config_pcie.trxse
index 803b429..dfc7f6a 100755
--- a/meta/meta-mediatek-mt2735/recipes-kernel/modules/files/wifi/wg870/config_pcie.trxse
+++ b/meta/meta-mediatek-mt2735/recipes-kernel/modules/files/wifi/wg870/config_pcie.trxse
Binary files differ
diff --git a/meta/meta-mediatek-mt2735/recipes-lynq/liblynq-wifi6/liblynq-wifi6.bb b/meta/meta-mediatek-mt2735/recipes-lynq/liblynq-wifi6/liblynq-wifi6.bb
index 5ec2c78..40e9441 100644
--- a/meta/meta-mediatek-mt2735/recipes-lynq/liblynq-wifi6/liblynq-wifi6.bb
+++ b/meta/meta-mediatek-mt2735/recipes-lynq/liblynq-wifi6/liblynq-wifi6.bb
@@ -6,7 +6,7 @@
 LICENSE = "CLOSED"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=e1696b147d49d491bcb4da1a57173fff"
 
-DEPENDS += "lynq-wg870 liblynq-log"
+DEPENDS += "lynq-wg870 liblynq-log platform-libs"
 
 inherit workonsrc
 WORKONSRC = "${TOPDIR}/../src/lynq/lib/liblynq-wifi6"
diff --git a/meta/meta-mediatek-mt2735/recipes-lynq/suspend-service/files/autosuspend_wakeup_count.c b/meta/meta-mediatek-mt2735/recipes-lynq/suspend-service/files/autosuspend_wakeup_count.c
index 3128a3b..1d8ce38 100755
--- a/meta/meta-mediatek-mt2735/recipes-lynq/suspend-service/files/autosuspend_wakeup_count.c
+++ b/meta/meta-mediatek-mt2735/recipes-lynq/suspend-service/files/autosuspend_wakeup_count.c
@@ -245,7 +245,9 @@
         ALOGI("lynq_screen off fail\n");
         return -1;
     }
-
+    system("echo mode 4 0 >/sys/devices/platform/10005000.pinctrl/mt_gpio");
+    system("echo out 4 1 >/sys/devices/platform/10005000.pinctrl/mt_gpio");
+    RLOGD("ring GPIO PASS\n");
     system("hwclock -w");
     RLOGD("TIME: sys to rtc\n");
     lseek(wakeup_count_fd, 0, SEEK_SET);
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/MCF_OTA_FILES.tar.gz b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/MCF_OTA_FILES.tar.gz
new file mode 100644
index 0000000..03dced8
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/MCF_OTA_FILES.tar.gz
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/MDDB.MCF.ODB.tar.gz b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/MDDB.MCF.ODB.tar.gz
new file mode 100644
index 0000000..3977d03
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/MDDB.MCF.ODB.tar.gz
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/MDDB.META.ODB_MT2735_S00_MOLY_NR15_R3_MD700_MP_V75_P4.XML.GZ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/MDDB.META.ODB_MT2735_S00_MOLY_NR15_R3_MD700_MP_V75_P4.XML.GZ
new file mode 100644
index 0000000..57a5195
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/MDDB.META.ODB_MT2735_S00_MOLY_NR15_R3_MD700_MP_V75_P4.XML.GZ
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/MDDB.META.ODB_MT2735_S00_MOLY_NR15_R3_MD700_MP_V75_P4_T800_20230328.XML.GZ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/MDDB.META.ODB_MT2735_S00_MOLY_NR15_R3_MD700_MP_V75_P4_T800_20230328.XML.GZ
new file mode 100644
index 0000000..56989aa
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/MDDB.META.ODB_MT2735_S00_MOLY_NR15_R3_MD700_MP_V75_P4_T800_20230328.XML.GZ
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/MDDB.META_MT2735_S00_MOLY_NR15_R3_MD700_MP_V75_P4.EDB b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/MDDB.META_MT2735_S00_MOLY_NR15_R3_MD700_MP_V75_P4.EDB
new file mode 100644
index 0000000..ce52d0c
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/MDDB.META_MT2735_S00_MOLY_NR15_R3_MD700_MP_V75_P4.EDB
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/MDDB.META_MT2735_S00_MOLY_NR15_R3_MD700_MP_V75_P4_T800_20230328.EDB b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/MDDB.META_MT2735_S00_MOLY_NR15_R3_MD700_MP_V75_P4_T800_20230328.EDB
new file mode 100644
index 0000000..1137bdf
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/MDDB.META_MT2735_S00_MOLY_NR15_R3_MD700_MP_V75_P4_T800_20230328.EDB
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/MDDB_InfoCustomAppSrcP_MT2735_S00_MOLY_NR15_R3_MD700_MP_V75_P4.EDB b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/MDDB_InfoCustomAppSrcP_MT2735_S00_MOLY_NR15_R3_MD700_MP_V75_P4.EDB
new file mode 100644
index 0000000..18c7efc
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/MDDB_InfoCustomAppSrcP_MT2735_S00_MOLY_NR15_R3_MD700_MP_V75_P4.EDB
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/MDDB_InfoCustomAppSrcP_MT2735_S00_MOLY_NR15_R3_MD700_MP_V75_P4_T800_20230328.EDB b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/MDDB_InfoCustomAppSrcP_MT2735_S00_MOLY_NR15_R3_MD700_MP_V75_P4_T800_20230328.EDB
new file mode 100644
index 0000000..d60d8bd
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/MDDB_InfoCustomAppSrcP_MT2735_S00_MOLY_NR15_R3_MD700_MP_V75_P4_T800_20230328.EDB
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/catcher_filter.bin b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/catcher_filter.bin
new file mode 100644
index 0000000..48a9301
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/catcher_filter.bin
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/catcher_filter_1_Moderate.bin b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/catcher_filter_1_Moderate.bin
new file mode 100644
index 0000000..570db68
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/catcher_filter_1_Moderate.bin
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/catcher_filter_2_Standard.bin b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/catcher_filter_2_Standard.bin
new file mode 100644
index 0000000..5bbf894
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/catcher_filter_2_Standard.bin
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/catcher_filter_3_Slim.bin b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/catcher_filter_3_Slim.bin
new file mode 100644
index 0000000..76e4798
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/catcher_filter_3_Slim.bin
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/catcher_filter_4_UltraSlim.bin b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/catcher_filter_4_UltraSlim.bin
new file mode 100644
index 0000000..af2f393
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/catcher_filter_4_UltraSlim.bin
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/catcher_filter_LowPowerMonitor.bin b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/catcher_filter_LowPowerMonitor.bin
new file mode 100644
index 0000000..15732d8
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/catcher_filter_LowPowerMonitor.bin
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/catcher_filter_PLS_PS_ONLY.bin b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/catcher_filter_PLS_PS_ONLY.bin
new file mode 100644
index 0000000..9d524d1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/catcher_filter_PLS_PS_ONLY.bin
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/dsp.bin b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/dsp.bin
new file mode 100644
index 0000000..983c095
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/dsp.bin
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/202_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/202_01.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/202_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/202_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/202_02.conf
new file mode 100755
index 0000000..f145903
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/202_02.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/202_05.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/202_05.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/202_05.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/202_09.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/202_09.conf
new file mode 100755
index 0000000..724ba0b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/202_09.conf
@@ -0,0 +1 @@
+ims:ims:IPV6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/202_10.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/202_10.conf
new file mode 100755
index 0000000..724ba0b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/202_10.conf
@@ -0,0 +1 @@
+ims:ims:IPV6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/204_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/204_02.conf
new file mode 100755
index 0000000..2b7345b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/204_02.conf
@@ -0,0 +1 @@
+ims:ims:IPV6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/204_04.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/204_04.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/204_04.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/204_08.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/204_08.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/204_08.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/204_16.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/204_16.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/204_16.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/204_20.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/204_20.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/204_20.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/204_69.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/204_69.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/204_69.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/206_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/206_01.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/206_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/206_10.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/206_10.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/206_10.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/206_20.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/206_20.conf
new file mode 100755
index 0000000..a97d0eb
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/206_20.conf
@@ -0,0 +1 @@
+:ia:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/208_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/208_01.conf
new file mode 100755
index 0000000..9700bc2
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/208_01.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:ia:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/208_10.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/208_10.conf
new file mode 100755
index 0000000..9700bc2
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/208_10.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:ia:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/208_15.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/208_15.conf
new file mode 100755
index 0000000..0f22202
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/208_15.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+free:default:IP:IP:::::::
\ No newline at end of file
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/208_20.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/208_20.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/208_20.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/208_88.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/208_88.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/208_88.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/214_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/214_01.conf
new file mode 100755
index 0000000..63094d1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/214_01.conf
@@ -0,0 +1 @@
+ims:ims:IP:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/214_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/214_02.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/214_02.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/214_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/214_03.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/214_03.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/214_04.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/214_04.conf
new file mode 100755
index 0000000..a97d0eb
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/214_04.conf
@@ -0,0 +1 @@
+:ia:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/214_07.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/214_07.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/214_07.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/216_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/216_01.conf
new file mode 100755
index 0000000..2b7345b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/216_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/216_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/216_03.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/216_03.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/216_30.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/216_30.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/216_30.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/216_70.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/216_70.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/216_70.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/219_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/219_01.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/219_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/219_10.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/219_10.conf
new file mode 100755
index 0000000..a97d0eb
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/219_10.conf
@@ -0,0 +1 @@
+:ia:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/220_05.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/220_05.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/220_05.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/222_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/222_01.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/222_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/222_06.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/222_06.conf
new file mode 100755
index 0000000..643b95f
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/222_06.conf
@@ -0,0 +1,2 @@
+ims:ims:IP:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:ia:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/222_10.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/222_10.conf
new file mode 100755
index 0000000..9700bc2
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/222_10.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:ia:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/222_88.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/222_88.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/222_88.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/226_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/226_01.conf
new file mode 100755
index 0000000..a97d0eb
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/226_01.conf
@@ -0,0 +1 @@
+:ia:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/226_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/226_03.conf
new file mode 100755
index 0000000..58a2c37
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/226_03.conf
@@ -0,0 +1,2 @@
+:ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/226_05.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/226_05.conf
new file mode 100755
index 0000000..ac7c524
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/226_05.conf
@@ -0,0 +1 @@
+ims:ims:IP:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/226_06.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/226_06.conf
new file mode 100755
index 0000000..58a2c37
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/226_06.conf
@@ -0,0 +1,2 @@
+:ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/226_10.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/226_10.conf
new file mode 100755
index 0000000..afcc748
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/226_10.conf
@@ -0,0 +1 @@
+ims:ims:IPV6:IPV6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/228_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/228_01.conf
new file mode 100755
index 0000000..afcc748
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/228_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV6:IPV6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/228_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/228_02.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/228_02.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/230_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/230_01.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/230_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/230_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/230_02.conf
new file mode 100755
index 0000000..724ba0b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/230_02.conf
@@ -0,0 +1 @@
+ims:ims:IPV6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/230_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/230_03.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/230_03.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/231_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/231_01.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/231_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/231_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/231_02.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/231_02.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/231_04.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/231_04.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/231_04.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/231_06.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/231_06.conf
new file mode 100755
index 0000000..4921cc1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/231_06.conf
@@ -0,0 +1 @@
+ims:ims:IPV6:IPV6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/232_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/232_01.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/232_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/232_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/232_03.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/232_03.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/232_05.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/232_05.conf
new file mode 100755
index 0000000..2b7345b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/232_05.conf
@@ -0,0 +1 @@
+ims:ims:IPV6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/232_07.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/232_07.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/232_07.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/232_10.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/232_10.conf
new file mode 100755
index 0000000..2b7345b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/232_10.conf
@@ -0,0 +1 @@
+ims:ims:IPV6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_02.conf
new file mode 100755
index 0000000..8fe0b67
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_02.conf
@@ -0,0 +1,2 @@
+mobile.o2.co.uk:default,ia,supl,mms,xcap:IPV4V6:IPV4V6:1:o2:p:1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_08.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_08.conf
new file mode 100755
index 0000000..413b63b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_08.conf
@@ -0,0 +1,3 @@
+ims:ims:IPV4V6:IPV4V6:1:::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV6:IPV4V6:::::::
+SOS:emergency:IPV4V6:IPV4V6::::18:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_10.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_10.conf
new file mode 100755
index 0000000..8fe0b67
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_10.conf
@@ -0,0 +1,2 @@
+mobile.o2.co.uk:default,ia,supl,mms,xcap:IPV4V6:IPV4V6:1:o2:p:1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_11.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_11.conf
new file mode 100755
index 0000000..8fe0b67
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_11.conf
@@ -0,0 +1,2 @@
+mobile.o2.co.uk:default,ia,supl,mms,xcap:IPV4V6:IPV4V6:1:o2:p:1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_15.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_15.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_15.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_20.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_20.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_20.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_30.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_30.conf
new file mode 100755
index 0000000..783b27b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_30.conf
@@ -0,0 +1,3 @@
+ims:ims:IPV6:IPV4V6:1:::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV6:IPV4V6:1::::::
+SOS:emergency:IPV6:IPV4V6:1:::18:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_31.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_31.conf
new file mode 100755
index 0000000..783b27b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_31.conf
@@ -0,0 +1,3 @@
+ims:ims:IPV6:IPV4V6:1:::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV6:IPV4V6:1::::::
+SOS:emergency:IPV6:IPV4V6:1:::18:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_32.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_32.conf
new file mode 100755
index 0000000..783b27b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_32.conf
@@ -0,0 +1,3 @@
+ims:ims:IPV6:IPV4V6:1:::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV6:IPV4V6:1::::::
+SOS:emergency:IPV6:IPV4V6:1:::18:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_33.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_33.conf
new file mode 100755
index 0000000..783b27b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_33.conf
@@ -0,0 +1,3 @@
+ims:ims:IPV6:IPV4V6:1:::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV6:IPV4V6:1::::::
+SOS:emergency:IPV6:IPV4V6:1:::18:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_34.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_34.conf
new file mode 100755
index 0000000..783b27b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_34.conf
@@ -0,0 +1,3 @@
+ims:ims:IPV6:IPV4V6:1:::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV6:IPV4V6:1::::::
+SOS:emergency:IPV6:IPV4V6:1:::18:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_86.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_86.conf
new file mode 100755
index 0000000..2b7345b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/234_86.conf
@@ -0,0 +1 @@
+ims:ims:IPV6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/235_91.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/235_91.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/235_91.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/235_94.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/235_94.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/235_94.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/238_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/238_01.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/238_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/238_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/238_02.conf
new file mode 100755
index 0000000..63094d1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/238_02.conf
@@ -0,0 +1 @@
+ims:ims:IP:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/238_06.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/238_06.conf
new file mode 100755
index 0000000..f145903
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/238_06.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/238_10.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/238_10.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/238_10.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/238_20.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/238_20.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/238_20.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/238_30.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/238_30.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/238_30.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/238_77.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/238_77.conf
new file mode 100755
index 0000000..63094d1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/238_77.conf
@@ -0,0 +1 @@
+ims:ims:IP:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/240_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/240_01.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/240_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/240_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/240_02.conf
new file mode 100755
index 0000000..f145903
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/240_02.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/240_05.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/240_05.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/240_05.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/240_07.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/240_07.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/240_07.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/240_08.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/240_08.conf
new file mode 100755
index 0000000..8b13789
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/240_08.conf
@@ -0,0 +1 @@
+
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/240_99.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/240_99.conf
new file mode 100755
index 0000000..f524693
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/240_99.conf
@@ -0,0 +1,3 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+sos:emergency:IPV4V6:IPV4V6::::18:::
+apn03.mtk:default,ia:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/242_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/242_01.conf
new file mode 100755
index 0000000..2b7345b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/242_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/242_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/242_02.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/242_02.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/242_05.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/242_05.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/242_05.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/242_14.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/242_14.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/242_14.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/244_05.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/244_05.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/244_05.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/244_12.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/244_12.conf
new file mode 100755
index 0000000..afcc748
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/244_12.conf
@@ -0,0 +1 @@
+ims:ims:IPV6:IPV6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/244_13.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/244_13.conf
new file mode 100755
index 0000000..afcc748
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/244_13.conf
@@ -0,0 +1 @@
+ims:ims:IPV6:IPV6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/244_21.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/244_21.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/244_21.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/244_91.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/244_91.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/244_91.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/246_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/246_01.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/246_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/248_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/248_01.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/248_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/250_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/250_01.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/250_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/250_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/250_02.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/250_02.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/250_11.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/250_11.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/250_11.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/250_20.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/250_20.conf
new file mode 100755
index 0000000..6c75109
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/250_20.conf
@@ -0,0 +1 @@
+ims.tele2.ru:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/250_99.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/250_99.conf
new file mode 100755
index 0000000..63094d1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/250_99.conf
@@ -0,0 +1 @@
+ims:ims:IP:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/259_15.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/259_15.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/259_15.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/260_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/260_01.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/260_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/260_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/260_02.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/260_02.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/260_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/260_03.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/260_03.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/260_06.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/260_06.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/260_06.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/260_34.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/260_34.conf
new file mode 100755
index 0000000..bd546e1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/260_34.conf
@@ -0,0 +1,2 @@
+:ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/260_98.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/260_98.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/260_98.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/262_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/262_01.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/262_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/262_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/262_02.conf
new file mode 100755
index 0000000..9700bc2
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/262_02.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:ia:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/262_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/262_03.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/262_03.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/262_06.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/262_06.conf
new file mode 100755
index 0000000..32efdf7
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/262_06.conf
@@ -0,0 +1 @@
+ims:ia,ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/262_07.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/262_07.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/262_07.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/262_09.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/262_09.conf
new file mode 100755
index 0000000..9700bc2
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/262_09.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:ia:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/262_77.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/262_77.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/262_77.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/262_80.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/262_80.conf
new file mode 100755
index 0000000..ab02885
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/262_80.conf
@@ -0,0 +1 @@
+ims01.epg78.ericsson.se:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/268_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/268_01.conf
new file mode 100755
index 0000000..643b95f
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/268_01.conf
@@ -0,0 +1,2 @@
+ims:ims:IP:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:ia:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/268_06.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/268_06.conf
new file mode 100755
index 0000000..a97d0eb
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/268_06.conf
@@ -0,0 +1 @@
+:ia:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/268_89.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/268_89.conf
new file mode 100755
index 0000000..643b95f
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/268_89.conf
@@ -0,0 +1,2 @@
+ims:ims:IP:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:ia:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/272_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/272_01.conf
new file mode 100755
index 0000000..63094d1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/272_01.conf
@@ -0,0 +1 @@
+ims:ims:IP:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/276_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/276_01.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/276_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/284_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/284_03.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/284_03.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/284_05.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/284_05.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/284_05.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/286_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/286_01.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/286_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/286_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/286_02.conf
new file mode 100755
index 0000000..f145903
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/286_02.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/286_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/286_03.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/286_03.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/293_41.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/293_41.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/293_41.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/294_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/294_01.conf
new file mode 100755
index 0000000..58a2c37
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/294_01.conf
@@ -0,0 +1,2 @@
+:ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/294_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/294_03.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/294_03.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/295_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/295_01.conf
new file mode 100755
index 0000000..afcc748
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/295_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV6:IPV6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/297_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/297_02.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/297_02.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_220.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_220.conf
new file mode 100755
index 0000000..7e2d716
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_220.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+sos:emergency:IPV6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_221.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_221.conf
new file mode 100755
index 0000000..7e2d716
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_221.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+sos:emergency:IPV6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_370.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_370.conf
new file mode 100755
index 0000000..c6f918b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_370.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+sos:emergency:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_490.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_490.conf
new file mode 100755
index 0000000..ab708a2
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_490.conf
@@ -0,0 +1,2 @@
+e911.mobilefrdm.ca:emergency:IPV4V6:IP:::::::
+volte.mobilefrdm.ca:ims:IPV4V6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_610.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_610.conf
new file mode 100755
index 0000000..9169443
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_610.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+sos:emergency:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_630.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_630.conf
new file mode 100755
index 0000000..9169443
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_630.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+sos:emergency:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_640.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_640.conf
new file mode 100755
index 0000000..9169443
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_640.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+sos:emergency:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_660.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_660.conf
new file mode 100755
index 0000000..9169443
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_660.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+sos:emergency:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_690.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_690.conf
new file mode 100755
index 0000000..9169443
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_690.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+sos:emergency:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_720.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_720.conf
new file mode 100755
index 0000000..c6f918b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/302_720.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+sos:emergency:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_030.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_030.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_030.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_070.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_070.conf
new file mode 100755
index 0000000..634d01d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_070.conf
@@ -0,0 +1,3 @@
+ims:ims:IPV4V6:IPV4V6:::::::
+:emergency:IPV4V6:IPV4V6:::::::
+sos:emergency:IPV4V6:IPV4V6::::18:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_090.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_090.conf
new file mode 100755
index 0000000..1bee1d8
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_090.conf
@@ -0,0 +1,3 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV4V6:IPV4V6:::::::
+sos:emergency:IPV4V6:IPV4V6::::18:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_120.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_120.conf
new file mode 100755
index 0000000..8b13789
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_120.conf
@@ -0,0 +1 @@
+
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_150.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_150.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_150.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_160.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_160.conf
new file mode 100755
index 0000000..dc47bc9
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_160.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV6:IP:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_170.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_170.conf
new file mode 100755
index 0000000..1bee1d8
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_170.conf
@@ -0,0 +1,3 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV4V6:IPV4V6:::::::
+sos:emergency:IPV4V6:IPV4V6::::18:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_200.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_200.conf
new file mode 100755
index 0000000..dc47bc9
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_200.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV6:IP:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_210.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_210.conf
new file mode 100755
index 0000000..dc47bc9
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_210.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV6:IP:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_220.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_220.conf
new file mode 100755
index 0000000..dc47bc9
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_220.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV6:IP:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_230.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_230.conf
new file mode 100755
index 0000000..dc47bc9
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_230.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV6:IP:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_240.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_240.conf
new file mode 100755
index 0000000..dc47bc9
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_240.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV6:IP:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_250.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_250.conf
new file mode 100755
index 0000000..dc47bc9
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_250.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV6:IP:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_260.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_260.conf
new file mode 100755
index 0000000..987a3c2
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_260.conf
@@ -0,0 +1,3 @@
+ims:ims:IPV6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV6:IP:::::::
+ims:ims:IPV6:IP:0:::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:GID:6D38:
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_270.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_270.conf
new file mode 100755
index 0000000..dc47bc9
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_270.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV6:IP:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_280.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_280.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_280.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_300.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_300.conf
new file mode 100755
index 0000000..dc47bc9
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_300.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV6:IP:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_310.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_310.conf
new file mode 100755
index 0000000..dc47bc9
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_310.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV6:IP:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_380.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_380.conf
new file mode 100755
index 0000000..1bee1d8
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_380.conf
@@ -0,0 +1,3 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV4V6:IPV4V6:::::::
+sos:emergency:IPV4V6:IPV4V6::::18:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_410.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_410.conf
new file mode 100755
index 0000000..1a9bda3
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_410.conf
@@ -0,0 +1,3 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|19|20:::
+sos:emergency:IPV4V6:IPV4V6::::18:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_490.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_490.conf
new file mode 100755
index 0000000..dc47bc9
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_490.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV6:IP:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_530.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_530.conf
new file mode 100755
index 0000000..dc47bc9
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_530.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV6:IP:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_560.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_560.conf
new file mode 100755
index 0000000..1bee1d8
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_560.conf
@@ -0,0 +1,3 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV4V6:IPV4V6:::::::
+sos:emergency:IPV4V6:IPV4V6::::18:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_590.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_590.conf
new file mode 100755
index 0000000..dc47bc9
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_590.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV6:IP:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_640.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_640.conf
new file mode 100755
index 0000000..dc47bc9
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_640.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV6:IP:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_660.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_660.conf
new file mode 100755
index 0000000..dc47bc9
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_660.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV6:IP:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_680.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_680.conf
new file mode 100755
index 0000000..1bee1d8
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_680.conf
@@ -0,0 +1,3 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV4V6:IPV4V6:::::::
+sos:emergency:IPV4V6:IPV4V6::::18:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_800.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_800.conf
new file mode 100755
index 0000000..dc47bc9
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_800.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV6:IP:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_950.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_950.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/310_950.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_180.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_180.conf
new file mode 100755
index 0000000..1bee1d8
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_180.conf
@@ -0,0 +1,3 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV4V6:IPV4V6:::::::
+sos:emergency:IPV4V6:IPV4V6::::18:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_220.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_220.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_220.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_221.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_221.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_221.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_222.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_222.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_222.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_223.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_223.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_223.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_224.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_224.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_224.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_225.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_225.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_225.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_226.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_226.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_226.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_227.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_227.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_227.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_228.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_228.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_228.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_229.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_229.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_229.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_270.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_270.conf
new file mode 100755
index 0000000..c72b622
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_270.conf
@@ -0,0 +1,3 @@
+IMS:ims,ia:IPV4V6:IPV6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV4V6:IPV6:::::::
+VZWEMERGENCY:emergency:IPV4V6:IPV6::::18:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_390.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_390.conf
new file mode 100755
index 0000000..64ebfb6
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_390.conf
@@ -0,0 +1,3 @@
+IMS:ims,ia:IPV4V6:IPV6:::::::
+:emergency:IPV4V6:IPV6:::::::
+VZWEMERGENCY:emergency:IPV4V6:IPV6::::18:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_480.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_480.conf
new file mode 100755
index 0000000..93d4407
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_480.conf
@@ -0,0 +1,6 @@
+IMS:ims,ia:IPV4V6:IPV6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV4V6:IPV6:::::::
+VZWEMERGENCY:emergency:IPV4V6:IPV6::::18:::
+VSBLIMS:ims,ia:IPV4V6:IPV6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:GID:BAE1:
+:emergency:IPV4V6:IPV6:::::GID:BAE1:
+VZWEMERGENCY:emergency:IPV4V6:IPV6::::18:GID:BAE1:
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_490.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_490.conf
new file mode 100755
index 0000000..8b13789
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_490.conf
@@ -0,0 +1 @@
+
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_580.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_580.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_580.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_581.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_581.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_581.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_582.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_582.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_582.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_583.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_583.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_583.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_584.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_584.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_584.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_585.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_585.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_585.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_586.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_586.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_586.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_587.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_587.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_587.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_588.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_588.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_588.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_589.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_589.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_589.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_870.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_870.conf
new file mode 100755
index 0000000..8b13789
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/311_870.conf
@@ -0,0 +1 @@
+
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/312_530.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/312_530.conf
new file mode 100755
index 0000000..8b13789
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/312_530.conf
@@ -0,0 +1 @@
+
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/312_670.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/312_670.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/312_670.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/312_770.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/312_770.conf
new file mode 100755
index 0000000..c72b622
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/312_770.conf
@@ -0,0 +1,3 @@
+IMS:ims,ia:IPV4V6:IPV6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV4V6:IPV6:::::::
+VZWEMERGENCY:emergency:IPV4V6:IPV6::::18:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/313_100.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/313_100.conf
new file mode 100755
index 0000000..db6a912
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/313_100.conf
@@ -0,0 +1,3 @@
+:emergency:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|19|20:::
+sos:emergency:IPV4V6:IPV4V6::::18:::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/313_110.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/313_110.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/313_110.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/313_120.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/313_120.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/313_120.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/313_130.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/313_130.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/313_130.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/313_140.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/313_140.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/313_140.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/330_110.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/330_110.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/330_110.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/334_020.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/334_020.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/334_020.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/334_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/334_03.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/334_03.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/334_030.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/334_030.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/334_030.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/334_050.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/334_050.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/334_050.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/334_090.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/334_090.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/334_090.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/334_140.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/334_140.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/334_140.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/370_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/370_02.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/370_02.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_01.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_02.conf
new file mode 100755
index 0000000..6901f7b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_02.conf
@@ -0,0 +1,2 @@
+airtelgprs.com:default,supl,ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_03.conf
new file mode 100755
index 0000000..6901f7b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_03.conf
@@ -0,0 +1,2 @@
+airtelgprs.com:default,supl,ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_04.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_04.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_04.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_05.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_05.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_05.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_07.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_07.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_07.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_10.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_10.conf
new file mode 100755
index 0000000..6901f7b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_10.conf
@@ -0,0 +1,2 @@
+airtelgprs.com:default,supl,ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_11.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_11.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_11.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_12.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_12.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_12.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_13.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_13.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_13.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_14.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_14.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_14.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_15.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_15.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_15.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_16.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_16.conf
new file mode 100755
index 0000000..6901f7b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_16.conf
@@ -0,0 +1,2 @@
+airtelgprs.com:default,supl,ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_19.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_19.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_19.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_20.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_20.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_20.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_22.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_22.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_22.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_24.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_24.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_24.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_27.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_27.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_27.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_30.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_30.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_30.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_31.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_31.conf
new file mode 100755
index 0000000..6901f7b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_31.conf
@@ -0,0 +1,2 @@
+airtelgprs.com:default,supl,ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_34.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_34.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_34.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_38.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_38.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_38.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_40.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_40.conf
new file mode 100755
index 0000000..6901f7b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_40.conf
@@ -0,0 +1,2 @@
+airtelgprs.com:default,supl,ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_43.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_43.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_43.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_44.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_44.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_44.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_45.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_45.conf
new file mode 100755
index 0000000..6901f7b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_45.conf
@@ -0,0 +1,2 @@
+airtelgprs.com:default,supl,ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_46.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_46.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_46.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_49.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_49.conf
new file mode 100755
index 0000000..6901f7b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_49.conf
@@ -0,0 +1,2 @@
+airtelgprs.com:default,supl,ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_51.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_51.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_51.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_53.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_53.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_53.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_54.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_54.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_54.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_55.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_55.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_55.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_56.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_56.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_56.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_57.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_57.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_57.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_58.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_58.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_58.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_59.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_59.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_59.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_60.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_60.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_60.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_62.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_62.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_62.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_64.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_64.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_64.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_66.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_66.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_66.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_70.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_70.conf
new file mode 100755
index 0000000..6901f7b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_70.conf
@@ -0,0 +1,2 @@
+airtelgprs.com:default,supl,ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_71.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_71.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_71.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_72.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_72.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_72.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_73.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_73.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_73.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_74.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_74.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_74.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_75.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_75.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_75.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_76.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_76.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_76.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_77.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_77.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_77.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_78.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_78.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_78.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_79.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_79.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_79.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_80.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_80.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_80.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_81.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_81.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_81.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_82.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_82.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_82.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_84.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_84.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_84.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_86.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_86.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_86.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_87.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_87.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_87.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_88.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_88.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_88.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_89.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_89.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_89.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_90.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_90.conf
new file mode 100755
index 0000000..6901f7b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_90.conf
@@ -0,0 +1,2 @@
+airtelgprs.com:default,supl,ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_92.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_92.conf
new file mode 100755
index 0000000..6901f7b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_92.conf
@@ -0,0 +1,2 @@
+airtelgprs.com:default,supl,ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_93.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_93.conf
new file mode 100755
index 0000000..6901f7b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_93.conf
@@ -0,0 +1,2 @@
+airtelgprs.com:default,supl,ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_94.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_94.conf
new file mode 100755
index 0000000..6901f7b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_94.conf
@@ -0,0 +1,2 @@
+airtelgprs.com:default,supl,ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_95.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_95.conf
new file mode 100755
index 0000000..6901f7b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_95.conf
@@ -0,0 +1,2 @@
+airtelgprs.com:default,supl,ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_96.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_96.conf
new file mode 100755
index 0000000..6901f7b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_96.conf
@@ -0,0 +1,2 @@
+airtelgprs.com:default,supl,ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_97.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_97.conf
new file mode 100755
index 0000000..6901f7b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_97.conf
@@ -0,0 +1,2 @@
+airtelgprs.com:default,supl,ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_98.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_98.conf
new file mode 100755
index 0000000..6901f7b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/404_98.conf
@@ -0,0 +1,2 @@
+airtelgprs.com:default,supl,ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_030.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_030.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_030.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_035.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_035.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_035.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_036.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_036.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_036.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_037.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_037.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_037.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_038.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_038.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_038.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_039.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_039.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_039.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_044.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_044.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_044.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_51.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_51.conf
new file mode 100755
index 0000000..6901f7b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_51.conf
@@ -0,0 +1,2 @@
+airtelgprs.com:default,supl,ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_52.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_52.conf
new file mode 100755
index 0000000..6901f7b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_52.conf
@@ -0,0 +1,2 @@
+airtelgprs.com:default,supl,ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_53.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_53.conf
new file mode 100755
index 0000000..6901f7b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_53.conf
@@ -0,0 +1,2 @@
+airtelgprs.com:default,supl,ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_54.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_54.conf
new file mode 100755
index 0000000..6901f7b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_54.conf
@@ -0,0 +1,2 @@
+airtelgprs.com:default,supl,ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_55.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_55.conf
new file mode 100755
index 0000000..6901f7b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_55.conf
@@ -0,0 +1,2 @@
+airtelgprs.com:default,supl,ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_56.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_56.conf
new file mode 100755
index 0000000..6901f7b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_56.conf
@@ -0,0 +1,2 @@
+airtelgprs.com:default,supl,ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_66.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_66.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_66.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_67.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_67.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_67.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_70.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_70.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_70.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_750.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_750.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_750.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_751.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_751.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_751.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_752.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_752.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_752.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_753.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_753.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_753.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_754.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_754.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_754.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_755.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_755.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_755.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_756.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_756.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_756.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_799.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_799.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_799.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_818.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_818.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_818.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_819.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_819.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_819.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_840.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_840.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_840.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_845.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_845.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_845.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_846.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_846.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_846.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_847.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_847.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_847.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_848.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_848.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_848.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_849.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_849.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_849.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_850.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_850.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_850.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_851.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_851.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_851.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_852.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_852.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_852.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_853.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_853.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_853.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_854.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_854.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_854.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_855.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_855.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_855.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_856.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_856.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_856.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_857.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_857.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_857.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_858.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_858.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_858.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_859.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_859.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_859.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_860.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_860.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_860.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_861.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_861.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_861.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_862.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_862.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_862.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_863.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_863.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_863.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_864.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_864.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_864.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_865.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_865.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_865.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_866.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_866.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_866.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_867.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_867.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_867.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_868.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_868.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_868.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_869.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_869.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_869.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_870.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_870.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_870.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_871.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_871.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_871.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_872.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_872.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_872.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_873.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_873.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_873.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_874.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_874.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_874.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_876.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_876.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_876.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_879.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_879.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_879.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_908.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_908.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_908.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_909.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_909.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_909.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_910.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_910.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_910.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_911.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_911.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_911.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_927.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_927.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_927.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_929.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_929.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/405_929.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/410_04.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/410_04.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/410_04.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/410_06.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/410_06.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/410_06.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/413_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/413_01.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/413_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/413_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/413_02.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/413_02.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/414_06.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/414_06.conf
new file mode 100755
index 0000000..e7f6ae5
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/414_06.conf
@@ -0,0 +1 @@
+ims:ims:IP:IP:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/414_09.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/414_09.conf
new file mode 100755
index 0000000..e1c6970
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/414_09.conf
@@ -0,0 +1 @@
+mytel-ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/418_66.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/418_66.conf
new file mode 100755
index 0000000..63094d1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/418_66.conf
@@ -0,0 +1 @@
+ims:ims:IP:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/419_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/419_02.conf
new file mode 100755
index 0000000..a1a540c
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/419_02.conf
@@ -0,0 +1 @@
+ims:ims:IP:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/419_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/419_03.conf
new file mode 100755
index 0000000..a1a540c
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/419_03.conf
@@ -0,0 +1 @@
+ims:ims:IP:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/419_04.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/419_04.conf
new file mode 100755
index 0000000..a1a540c
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/419_04.conf
@@ -0,0 +1 @@
+ims:ims:IP:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/420_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/420_01.conf
new file mode 100755
index 0000000..63094d1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/420_01.conf
@@ -0,0 +1 @@
+ims:ims:IP:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/420_04.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/420_04.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/420_04.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/424_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/424_02.conf
new file mode 100755
index 0000000..63094d1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/424_02.conf
@@ -0,0 +1 @@
+ims:ims:IP:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/424_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/424_03.conf
new file mode 100755
index 0000000..63094d1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/424_03.conf
@@ -0,0 +1 @@
+ims:ims:IP:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/426_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/426_02.conf
new file mode 100755
index 0000000..a1a540c
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/426_02.conf
@@ -0,0 +1 @@
+ims:ims:IP:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/426_04.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/426_04.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/426_04.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/427_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/427_01.conf
new file mode 100755
index 0000000..724ba0b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/427_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/440_10.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/440_10.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/440_10.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/440_20.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/440_20.conf
new file mode 100755
index 0000000..627a378
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/440_20.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/440_51.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/440_51.conf
new file mode 100755
index 0000000..296e25f
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/440_51.conf
@@ -0,0 +1,3 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|19|20:::
+sos:emergency:IPV4V6:IPV4V6::::18:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/440_54.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/440_54.conf
new file mode 100755
index 0000000..e80b14b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/440_54.conf
@@ -0,0 +1,3 @@
+IMS:ims:IPV4V6:IPV4V6:::::::
+:emergency:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|19|20:::
+sos:emergency:IPV4V6:IPV4V6::::18:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/450_05.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/450_05.conf
new file mode 100755
index 0000000..b33ba12
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/450_05.conf
@@ -0,0 +1,3 @@
+ims:ims:IPV4V6:IPV4V6:::::::
+sos:emergency:IPV4V6:IPV4V6:::::::
+:ia:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/450_06.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/450_06.conf
new file mode 100755
index 0000000..3da0685
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/450_06.conf
@@ -0,0 +1,3 @@
+ims:ims:IPV4V6:IPV4V6:::::::
+emergency.lguplus.co.kr:emergency:IP:IP:::::::
+:ia:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/450_08.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/450_08.conf
new file mode 100755
index 0000000..4a6acc1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/450_08.conf
@@ -0,0 +1,3 @@
+ims:ims:IPV4V6:IPV4V6:::::::
+sos:emergency:IPV4V6:IP:::::::
+:ia:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/452_04.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/452_04.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/452_04.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/452_05.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/452_05.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/452_05.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_00.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_00.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_00.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_02.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_02.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_03.conf
new file mode 100755
index 0000000..77c21ae
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_03.conf
@@ -0,0 +1 @@
+ims.lte.three.com.hk:ims:IPV4V6:IPV4V6:0:::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_04.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_04.conf
new file mode 100755
index 0000000..77c21ae
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_04.conf
@@ -0,0 +1 @@
+ims.lte.three.com.hk:ims:IPV4V6:IPV4V6:0:::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_05.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_05.conf
new file mode 100755
index 0000000..77c21ae
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_05.conf
@@ -0,0 +1 @@
+ims.lte.three.com.hk:ims:IPV4V6:IPV4V6:0:::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_06.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_06.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_06.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_10.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_10.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_10.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_12.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_12.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_12.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_13.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_13.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_13.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_14.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_14.conf
new file mode 100755
index 0000000..77c21ae
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_14.conf
@@ -0,0 +1 @@
+ims.lte.three.com.hk:ims:IPV4V6:IPV4V6:0:::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_15.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_15.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_15.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_16.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_16.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_16.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_17.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_17.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_17.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_18.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_18.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_18.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_19.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_19.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_19.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_20.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_20.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_20.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_29.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_29.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_29.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_31.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_31.conf
new file mode 100755
index 0000000..8b13789
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/454_31.conf
@@ -0,0 +1 @@
+
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/455_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/455_01.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/455_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/455_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/455_02.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/455_02.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/455_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/455_03.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/455_03.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/455_04.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/455_04.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/455_04.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/455_05.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/455_05.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/455_05.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/455_07.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/455_07.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/455_07.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/456_06.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/456_06.conf
new file mode 100755
index 0000000..63094d1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/456_06.conf
@@ -0,0 +1 @@
+ims:ims:IP:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/456_08.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/456_08.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/456_08.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/456_11.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/456_11.conf
new file mode 100755
index 0000000..e7f6ae5
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/456_11.conf
@@ -0,0 +1 @@
+ims:ims:IP:IP:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_00.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_00.conf
new file mode 100755
index 0000000..e3dd799
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_00.conf
@@ -0,0 +1,2 @@
+:ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_01.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_02.conf
new file mode 100755
index 0000000..e3dd799
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_02.conf
@@ -0,0 +1,2 @@
+:ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_03.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_03.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_07.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_07.conf
new file mode 100755
index 0000000..e3dd799
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_07.conf
@@ -0,0 +1,2 @@
+:ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_08.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_08.conf
new file mode 100755
index 0000000..e3dd799
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_08.conf
@@ -0,0 +1,2 @@
+:ia:IPV4V6:IPV4V6:::::::
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_09.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_09.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_09.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_11.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_11.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_11.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_12.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_12.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_12.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_13.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_13.conf
new file mode 100755
index 0000000..a8e6bd4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/460_13.conf
@@ -0,0 +1 @@
+IMS:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/466_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/466_01.conf
new file mode 100755
index 0000000..10608ca
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/466_01.conf
@@ -0,0 +1,3 @@
+ims:ims:IP:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+:emergency:IPV4V6:IPV4V6:::::::
+sos:emergency:IPV4V6:IPV4V6::::18:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/466_05.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/466_05.conf
new file mode 100755
index 0000000..9169443
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/466_05.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+sos:emergency:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/466_89.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/466_89.conf
new file mode 100755
index 0000000..63094d1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/466_89.conf
@@ -0,0 +1 @@
+ims:ims:IP:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/466_92.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/466_92.conf
new file mode 100755
index 0000000..d6fa84b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/466_92.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV4V6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+sos:emergency:IP:IP::::18:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/466_93.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/466_93.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/466_93.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/466_97.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/466_97.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/466_97.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/466_99.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/466_99.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/466_99.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/470_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/470_01.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/470_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/470_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/470_02.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/470_02.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/470_07.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/470_07.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/470_07.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/502_08.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/502_08.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/502_08.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/502_152.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/502_152.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/502_152.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/502_153.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/502_153.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/502_153.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/502_16.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/502_16.conf
new file mode 100755
index 0000000..afcc748
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/502_16.conf
@@ -0,0 +1 @@
+ims:ims:IPV6:IPV6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/502_18.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/502_18.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/502_18.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_01.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_02.conf
new file mode 100755
index 0000000..30e1591
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_02.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+SOS:emergency:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_03.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_03.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_06.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_06.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_06.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_11.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_11.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_11.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_39.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_39.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_39.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_71.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_71.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_71.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_72.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_72.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_72.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_90.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_90.conf
new file mode 100755
index 0000000..30e1591
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/505_90.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+SOS:emergency:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/510_09.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/510_09.conf
new file mode 100755
index 0000000..56708ed
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/510_09.conf
@@ -0,0 +1 @@
+ims:ims,xcap:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/510_10.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/510_10.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/510_10.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/510_28.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/510_28.conf
new file mode 100755
index 0000000..318984f
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/510_28.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV4V6:IPV4V6:::::::
+ims:ims,xcap:IPV4V6:IPV4V6::::18:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/515_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/515_02.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/515_02.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/515_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/515_03.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/515_03.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/520_00.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/520_00.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/520_00.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/520_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/520_03.conf
new file mode 100755
index 0000000..5ed164d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/520_03.conf
@@ -0,0 +1 @@
+ims:ims:IPV6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/520_04.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/520_04.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/520_04.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/520_05.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/520_05.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/520_05.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/525_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/525_01.conf
new file mode 100755
index 0000000..52d6f48
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/525_01.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+e-ideas:default,supl,ia:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/525_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/525_03.conf
new file mode 100755
index 0000000..f145903
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/525_03.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/525_05.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/525_05.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/525_05.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/525_10.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/525_10.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/525_10.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/530_001.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/530_001.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/530_001.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/530_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/530_01.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/530_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/530_05.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/530_05.conf
new file mode 100755
index 0000000..4921cc1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/530_05.conf
@@ -0,0 +1 @@
+ims:ims:IPV6:IPV6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/530_099.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/530_099.conf
new file mode 100755
index 0000000..4921cc1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/530_099.conf
@@ -0,0 +1 @@
+ims:ims:IPV6:IPV6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/530_24.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/530_24.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/530_24.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/602_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/602_02.conf
new file mode 100755
index 0000000..724ba0b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/602_02.conf
@@ -0,0 +1 @@
+ims:ims:IPV6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/602_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/602_03.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/602_03.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/602_04.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/602_04.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/602_04.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/621_27.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/621_27.conf
new file mode 100755
index 0000000..63094d1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/621_27.conf
@@ -0,0 +1 @@
+ims:ims:IP:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/621_40.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/621_40.conf
new file mode 100755
index 0000000..63094d1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/621_40.conf
@@ -0,0 +1 @@
+ims:ims:IP:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/639_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/639_02.conf
new file mode 100755
index 0000000..f145903
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/639_02.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/639_10.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/639_10.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/639_10.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/640_11.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/640_11.conf
new file mode 100755
index 0000000..63094d1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/640_11.conf
@@ -0,0 +1 @@
+ims:ims:IP:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/641_33.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/641_33.conf
new file mode 100755
index 0000000..63094d1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/641_33.conf
@@ -0,0 +1 @@
+ims:ims:IP:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/645_05.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/645_05.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/645_05.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/653_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/653_02.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/653_02.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/655_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/655_01.conf
new file mode 100755
index 0000000..63094d1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/655_01.conf
@@ -0,0 +1 @@
+ims:ims:IP:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/655_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/655_02.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/655_02.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/655_07.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/655_07.conf
new file mode 100755
index 0000000..4eaf62e
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/655_07.conf
@@ -0,0 +1 @@
+ims:ims:IP:IP::::18:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/655_10.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/655_10.conf
new file mode 100755
index 0000000..63094d1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/655_10.conf
@@ -0,0 +1 @@
+ims:ims:IP:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/704_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/704_01.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/704_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/704_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/704_02.conf
new file mode 100755
index 0000000..dfb7ade
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/704_02.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/704_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/704_03.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/704_03.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/706_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/706_01.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/706_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/706_04.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/706_04.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/706_04.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/708_001.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/708_001.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/708_001.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/710_21.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/710_21.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/710_21.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/710_30.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/710_30.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/710_30.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/710_300.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/710_300.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/710_300.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/712_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/712_03.conf
new file mode 100755
index 0000000..c08e17a
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/712_03.conf
@@ -0,0 +1 @@
+ims.claro:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/712_04.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/712_04.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/712_04.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/714_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/714_01.conf
new file mode 100755
index 0000000..63094d1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/714_01.conf
@@ -0,0 +1 @@
+ims:ims:IP:IP::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/714_020.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/714_020.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/714_020.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/714_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/714_03.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/714_03.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/716_06.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/716_06.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/716_06.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/716_07.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/716_07.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/716_07.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/716_10.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/716_10.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/716_10.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/716_17.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/716_17.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/716_17.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/722_07.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/722_07.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/722_07.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/722_310.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/722_310.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/722_310.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/722_34.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/722_34.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/722_34.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_02.conf
new file mode 100755
index 0000000..6b627ee
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_02.conf
@@ -0,0 +1 @@
+ims:ims,xcap:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_03.conf
new file mode 100755
index 0000000..6b627ee
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_03.conf
@@ -0,0 +1 @@
+ims:ims,xcap:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_04.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_04.conf
new file mode 100755
index 0000000..6b627ee
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_04.conf
@@ -0,0 +1 @@
+ims:ims,xcap:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_05.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_05.conf
new file mode 100755
index 0000000..afcc748
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_05.conf
@@ -0,0 +1 @@
+ims:ims:IPV6:IPV6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_06.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_06.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_06.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_10.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_10.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_10.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_11.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_11.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_11.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_23.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_23.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_23.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_80.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_80.conf
new file mode 100755
index 0000000..3e35f0d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/724_80.conf
@@ -0,0 +1 @@
+ims.mnc080.mcc724.3gppnetwork.org:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/730_01.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/730_01.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/730_01.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/730_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/730_02.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/730_02.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/730_03.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/730_03.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/730_03.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/730_07.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/730_07.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/730_07.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/730_09.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/730_09.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/730_09.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/730_23.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/730_23.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/730_23.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/732_101.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/732_101.conf
new file mode 100755
index 0000000..9169443
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/732_101.conf
@@ -0,0 +1,2 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
+sos:emergency:IPV4V6:IPV4V6:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/732_103.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/732_103.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/732_103.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/732_111.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/732_111.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/732_111.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/732_123.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/732_123.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/732_123.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/732_130.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/732_130.conf
new file mode 100755
index 0000000..66a2909
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/732_130.conf
@@ -0,0 +1 @@
+ims.avt.com:ims,xcap:IP:IP:::::::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/734_04.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/734_04.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/734_04.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/740_00.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/740_00.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/740_00.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/744_02.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/744_02.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/744_02.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/748_07.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/748_07.conf
new file mode 100755
index 0000000..2b7345b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/748_07.conf
@@ -0,0 +1 @@
+ims:ims:IPV6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/748_10.conf b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/748_10.conf
new file mode 100755
index 0000000..487e63d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/apncfg/748_10.conf
@@ -0,0 +1 @@
+ims:ims:IPV4V6:IPV4V6::::1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20:::
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/DigiCertGlobalRootCA.crt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/DigiCertGlobalRootCA.crt
new file mode 100755
index 0000000..2f1e552
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/DigiCertGlobalRootCA.crt
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/DigiCertGlobalRootG2.crt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/DigiCertGlobalRootG2.crt
new file mode 100755
index 0000000..1e927a7
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/DigiCertGlobalRootG2.crt
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/DigiCertGlobalRootG3.crt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/DigiCertGlobalRootG3.crt
new file mode 100755
index 0000000..6dda6a3
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/DigiCertGlobalRootG3.crt
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/Entrust.net_Certification_Authority_2048.cer b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/Entrust.net_Certification_Authority_2048.cer
new file mode 100755
index 0000000..4fdfa0b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/Entrust.net_Certification_Authority_2048.cer
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u
+ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp
+bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV
+BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx
+NzUwNTFaFw0yOTA3MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3
+d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl
+MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u
+ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL
+Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr
+hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW
+nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi
+VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo0IwQDAOBgNVHQ8BAf8E
+BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJ
+KoZIhvcNAQEFBQADggEBADubj1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPy
+T/4xmf3IDExoU8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf
+zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5bu/8j72gZyxKT
+J1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+bYQLCIt+jerXmCHG8+c8eS9e
+nNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/ErfF6adulZkMV8gzURZVE=
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/GeoTrust_PCA_G3_Root.der b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/GeoTrust_PCA_G3_Root.der
new file mode 100755
index 0000000..94c5cda
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/GeoTrust_PCA_G3_Root.der
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/GeoTrust_Primary_CA.der b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/GeoTrust_Primary_CA.der
new file mode 100755
index 0000000..3a1ea37
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/GeoTrust_Primary_CA.der
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/GeoTrust_Primary_CA_G2_ECC.der b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/GeoTrust_Primary_CA_G2_ECC.der
new file mode 100755
index 0000000..75dfaf3
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/GeoTrust_Primary_CA_G2_ECC.der
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/GlobalSign_root_CA.crt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/GlobalSign_root_CA.crt
new file mode 100755
index 0000000..f4ce4ca
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/GlobalSign_root_CA.crt
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG
+A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
+b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
+MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
+YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
+aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
+jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
+xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
+1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
+snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
+U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
+9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
+BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B
+AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz
+yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE
+38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP
+AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad
+DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
+HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
+-----END CERTIFICATE-----
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/Root-R3.cer b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/Root-R3.cer
new file mode 100755
index 0000000..232c4b6
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/Root-R3.cer
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/Root_CA_1003.crt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/Root_CA_1003.crt
new file mode 100755
index 0000000..2344633
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/Root_CA_1003.crt
@@ -0,0 +1,26 @@
+-----BEGIN CERTIFICATE-----
+MIIEZTCCA02gAwIBAgICEAEwDQYJKoZIhvcNAQEFBQAwRDEUMBIGA1UECgwLT3Bl
+bkNBIExhYnMxFTATBgNVBAsMDEFwcGxpY2F0aW9uczEVMBMGA1UEAwwMcm9vdCBj
+YSBlcGRnMB4XDTE0MDIyNTA4MzM0NloXDTI0MDIyMzA4MzM0NlowRDEUMBIGA1UE
+CgwLT3BlbkNBIExhYnMxFTATBgNVBAsMDEFwcGxpY2F0aW9uczEVMBMGA1UEAwwM
+cm9vdCBjYSBlcGRnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoyJR
+tlJHAWVtZg/zXQg38MZtyschiHGA5WcQOaXsE0ojf5yRQmoY8ipuTvUEWBnKlzur
+5huUf6PJNACI3hCA4wgIuz/Efs0DUjd1pGQTm5Rkv+FkWIafl87R7S1A6uauZe59
+mB4o2EATQtHkhPqWkL2OVuxBqKsvlEBO7wtjpM+MLbliYnfppA54UTX1W0GlkmpD
+zYiIyHHIEKsH+V+G0QMICZipi1Z8u3Zh0nG9ffmCHev534bXwSx9IlOFHHdSL8rA
+VDuipqMT/AzawgHQW2LhqhxK16orIk3WrkkwLnACNKAyFibx4EsY0pjAaXx8Hvjw
+sQy9LmI+0IRsrG/HpwIDAQABo4IBXzCCAVswDwYDVR0TAQH/BAUwAwEB/zALBgNV
+HQ8EBAMCAQYwHQYDVR0OBBYEFKQysYrn04rdld3bPOtvoRyuuW0mMB8GA1UdIwQY
+MBaAFKQysYrn04rdld3bPOtvoRyuuW0mMBwGA1UdEQQVMBOBEXdlYm1hc3RlckBl
+emMuY29tMBwGA1UdEgQVMBOBEXdlYm1hc3RlckBlemMuY29tMIGHBggrBgEFBQcB
+AQR7MHkwNAYIKwYBBQUHMAKGKGh0dHA6Ly9zc3Itc2ltL3BraS9wdWIvY2FjZXJ0
+L2NhY2VydC5jcnQwIAYIKwYBBQUHMAGGFGh0dHA6Ly9zc3Itc2ltOjI1NjAvMB8G
+CCsGAQUFBzAMhhNodHRwOi8vc3NyLXNpbTo4MzAvMDUGA1UdHwQuMCwwKqAooCaG
+JGh0dHA6Ly9zc3Itc2ltL3BraS9wdWIvY3JsL2NhY3JsLmNybDANBgkqhkiG9w0B
+AQUFAAOCAQEAJg2zRv5qD8OXiegzfCeaDsYk4uZZ1Vp8hhKtUOkBEg6Qpl8Tpng3
+/nnSmjMIhBvlcYdd7oN6RcQ2PjD4ceKizt48wnFIcppeI5OnK0Eaq5cPDvy8y90Z
+Iw+JBc3YMS6czq0einbX1x1kcZBxQGZCEQnCH3qauDZG9R1xV1o4bsev8VV8TREN
+tk0zeoL2aKdzWtPQxF526PxrQZLfiGlF57UMjNaQKxBi8Zi1TkEHl95XxgxIuxDj
+6W4EQeiusuMd4ZXBvgbAP1gV/CXNPP5Y0ydVDd9U5g1Is0iDFyN2YCkr67gTpa8l
+Q4lom0pEhdl0a/CIPE3HZO7l/IGrAu31aA==
+-----END CERTIFICATE-----
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/VeriSignClass3G4.der b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/VeriSignClass3G4.der
new file mode 100755
index 0000000..101d361
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/VeriSignClass3G4.der
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/VeriSignClass3G5.der b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/VeriSignClass3G5.der
new file mode 100755
index 0000000..9818d19
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/VeriSignClass3G5.der
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/VeriSignUniversalRootCertification.der b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/VeriSignUniversalRootCertification.der
new file mode 100755
index 0000000..1353d28
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/VeriSignUniversalRootCertification.der
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/thawte.der b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/thawte.der
new file mode 100755
index 0000000..8abe3c8
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/ikev2/thawte.der
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/AAACertificateServices.crt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/AAACertificateServices.crt
new file mode 100755
index 0000000..5c715fa
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/AAACertificateServices.crt
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/CertumCA.crt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/CertumCA.crt
new file mode 100755
index 0000000..d39b2a2
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/CertumCA.crt
@@ -0,0 +1,72 @@
+-----BEGIN CERTIFICATE-----
+MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBM
+MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
+QTAeFw0wMjA2MTExMDQ2MzlaFw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBM
+MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
+QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6xwS7TT3zNJc4YPk/E
+jG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdLkKWo
+ePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GI
+ULdtlkIJ89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapu
+Ob7kky/ZR6By6/qmW6/KUz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUg
+AKpoC6EahQGcxEZjgoi2IrHu/qpGWX7PNSzVttpd90gzFFS269lvzs2I1qsb2pY7
+HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEA
+uI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+GXYkHAQa
+TOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTg
+xSvgGrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1q
+CjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x
+O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs
+6GAqm4VKQPNriiTsBhYscw==
+-----END CERTIFICATE-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 65568 (0x10020)
+    Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=PL, O=Unizeto Sp. z o.o., CN=Certum CA
+        Validity
+            Not Before: Jun 11 10:46:39 2002 GMT
+            Not After : Jun 11 10:46:39 2027 GMT
+        Subject: C=PL, O=Unizeto Sp. z o.o., CN=Certum CA
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:ce:b1:c1:2e:d3:4f:7c:cd:25:ce:18:3e:4f:c4:
+                    8c:6f:80:6a:73:c8:5b:51:f8:9b:d2:dc:bb:00:5c:
+                    b1:a0:fc:75:03:ee:81:f0:88:ee:23:52:e9:e6:15:
+                    33:8d:ac:2d:09:c5:76:f9:2b:39:80:89:e4:97:4b:
+                    90:a5:a8:78:f8:73:43:7b:a4:61:b0:d8:58:cc:e1:
+                    6c:66:7e:9c:f3:09:5e:55:63:84:d5:a8:ef:f3:b1:
+                    2e:30:68:b3:c4:3c:d8:ac:6e:8d:99:5a:90:4e:34:
+                    dc:36:9a:8f:81:88:50:b7:6d:96:42:09:f3:d7:95:
+                    83:0d:41:4b:b0:6a:6b:f8:fc:0f:7e:62:9f:67:c4:
+                    ed:26:5f:10:26:0f:08:4f:f0:a4:57:28:ce:8f:b8:
+                    ed:45:f6:6e:ee:25:5d:aa:6e:39:be:e4:93:2f:d9:
+                    47:a0:72:eb:fa:a6:5b:af:ca:53:3f:e2:0e:c6:96:
+                    56:11:6e:f7:e9:66:a9:26:d8:7f:95:53:ed:0a:85:
+                    88:ba:4f:29:a5:42:8c:5e:b6:fc:85:20:00:aa:68:
+                    0b:a1:1a:85:01:9c:c4:46:63:82:88:b6:22:b1:ee:
+                    fe:aa:46:59:7e:cf:35:2c:d5:b6:da:5d:f7:48:33:
+                    14:54:b6:eb:d9:6f:ce:cd:88:d6:ab:1b:da:96:3b:
+                    1d:59
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:TRUE
+    Signature Algorithm: sha1WithRSAEncryption
+         b8:8d:ce:ef:e7:14:ba:cf:ee:b0:44:92:6c:b4:39:3e:a2:84:
+         6e:ad:b8:21:77:d2:d4:77:82:87:e6:20:41:81:ee:e2:f8:11:
+         b7:63:d1:17:37:be:19:76:24:1c:04:1a:4c:eb:3d:aa:67:6f:
+         2d:d4:cd:fe:65:31:70:c5:1b:a6:02:0a:ba:60:7b:6d:58:c2:
+         9a:49:fe:63:32:0b:6b:e3:3a:c0:ac:ab:3b:b0:e8:d3:09:51:
+         8c:10:83:c6:34:e0:c5:2b:e0:1a:b6:60:14:27:6c:32:77:8c:
+         bc:b2:72:98:cf:cd:cc:3f:b9:c8:24:42:14:d6:57:fc:e6:26:
+         43:a9:1d:e5:80:90:ce:03:54:28:3e:f7:3f:d3:f8:4d:ed:6a:
+         0a:3a:93:13:9b:3b:14:23:13:63:9c:3f:d1:87:27:79:e5:4c:
+         51:e3:01:ad:85:5d:1a:3b:b1:d5:73:10:a4:d3:f2:bc:6e:64:
+         f5:5a:56:90:a8:c7:0e:4c:74:0f:2e:71:3b:f7:c8:47:f4:69:
+         6f:15:f2:11:5e:83:1e:9c:7c:52:ae:fd:02:da:12:a8:59:67:
+         18:db:bc:70:dd:9b:b1:69:ed:80:ce:89:40:48:6a:0e:35:ca:
+         29:66:15:21:94:2c:e8:60:2a:9b:85:4a:40:f3:6b:8a:24:ec:
+         06:16:2c:73
+SHA1 Fingerprint=62:52:DC:40:F7:11:43:A2:2F:DE:9E:F7:34:8E:06:42:51:B1:81:18
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/CertumOrganizationValidationCASHA2.crt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/CertumOrganizationValidationCASHA2.crt
new file mode 100755
index 0000000..d0487c1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/CertumOrganizationValidationCASHA2.crt
@@ -0,0 +1,28 @@
+-----BEGIN CERTIFICATE-----
+MIIE1TCCA72gAwIBAgIRALWtD2OFTMRiLks5I7KQAhYwDQYJKoZIhvcNAQELBQAw
+fjELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu
+QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEiMCAG
+A1UEAxMZQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQTAeFw0xNDA5MTExMjAwMDBa
+Fw0yNzA2MDkxMDQ2MzlaMIGLMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0
+byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRp
+b24gQXV0aG9yaXR5MS8wLQYDVQQDEyZDZXJ0dW0gT3JnYW5pemF0aW9uIFZhbGlk
+YXRpb24gQ0EgU0hBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMQu
+1QDMW2HpTB+NQ14+w+dvSV0k/bXvNTz9K6KrTKgXDm1eJZ44QNMo9Hb5230nvrJh
+wenVEmOsJRD/Ux/oSGDASK58+ckfgY8CeMMsk7rNkwAlBgDp3mBpdhBADMFevgxb
+B+ADq01B91Mit5Tbkc2wP1VlMr2bglVZxmGS39NjpwFRmrzEdxpWdWSX48Ksowt7
+QH7QGQ0Af/972ZIam1ctsRGcOkA5h6t/iZXlV5Y2+H4/4pcr4uF4z30I5VHyJWqx
+dhbFlaBnmnj/ChLa4wdpObqZl7IUz3MOBioMzH8DyiuEAZ5O1+wPALidIlc3GbVJ
+gl6/SwKwh4O4EywWxZMCAwEAAaOCAT4wggE6MA8GA1UdEwEB/wQFMAMBAf8wHQYD
+VR0OBBYEFO7t6FRgEws1g6D6a3pGOvc+MLtmMB8GA1UdIwQYMBaAFAh2zcsH/yT2
+xc3tu5C84oQ3RnX3MA4GA1UdDwEB/wQEAwIBBjAvBgNVHR8EKDAmMCSgIqAghh5o
+dHRwOi8vY3JsLmNlcnR1bS5wbC9jdG5jYS5jcmwwawYIKwYBBQUHAQEEXzBdMCgG
+CCsGAQUFBzABhhxodHRwOi8vc3ViY2Eub2NzcC1jZXJ0dW0uY29tMDEGCCsGAQUF
+BzAChiVodHRwOi8vcmVwb3NpdG9yeS5jZXJ0dW0ucGwvY3RuY2EuY2VyMDkGA1Ud
+IAQyMDAwLgYEVR0gADAmMCQGCCsGAQUFBwIBFhhodHRwOi8vd3d3LmNlcnR1bS5w
+bC9DUFMwDQYJKoZIhvcNAQELBQADggEBACNWGnCyexPgGwHHefwKh8dJHoTEPxbM
+M7C2+8tFUiTHKroVdqfPHywdmZ7k0H/0lm0uP1wlcbj1k/dLPb4gugp0UYNB7qk8
+os22unSI9Yy/1xpMqNH9Udg7zK4F81YC2YtD942HVWQ1/8GYRNWbMmZmPSJ8ijXz
+G6xOSIu3WZgh+qm/B5UpdA1kVXeWL6IcGIj5vnNVwVQiSRroPT+qqHcgVxrs5IAj
+BFUNKdQQrInpvGFqiQ8uwOde6gp58IpH1e1h8DIoc/vNa9v/7lZ5s48Q172lFkug
+v4FHHMdGV2C1grGQtXyS876ZGk9D5b9Q+SerjBC80hlfGAOt96PK+j0=
+-----END CERTIFICATE-----
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/CertumTrustedNetworkCA.crt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/CertumTrustedNetworkCA.crt
new file mode 100755
index 0000000..403a1cd
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/CertumTrustedNetworkCA.crt
@@ -0,0 +1,28 @@
+-----BEGIN CERTIFICATE-----
+MIIEtDCCA5ygAwIBAgIRAJOShUABZXFflH8oj+/JmygwDQYJKoZIhvcNAQELBQAw
+PjELMAkGA1UEBhMCUEwxGzAZBgNVBAoTElVuaXpldG8gU3AuIHogby5vLjESMBAG
+A1UEAxMJQ2VydHVtIENBMB4XDTA4MTAyMjEyMDczN1oXDTI3MDYxMDEwNDYzOVow
+fjELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu
+QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEiMCAG
+A1UEAxMZQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQTCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBAOP7faNyusLwyRSH9WsBTuFuQAe6bSddf/dbLbNax1Ff
+q6QypmGHtm4PhtIwApf412lXoRg5XWpkecYBWaw8MUo4fNIE0kso6CBfOweizE1z
+2/OuT8dW1Vqnlon686to1COGWSfPCSe8rG5ygxwwct/gounS4XR1Gb0qnnsVVAQb
+10M5rVUoxeIau/TA5K44STPMdoWfOUXSpJ7yEoxR+HzkLX/1rF/rFp+xLdG6zJFC
+d0wlyZA4b9vwzPuOHpdZPtVgTuYFKO1JeRNLukjbL/ly0znK/h/YNHL1tEDPMQHD
+7N4RLRddH7hQ0V4Zp2neBzMoylCV+adUy1SGUEWp+UkCAwEAAaOCAWswggFnMA8G
+A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFAh2zcsH/yT2xc3tu5C84oQ3RnX3MFIG
+A1UdIwRLMEmhQqRAMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNw
+LiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBDQYIDAQAgMA4GA1UdDwEB/wQEAwIB
+BjAsBgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vY3JsLmNlcnR1bS5wbC9jYS5jcmww
+aAYIKwYBBQUHAQEEXDBaMCgGCCsGAQUFBzABhhxodHRwOi8vc3ViY2Eub2NzcC1j
+ZXJ0dW0uY29tMC4GCCsGAQUFBzAChiJodHRwOi8vcmVwb3NpdG9yeS5jZXJ0dW0u
+cGwvY2EuY2VyMDkGA1UdIAQyMDAwLgYEVR0gADAmMCQGCCsGAQUFBwIBFhhodHRw
+Oi8vd3d3LmNlcnR1bS5wbC9DUFMwDQYJKoZIhvcNAQELBQADggEBAI3m/UBmo0yc
+p6uh2oTdHDAH5tvHLeyDoVbkHTwmoaUJK+h9Yr6ydZTdCPJ/KEHkgGcCToqPwzXQ
+1aknKOrS9KsGhkOujOP5iH3g271CgYACEnWy6BdxqyGVMUZCDYgQOdNv7C9C6kBT
+Yr/rynieq6LVLgXqM6vp1peUQl4E7Sztapx6lX0FKgV/CF1mrWHUdqx1lpdzY70a
+QVkppV4ig8OLWfqaova9ML9yHRyZhpzyhTwd9yaWLy75ArG1qVDoOPqbCl60BMDO
+TjksygtbYvBNWFA0meaaLNKQ1wmB1sCqXs7+0vehukvZ1oaOGR+mBkdCcuBWCgAc
+eLmNzJkEN0k=
+-----END CERTIFICATE-----
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/CyberTrustJapanPublicCAG3.crt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/CyberTrustJapanPublicCAG3.crt
new file mode 100755
index 0000000..4543fb3
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/CyberTrustJapanPublicCAG3.crt
@@ -0,0 +1,26 @@
+-----BEGIN CERTIFICATE-----
+MIIEWjCCA0KgAwIBAgIQBUNA0KLEzIER+qg3fUbgbzANBgkqhkiG9w0BAQsFADBa
+MQswCQYDVQQGEwJJRTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJl
+clRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTE2
+MTExNTEyMDMzMVoXDTI1MDUxMDEyMDAwMFowWjELMAkGA1UEBhMCSlAxIzAhBgNV
+BAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMSYwJAYDVQQDEx1DeWJlcnRy
+dXN0IEphcGFuIFB1YmxpYyBDQSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAJRWo0VEVKpgZL+4V59O29R5aF8TBfQ/zSXdPF5Ydxyd5p/jMknvAjo0
+U41S5eM5Zh/nM2G2J8YkVVAnAmXwsIxBjTBeR1uCb8ecoyhDbVh7yBWYTiVvy3Yn
+WwssLLWYI+eLfP13GsRSul0Z7nghTSGa2RJ8MxVrGsmB6traV7fVL84fS/y0M+Cg
+yZQnuydAtpDbrJ51phErSRktw8JDBwm7PW6Io+OKxdKG9mVbNMOfTALlCbosxnZm
+69F2JfQwE/tYYKhY41FvSwgEYY2sqTAvUkGjIsEzWat7WfmTZ0vJiXVS7ylJNJMc
+nJNznBnOXBjNTAknwT/1Sez04t9Lr48CAwEAAaOCARowggEWMB0GA1UdDgQWBBRz
+qAhTKbgV+5mA5cU32Pg5e6QTBjAfBgNVHSMEGDAWgBTlnVkwgkdYzKz6CFQ2hns6
+tQRN8DASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjA0BggrBgEF
+BQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTA6
+BgNVHR8EMzAxMC+gLaArhilodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vT21uaXJv
+b3QyMDI1LmNybDA+BgNVHSAENzA1MDMGBWeBDAECMCowKAYIKwYBBQUHAgEWHGh0
+dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwDQYJKoZIhvcNAQELBQADggEBABqR
+cPGWxhjLeEP8gzZ29OHVpL8EFWNvpnEbpnAWa1uYmFNf0fsSoibP04UCB0Ye21KA
+jPNuTE2OWpgxlTVvl99sIJFKhXCIn6OWCLQpbjFMu8Ro5rdzg4ekedsihWN9NMwU
++K8DqO+oukIYjF2zPnnwcSykKaUhdi0BqUtmzJhHkFjoslJllOXiJ4DQkbpjiQpR
+yjPfliI1wzAcOM3xxswHAxOq8BVHKErKYUqHkHgHFZ6Ycts+sShKqVf+Zdx9zYJV
+pItiSs0DDCCFapxWACouIVY+xPYG8EMUWXz0gK8SAwNHXLRxBtjNWhCGOiSN+ihp
+277L8LbKp8eA8OlOMiU=
+-----END CERTIFICATE-----
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/DigiCertGlobalRootCA.crt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/DigiCertGlobalRootCA.crt
new file mode 100755
index 0000000..2f1e552
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/DigiCertGlobalRootCA.crt
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/DigiCertSHA2SecureServerCA.crt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/DigiCertSHA2SecureServerCA.crt
new file mode 100755
index 0000000..24d1795
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/DigiCertSHA2SecureServerCA.crt
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/DomenySslDvCertificationAuthority.crt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/DomenySslDvCertificationAuthority.crt
new file mode 100755
index 0000000..ed48838
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/DomenySslDvCertificationAuthority.crt
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----
+MIIGCTCCA/GgAwIBAgIRAPU2lIjQ1i9wpV8pmPEagpcwDQYJKoZIhvcNAQEMBQAw
+gYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtK
+ZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMS4wLAYD
+VQQDEyVVU0VSVHJ1c3QgUlNBIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTE0
+MTIwMjAwMDAwMFoXDTI0MTIwMTIzNTk1OVowgYQxCzAJBgNVBAYTAlBMMRUwEwYD
+VQQIDAxNYcWCb3BvbHNraWUxEDAOBgNVBAcMB0tyYWvDs3cxHDAaBgNVBAoTE0RP
+TUVOWS5QTCBzcC4geiBvLm8xLjAsBgNVBAMTJURPTUVOWSBTU0wgRFYgQ2VydGlm
+aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQC1tVhIdZ3PBSv7K1nqiubxWpgt1QPtfBoinH7qM0+pftrY8Zk0YuNPEx7U4vVR
+96THm/oQIIUTHz1Fb++yEYOlozD4rd9yagL9BBOBx4czugegBUX1PjB5fwFo5ucF
+x3xjzd6hgLHy+hxAARG6Bv9q0j9KFWMno22Zx+t97mLSpxWVQ/16nTJ83GnASGLQ
+JxR4WGJ6WcFOhddxbEc79TXVWESTKiQT3QtazAwAtGwJbkJkRBO8RNt/7hYOdsU0
+FqAvkMB0Lipi1U5INchwmkAWmXpWNT3m7NHlv2ZWK/Bp9N0TePCsQvTgyZ9gxdFK
++lYNcU3Kl2v2mhm3l7h5ATpHAgMBAAGjggFuMIIBajAfBgNVHSMEGDAWgBRTeb9a
+qitKz1SA4dibwJ3ysgNmyzAdBgNVHQ4EFgQUVjQFv0RyVj2WKdP/MXvvnUVJOakw
+DgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0lBBYwFAYI
+KwYBBQUHAwEGCCsGAQUFBwMCMBsGA1UdIAQUMBIwBgYEVR0gADAIBgZngQwBAgEw
+UAYDVR0fBEkwRzBFoEOgQYY/aHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VTRVJU
+cnVzdFJTQUNlcnRpZmljYXRpb25BdXRob3JpdHkuY3JsMHYGCCsGAQUFBwEBBGow
+aDA/BggrBgEFBQcwAoYzaHR0cDovL2NydC51c2VydHJ1c3QuY29tL1VTRVJUcnVz
+dFJTQUFkZFRydXN0Q0EuY3J0MCUGCCsGAQUFBzABhhlodHRwOi8vb2NzcC51c2Vy
+dHJ1c3QuY29tMA0GCSqGSIb3DQEBDAUAA4ICAQBtk0TwGOFQ95Hphul6hSNPPiZw
+vPGtbuLlNDQQ6tqE0Z03skU3Ec/U9/MmLvHGGt7h4mSbCQ5EszHL2BbSnj6REfn0
+8M5IsyJCyhpQosgyK4h+RU6dbZZp8evQCEfNhGc52GK4rVAkw0f16dakW4fARJUe
+1khn8JprEoP/ir5mi7Qlvnk6B2IUNTdSWc7QqiUgkYlWyUypuvTsSshtgINeIXkR
+seeHucuRZVmBYC2NlGeCD8Nho4f+AH9oZr//+HmcF7C8qGSCN23u1fQWZzFpn8qu
+hoDiKlzOki20y6JT6CEroWtkmx+d4fLLChOxzh/tkI9XqWR7qysK+nv0hnOYdKl5
+qA3icUh6RSdX74VobbMy2C4iM2mt8QcMEs/PqZrosigqwZILJ1Fd+5UPudMY5eb+
+kTiMFg8uPbsLiE3Y+DylCvTEoneRr4LHrIDklFjn1cBYO25HVkCn16J0QZyiBJXU
+cnhbkaHlJuEcKK0Fzlq78qHyNVZdVcplwcHZZ02VwfrsdWELkC+r2bgrvq+43uo7
+NgMVsrokbo7Of2ih1SzfpgU6q4SpbmAGNRzeVV0aZoRVR93K9uVtdZQQYMlh5emW
+AmFlgttlgDK3vwGj7fFOcNVwD49tJG65bZy2LQZMQS7fNsG0nGpUyYKJOnUbmSg6
+InpRnOhcq7sctB+0zQ==
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/EntrustCertificationAuthorityL1K.cer b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/EntrustCertificationAuthorityL1K.cer
new file mode 100755
index 0000000..ec8a906
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/EntrustCertificationAuthorityL1K.cer
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/EntrustRootCertificationAuthority.crt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/EntrustRootCertificationAuthority.crt
new file mode 100755
index 0000000..704c266
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/EntrustRootCertificationAuthority.crt
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC

+VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0

+Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW

+KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl

+cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw

+NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw

+NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy

+ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV

+BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ

+KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo

+Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4

+4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9

+KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI

+rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi

+94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB

+sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi

+gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo

+kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE

+vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA

+A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t

+O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua

+AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP

+9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/

+eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m

+0vdXcDazv/wor3ElhVsT/h5/WrQ8
+-----END CERTIFICATE-----
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/EntrustRootCertificationAuthorityG2.crt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/EntrustRootCertificationAuthorityG2.crt
new file mode 100755
index 0000000..c10bc62
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/EntrustRootCertificationAuthorityG2.crt
@@ -0,0 +1,29 @@
+-----BEGIN CERTIFICATE-----
+MIIE/zCCA+egAwIBAgIEUdNARDANBgkqhkiG9w0BAQsFADCBsDELMAkGA1UEBhMC

+VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0

+Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW

+KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl

+cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTE0MDkyMjE3MTQ1N1oXDTI0MDkyMzAx

+MzE1M1owgb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgw

+JgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQL

+EzAoYykgMjAwOSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9u

+bHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0

+eSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuoS2ctueDGvi

+mekwAad26jK4lUEaydphTlhyz/72gnm/c2EGCqUn2LNf00VOHHLWTjLycooP94MZ

+0GqAgABFHrDH55q/ElcnHKNoLwqHvWprDl5l8xx31dSFjXAhtLMy54ui1YY5ArG4

+0kfO5MlJxDun3vtUfVe+8OhuwnmyOgtV4lCYFjITXC94VsHClLPyWuQnmp8k18bs

+0JslguPMwsRFxYyXegZrKhGfqQpuSDtv29QRGUL3jwe/9VNfnD70FyzmaaxOMkxi

+d+q36OW7NLwZi66cUee3frVTsTMi5W3PcDwa+uKbZ7aD9I2lr2JMTeBYrGQ0EgP4

+to2UYySkcQIDAQABo4IBDzCCAQswDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQI

+MAYBAf8CAQEwMwYIKwYBBQUHAQEEJzAlMCMGCCsGAQUFBzABhhdodHRwOi8vb2Nz

+cC5lbnRydXN0Lm5ldDAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3JsLmVudHJ1

+c3QubmV0L3Jvb3RjYTEuY3JsMDsGA1UdIAQ0MDIwMAYEVR0gADAoMCYGCCsGAQUF

+BwIBFhpodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NQUzAdBgNVHQ4EFgQUanImetAe

+733nO2lR1GyNn5ASZqswHwYDVR0jBBgwFoAUaJDkZ6SmU4DHhmak8fdLQ/uEvW0w

+DQYJKoZIhvcNAQELBQADggEBAGkzg/woem99751V68U+ep11s8zDODbZNKIoaBjq

+HmnTvefQd9q4AINOSs9v0fHBIj905PeYSZ6btp7h25h3LVY0sag82f3Azce/BQPU

+AsXx5cbaCKUTx2IjEdFhMB1ghEXveajGJpOkt800uGnFE/aRs8lFc3a2kvZ2Clvh

+A0e36SlMkTIjN0qcNdh4/R0f5IOJJICtt/nP5F2l1HHEhVtwH9s/HAHrGkUmMRTM

+Zb9n3srMM2XlQZHXN75BGpad5oqXnafOrE6aPb0BoGrZTyIAi0TVaWJ7LuvMuueS

+fWlnPfy4fN5Bh9Bp6roKGHoalUOzeXEodm2h+1dK7E3IDhA=
+-----END CERTIFICATE-----
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/GoDaddyRootCertificateAuthorityG2.crt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/GoDaddyRootCertificateAuthorityG2.crt
new file mode 100755
index 0000000..c2b2907
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/GoDaddyRootCertificateAuthorityG2.crt
@@ -0,0 +1,23 @@
+-----BEGIN CERTIFICATE-----
+MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
+EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
+ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz
+NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
+EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE
+AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD
+E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH
+/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy
+DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh
+GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR
+tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA
+AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
+FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX
+WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu
+9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr
+gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
+2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
+LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
+4uJEvlz36hz1
+-----END CERTIFICATE-----
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/GoDaddySecureCertificateAuthorityG2.crt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/GoDaddySecureCertificateAuthorityG2.crt
new file mode 100755
index 0000000..885c45a
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/GoDaddySecureCertificateAuthorityG2.crt
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/KPN_BV_PKIoverheid_Organisatie_Server_CA-G3_2019.cer b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/KPN_BV_PKIoverheid_Organisatie_Server_CA-G3_2019.cer
new file mode 100755
index 0000000..acc2e74
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/KPN_BV_PKIoverheid_Organisatie_Server_CA-G3_2019.cer
@@ -0,0 +1,42 @@
+-----BEGIN CERTIFICATE-----
+MIIHVTCCBT2gAwIBAgIUe3SFufBRSlUh5S05Ghqu25Ntj4wwDQYJKoZIhvcNAQEL
+BQAwajELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRl
+bjE7MDkGA1UEAwwyU3RhYXQgZGVyIE5lZGVybGFuZGVuIE9yZ2FuaXNhdGllIFNl
+cnZpY2VzIENBIC0gRzMwHhcNMTkwNDE2MDg0MDE2WhcNMjgxMTEyMDAwMDAwWjBx
+MQswCQYDVQQGEwJOTDERMA8GA1UECgwIS1BOIEIuVi4xFzAVBgNVBGEMDk5UUk5M
+LTI3MTI0NzAxMTYwNAYDVQQDDC1LUE4gQlYgUEtJb3ZlcmhlaWQgT3JnYW5pc2F0
+aWUgU2VydmVyIENBIC0gRzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
+AQDNZfwvQT6bhd9JwjU5SOrZd0Fe3Fmcftf2KIGrbBgIjJZKkiRximQqWZtfwyzh
+by/Pyli8HAQVsXNPKHPqrJ/iv1YtTlDntuRk+w8IaZzWo0Rf4IO5VmrnjFUGkmvS
+QcTyCN1LdNBoHI185aa3Br7lGUltBv86Q+nlymHJmMKjC0y6C0+Xpt7SuWr0nO15
+wqiBZdUlFF05XcxXbTOG9UouVhlSKU9ujnkfNSKw7N3x4gqJNQ9C0W5O2zVO2jWy
+BaK20vnbN955FQM84O2prhMFQrCi3e6lVvtTamxlnzVOiVUpH+59Rh0PeOw8OwCn
+k8GLXwkvIrxPgi3MFIpVy30q52eGHwzEkvExTHkuTm4pUSKI3N8zypfKBkfPUCnF
+k6PluFkQZYvZSVWMNbLst6DOuStKSgsWtH3lQGz3qNgyLgtWjFBS6S7+lgb06On9
+SadJ7MgLTyvaPXGOieDwEq3BhjTnioNswPjIJCKjGad6EtnFaK+kG0wzE2v+gger
+4shh72Vj7GM4305UPBCEIlvmafyCHSD8r2lMBX1bqnbp2aw9ocdDbkCTzJ+N2Dkm
+KkAp87NFRsFXgfnqgOjG50owXLNaEsXhOwI3lBOCCz8FG7u0jD44k67lU8n3LvKh
+BenixXYylak9vulc1q13uICa04NbMKegL0uW7Wb2anw1+QIDAQABo4IB6jCCAeYw
+gZkGCCsGAQUFBwEBBIGMMIGJMEYGCCsGAQUFBzAChjpodHRwOi8vY2VydC5wa2lv
+dmVyaGVpZC5ubC9Eb21PcmdhbmlzYXRpZVNlcnZpY2VzQ0EtRzMuY2VyMD8GCCsG
+AQUFBzABhjNodHRwOi8vZG9tb3JnYW5pc2F0aWVzZXJ2aWNlc29jc3AtZzMucGtp
+b3ZlcmhlaWQubmwwHQYDVR0OBBYEFMOapntedCuCtsZy/XROhdKXzf0YMBIGA1Ud
+EwEB/wQIMAYBAf8CAQAwHwYDVR0jBBgwFoAUQ+tNANOVk86mfEANbRG+OdEyruIw
+JQYIKwYBBQUHAQMEGTAXMBUGCCsGAQUFBwsCMAkGBwQAi+xJAQIwQQYDVR0gBDow
+ODA2BgpghBABh2sBAgUGMCgwJgYIKwYBBQUHAgEWGmh0dHBzOi8vY3BzLnBraW92
+ZXJoZWlkLm5sMFEGA1UdHwRKMEgwRqBEoEKGQGh0dHA6Ly9jcmwucGtpb3Zlcmhl
+aWQubmwvRG9tT3JnYW5pc2F0aWVTZXJ2aWNlc0xhdGVzdENSTC1HMy5jcmwwDgYD
+VR0PAQH/BAQDAgEGMCcGA1UdJQQgMB4GCCsGAQUFBwMCBggrBgEFBQcDCQYIKwYB
+BQUHAwEwDQYJKoZIhvcNAQELBQADggIBALuwQ/7/bwHCXqLJS1ZACMmTm2GpkvQm
+plXC3HHpRV8DTQ4u/jMhtkSLzLsf6AcLGKTGQLrYv2lGBglFxtlZWTGOirTmWFyR
+OUbSSzkbSd5H8jvt/zswWffiSPRdMMncrc+yMMjD44lDfIytwZXrKYroI4ftYt5j
+aJ8wwMTOJTk9apzFajhIgGtMybXfmgVJDr9xPP53aMOjhHmlqlQ4yNdZTlNOO9LK
+KRxw+injitKp6jqoVSCL0TBvrbKu4pw0TqtK9NfaMwWGt55lZV8ZSWZaqNX97Umm
+xHqlqjvX7z0gE7s6wzvcgYyoR1Qo+2A60tLm4A1mr2mB9+aTnupdaGsBzCdkqKIR
+JcnEEeb+cffgKt0upfAAnqXAwkxTiG0NMjJp3RBkBFItOByy8ARduxiH6w7ZFHhs
+B8W1kL9/26hbYY1RTyAe86hfb6NuibTg16blnqNF/xCjVqCiTGXop1CQLBDlx4Hp
+wIrKEDvIGGBZRIzPqDI9I2KMlJEywa7k8Rm+HaILymBz5jU9NUD2CIBCCp94RqBr
+4XFcJnXvSIjfS0+2tIzljXImImIxxZkYLNiWElB6ytiHi0fKBvQ+cgDAOmbfLvhE
+Nankk8qgo22on1buVddUW7vYjA0qiXIQYr0N5mrJqbLGdrSCVceMgVOVSI/b1a31
+cVXLiGvOxK8W
+-----END CERTIFICATE-----
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/StaatDerNederlandenEVRootCA.crt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/StaatDerNederlandenEVRootCA.crt
new file mode 100755
index 0000000..d189e90
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/StaatDerNederlandenEVRootCA.crt
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/StaatderNederlandenOrganisatieServicesCA-G3.cer b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/StaatderNederlandenOrganisatieServicesCA-G3.cer
new file mode 100755
index 0000000..6e4ed7a
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/StaatderNederlandenOrganisatieServicesCA-G3.cer
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/StaatderNederlandenRootCA-G3.cer b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/StaatderNederlandenRootCA-G3.cer
new file mode 100755
index 0000000..c4cc8bb
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/cacerts/tls/StaatderNederlandenRootCA-G3.cer
Binary files differ
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/02.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/02.txt
new file mode 100755
index 0000000..478c6fc
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/02.txt
@@ -0,0 +1,4 @@
+20201,GR COSMOTE,C-OTE

+20205,vodafone GR,voda GR

+20209,WIND GR,WIND

+20210,WIND GR,WIND

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/04.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/04.txt
new file mode 100755
index 0000000..19fca28
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/04.txt
@@ -0,0 +1,4 @@
+20404,vodafone NL,voda NL

+20408,NL KPN,NL KPN

+20412,NL Telfort,NL Tlfrt

+20416,T-Mobile NL,TMO NL

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/06.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/06.txt
new file mode 100755
index 0000000..a08a6ef
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/06.txt
@@ -0,0 +1,3 @@
+20601,Proximus,Proximus

+20610,Orange B,OBE

+20620,BASE,BASE

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/08.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/08.txt
new file mode 100755
index 0000000..29226f7
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/08.txt
@@ -0,0 +1,10 @@
+20801,Orange F,Orange

+20802,F-Contact,Contact

+20809,F SFR,SFR

+20810,F SFR,SFR

+20811,SFR FEMTO,SFRFEMTO

+20813,F - Contact,Contact

+20815,Free,Free

+20816,Free,Free

+20820,F-Bouygues Telecom,BYTEL

+20888,F - Contact,Contact

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/12.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/12.txt
new file mode 100755
index 0000000..c47e8f3
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/12.txt
@@ -0,0 +1,2 @@
+21201,vala,vala

+21210,Monaco,MONACO

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/13.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/13.txt
new file mode 100755
index 0000000..b146876
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/13.txt
@@ -0,0 +1 @@
+21303,AndorraTelecom,AndorraT

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/14.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/14.txt
new file mode 100755
index 0000000..9821536
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/14.txt
@@ -0,0 +1,4 @@
+21401,vodafone ES,voda ES

+21403,Orange SP,ESPRT

+21404,YOIGO,YOIGO

+21407,Movistar,Movistar

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/16.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/16.txt
new file mode 100755
index 0000000..f0051da
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/16.txt
@@ -0,0 +1,4 @@
+21601,Telenor HU,TelenorH

+21603,Digi.Mobil HU,Digi HU

+21630,Telekom HU,THU

+21670,vodafone HU,voda HU

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/18.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/18.txt
new file mode 100755
index 0000000..49fa4ad
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/18.txt
@@ -0,0 +1,3 @@
+21803,HT ERONET,HTERONET

+21805,m:tel,m:tel

+21890,BH Mobile,BHMOBILE

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/19.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/19.txt
new file mode 100755
index 0000000..be13258
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/19.txt
@@ -0,0 +1,3 @@
+21901,HT HR,HT HR

+21902,Tele2 HR,Tele2 HR

+21910,A1 HR,A1 HR

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/20.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/20.txt
new file mode 100755
index 0000000..52463ae
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/20.txt
@@ -0,0 +1,3 @@
+22001,Telenor SRB,Telenor

+22003,mt:s,MTS

+22005,Vip SRB,Vip SRB

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/21.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/21.txt
new file mode 100755
index 0000000..83526aa
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/21.txt
@@ -0,0 +1,2 @@
+22101,vala,vala

+22102,IPKO,IPKO

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/22.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/22.txt
new file mode 100755
index 0000000..1cc9d0c
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/22.txt
@@ -0,0 +1,4 @@
+22201,I TIM,TIM

+22210,vodafone IT,voda IT

+22250,ILIAD,ILIAD

+22288,WINDTRE,WINDTRE

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/26.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/26.txt
new file mode 100755
index 0000000..252b25a
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/26.txt
@@ -0,0 +1,4 @@
+22601,RO Vodafone RO,VF-RO

+22603,TELEKOM.RO,TELEKOM

+22605,RO Digi.Mobil,Digi

+22610,RO ORANGE,ORANGE

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/28.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/28.txt
new file mode 100755
index 0000000..047dbf2
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/28.txt
@@ -0,0 +1,3 @@
+22801,Swisscom,Swisscom

+22802,Sunrise,Sunrise

+22803,Salt,Salt

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/30.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/30.txt
new file mode 100755
index 0000000..b0ee80e
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/30.txt
@@ -0,0 +1,3 @@
+23001,T-Mobile CZ,TMO CZ

+23002,O2 - CZ,O2 - CZ

+23003,Vodafone CZ,Vodafone

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/31.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/31.txt
new file mode 100755
index 0000000..09b47c4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/31.txt
@@ -0,0 +1,4 @@
+23101,Orange SK,Orange

+23102,Telekom SK,Telekom

+23103,SWAN SK,SWAN SK

+23106,O2 - SK,O2 - SK

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/32.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/32.txt
new file mode 100755
index 0000000..390c117
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/32.txt
@@ -0,0 +1,7 @@
+23201,A1,A1

+23203,Magenta-T-,MagentaT

+23205,3 AT,3 AT

+23207,telering,telering

+23210,3 AT,3 AT

+23213,Magenta-T-,MagentaT

+23217,spusu,spusu

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/34.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/34.txt
new file mode 100755
index 0000000..9b3626e
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/34.txt
@@ -0,0 +1,10 @@
+23403,Airtel-Vodafone,ATL-VOD

+23410,O2 - UK,O2 - UK

+23415,vodafone UK,voda UK

+23420,3 UK,3 UK

+23428,Marathon,Marathon

+23430,EE,EE

+23433,EE,EE

+23450,JT,JT

+23455,Sure,Sure

+23458,Manx Telecom,MANX

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/38.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/38.txt
new file mode 100755
index 0000000..b035c42
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/38.txt
@@ -0,0 +1,6 @@
+23801,TDC,TDC

+23802,Telenor DK,TelenoDK

+23806,3 DK,3 DK

+23820,Telia DK,Telia

+23866,Telia-Telenor DK,TT DK

+23877,Telenor DK,TelenoDK

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/40.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/40.txt
new file mode 100755
index 0000000..8feaf6b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/40.txt
@@ -0,0 +1,7 @@
+24001,TELIA S,TELIA

+24002,3 SE,3 SE

+24004,SWEDEN,SWE

+24005,Sweden,Sweden3G

+24007,Tele2,Tele2 SE

+24008,Telenor SE,TelenorS

+24024,Sweden Mobile,MobileS

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/42.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/42.txt
new file mode 100755
index 0000000..f3b2294
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/42.txt
@@ -0,0 +1,4 @@
+24201,N Telenor,TELENOR

+24202,N NetCom,NetCom

+24214,N ice,ice

+24299,Tampnet,Tampnet

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/44.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/44.txt
new file mode 100755
index 0000000..915ecb3
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/44.txt
@@ -0,0 +1,7 @@
+24403,FI DNA,DNA

+24405,FI elisa,elisa

+24412,FI DNA,DNA

+24414,FI AMT,FI AMT

+24421,FI elisa,elisa

+24436,DNA - Telia FI,SuomenYV

+24491,Telia FI,Telia

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/46.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/46.txt
new file mode 100755
index 0000000..dbd952a
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/46.txt
@@ -0,0 +1,3 @@
+24601,Telia LT,Telia

+24602,LT BITE GSM,BITE

+24603,Tele2 LT,Tele2 LT

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/47.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/47.txt
new file mode 100755
index 0000000..a23e73e
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/47.txt
@@ -0,0 +1,3 @@
+24701,LV LMT,LMT

+24702,Tele2 LV,Tele2 LV

+24705,BITE LV,BITE LV

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/48.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/48.txt
new file mode 100755
index 0000000..8320fb5
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/48.txt
@@ -0,0 +1,3 @@
+24801,Telia,Telia

+24802,Elisa EE,ELISA

+24803,Tele2 EE,Tele2 EE

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/50.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/50.txt
new file mode 100755
index 0000000..e52137e
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/50.txt
@@ -0,0 +1,7 @@
+25001,MTS RUS,MTS RUS

+25002,MegaFon RUS,MegaFon

+25020,Tele2 RU,Tele2

+25027,LETAI,LETAI

+25028,voda,voda

+25035,MOTIV,MOTIV

+25099,Beeline,Beeline

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/55.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/55.txt
new file mode 100755
index 0000000..ca0ad44
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/55.txt
@@ -0,0 +1,5 @@
+25501,VODAFONE,VODAFONE

+25502,Beeline UA,Beeline

+25503,UA-KYIVSTAR,UA-KS

+25506,life:),life:)

+25507,TriMob,TriMob

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/57.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/57.txt
new file mode 100755
index 0000000..52892ec
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/57.txt
@@ -0,0 +1,3 @@
+25701,BY VELCOM,VELCOM

+25702,MTS BY,MTS BY

+25704,life:) BY,life:)BY

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/59.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/59.txt
new file mode 100755
index 0000000..afab60d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/59.txt
@@ -0,0 +1,4 @@
+25901,Orange MD,Orange

+25902,Moldcell,Moldcell

+25905,UNITE,UNITE

+25915,IDC,IDC

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/60.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/60.txt
new file mode 100755
index 0000000..8f265b2
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/60.txt
@@ -0,0 +1,4 @@
+26001,Plus,PLUS

+26002,T-Mobile.pl,TM PL

+26003,Orange PL,Orange

+26006,Play,Play

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/62.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/62.txt
new file mode 100755
index 0000000..4aba278
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/62.txt
@@ -0,0 +1,4 @@
+26201,Telekom.de,TDG

+26202,Vodafone.de,Vodafone

+26203,o2 - de,o2 - de

+26207,o2 - de,o2 - de

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/66.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/66.txt
new file mode 100755
index 0000000..6e6f0eb
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/66.txt
@@ -0,0 +1 @@
+26601,GIBTEL,GIBTEL

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/68.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/68.txt
new file mode 100755
index 0000000..2a9c73b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/68.txt
@@ -0,0 +1,3 @@
+26801,vodafone P,voda P

+26803,NOS,NOS

+26806,MEO,MEO

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/70.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/70.txt
new file mode 100755
index 0000000..9c4810f
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/70.txt
@@ -0,0 +1,3 @@
+27001,POST,POST

+27077,L TANGO,TANGO

+27099,L Orange-LU,Orange

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/72.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/72.txt
new file mode 100755
index 0000000..88e1f35
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/72.txt
@@ -0,0 +1,4 @@
+27201,vodafone IE,voda IE

+27202,3,3

+27203,IRL - METEOR,METEOR

+27205,3,3

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/74.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/74.txt
new file mode 100755
index 0000000..68957aa
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/74.txt
@@ -0,0 +1,5 @@
+27401,IS SIMINN,SIMINN

+27402,Vodafone,Vodafone

+27404,Viking,Viking

+27408,IS OnWaves,OnWaves

+27411,NOVA IS,NOVA

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/76.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/76.txt
new file mode 100755
index 0000000..a938e7d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/76.txt
@@ -0,0 +1,3 @@
+27601,Telekom.al,T.al

+27602,Voda AL,Voda AL

+27603,ALBtelecom,ATmobile

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/78.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/78.txt
new file mode 100755
index 0000000..dba0e13
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/78.txt
@@ -0,0 +1,3 @@
+27801,vodafone MT,voda MT

+27821,go mobile,gomobile

+27877,Melita Mobile,Melita

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/80.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/80.txt
new file mode 100755
index 0000000..1baa11c
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/80.txt
@@ -0,0 +1,3 @@
+28001,Cyta-Voda,CytaVoda

+28010,epic,epic

+28020,PrimeTel PLC,PrimeTel

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/82.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/82.txt
new file mode 100755
index 0000000..476cc52
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/82.txt
@@ -0,0 +1,3 @@
+28201,GEO-GEOCELL,GCELL

+28202,MAGTI-GSM-GEO,MAGTI

+28204,BEELINE,BEE

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/83.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/83.txt
new file mode 100755
index 0000000..2e683f8
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/83.txt
@@ -0,0 +1,3 @@
+28301,Beeline AM,Beeline

+28305,MTS ARM,MTS Arm

+28310,Ucom AM,Ucom

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/84.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/84.txt
new file mode 100755
index 0000000..8ee4670
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/84.txt
@@ -0,0 +1,3 @@
+28401,A1 BG,A1 BG

+28403,Vivacom BG,Vivacom

+28405,Telenor BG,Telenor

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/86.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/86.txt
new file mode 100755
index 0000000..3a6f717
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/86.txt
@@ -0,0 +1,3 @@
+28601,TR TURKCELL,TCELL

+28602,Vodafone Turkiye,VF-TR

+28603,AVEA,AVEA

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/88.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/88.txt
new file mode 100755
index 0000000..a8ab8f5
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/88.txt
@@ -0,0 +1,2 @@
+28801,Foroya Tele,FT-GSM

+28802,VODAFONE FO,VODAFONE

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/90.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/90.txt
new file mode 100755
index 0000000..41ee5e2
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/90.txt
@@ -0,0 +1 @@
+29001,TELE Greenland,TELE GRL

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/93.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/93.txt
new file mode 100755
index 0000000..9818653
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/93.txt
@@ -0,0 +1,4 @@
+29340,A1 SI,A1 SI

+29341,MOBITEL,MOBITEL

+29364,T-2,T-2

+29370,TELEMACH,TELEMACH

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/94.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/94.txt
new file mode 100755
index 0000000..79c471a
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/94.txt
@@ -0,0 +1,2 @@
+29401,Telekom MK,MKT MK

+29403,A1 MK,A1 MK

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/95.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/95.txt
new file mode 100755
index 0000000..f1f95ee
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/95.txt
@@ -0,0 +1,3 @@
+29501,SwisscomFL,Swiss FL

+29502,Salt.li,Salt.li

+29505,FL1,FL1

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/97.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/97.txt
new file mode 100755
index 0000000..88065ef
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/2/97.txt
@@ -0,0 +1,3 @@
+29701,Telenor,Telenor

+29702,Telekom.me,T.me

+29703,MTEL,MTEL

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/02.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/02.txt
new file mode 100755
index 0000000..ddaf8ba
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/02.txt
@@ -0,0 +1,16 @@
+302130,Xplore,Xplore

+302220,TELUS,TELUS

+302270,Eastlink,Eastlink

+302340,Execulink Telecom,ETI

+302370,Fido,Fido

+302380,KNET,KNET

+302480,SSi,SSi

+302490,Freedom,Freedom

+302500,Videotron,CANVT

+302520,Videotron,CANVT

+302610,Bell,Bell

+302620,Ice Wireless Inc,Ice

+302720,Rogers Wireless,ROGERS

+302780,SaskTel,SaskTel

+302880,FastRoam,FastRoam

+302940,Wightman,Wightman

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/08.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/08.txt
new file mode 100755
index 0000000..5542952
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/08.txt
@@ -0,0 +1 @@
+30801,SPM AMERIS,AMERIS

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/10.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/10.txt
new file mode 100755
index 0000000..a06694b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/10.txt
@@ -0,0 +1,44 @@
+310020,US - Union Telephone,UnionTel

+310030,AT&T,AT&T

+310032,IT&E,IT&E

+310050,GCI,GCI

+310110,IT&E,IT&E

+310120,Sprint,Sprint

+310140,GTA,GTA

+310150,AT&T,AT&T

+310160,T-Mobile,T-Mobile

+310170,AT&T,AT&T

+310180,West Central Wireless,WCW

+310190,USA Dutch Harbor,D-HARBOR

+310200,T-Mobile,T-Mobile

+310210,T-Mobile,T-Mobile

+310220,T-Mobile,T-Mobile

+310230,T-Mobile,T-Mobile

+310240,T-Mobile,T-Mobile

+310250,T-Mobile,T-Mobile

+310260,T-Mobile,T-Mobile

+310270,T-Mobile,T-Mobile

+310280,AT&T,AT&T

+310300,BigSkyUS,Big Sky

+310310,T-Mobile,T-Mobile

+310320,USA - CellularOne,Cell

+310340,Limitless Mobile,LMUSA

+310370,DOCOMO PACIFIC,DPAC

+310380,AT&T,AT&T

+310410,AT&T,AT&T

+310450,Cell One of NE Colorado,NECCI

+310460,USA1L,USA1L

+310470,DOCOMO PACIFIC,DPAC

+310490,T-Mobile,T-Mobile

+310530,Iowa Wireless USA,IWS

+310570,Cell One,Cell One

+31058,Inland Cellular,IC

+310630,USA AmeriLink,AMERLINK

+310660,T-Mobile,T-Mobile

+310690,Limitless Mobile,LMUSA

+310730,U.S.Cellular,USCC

+310740,USA OTZ,OTZ

+310770,Iowa Wireless USA,IWS

+310800,T-Mobile,T-Mobile

+310840,telna Mobile,telna

+310990,Worldcall,Evolve

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/11.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/11.txt
new file mode 100755
index 0000000..bfb8b4b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/11.txt
@@ -0,0 +1,19 @@
+311030,Indigo,Indigo

+311040,USA - Commnet,Commnet

+311080,Pine Cellular,PINECell

+311170,Tampnet,Tampnet

+311190,USAC1ECI,C1ECI

+311230,C Spire,C Spire

+311240,USACWCI,CWCI

+311270,Verizon,Verizon

+311370,GCI,GCI

+311480,Verizon,Verizon

+311530,USANW,USANW

+311580,U.S.Cellular,USCC

+311600,Limitless Mobile,LMUSA

+311630,C Spire,C Spire

+311660,Metro PCS,MPCS

+311710,Northeast Wireless,NEWN

+311740,TCI,TCI

+311810,Bluegrass Wireless,BW

+311990,VTW US,VTW

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/12.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/12.txt
new file mode 100755
index 0000000..214f2b7
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/12.txt
@@ -0,0 +1,9 @@
+312180,Limitless Mobile,LMUSA

+312260,USACL,USACL

+312280,Pioneer,CNP

+312290,Strata Networks USA,Strata

+312420,Nex-Tech Wireless USA,NTW

+312480,Nemont,Nemont

+312630,NetGenuity,NetGenui

+312720,Southern Linc,SLINC

+312870,GigSky,GigSky

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/13.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/13.txt
new file mode 100755
index 0000000..769b9a5
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/13.txt
@@ -0,0 +1,2 @@
+313070,MNSHub,MNSHub

+313380,OptimERA,OptimERA

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/30.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/30.txt
new file mode 100755
index 0000000..fdbf906
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/30.txt
@@ -0,0 +1,2 @@
+330110,PR Claro,Claro

+330120,Open Mob PRI,Open Mob

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/34.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/34.txt
new file mode 100755
index 0000000..e888050
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/34.txt
@@ -0,0 +1,5 @@
+334020,TELCEL,TELCEL

+33403,Movistar,TEMM

+334050,AT&T,AT&T

+334070,AT&T,AT&T

+33490,AT&T,AT&T

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/38.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/38.txt
new file mode 100755
index 0000000..bb0542b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/38.txt
@@ -0,0 +1,2 @@
+338050,Digicel,Digicel

+338180,FLOW,FLOW

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/40.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/40.txt
new file mode 100755
index 0000000..63b1daf
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/40.txt
@@ -0,0 +1,4 @@
+34001,F-Orange,Orange

+34002,SFR,SFR

+34020,Digicel,DigicelF

+34009,Free,Free

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/42.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/42.txt
new file mode 100755
index 0000000..90f2968
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/42.txt
@@ -0,0 +1,2 @@
+342600,FLOW,FLOW

+342750,DIGICEL,DIGICEL

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/44.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/44.txt
new file mode 100755
index 0000000..db60c94
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/44.txt
@@ -0,0 +1,3 @@
+34403,APUA inet,inet

+344920,FLOW,FLOW

+344930,Cingular,Cingular

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/46.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/46.txt
new file mode 100755
index 0000000..8c42cec
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/46.txt
@@ -0,0 +1 @@
+346140,FLOW,FLOW

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/48.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/48.txt
new file mode 100755
index 0000000..2fcc6e8
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/48.txt
@@ -0,0 +1,2 @@
+348170,FLOW,FLOW

+348570,CCT Boatphone,CCTBVI

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/50.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/50.txt
new file mode 100755
index 0000000..ad6bd8e
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/50.txt
@@ -0,0 +1 @@
+350000,CELLONE,CELLONE

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/52.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/52.txt
new file mode 100755
index 0000000..3c99a85
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/52.txt
@@ -0,0 +1,2 @@
+352030,DIGICEL,DIGICEL

+352110,FLOW,FLOW

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/54.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/54.txt
new file mode 100755
index 0000000..95b7e85
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/54.txt
@@ -0,0 +1 @@
+354860,FLOW,FLOW

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/56.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/56.txt
new file mode 100755
index 0000000..ad0f132
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/56.txt
@@ -0,0 +1 @@
+356110,FLOW,FLOW

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/58.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/58.txt
new file mode 100755
index 0000000..b269923
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/58.txt
@@ -0,0 +1,2 @@
+358050,DIGICEL,DIGICEL

+358110,FLOW,FLOW

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/60.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/60.txt
new file mode 100755
index 0000000..554c0df
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/60.txt
@@ -0,0 +1,2 @@
+360070,DIGICEL,DIGICEL

+360110,FLOW,FLOW

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/62.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/62.txt
new file mode 100755
index 0000000..3f2494a
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/62.txt
@@ -0,0 +1,4 @@
+36251,Telcell GSM,Telcell

+36269,Digicel,Digicel

+36278,Kla,Kla

+36291,CHIPPIE,CHIPPIE

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/63.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/63.txt
new file mode 100755
index 0000000..08ac8bc
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/63.txt
@@ -0,0 +1,2 @@
+36301,SETAR,SETAR

+36302,AW Digicel,Digicel

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/64.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/64.txt
new file mode 100755
index 0000000..9aa8a4e
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/64.txt
@@ -0,0 +1,2 @@
+36439,BTC,BTC

+36449,aliv,aliv

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/65.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/65.txt
new file mode 100755
index 0000000..850bba9
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/65.txt
@@ -0,0 +1 @@
+365840,FLOW,FLOW

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/66.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/66.txt
new file mode 100755
index 0000000..6b1e078
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/66.txt
@@ -0,0 +1 @@
+366110,FLOW,FLOW

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/68.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/68.txt
new file mode 100755
index 0000000..bdad90c
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/68.txt
@@ -0,0 +1 @@
+36801,CUBACEL,CUBACEL

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/70.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/70.txt
new file mode 100755
index 0000000..91e84f8
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/70.txt
@@ -0,0 +1,4 @@
+37001,ALTICE,ALTICE

+37002,CLARO DOM,ClaroDOM

+37004,Viva DO,Viva

+37005,Wind Telecom DO,Wind

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/72.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/72.txt
new file mode 100755
index 0000000..9fb7391
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/72.txt
@@ -0,0 +1 @@
+37203,Natcom,Natcom

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/74.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/74.txt
new file mode 100755
index 0000000..630a815
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/74.txt
@@ -0,0 +1,2 @@
+37412,TSTT,TSTT

+374130,Digicel,Digicel

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/76.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/76.txt
new file mode 100755
index 0000000..25e6025
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/3/76.txt
@@ -0,0 +1 @@
+376350,FLOW,FLOW

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/00.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/00.txt
new file mode 100755
index 0000000..e7c9c62
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/00.txt
@@ -0,0 +1,3 @@
+40001,AZEAC,Azercell

+40002,BAKCELL AZ,BAKCELL

+40004,AZ Nar,Nar

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/01.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/01.txt
new file mode 100755
index 0000000..4b401fa
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/01.txt
@@ -0,0 +1,4 @@
+40101,Beeline KZ,Beeline

+40102,Kcell,Kcell

+40107,ALTEL,ALTEL

+40177,Tele2,Tele2

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/02.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/02.txt
new file mode 100755
index 0000000..1bfdd3d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/02.txt
@@ -0,0 +1,2 @@
+40211,BT B-Mobile,B-Mobile

+40277,TASHICELL,TASHICEL

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/04.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/04.txt
new file mode 100755
index 0000000..945195f
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/04.txt
@@ -0,0 +1,54 @@
+40402,IND airtel,airtel

+40403,IND airtel,airtel

+40404,IDEA,IDEA

+40407,IDEA,IDEA

+40410,IND airtel,airtel

+40412,IDEA,IDEA

+40414,IDEA,IDEA

+40416,IND airtel,airtel

+40419,IDEA,IDEA

+40422,IDEA,IDEA

+40424,IDEA,IDEA

+40431,IND airtel,airtel

+40434,CellOne,CellOne

+40438,CellOne,CellOne

+40440,IND airtel,airtel

+40444,IDEA,IDEA

+40445,IND airtel,airtel

+40449,IND airtel,airtel

+40451,CellOne,CellOne

+40453,CellOne,CellOne

+40454,CellOne,CellOne

+40455,CellOne,CellOne

+40456,IDEA,IDEA

+40457,CellOne,CellOne

+40458,CellOne,CellOne

+40459,CellOne,CellOne

+40462,CellOne,CellOne

+40464,CellOne,CellOne

+40466,CellOne,CellOne

+40468,IN-DOLPHIN,DOLPHIN

+40469,IN-DOLPHIN,DOLPHIN

+40470,IND airtel,airtel

+40471,CellOne,CellOne

+40472,CellOne,CellOne

+40473,CellOne,CellOne

+40474,CellOne,CellOne

+40475,CellOne,CellOne

+40476,CellOne,CellOne

+40477,CellOne,CellOne

+40478,IDEA,IDEA

+40479,CellOne,CellOne

+40480,CellOne,CellOne

+40481,CellOne,CellOne

+40482,IDEA,IDEA

+40487,IDEA,IDEA

+40489,IDEA,IDEA

+40490,IND airtel,airtel

+40492,IND airtel,airtel

+40493,IND airtel,airtel

+40494,IND airtel,airtel

+40495,IND airtel,airtel

+40496,IND airtel,airtel

+40497,IND airtel,airtel

+40498,IND airtel,airtel

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/05.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/05.txt
new file mode 100755
index 0000000..533bbc7
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/05.txt
@@ -0,0 +1,56 @@
+40551,IND airtel,airtel

+40552,IND airtel,airtel

+40553,IND airtel,airtel

+40554,IND airtel,airtel

+40555,IND airtel,airtel

+40556,IND airtel,airtel

+40570,IDEA,IDEA

+405799,IDEA,IDEA

+405823,VIDEOCON,VIDEOCON

+405824,VIDEOCON,VIDEOCON

+405825,VIDEOCON,VIDEOCON

+405827,VIDEOCON,VIDEOCON

+405828,VIDEOCON,VIDEOCON

+405829,VIDEOCON,VIDEOCON

+405830,VIDEOCON,VIDEOCON

+405831,VIDEOCON,VIDEOCON

+405832,VIDEOCON,VIDEOCON

+405833,VIDEOCON,VIDEOCON

+405834,VIDEOCON,VIDEOCON

+405835,VIDEOCON,VIDEOCON

+405836,VIDEOCON,VIDEOCON

+405837,VIDEOCON,VIDEOCON

+405838,VIDEOCON,VIDEOCON

+405839,VIDEOCON,VIDEOCON

+405840,IND-JIO,JIO

+405841,VIDEOCON,VIDEOCON

+405842,VIDEOCON,VIDEOCON

+405843,VIDEOCON,VIDEOCON

+405845,IDEA,IDEA

+405846,IDEA,IDEA

+405848,IDEA,IDEA

+405849,IDEA,IDEA

+405850,IDEA,IDEA

+405852,IDEA,IDEA

+405853,IDEA,IDEA

+405854,IND-JIO,JIO

+405855,IND-JIO,JIO

+405856,IND-JIO,JIO

+405857,IND-JIO,JIO

+405858,IND-JIO,JIO

+405859,IND-JIO,JIO

+405860,IND-JIO,JIO

+405861,IND-JIO,JIO

+405862,IND-JIO,JIO

+405863,IND-JIO,JIO

+405864,IND-JIO,JIO

+405865,IND-JIO,JIO

+405866,IND-JIO,JIO

+405867,IND-JIO,JIO

+405868,IND-JIO,JIO

+405869,IND-JIO,JIO

+405870,IND-JIO,JIO

+405871,IND-JIO,JIO

+405872,IND-JIO,JIO

+405873,IND-JIO,JIO

+405874,IND-JIO,JIO

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/10.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/10.txt
new file mode 100755
index 0000000..a4c94d7
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/10.txt
@@ -0,0 +1,6 @@
+41001,Jazz,Jazz

+41003,PK-UFONE,UFONE

+41004,ZONG,ZONG

+41005,SCOM-PK,SCOM

+41006,Telenor PK,TELENOR

+41007,Jazz,Jazz

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/12.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/12.txt
new file mode 100755
index 0000000..b450dc3
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/12.txt
@@ -0,0 +1,4 @@
+41201,AF AWCC,AWCC

+41220,ROSHAN,ROSHAN

+41240,MTN AF,MTN

+41250,Etisalat Af,Etisalat

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/13.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/13.txt
new file mode 100755
index 0000000..5d298d3
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/13.txt
@@ -0,0 +1,5 @@
+41301,Mobitel LK,Mobitel

+41302,DIALOG,DIALOG

+41303,SRI Etisalat,Etisalat

+41305,SRI AIRTEL,Airtel

+41308,Hutch,Hutch

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/14.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/14.txt
new file mode 100755
index 0000000..bbe363d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/14.txt
@@ -0,0 +1,4 @@
+41401,MM 900,MPTGSM

+41405,Ooredoo,Ooredoo

+41406,Telenor,TNM

+41409,MYTEL,MYTEL

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/15.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/15.txt
new file mode 100755
index 0000000..77898a1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/15.txt
@@ -0,0 +1,3 @@
+41501,alfa,alfa

+41503,touch,touch

+41505,LBN OGERO Mobile,OM

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/16.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/16.txt
new file mode 100755
index 0000000..1e276ff
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/16.txt
@@ -0,0 +1,3 @@
+41601,Zain JO,Zain JO

+41603,UMNIAH,UMNIAH

+41677,Orange JO,OrangeJO

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/17.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/17.txt
new file mode 100755
index 0000000..2b5d1a7
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/17.txt
@@ -0,0 +1 @@
+41702,MTN,MTN

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/18.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/18.txt
new file mode 100755
index 0000000..9801c5b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/18.txt
@@ -0,0 +1,4 @@
+41805,ASIACELL,ASIACELL

+41820,zain IQ,zain IQ

+41830,IRAQNA,IRAQNA

+41840,KOREK,KOREK

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/19.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/19.txt
new file mode 100755
index 0000000..0521a5a
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/19.txt
@@ -0,0 +1,3 @@
+41902,Zain KW,zain KW

+41903,Ooredoo,Ooredoo

+41904,stc Kuwait,,stc

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/20.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/20.txt
new file mode 100755
index 0000000..20b6ccc
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/20.txt
@@ -0,0 +1,3 @@
+42001,stc,stc

+42003,Mobily-KSA,Mobily

+42004,Zain KSA,Zain KSA

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/21.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/21.txt
new file mode 100755
index 0000000..8afb91b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/21.txt
@@ -0,0 +1,2 @@
+42101,SabaFon,SABAFON

+42102,MTN,MTN

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/22.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/22.txt
new file mode 100755
index 0000000..614ece2
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/22.txt
@@ -0,0 +1,2 @@
+42202,Omantel,Omantel

+42203,Ooredoo Oman,Ooredoo

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/24.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/24.txt
new file mode 100755
index 0000000..feaea24
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/24.txt
@@ -0,0 +1,2 @@
+42402,ETISALAT,ETISALAT

+42403,du,du

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/25.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/25.txt
new file mode 100755
index 0000000..0043545
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/25.txt
@@ -0,0 +1,8 @@
+42501,Partner IL,Partner

+42502,Cellcom IL,Cellcom

+42503,IL Pelephone,PCL

+42505,JAWWAL-PALESTINE,JAWWAL

+42506,Ooredoo Palestine,Ooredoo

+42507,Hot Mobile Ltd.,HOT IL

+42508,Golan IL,Golan T

+42528,Hot Mobile Ltd.,Israel

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/26.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/26.txt
new file mode 100755
index 0000000..c840b1f
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/26.txt
@@ -0,0 +1,3 @@
+42601,BATELCO,BATELCO

+42602,Zain BH,Zain BH

+42604,stc,stc

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/27.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/27.txt
new file mode 100755
index 0000000..526d726
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/27.txt
@@ -0,0 +1,2 @@
+42701,Ooredoo,Ooredoo

+42702,vodafone,VF-QA

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/28.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/28.txt
new file mode 100755
index 0000000..386c888
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/28.txt
@@ -0,0 +1,3 @@
+42801,Skytel MN,Skytel

+42888,MONGOLIA UNITEL LLC,UNTLMN

+42899,MN MobiCom,MobiCom

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/29.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/29.txt
new file mode 100755
index 0000000..a4648de
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/29.txt
@@ -0,0 +1,3 @@
+42901,Nepal Telecom,NT

+42902,Ncell,Ncell

+42904,SmartCell,ST

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/34.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/34.txt
new file mode 100755
index 0000000..4fa9e34
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/34.txt
@@ -0,0 +1,4 @@
+43404,Beeline UZ,Beeline

+43405,UZB Ucell,Ucell

+43407,UMS-UZB,UMS

+43408,UzMobile,UzMobile

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/36.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/36.txt
new file mode 100755
index 0000000..b043a67
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/36.txt
@@ -0,0 +1,5 @@
+43601,TCELL,TCELL

+43602,TCELL,TCELL

+43603,MegaFon TJK,MegaFon

+43604,Babilon-M,Babilon

+43605,ZET-MOBILE,Z-MOBILE

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/37.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/37.txt
new file mode 100755
index 0000000..eb3c927
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/37.txt
@@ -0,0 +1,3 @@
+43701,Beeline KG,Beeline

+43705,MegaCom,MegaCom

+43709,O!,O!

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/38.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/38.txt
new file mode 100755
index 0000000..ed855f9
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/38.txt
@@ -0,0 +1 @@
+43802,TM CELL,TM CELL

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/40.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/40.txt
new file mode 100755
index 0000000..a3b2025
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/40.txt
@@ -0,0 +1,4 @@
+44010,JP DOCOMO,DOCOMO

+44020,SoftBank,SoftBank

+44050,KDDI,KDDI

+44051,KDDI,KDDI

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/50.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/50.txt
new file mode 100755
index 0000000..a4baa2c
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/50.txt
@@ -0,0 +1,4 @@
+45005,KOR SK Telecom,SKT

+45006,KOR LG Uplus,LG U+

+45008,KT,KT

+45010,KOR LG Uplus,LG U+

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/52.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/52.txt
new file mode 100755
index 0000000..9132dfc
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/52.txt
@@ -0,0 +1,4 @@
+45201,VN Mobifone,Mobifone

+45202,VN VINAPHONE,GPC

+45204,VIETTEL,VIETTEL

+45205,Vietnamobile,VNMOBILE

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/54.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/54.txt
new file mode 100755
index 0000000..386f1f8
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/54.txt
@@ -0,0 +1,14 @@
+45400,CSL,CSL

+45402,CSL,CSL

+45403,3,3

+45404,3,3

+45406,SmarTone HK,SMC HK

+45410,CSL,CSL

+45412,China Mobile HK,CMHK

+45413,China Mobile HK,CMHK

+45415,SmarTone HK,SMC HK

+45416,CSL,CSL

+45417,SmarTone HK,SMC HK

+45418,CSL,CSL

+45419,CSL,CSL

+45420,CSL,CSL

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/55.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/55.txt
new file mode 100755
index 0000000..1c588ae
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/55.txt
@@ -0,0 +1,5 @@
+45500,SmarTone MAC,SMC MAC

+45501,CTM,CTM

+45503,3 Macau,3 Macau

+45504,CTM,CTM

+45505,3 Macau,3 Macau

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/56.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/56.txt
new file mode 100755
index 0000000..c22ec9b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/56.txt
@@ -0,0 +1,7 @@
+45601,Cellcard,Cellcard

+45602,Smart,Smart

+45604,qb,qb

+45605,Smart,Smart

+45606,Smart,Smart

+45608,Metfone,Metfone

+45611,KH SEATEL,SEATEL

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/57.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/57.txt
new file mode 100755
index 0000000..cda0dc4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/57.txt
@@ -0,0 +1,4 @@
+45701,LAO GSM,LAO GSM

+45702,ETL MOBILE NETWORK,ETLMNW

+45703,Unitel,UNITEL

+45708,TPLUS,TPLUS

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/60.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/60.txt
new file mode 100755
index 0000000..f902ee3
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/60.txt
@@ -0,0 +1,9 @@
+46000,CHINA MOBILE,CMCC

+46001,CHN-UNICOM,UNICOM

+46002,CHINA MOBILE,CMCC

+46003,CHN-CT,CT

+46004,CHINA MOBILE,CMCC

+46007,CHINA MOBILE,CMCC

+46008,CHINA MOBILE,CMCC

+46009,CHN-UNICOM,UNICOM

+46011,CHN-CT,CT

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/66.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/66.txt
new file mode 100755
index 0000000..10ec1c1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/66.txt
@@ -0,0 +1,9 @@
+46601,Far EasTone,FET

+46605,TWN APT,APT

+46612,TWN APT,APT

+46688,KGT-Online,KGT

+46689,T Star,T Star

+46692,Chunghwa Telecom,Chunghwa

+46693,TWN MOBITAI,TW MOB

+46697,TW Mobile,TWM

+46699,TWM TransAsi,TWM TAT

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/70.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/70.txt
new file mode 100755
index 0000000..e21c89b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/70.txt
@@ -0,0 +1,5 @@
+470001,Grameenphone,Grameen

+47002,robi axiata,robi

+47003,Banglalink,BL

+47004,BGD bMobile,bMobile

+47007,Airtel,Airtel

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/72.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/72.txt
new file mode 100755
index 0000000..f7d2782
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/4/72.txt
@@ -0,0 +1,2 @@
+47201,DHIRAAGU,DHIRAAGU

+47202,Ooredoo Maldives PVT LTD,Ooredoo

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/02.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/02.txt
new file mode 100755
index 0000000..34de30b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/02.txt
@@ -0,0 +1,7 @@
+50212,MY MAXIS,MY MAXIS

+50213,MY CELCOM,CELCOM

+502152,Yes,Yes 4G

+502153,unifi,unifi

+502156,MYSALTEL,ALTEL

+50218,U MOBILE,U MOBILE

+50219,MY CELCOM,CELCOM

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/05.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/05.txt
new file mode 100755
index 0000000..01aad9f
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/05.txt
@@ -0,0 +1,7 @@
+50501,Telstra Mobile,Telstra

+50502,Optus AU,Optus

+50503,vodafone AU,voda AU

+50510,Norfolk Telecom,NT

+50550,Pivotel,Pivotel

+50571,Telstra Mobile,Telstra

+50572,Telstra Mobile,Telstra

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/10.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/10.txt
new file mode 100755
index 0000000..0d9d4cf
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/10.txt
@@ -0,0 +1,8 @@
+51001,IND INDOSAT,INDOSAT

+51008,IND XL,Axis

+51009,Smartfren,SF

+51010,IND TELKOMSEL,T-SEL

+51011,IND XL,XL

+51021,IND INDOSAT,INDOSAT

+51028,Smartfren,SF

+51089,3,3

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/14.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/14.txt
new file mode 100755
index 0000000..f7f47bb
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/14.txt
@@ -0,0 +1,2 @@
+51401,TLS-TC,TCEL

+51402,TLS-TT,TT

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/15.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/15.txt
new file mode 100755
index 0000000..fa1c0f5
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/15.txt
@@ -0,0 +1,3 @@
+51502,Globe Telecom-PH,GLOBE

+51503,SMART,SMART

+51505,PH Sun Cellular,SUN

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/20.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/20.txt
new file mode 100755
index 0000000..b2072a5
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/20.txt
@@ -0,0 +1,8 @@
+52000,TH,TH 3G+

+52001,AIS,AIS

+52003,AIS,AIS

+52004,TRUE-H,TRUE-H

+52005,dtac TriNet,dtac

+52015,TOT Mobile,TOT

+52047,TOT Mobile,TOT

+52099,TRUE-H,TRUE-H

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/25.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/25.txt
new file mode 100755
index 0000000..0880cdb
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/25.txt
@@ -0,0 +1,7 @@
+52501,Singtel,Singtel

+52502,Singtel,Singtel

+52503,SGP-M1,M1

+52505,StarHub,StarHub

+52507,SGP Call Zone,CallZone

+52508,StarHub,StarHub

+52510,TPG SG,TPG SG

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/28.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/28.txt
new file mode 100755
index 0000000..3a471fd
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/28.txt
@@ -0,0 +1,2 @@
+52802,PCSB,PCSB

+52811,BRU-DSTCom,DSTCom

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/30.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/30.txt
new file mode 100755
index 0000000..f9d0a24
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/30.txt
@@ -0,0 +1,3 @@
+53001,vodafone NZ,voda NZ

+53005,Spark NZ,Spark NZ

+53024,2degrees,2degrees

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/36.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/36.txt
new file mode 100755
index 0000000..3529d58
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/36.txt
@@ -0,0 +1 @@
+53601,PacCell,PacCell
\ No newline at end of file
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/37.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/37.txt
new file mode 100755
index 0000000..b601397
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/37.txt
@@ -0,0 +1,2 @@
+53701,bmobile,bmobile

+53703,DIGICEL,DIGICEL

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/39.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/39.txt
new file mode 100755
index 0000000..91fbf47
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/39.txt
@@ -0,0 +1,2 @@
+53901,U-CALL,U-CALL

+53988,Digicel Tonga,Digicel

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/40.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/40.txt
new file mode 100755
index 0000000..9361772
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/40.txt
@@ -0,0 +1,2 @@
+54001,Our Telekom,Telekom

+54002,bmobile,bmobile

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/41.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/41.txt
new file mode 100755
index 0000000..274331e
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/41.txt
@@ -0,0 +1,2 @@
+54101,VUT SMILE,SMILE

+54105,Digicel,Digicel

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/42.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/42.txt
new file mode 100755
index 0000000..1e5e48f
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/42.txt
@@ -0,0 +1,2 @@
+54201,FJ VODAFONE,VODAFONE

+54202,DIGICEL,DIGICEL

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/43.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/43.txt
new file mode 100755
index 0000000..ae9e9dc
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/43.txt
@@ -0,0 +1 @@
+54301,Manuia,Manuia

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/44.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/44.txt
new file mode 100755
index 0000000..191a5ed
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/44.txt
@@ -0,0 +1 @@
+544110,Bluesky Communications,BLUESKY

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/46.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/46.txt
new file mode 100755
index 0000000..8b486e3
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/46.txt
@@ -0,0 +1 @@
+54601,NCL MOBILIS,MOBNCL

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/47.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/47.txt
new file mode 100755
index 0000000..144bc90
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/47.txt
@@ -0,0 +1,3 @@
+54705,VITI,VITI

+54715,VODAFONE PF,VODAFONE

+54720,F-VINI,VINI

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/48.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/48.txt
new file mode 100755
index 0000000..c71de07
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/48.txt
@@ -0,0 +1 @@
+54801,CK KOKANET,KOKANET

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/49.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/49.txt
new file mode 100755
index 0000000..2d86026
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/49.txt
@@ -0,0 +1,2 @@
+54900,DIGICEL,DIGICEL

+54927,Bluesky,Bluesky

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/50.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/50.txt
new file mode 100755
index 0000000..4445d26
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/50.txt
@@ -0,0 +1 @@
+55001,FSM Telecom,FSM Tele

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/52.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/52.txt
new file mode 100755
index 0000000..3b6cdcd
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/52.txt
@@ -0,0 +1 @@
+55201,PalauCel,PalauCel

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/54.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/54.txt
new file mode 100755
index 0000000..f46f28e
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/5/54.txt
@@ -0,0 +1 @@
+55401,Teletok,TTOK

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/02.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/02.txt
new file mode 100755
index 0000000..0fe1538
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/02.txt
@@ -0,0 +1,4 @@
+60201,Orange EG,Orange

+60202,vodafone EG,voda EG

+60203,Etisalat,Etisalat

+60204,EGYwe,we

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/03.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/03.txt
new file mode 100755
index 0000000..8f4af7a
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/03.txt
@@ -0,0 +1,3 @@
+60301,ALG Mobilis,Mobilis

+60302,Djezzy,Djezzy

+60303,ooredoo Algeria,Ooredoo

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/04.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/04.txt
new file mode 100755
index 0000000..ce80a51
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/04.txt
@@ -0,0 +1,3 @@
+60400,Orange MA,Orange

+60401,MOR IAM,IAM

+60402,inwi,inwi

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/05.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/05.txt
new file mode 100755
index 0000000..f678f6b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/05.txt
@@ -0,0 +1,3 @@
+60501,Orange TN,OrangeTN

+60502,TUNISIE TELECOM,TUNTEL

+60503,TUNISIANA,TUNISIAN

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/06.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/06.txt
new file mode 100755
index 0000000..e08f065
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/06.txt
@@ -0,0 +1,2 @@
+60600,Libyana,Libyana

+60601,Al Madar,Al Madar

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/07.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/07.txt
new file mode 100755
index 0000000..9203202
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/07.txt
@@ -0,0 +1,4 @@
+60701,GAMCEL,GAMCEL

+60702,AFRICELL,AFRICELL

+60703,GM COMIUM,GMCOMIUM

+60704,Qcell,QC

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/08.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/08.txt
new file mode 100755
index 0000000..299a8a4
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/08.txt
@@ -0,0 +1,2 @@
+60801,Orange SN,OrangeSN

+60803,SEN expresso,Expresso

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/09.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/09.txt
new file mode 100755
index 0000000..ea6db2d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/09.txt
@@ -0,0 +1,3 @@
+60901,MR MATTEL,MATTEL

+60902,MR Expresso,EMR

+60910,MAURITEL,MAURITEL

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/10.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/10.txt
new file mode 100755
index 0000000..c4829d0
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/10.txt
@@ -0,0 +1,3 @@
+61001,MALITEL ML,MALITEL

+61002,ORANGE ML,OML

+61003,TELECEL ML,TELECEL

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/11.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/11.txt
new file mode 100755
index 0000000..5c7faff
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/11.txt
@@ -0,0 +1,3 @@
+61101,Orange GN,ORANGEGN

+61104,GNMTN,GNAreeba

+61105,GINCL,Cellcom

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/12.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/12.txt
new file mode 100755
index 0000000..685bc31
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/12.txt
@@ -0,0 +1,4 @@
+61202,MOOV CI,MOOV

+61203,Orange,Orange

+61204,KoZ,KoZ

+61205,MTN CI,MTN CI

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/13.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/13.txt
new file mode 100755
index 0000000..f216f46
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/13.txt
@@ -0,0 +1,2 @@
+61301,ONATEL,ONATEL

+61302,Orange BF,Orange

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/14.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/14.txt
new file mode 100755
index 0000000..8df939b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/14.txt
@@ -0,0 +1,3 @@
+61402,Airtel,Airtel

+61403,ETISALAT NER,ETISALAT

+61404,Orange,Orange

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/15.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/15.txt
new file mode 100755
index 0000000..8a0c62c
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/15.txt
@@ -0,0 +1,2 @@
+61501,TG-TOGO CELL,TGCELL

+61503,ETISALAT TOGO,ETISALAT

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/16.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/16.txt
new file mode 100755
index 0000000..112e985
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/16.txt
@@ -0,0 +1,2 @@
+61602,ETISALAT BENIN,ETISALAT

+61603,MTN BENIN,MTNBENIN

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/17.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/17.txt
new file mode 100755
index 0000000..1dd5999
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/17.txt
@@ -0,0 +1,3 @@
+61701,CELLPLUS-MRU,my.t

+61703,MTML,MTML

+61710,EMTEL-MRU,EMTEL

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/18.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/18.txt
new file mode 100755
index 0000000..c3a0109
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/18.txt
@@ -0,0 +1,3 @@
+61801,LBR Lonestar Cell,LoneStar

+61804,Novafone,Novafone

+61807,Orange LBR,Orange L

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/19.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/19.txt
new file mode 100755
index 0000000..19aeddd
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/19.txt
@@ -0,0 +1,3 @@
+61901,Orange SL,OrangeSL

+61905,Africell,Africell

+61907,QCell,QC

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/20.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/20.txt
new file mode 100755
index 0000000..1962e26
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/20.txt
@@ -0,0 +1,5 @@
+62001,GH MTN,MTN

+62002,GH Vodafone,Vodafone

+62003,AirtelTigo,ATL-TIGO

+62006,AirtelTigo,ATL-TIGO

+62007,Glo Ghana,GloGhana

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/21.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/21.txt
new file mode 100755
index 0000000..8db9b9c
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/21.txt
@@ -0,0 +1,4 @@
+62120,Airtel,Airtel

+62130,MTN - NG,MTN-NG

+62140,ntel,ntel

+62150,Glo NG,glo

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/22.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/22.txt
new file mode 100755
index 0000000..439133e
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/22.txt
@@ -0,0 +1,2 @@
+62201,Airtel,Airtel

+62203,Tigo TD,Tigo

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/23.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/23.txt
new file mode 100755
index 0000000..ef99e91
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/23.txt
@@ -0,0 +1,2 @@
+62301,ETISALAT RCA,ETISALAT

+62302,Telecel,Telecel

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/24.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/24.txt
new file mode 100755
index 0000000..de6cc80
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/24.txt
@@ -0,0 +1,3 @@
+62401,MTN CAM,MTN CAM

+62402,Orange CM,Orange

+62404,Nexttel,Nexttel

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/25.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/25.txt
new file mode 100755
index 0000000..1e69743
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/25.txt
@@ -0,0 +1,2 @@
+62501,CVMOVEL,CVMOVEL

+62502,Unitel T+,UnitelT+

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/26.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/26.txt
new file mode 100755
index 0000000..7238b8d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/26.txt
@@ -0,0 +1,2 @@
+62601,STP CSTmovel,CSTmovel

+62602,Unitel STP,Unitel

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/27.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/27.txt
new file mode 100755
index 0000000..8fd5d5e
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/27.txt
@@ -0,0 +1,2 @@
+62701,GETESA,GETESA

+62703,GNQ-Muni,Muni-GQ

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/28.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/28.txt
new file mode 100755
index 0000000..8190503
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/28.txt
@@ -0,0 +1,2 @@
+62801,LIBERTIS,LIBERTIS

+62802,ETISALAT GAB,ETISALAT

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/29.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/29.txt
new file mode 100755
index 0000000..0529d58
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/29.txt
@@ -0,0 +1,2 @@
+62901,Airtel,Airtel

+62910,COG MTN,MTN-CG

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/30.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/30.txt
new file mode 100755
index 0000000..68fce9a
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/30.txt
@@ -0,0 +1,5 @@
+63001,Vodacom Congo,VODACOM

+63002,Airtel,Airtel

+63086,Orange RDC,Orange

+63089,TIGO DRC,TIGO

+63090,Africell RDC,AFRICELL

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/31.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/31.txt
new file mode 100755
index 0000000..a0e4e6e
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/31.txt
@@ -0,0 +1,2 @@
+63102,UNITEL,UNITEL

+63104,MOVICEL,AGOMV

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/32.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/32.txt
new file mode 100755
index 0000000..9400296
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/32.txt
@@ -0,0 +1,2 @@
+63202,MTN,MTN

+63203,Orange GB,OrangeGB

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/33.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/33.txt
new file mode 100755
index 0000000..8f7c70d
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/33.txt
@@ -0,0 +1,2 @@
+63301,C&W SEY,C&W SEY

+63310,Airtel,Airtel

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/34.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/34.txt
new file mode 100755
index 0000000..0d253a2
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/34.txt
@@ -0,0 +1,2 @@
+63401,Zain SDN,Zain SD

+63402,MTN,MTN

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/35.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/35.txt
new file mode 100755
index 0000000..d0736e6
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/35.txt
@@ -0,0 +1,2 @@
+63510,MTN RWANDA,MTN

+63514,Airtel,Airtel

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/36.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/36.txt
new file mode 100755
index 0000000..8ed6f4c
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/36.txt
@@ -0,0 +1 @@
+63601,ETH MTN,ET-MTN

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/37.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/37.txt
new file mode 100755
index 0000000..8cb3d28
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/37.txt
@@ -0,0 +1,3 @@
+63701,SO Telesom,Tele

+63730,Som Golis,Golis

+63750,Hormuud Telecom,Hormuud

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/38.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/38.txt
new file mode 100755
index 0000000..4084c06
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/38.txt
@@ -0,0 +1 @@
+63801,DJ EVATIS,EVATIS

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/39.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/39.txt
new file mode 100755
index 0000000..38eae29
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/39.txt
@@ -0,0 +1,4 @@
+63902,Safaricom,SAF-COM

+63903,Airtel,Airtel

+63907,Telkom,Telkom

+63910,FAIBA,FAIBA

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/40.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/40.txt
new file mode 100755
index 0000000..19247cb
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/40.txt
@@ -0,0 +1,4 @@
+64002,TIGO - TZ,TIGO

+64003,ZANTEL-TZ,ZANTEL

+64004,VodaCom,VodaCom

+64005,Airtel,Airtel

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/41.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/41.txt
new file mode 100755
index 0000000..ea82138
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/41.txt
@@ -0,0 +1,7 @@
+64101,Airtel,Airtel

+64104,UG TANG,TANG

+64110,MTN-UGANDA,MTN-UG

+64111,Uganda Telecom,UTL

+64114,Africell Uganda,AUL

+64118,Suretelcom,suretel

+64122,Airtel,Airtel

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/42.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/42.txt
new file mode 100755
index 0000000..218033a
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/42.txt
@@ -0,0 +1,3 @@
+64203,ONATEL BDI,ONATEL

+64207,SMART,SMART

+64282,TELECEL-BDI,BDITL

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/43.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/43.txt
new file mode 100755
index 0000000..6684dc1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/43.txt
@@ -0,0 +1,2 @@
+64301,MOZ - mCel,mCel

+64304,VodaCom-MZ,VodaCom

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/45.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/45.txt
new file mode 100755
index 0000000..51f1fea
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/45.txt
@@ -0,0 +1,3 @@
+64501,Airtel,Airtel

+64502,MTN ZM,MTN ZM

+64503,ZAMTEL,ZAMTEL

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/46.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/46.txt
new file mode 100755
index 0000000..20f67a1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/46.txt
@@ -0,0 +1,4 @@
+64601,Airtel,Airtel

+64602,Orange,Orange

+64604,TELMA,TELMA

+64605,Bip,Bip

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/47.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/47.txt
new file mode 100755
index 0000000..a700ec5
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/47.txt
@@ -0,0 +1,6 @@
+64700,Orange re,Orange

+64701,MAORE MOBILE,MMOBILE

+64702,TELCO OI,TELCO OI

+64703,FREE MOBILE RE,FREE RE

+64704,ZEOP,ZEOP

+64710,SRR,SRR

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/48.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/48.txt
new file mode 100755
index 0000000..9a81751
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/48.txt
@@ -0,0 +1,3 @@
+64801,ZW NET*ONE,NETONE

+64803,TELECEL ZW,TELECEL

+64804,ZW ECONET,ECONET

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/49.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/49.txt
new file mode 100755
index 0000000..711f429
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/49.txt
@@ -0,0 +1,2 @@
+64901,MTC NAMIBIA,MTCNAM

+64903,tnmobile,tnmobile

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/50.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/50.txt
new file mode 100755
index 0000000..7a706f1
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/50.txt
@@ -0,0 +1,2 @@
+65001,TNM,TNM

+65010,Airtel,Airtel

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/51.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/51.txt
new file mode 100755
index 0000000..4f77c01
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/51.txt
@@ -0,0 +1,2 @@
+65101,Vodacom Lesotho,VODACOM

+65102,LS-ETL,ETL

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/52.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/52.txt
new file mode 100755
index 0000000..ff0f16f
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/52.txt
@@ -0,0 +1,3 @@
+65201,BW MASCOM,MASCOM

+65202,Orange,Orange

+65204,BTC,BTC

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/53.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/53.txt
new file mode 100755
index 0000000..5e2926e
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/53.txt
@@ -0,0 +1,2 @@
+65302,Swazi Mobile,Swazi Mo

+65310,Swazi-MTN,SwaziMTN

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/54.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/54.txt
new file mode 100755
index 0000000..69cd469
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/54.txt
@@ -0,0 +1,2 @@
+65401,HURI,HURI

+65402,TELCO,COMTM

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/55.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/55.txt
new file mode 100755
index 0000000..8c2ea26
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/55.txt
@@ -0,0 +1,6 @@
+65501,VodaCom-SA,Vodacom

+65502,TelkomSA,Telkom

+65505,TelkomSA-R,Telkom-R

+65507,Cell C,Cell C

+65510,MTN-SA,MTN

+65538,rain,rain

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/57.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/57.txt
new file mode 100755
index 0000000..34b2108
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/57.txt
@@ -0,0 +1 @@
+65701,EriTel,EriTel
\ No newline at end of file
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/58.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/58.txt
new file mode 100755
index 0000000..b2ef780
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/58.txt
@@ -0,0 +1 @@
+65801,Sure,Sure

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/59.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/59.txt
new file mode 100755
index 0000000..42efdd6
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/6/59.txt
@@ -0,0 +1,2 @@
+65902,MTN,MTN

+65906,ZAIN SS,ZAIN SS

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/02.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/02.txt
new file mode 100755
index 0000000..c7b0715
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/02.txt
@@ -0,0 +1,2 @@
+70267,BTL,BTL

+70269,Smart,Smart

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/04.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/04.txt
new file mode 100755
index 0000000..0260d6c
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/04.txt
@@ -0,0 +1,3 @@
+70401,CLARO GTM,CLAROGTM

+70402,TIGO,TIGO

+70403,CLARO GTM,CLAROGTM

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/06.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/06.txt
new file mode 100755
index 0000000..690a8de
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/06.txt
@@ -0,0 +1,4 @@
+70601,CLARO SLV,ClaroSLV

+70602,Digicel,DIGICEL

+70603,Tigo SV,Tigo

+70604,Movistar,Movistar

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/08.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/08.txt
new file mode 100755
index 0000000..23b64dd
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/08.txt
@@ -0,0 +1,3 @@
+708001,CLARO HND,ClaroHND

+70802,TIGOHND,TIGO

+708030,HND,HT - 200

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/10.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/10.txt
new file mode 100755
index 0000000..90bc95c
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/10.txt
@@ -0,0 +1,3 @@
+71021,CLARO NIC,ClaroNIC

+710300,Movistar,Movistar

+71073,CLARO NIC,ClaroNIC

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/12.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/12.txt
new file mode 100755
index 0000000..c93711a
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/12.txt
@@ -0,0 +1,4 @@
+71201,I.C.E.,I.C.E.

+71202,I.C.E.,I.C.E.

+71203,CLARO CR,CLARO CR

+71204,Movistar,Movistar

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/14.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/14.txt
new file mode 100755
index 0000000..9236049
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/14.txt
@@ -0,0 +1,4 @@
+71401,+Movil - C&W PAN,PANCW

+714020,Movistar,Movistar

+71403,CLARO PA,CLARO PA

+71404,DIGICEL,DIGICEL

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/16.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/16.txt
new file mode 100755
index 0000000..d364fb9
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/16.txt
@@ -0,0 +1,4 @@
+71606,MOVISTAR,MOVISTAR

+71610,CLARO PER,ClaroPER

+71615,Viettel Peru,VTP

+71617,Entel,Entel

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/22.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/22.txt
new file mode 100755
index 0000000..2f7299c
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/22.txt
@@ -0,0 +1,5 @@
+722010,AR - TEFMVNO,TEFMVNO

+72207,AR - Movistar,Movistar

+722310,CLARO ARGENTINA,CLARO AR

+72234,AR PERSONAL,AR TP

+72236,AR PERSONAL,AR TP

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/24.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/24.txt
new file mode 100755
index 0000000..7ccac6b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/24.txt
@@ -0,0 +1,16 @@
+72402,TIM BRA,TIM

+72403,TIM BRA,TIM

+72404,TIM BRA,TIM

+72405,Claro BRA,Claro

+72406,VIVO,VIVO

+72410,VIVO,VIVO

+72411,VIVO,VIVO

+72415,BRA SCTL,SCTL

+72416,Oi,Oi

+72423,VIVO,VIVO

+72424,Oi,Oi

+72431,Oi,Oi

+72432,Algar Telecom,Algar

+72433,Algar Telecom,Algar

+72434,Algar Telecom,Algar

+72439,Nextel Brasil,Nextel

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/30.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/30.txt
new file mode 100755
index 0000000..d88b305
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/30.txt
@@ -0,0 +1,6 @@
+73001,ENTEL PCS,ENTEL

+73002,Movistar,Movistar

+73003,CLARO CHL,ClaroCHL

+73007,Movistar,Movistar

+73009,WOM,WOM

+73010,ENTEL PCS,ENTEL

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/32.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/32.txt
new file mode 100755
index 0000000..ea294e5
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/32.txt
@@ -0,0 +1,6 @@
+732101,Claro,Claro

+732103,TIGO,TIGO

+732111,TIGO,TIGO

+732123,Movistar,Movistar

+732130,Avantel,Avantel

+732187,ETB,ETB

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/34.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/34.txt
new file mode 100755
index 0000000..ab71574
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/34.txt
@@ -0,0 +1,3 @@
+73402,DIGITEL,DIGITEL

+73404,Movistar,Movistar

+73406,VE_MOVILNET,Movilnet

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/36.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/36.txt
new file mode 100755
index 0000000..42d1a0b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/36.txt
@@ -0,0 +1,3 @@
+73601,VIVA,VIVA

+73602,BOMOV,EMOVIL

+73603,TIGO,TIGO

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/38.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/38.txt
new file mode 100755
index 0000000..fbf2223
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/38.txt
@@ -0,0 +1,2 @@
+738002,GUY GTT + Do More,GTT+

+73801,Digicel,Digicel

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/40.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/40.txt
new file mode 100755
index 0000000..c82062e
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/40.txt
@@ -0,0 +1,3 @@
+74000,Movistar,Movistar

+74001,CLARO,CLARO

+74002,CNT,CNT

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/44.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/44.txt
new file mode 100755
index 0000000..48ef669
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/44.txt
@@ -0,0 +1,4 @@
+74401,HOLA PARAGUAY S.A.,HPGYSA

+74402,CLARO PY,CLARO PY

+74404,TIGO PY,TIGO

+74405,PY Personal,Personal

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/46.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/46.txt
new file mode 100755
index 0000000..66e535b
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/46.txt
@@ -0,0 +1,2 @@
+74602,SR.TELESUR.GSM,TeleG

+74603,DIGICEL,DIGICEL

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/48.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/48.txt
new file mode 100755
index 0000000..1ae5ace
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/48.txt
@@ -0,0 +1,3 @@
+74801,Antel,Antel

+74807,Movistar,Movistar

+74810,CLARO URUGUAY,CLARO UY

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/50.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/50.txt
new file mode 100755
index 0000000..5241670
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/7/50.txt
@@ -0,0 +1 @@
+750001,Sure FLK,Sure

diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/9/01.txt b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/9/01.txt
new file mode 100755
index 0000000..29f83a6
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/mddata/plmn/TS25/9/01.txt
@@ -0,0 +1,9 @@
+90111,Inmarsat,INX

+90112,Telenor Maritime,TelenorM

+90114,AeroMobile,AeroMob

+90115,OnAir,OnAir

+90126,TIM@sea,TIM@sea

+90144,AT&T,AT&T

+90145,AISatSea,AISatSea

+90146,Telecom26,T26

+90150,EchoStar Mobile,EML
\ No newline at end of file
diff --git a/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/modem.img b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/modem.img
new file mode 100644
index 0000000..3857613
--- /dev/null
+++ b/prebuilt/modem/mt2735/MT2735_V02.MP1_MR3_NLWG_P4_20230328/modem.img
Binary files differ
diff --git a/src/bsp/lk/platform/mt2735/drivers/gpio/mt_gpio.c b/src/bsp/lk/platform/mt2735/drivers/gpio/mt_gpio.c
index 38c9470..ad804ad 100755
--- a/src/bsp/lk/platform/mt2735/drivers/gpio/mt_gpio.c
+++ b/src/bsp/lk/platform/mt2735/drivers/gpio/mt_gpio.c
@@ -798,6 +798,14 @@
 	/* GPIO202 */
     //you.chen2022/4/8 modify for wifi gpio start
 	//mt_set_gpio_mode(GPIO202, 3);
+	mt_set_gpio_mode(GPIO202, 0);
+	mt_set_gpio_dir(GPIO202, GPIO_DIR_OUT);
+	mt_set_gpio_out(GPIO202, GPIO_OUT_ZERO);
+	mt_set_gpio_mode(GPIO182, 0);
+	mt_set_gpio_dir(GPIO182, GPIO_DIR_OUT);
+	mt_set_gpio_out(GPIO182, GPIO_OUT_ONE);
+    //you.chen2022/4/8 modify for wifi gpio end
+	//mt_set_gpio_mode(GPIO202, 3);
 #endif
 	
 #ifdef MOBILETEK_PLATFORM_GPIO
@@ -811,7 +819,7 @@
 #ifdef MOBILETEK_PLATFORM_GPIO
 	mt_set_gpio_mode(GPIO202, 3);
 #endif
-	
+
 #ifdef GENVICT_GPIO
 	//you.chen@2022-07-19 add for wifi gpio begin
 	mt_set_gpio_mode(GPIO202, 0);
diff --git a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/spm/mt_spm_suspend.c b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/spm/mt_spm_suspend.c
index 1a3263f..2638448 100644
--- a/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/spm/mt_spm_suspend.c
+++ b/src/bsp/trustzone/atf/v1.6/mt2xxx/plat/mediatek/mt2735/drivers/spm/mt_spm_suspend.c
@@ -27,9 +27,10 @@
 	(SPM_FLAG_DISABLE_VCORE_DFS) | \
 	(SPM_FLAG_ENABLE_LVTS_WORKAROUND) | \
 	(SPM_FLAG_ENABLE_PCIE_0P6V_WORKAROUND) | \
+	(SPM_FLAG_ENABLE_MD_MUMTAS) | \
 	(SPM_FLAG_USE_SRCCLKENO2) | \
 	(SPM_FLAG_NETSYS_DVFS_ENABLE))
-
+//jb.qi change for abnormal resume on 20230328
 #define SPM_SUSPEND_SLEEP_PCM_FLAG1		(0)
 
 #define SPM_SUSPEND_PCM_FLAG	( \
@@ -37,8 +38,9 @@
 	(SPM_FLAG_DISABLE_VCORE_DFS) | \
 	(SPM_FLAG_ENABLE_LVTS_WORKAROUND) | \
 	(SPM_FLAG_ENABLE_PCIE_0P6V_WORKAROUND) | \
+	(SPM_FLAG_ENABLE_MD_MUMTAS) | \
 	(SPM_FLAG_NETSYS_DVFS_ENABLE))
-
+//jb.qi change for abnormal resume on 20230328
 #define SPM_SUSPEND_PCM_FLAG1		(0)
 
 /* Suspend spm power control */
diff --git a/src/connectivity/gps/2.0/mtk_mnld/mnld_entity/src/epo.c b/src/connectivity/gps/2.0/mtk_mnld/mnld_entity/src/epo.c
index 1516179..5d59ddf 100644
--- a/src/connectivity/gps/2.0/mtk_mnld/mnld_entity/src/epo.c
+++ b/src/connectivity/gps/2.0/mtk_mnld/mnld_entity/src/epo.c
@@ -1253,8 +1253,8 @@
         }
 
         curl_easy_setopt(curl, CURLOPT_URL, url);
-        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
-        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
+        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
+        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 1L);
         curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
         curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60);
         //   curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
diff --git a/src/kernel/linux/v4.19/arch/arm64/configs/auto2735evb_defconfig b/src/kernel/linux/v4.19/arch/arm64/configs/auto2735evb_defconfig
index a9c4cc4..e6722bb 100644
--- a/src/kernel/linux/v4.19/arch/arm64/configs/auto2735evb_defconfig
+++ b/src/kernel/linux/v4.19/arch/arm64/configs/auto2735evb_defconfig
@@ -67,6 +67,7 @@
 CONFIG_BCMDHD=m
 CONFIG_CYW89570=y
 CONFIG_RFKILL=y
+CONFIG_BCMDHD_WPA3=y
 #tianyan@2021.10.15 modify for open wifi6 module end
 #tianyan@2021.10.15 modify for open wifi5 module start
 CONFIG_WLAN=y
diff --git a/src/kernel/linux/v4.19/arch/arm64/configs/auto2735evb_gsw_defconfig b/src/kernel/linux/v4.19/arch/arm64/configs/auto2735evb_gsw_defconfig
index 2e4d997..08eb9a9 100755
--- a/src/kernel/linux/v4.19/arch/arm64/configs/auto2735evb_gsw_defconfig
+++ b/src/kernel/linux/v4.19/arch/arm64/configs/auto2735evb_gsw_defconfig
@@ -67,6 +67,7 @@
 CONFIG_BCMDHD=m
 CONFIG_CYW89570=y
 CONFIG_RFKILL=y
+CONFIG_BCMDHD_WPA3=y
 #tianyan@2021.10.15 modify for open wifi6 module end
 #tianyan@2021.10.15 modify for open wifi5 module start
 CONFIG_WLAN=y
diff --git a/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/hif/ccci_hif_ccif.c b/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/hif/ccci_hif_ccif.c
index c00d4f7..0e491ff 100644
--- a/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/hif/ccci_hif_ccif.c
+++ b/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/hif/ccci_hif_ccif.c
@@ -202,8 +202,7 @@
 		i += 4;
 	}
 
-	if (atomic_cmpxchg(&md_ctrl->wakeup_src, 1, 0) == 1) {
-		md_ctrl->wakeup_count++;
+	if (test_and_clear_bit((D2H_SRAM), &md_ctrl->wakeup_ch)) { //jb.qi change for abnormal resume on 20230328
 		CCCI_NOTICE_LOG(md_ctrl->md_id, TAG,
 			"CCIF_MD wakeup source:(SRX_IDX/%d)(%u)\n",
 			ccci_h->channel, md_ctrl->wakeup_count);
@@ -375,12 +374,15 @@
 		}
 		ccci_h = (struct ccci_header *)skb->data;
 
-		if (atomic_cmpxchg(&md_ctrl->wakeup_src, 1, 0) == 1) {
-			md_ctrl->wakeup_count++;
+		if (test_and_clear_bit(queue->index, &md_ctrl->wakeup_ch)) { //jb.qi change for abnormal resume on 20230328
 			CCCI_NOTICE_LOG(md_ctrl->md_id, TAG,
 				"CCIF_MD wakeup source:(%d/%d/%x)(%u)\n",
 				queue->index, ccci_h->channel,
 				ccci_h->reserved, md_ctrl->wakeup_count);
+			/*jb.qi change for abnormal resume start on 20230328*/
+			if (ccci_h->channel == CCCI_FS_RX)
+				ccci_h->data[0] |= CCCI_FS_AP_CCCI_WAKEUP;
+			/*jb.qi change for abnormal resume end on 20230328*/
 		}
 
 		ccci_hdr = *ccci_h;
@@ -713,8 +715,7 @@
 	if (md_ctrl->channel_id & (1 << AP_MD_CCB_WAKEUP)) {
 		clear_bit(AP_MD_CCB_WAKEUP, &md_ctrl->channel_id);
 		CCCI_DEBUG_LOG(md_ctrl->md_id, TAG, "CCB wakeup\n");
-		if (atomic_cmpxchg(&md_ctrl->wakeup_src, 1, 0) == 1) {
-			md_ctrl->wakeup_count++;
+		if (test_and_clear_bit(AP_MD_CCB_WAKEUP, &md_ctrl->wakeup_ch)) { //jb.qi change for abnormal resume on 20230328
 			CCCI_NOTICE_LOG(md_ctrl->md_id, TAG,
 			"CCIF_MD wakeup source:(CCB)(%u)\n",
 			md_ctrl->wakeup_count);
@@ -1259,7 +1260,7 @@
 	md_ctrl->md_id = md_id;
 	md_ctrl->hif_id = hif_id;
 	atomic_set(&md_ctrl->reset_on_going, 1);
-	atomic_set(&md_ctrl->wakeup_src, 0);
+	md_ctrl->wakeup_ch = 0; //jb.qi change for abnormal resume on 20230328
 	ccci_reset_seq_num(&md_ctrl->traffic_info);
 
 	/*init queue */
diff --git a/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/hif/ccci_hif_ccif.h b/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/hif/ccci_hif_ccif.h
index e79c0c0..29b2286 100644
--- a/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/hif/ccci_hif_ccif.h
+++ b/src/kernel/linux/v4.19/drivers/misc/mediatek/eccci/hif/ccci_hif_ccif.h
@@ -21,7 +21,11 @@
 #else
 #define QUEUE_NUM   8
 #endif
-
+/*jb.qi change for abnormal resume start on 20230328*/
+/* speciall for user: ccci_fsd data[0] */
+#define CCCI_FS_AP_CCCI_WAKEUP (0x40000000)
+#define CCCI_FS_REQ_SEND_AGAIN 0x80000000
+/*jb.qi change for abnormal resume end on 20230328*/
 /*#define FLOW_CTRL_ENABLE*/
 #define FLOW_CTRL_HEAD		0x464C4F57	/*FLOW*/
 #define FLOW_CTRL_TAIL		0x4354524C	/*CTRL*/
@@ -91,7 +95,7 @@
 	struct timer_list bus_timeout_timer;
 	void __iomem *ccif_ap_base;
 	void __iomem *ccif_md_base;
-	atomic_t wakeup_src;
+	unsigned long wakeup_ch; //jb.qi change for abnormal resume on 20230328
 	unsigned int wakeup_count;
 
 	struct work_struct wdt_work;
@@ -229,9 +233,18 @@
 {
 	struct md_ccif_ctrl *md_ctrl =
 		(struct md_ccif_ctrl *)ccci_hif_get_by_id(hif_id);
-
-	if (md_ctrl)
-		return atomic_set(&md_ctrl->wakeup_src, value);
+	unsigned int ccif_ch = 0; //jb.qi change for abnormal resume on 20230328
+	/*jb.qi change for abnormal resume start on 20230328 */
+	if (md_ctrl) {
+		ccif_ch = ccif_read32(md_ctrl->ccif_ap_base, APCCIF_RCHNUM);
+		pr_notice("[ccci1/cif] CCIF wakeup channel: 0x%x\n", ccif_ch);
+		if (value == 1) {
+			md_ctrl->wakeup_ch = ccif_ch;
+			md_ctrl->wakeup_count++;
+		}
+		return value;
+	}
+	/*jb.qi change for abnormal resume end on 20230328 */
 	else
 		return -1;
 }
diff --git a/src/kernel/linux/v4.19/drivers/misc/mediatek/wakeup_dtr/wakeup_dtr.c b/src/kernel/linux/v4.19/drivers/misc/mediatek/wakeup_dtr/wakeup_dtr.c
index d361274..6efba68 100644
--- a/src/kernel/linux/v4.19/drivers/misc/mediatek/wakeup_dtr/wakeup_dtr.c
+++ b/src/kernel/linux/v4.19/drivers/misc/mediatek/wakeup_dtr/wakeup_dtr.c
@@ -235,7 +235,7 @@
 static int wakeup_dtr_suspend(struct platform_device *dev,pm_message_t state)
 {
 	printk("wakeup_dtr_suspend\n");
-	gpio_set_value(wakeup_ri,1);
+	//gpio_set_value(wakeup_ri,1); jb.qi add for fix gpio ring status on 20230401
 	if(device_may_wakeup(&dev->dev)){
 		enable_irq_wake(wakeup_irq);
 	}
@@ -247,7 +247,7 @@
 static int wakeup_dtr_resume(struct platform_device *dev)
 {
 	printk("wakeup_dtr_resume\n");
-	gpio_set_value(wakeup_ri,0);
+	//gpio_set_value(wakeup_ri,0); jb.qi add for fix gpio ring status on 20230401
 	if(device_may_wakeup(&dev->dev)){
 		printk("tianyan add wakeup_dtr_resume device_may_wakeup\n");
 		disable_irq_wake(wakeup_irq);
diff --git a/src/kernel/linux/v4.19/drivers/net/phy/marvell-88q.c b/src/kernel/linux/v4.19/drivers/net/phy/marvell-88q.c
index 9010740..ab00fb0 100755
--- a/src/kernel/linux/v4.19/drivers/net/phy/marvell-88q.c
+++ b/src/kernel/linux/v4.19/drivers/net/phy/marvell-88q.c
@@ -232,6 +232,7 @@
 {
     //xf.li 2022/11/9 modify for API-647
     printk("phy sleep start\n");
+    gpio_direction_output(205 + 268, 0);
     gpio_direction_output(NAD_WAKEUP_PHY1, 0);
     mdelay(1);//ensure do not wake up
     //phy_write(phydev, MII_ADDR_C45 | 0x038022, 0x1);
@@ -255,13 +256,15 @@
     if(if_suspend == 1)
     {
         printk("phy awake start\n");
+	gpio_direction_output(205 + 268, 1);
         gpio_direction_output(PHY_POWER_SUPPLY, 1);
         mdelay(1);
         gpio_direction_output(NAD_WAKEUP_PHY1, 1);
-        udelay(1100);
+        mdelay(1000);
         gpio_direction_output(NAD_WAKEUP_PHY1, 0);
         mdelay(1);
         gpio_direction_output(NAD_RESET_PHY1, 1);
+        gpio_direction_output(205 + 268, 0);
         mdelay(10);//at lest 4ms for reset phy
         q2110_config_init(phydev);
 	if_suspend = 0;
diff --git a/src/kernel/linux/v4.19/drivers/net/phy/mdio_bus.c b/src/kernel/linux/v4.19/drivers/net/phy/mdio_bus.c
index c5588d4..5b1d466 100644
--- a/src/kernel/linux/v4.19/drivers/net/phy/mdio_bus.c
+++ b/src/kernel/linux/v4.19/drivers/net/phy/mdio_bus.c
@@ -384,7 +384,10 @@
 	}
 
 	mutex_init(&bus->mdio_lock);
-
+#ifdef PHY_DRIVER_GSW
+	gpio_direction_output(205 + 268, 1);
+	printk("----------INIT GPIO 205 END----------");
+#endif
 	/* de-assert bus level PHY GPIO reset */
 	gpiod = devm_gpiod_get_optional(&bus->dev, "reset", GPIOD_OUT_LOW);
 	if (IS_ERR(gpiod)) {
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/Kconfig b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/Kconfig
index 29835c5..3b046c4 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/Kconfig
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/Kconfig
@@ -7,7 +7,7 @@
 
 config BCMDHD
 	tristate "Broadcom FullMAC wireless cards support"
-	---help---
+	help
 	  This module adds support for wireless adapters based on
 	  Broadcom FullMAC chipset.
 
@@ -60,20 +60,20 @@
 	depends on BCMDHD
 	string "Firmware path"
 	default "/system/vendor/firmware/fw_bcmdhd.bin"
-	---help---
+	help
 	  Path to the firmware file.
 
 config BCMDHD_NVRAM_PATH
 	depends on BCMDHD
 	string "NVRAM path"
 	default "/system/etc/wifi/bcmdhd.cal"
-	---help---
+	help
 	  Path to the calibration file.
 
 config BROADCOM_WIFI_RESERVED_MEM
 	bool "BROADCOM Reserved memory for wifi device"
 	depends on BCMDHD
-	---help---
+	help
 	  This is a configuration for Broadcom WLAN driver.
 
 config BCMDHD_WEXT
@@ -88,28 +88,28 @@
 	bool "Enable memory preallocation"
 	depends on BCMDHD
 	default n
-	---help---
+	help
 	  Use memory preallocated in platform
 
 config DHD_USE_SCHED_SCAN
 	bool "Use CFG80211 sched scan"
 	depends on BCMDHD && CFG80211
 	default n
-	---help---
+	help
 	  Use CFG80211 sched scan
 
 config DHD_SET_RANDOM_MAC_VAL
 	hex "Vendor OUI"
 	depends on BCMDHD
 	default 0x001A11
-	---help---
+	help
 	  Set vendor OUI for SoftAP
 
 config WLAN_REGION_CODE
 	int "---Region codes for Broadcom WiFi Driver"
 	depends on BCMDHD
 	default 100
-	---help---
+	help
 		This is a region code for Broadcom Wi-Fi featured functions.
 		- 100 : EUR OPEN
 		- 101 : EUR ORG
@@ -123,58 +123,58 @@
 	bool "Advanced IBSS mode"
 	depends on (BCM4335 || BCM4339 || BCM4354 || BCM4358 || BCM4359 || BCM4361)
 	default y
-	---help---
+	help
 	  This is a configuration for Oxygen Network.
 
 config WL_RELMCAST
 	bool "Reliable Multicast Support"
 	depends on (BCM4335 || BCM4339 || BCM4354 || BCM4358 || BCM4359 || BCM4361)
 	default y
-	---help---
+	help
 	  This is a configuration for RMC.
 
 config WL_NAN
 	bool "NAN Feature"
 	depends on BCMDHD
 	default n
-	---help---
+	help
 	  This is a configuration for NAN Feature.
 
 config WL_AP_IF
 	bool "Create additional AP interface during intialization"
 	default n
-	---help---
+	help
 	  Create additional AP interface during initialization.
 
 config BCMDHD_PREALLOC_PKTIDMAP
 	bool "BROADCOM PCIE specific memory reserved for PKTIDMAP"
 	depends on BROADCOM_WIFI_RESERVED_MEM && BCMDHD_PCIE
-	---help---
+	help
 	  Preallocated memory support for PCIE interface in Broadcom
 	  WLAN driver.
 
 config BCMDHD_PREALLOC_MEMDUMP
 	bool "BROADCOM PCIE specific memory reserved for MEMDUMP"
 	depends on BROADCOM_WIFI_RESERVED_MEM
-	---help---
+	help
 	  Preallocated memory support for dongle memory dump
 
 config BCMDHD_OOB_HOST_WAKE
         bool "Use the external WLAN_HOST_WAKE pin"
         depends on BCMDHD
-        ---help---
+        help
           Use the external GPIO pin to wake up host
 
 config BCMDHD_GET_OOB_STATE
         bool "Support WLAN_HOST_WAKE pin level information"
         depends on BCMDHD_OOB_HOST_WAKE
         default y
-        ---help---
+        help
           Support WLAN_HOST_WAKE pin level information
 
 config BCMDHD_WPA3
 	bool "Support WPA3 feature"
 	depends on BCMDHD
 	default n
-	---help---
+	help
 	  This will enable WPA3 support
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/Makefile b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/Makefile
index 6507e16..bbfd16e 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/Makefile
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/Makefile
@@ -1,8 +1,8 @@
 # bcmdhd
 #
-# Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+# Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
 #
-# Copyright (C) 1999-2017, Broadcom Corporation
+# Copyright (C) 1999-2016, Broadcom Corporation
 #
 #      Unless you and Broadcom execute a separate written software license
 # agreement governing use of this software, this software is licensed to you
@@ -39,12 +39,16 @@
 	-DGET_CUSTOM_MAC_ENABLE      \
 	-DSEC_ENHANCEMENT -DDHD_FW_COREDUMP -DCHIPS_CUSTOMER_HW6	\
 	-DDHD_RND_DEBUG -DDHD_DUMP_FILE_WRITE_FROM_KERNEL		\
-	-DDHD_DONOT_FORWARD_BCMEVENT_AS_NETWORK_PKT -DWL11AX
+	-DDHD_DONOT_FORWARD_BCMEVENT_AS_NETWORK_PKT
 
 GCCVERSIONGTEQ9 := $(shell expr `$(CROSS_COMPILE)gcc -dumpversion | cut -f1 -d.` \>= 9)
 ifeq "$(GCCVERSIONGTEQ9)" "1"
     DHDCFLAGS += -Wno-error=date-time
 endif
+GCCVERSIONGTEQ7 := $(shell expr `$(CROSS_COMPILE)gcc -dumpversion | cut -f1 -d.` \>= 7)
+ifeq "$(GCCVERSIONGTEQ7)" "1"
+    DHDCFLAGS += -Wimplicit-fallthrough=3
+endif
 DHDCFLAGS += $(call cc-disable-warning, date-time)
 DHDCFLAGS += $(call cc-disable-warning, stringop-overflow)
 
@@ -115,6 +119,12 @@
 # keepalive
 DHDCFLAGS += -DCUSTOM_KEEP_ALIVE_SETTING=28000
 
+#OCE enable/disable in dhd
+DHDCFLAGS += -DOCE_SUPPORT
+
+#OWE enable in dhd
+DHDCFLAGS += -DWL_OWE
+
 DHDCFLAGS += -DVSDB
 
 # For p2p connection issue
@@ -146,10 +156,10 @@
 DHDCFLAGS += -DDHD_LOSSLESS_ROAMING
 
 # Hog flags
-#DHDCFLAGS += -DENABLE_HOGSQS
-#ifeq ($(ENABLE_HOGSQS), y)
-#DHDCFLAGS += -DM_HOGSQS_CFG=0x1910
-#endif // endif
+ifeq ($(CONFIG_ENABLE_HOGSQS), y)
+DHDCFLAGS += -DENABLE_HOGSQS
+DHDCFLAGS += -DM_HOGSQS_CFG=0x1910
+endif
 
 # For special PNO Event keep wake lock for 10sec
 DHDCFLAGS += -DCUSTOM_PNO_EVENT_LOCK_xTIME=10
@@ -218,14 +228,23 @@
   DHDCFLAGS += -DKEEP_WIFION_OPTION
   DHDCFLAGS += -Wno-date-time
 
-# To support android12 Wifi-HAL
-ifeq ($(CONFIG_ANDROID12),y)
- DHDCFLAGS += -DANDROID12_SUPPORT
-endif
+#Android features
+ifeq ($(shell expr $(CONFIG_ANDROID_VERSION) \>= 12), 1)
+ DHDCFLAGS += -DCONFIG_ANDROID_VERSION=$(CONFIG_ANDROID_VERSION)
+ DHDCFLAGS += -DP2P_RAND
+ DHDCFLAGS += -DSOFTAP_RAND
+#To support Android12 CDD [C-1-7] [C-1-8] [C-1-9] [C-1-10]
+ DHDCFLAGS += -DSUPPORT_RANDOM_MAC_SCAN
+
+#To support recovery
+ DHDCFLAGS += -DWL_CFGVENDOR_SEND_HANG_EVENT
+
+ DHDCFLAGS += -DWL_SELF_MANAGED_REGDOM
 
 # To support ACS on hostapd
 # DHDCFLAGS += -DWL_SUPPORT_ACS_OFFLOAD
 endif
+endif
 
 # SoftAP
 DHDCFLAGS += -DSET_RANDOM_MAC_SOFTAP
@@ -255,11 +274,18 @@
 DHDCFLAGS += -DDHD_4WAYM4_FAIL_DISCONNECT
 endif
 
-#6Ghz
-ifneq ($(CONFIG_BCMDHD_6E),)
+#802.11ax and 6Ghz Support
+ifeq ($(CONFIG_BCMDHD_WIFI6_6E),y)
+ DHDCFLAGS += -DWL11AX
  DHDCFLAGS += -DWL_6E
 endif
 
+#IFX cfg80211 support
+ifeq ($(CONFIG_BCMDHD_IFX_CFG80211),y)
+ #For 5.4.21 kernel
+ DHDCFLAGS += -DIFX_CFG80211_5_4_21
+endif
+
 # Uncomment the below line for AP to receive disconnect management frame.
 # DHDCFLAGS += -DWL_CFG80211_AP_RX_MGMT_DISCONNECT
 
@@ -375,7 +401,9 @@
 ifeq ($(CONFIG_DHD_USE_STATIC_BUF),y)
   DHDCFLAGS += -DDHD_USE_STATIC_IOCTLBUF
 endif
-
+ifeq ($(CONFIG_BCMDHD_COHERENT_MEM_RING),y)
+DHDCFLAGS += -DDHD_USE_COHERENT_MEM_FOR_RING
+endif
 # Enable health check event handling
   DHDCFLAGS += -DDNGL_EVENT_SUPPORT
   DHDCFLAGS += -DHCHK_COMMON_SW_EVENT
@@ -497,10 +525,9 @@
 endif
 
 #EXTRA_LDFLAGS += --strip-debug
-#tianyan
+#qs.xiong
 DHDCFLAGS += -Wno-array-bounds -Wno-sizeof-pointer-memaccess -Wno-unused-function
 
-
 ifeq ($(DRIVER_TYPE),y)
   DHDCFLAGS += -DENABLE_INSMOD_NO_FW_LOAD
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
@@ -516,7 +543,7 @@
     dhd_pno.o dhd_linux_pktdump.o wl_cfg_btcoex.o hnd_pktq.o \
     hnd_pktpool.o wl_cfgvendor.o bcmxtlv.o bcm_app_utils.o dhd_debug.o \
     dhd_debug_linux.o dhd_mschdbg.o bcmbloom.o dhd_dbg_ring.o bcmstdlib_s.o \
-    dhd_linux_exportfs.o
+    dhd_linux_exportfs.o wl_twt.o
 
 ifneq ($(CONFIG_DHD_MONITOR_INTERFACE),)
     DHDCFLAGS += -DDHD_MONITOR_INTERFACE
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/aiutils.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/aiutils.c
old mode 100644
new mode 100755
index 328f836..798fd10
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/aiutils.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/aiutils.c
@@ -2,9 +2,9 @@
  * Misc utility routines for accessing chip-specific features
  * of the SiliconBackplane-based Broadcom chips.
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcm_app_utils.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcm_app_utils.c
old mode 100644
new mode 100755
index ec4b9dc..393e132
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcm_app_utils.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcm_app_utils.c
@@ -3,9 +3,9 @@
  * Contents are wifi-specific, used by any kernel or app-level
  * software that might want wifi things as it grows.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmbloom.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmbloom.c
old mode 100644
new mode 100755
index 94e0e3c..e06b1ce
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmbloom.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmbloom.c
@@ -1,9 +1,9 @@
 /*
  * Bloom filter support
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -31,9 +31,6 @@
 
 #include <typedefs.h>
 #include <bcmdefs.h>
-
-#include <stdarg.h>
-
 #ifdef BCMDRIVER
 #include <osl.h>
 #include <bcmutils.h>
@@ -44,6 +41,7 @@
 #define ASSERT(exp)
 #endif // endif
 #endif /* !BCMDRIVER */
+#include <stdarg.h>
 #include <bcmutils.h>
 
 #include <bcmbloom.h>
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmevent.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmevent.c
old mode 100644
new mode 100755
index 1e5a250..8f0c74c
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmevent.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmevent.c
@@ -1,9 +1,9 @@
 /*
  * bcmevent read-only data shared by kernel or app layers
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdh.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdh.c
index f27c1c2..540ea20 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdh.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdh.c
@@ -2,9 +2,9 @@
  *  BCMSDH interface glue
  *  implement bcmsdh API for SDIOH driver
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdh_linux.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdh_linux.c
old mode 100644
new mode 100755
index 7173f1b..635041f
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdh_linux.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdh_linux.c
@@ -1,9 +1,9 @@
 /*
  * SDIO access interface for drivers - linux specific (pci only)
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -311,6 +311,12 @@
 	bcmsdh_unregister_client_driver();
 }
 
+void *bcmsdh_get_dev(bcmsdh_info_t *sdh)
+{
+	bcmsdh_os_info_t *bcmsdh_osinfo = sdh->os_cxt;
+	return bcmsdh_osinfo->dev;
+}
+
 void bcmsdh_dev_pm_stay_awake(bcmsdh_info_t *bcmsdh)
 {
 #if (!defined(CONFIG_PM_WAKELOCKS) || !defined(CONFIG_HAS_WAKELOCK)) && \
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c
old mode 100644
new mode 100755
index ede9593..a0bee0c
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c
@@ -1,9 +1,9 @@
 /*
  * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
old mode 100644
new mode 100755
index 149f2da..b0e401d
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
@@ -1,9 +1,9 @@
 /*
  * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -191,6 +191,10 @@
 	{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43014_D11N2G_ID) },
 	{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43014_D11N5G_ID) },
 	{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM4373_CHIP_ID) },
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43430_CHIP_ID) },
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43439_CHIP_ID) },
+	{ SDIO_DEVICE(CY_DNGL_VID, BCM43439_CHIP_ID) },
+	{ SDIO_DEVICE(CY_DNGL_VID, BCM_DNGL_BL_PID_43439) },
 	/* { SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_ANY_ID) }, */
 	 /* end: all zeroes */
 	{ 0, 0, 0, 0},
@@ -272,7 +276,8 @@
 	if (id) {
 		sd_err(("%s: class=0x%x; vendor=0x%x; device=0x%x\n", __FUNCTION__,
 			id->class, id->vendor, id->device));
-		if (id->vendor != SDIO_VENDOR_ID_BROADCOM)
+		if ((id->vendor != SDIO_VENDOR_ID_BROADCOM) &&
+			(id->vendor != CY_DNGL_VID))
 				return -ENODEV;
 	}
 	if (func && (func->num != 2)) {
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdspi_linux.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdspi_linux.c
old mode 100644
new mode 100755
index eef1190..b13ed80
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdspi_linux.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdspi_linux.c
@@ -1,9 +1,9 @@
 /*
  * Broadcom SPI Host Controller Driver - Linux Per-port
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -43,7 +43,11 @@
 #include <pcicfg.h>
 #include <sdio.h>		/* SDIO Device and Protocol Specs */
 #include <linux/sched.h>	/* request_irq(), free_irq() */
+#ifndef GSPIBCM
 #include <bcmsdspi.h>
+#else
+#include <bcmgspi.h>
+#endif /* GSPIBCM */
 #include <bcmdevs.h>
 #include <bcmspi.h>
 #endif /* BCMSPI_ANDROID */
@@ -147,7 +151,6 @@
 {
 	osl_t *osh = NULL;
 	sdioh_info_t *sdioh = NULL;
-	void *bcmsdh;
 
 	int rc;
 
@@ -231,13 +234,8 @@
 		goto err;
 	}
 
-#ifdef GSPIBCM
-	bcmsdh = bcmsdh_probe(osh, &pdev->dev, sdioh, NULL, PCI_BUS, -1, -1);
-	if (bcmsdh == NULL) {
-#else
 	sdioh->bcmsdh = bcmsdh_probe(osh, &pdev->dev, sdioh, NULL, PCI_BUS, -1, -1);
 	if (sdioh->bcmsdh == NULL) {
-#endif /* GSPIBCM */
 		sd_err(("%s: bcmsdh_probe failed\n", __FUNCTION__));
 		goto err;
 	}
@@ -272,6 +270,7 @@
 	}
 
 	osh = sdioh->osh;
+
 	bcmsdh_remove(sdioh->bcmsdh);
 	sdioh_detach(osh, sdioh);
 	osl_detach(osh);
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdstd.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdstd.c
old mode 100644
new mode 100755
index 104b3c3..193d12a
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdstd.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdstd.c
@@ -1,9 +1,9 @@
 /*
  *  'Standard' SDIO HOST CONTROLLER driver
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdstd_linux.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdstd_linux.c
old mode 100644
new mode 100755
index 0d39c6d..4b5cfbb
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdstd_linux.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmsdstd_linux.c
@@ -1,9 +1,9 @@
 /*
  *  'Standard' SDIO HOST CONTROLLER driver - linux portion
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmspibrcm.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmspibrcm.c
old mode 100644
new mode 100755
index c7ba27b..354bd04
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmspibrcm.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmspibrcm.c
@@ -1,9 +1,9 @@
 /*
  * Broadcom BCMSDH to gSPI Protocol Conversion Layer
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmstdlib_s.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmstdlib_s.c
old mode 100644
new mode 100755
index 12d8984..9ce39cf
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmstdlib_s.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmstdlib_s.c
@@ -1,9 +1,9 @@
 /*
  * Broadcom Secure Standard Library.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmutils.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmutils.c
old mode 100644
new mode 100755
index 9021aea..f026432
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmutils.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmutils.c
@@ -1,9 +1,9 @@
 /*
  * Driver O/S-independent utility routines
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -32,7 +32,6 @@
 #include <bcm_cfg.h>
 #include <typedefs.h>
 #include <bcmdefs.h>
-#include <stdarg.h>
 #ifdef BCMDRIVER
 #include <osl.h>
 #include <bcmutils.h>
@@ -53,7 +52,7 @@
 #endif // endif
 
 #endif /* !BCMDRIVER */
-
+#include <stdarg.h>
 #ifdef WL_UNITTEST
 #ifdef ASSERT
 #undef ASSERT
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_channels.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_channels.c
old mode 100644
new mode 100755
index 18747aa..d242b6c
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_channels.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_channels.c
@@ -3,9 +3,9 @@
  * Contents are wifi-specific, used by any kernel or app-level
  * software that might want wifi things as it grows.
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -835,6 +835,11 @@
 			}
 		}
 	}
+#ifdef WL_6E
+	else if (CHSPEC_IS6G(chanspec)) {
+		return TRUE;
+	}
+#endif /* WL_6E */
 
 	return FALSE;
 }
@@ -1012,6 +1017,61 @@
 	return chspec;
 }
 
+#ifdef WL_6E
+/* return chanspec for 6E given primary 20MHz channel and bandwidth
+ * return 0 on error. Below separate func added for 6E as 6ghz channels
+ * overlap with legacy bands and there was no way in older func to
+ * differentiate this through just channel number and bw.
+ */
+uint16
+wf_channel2chspec6E(uint pri_ch, uint bw)
+{
+	uint16 chspec = 0;
+	const uint8 *center_ch = NULL;
+	int num_ch = 0;
+	int sb = -1;
+	int i = 0;
+
+	chspec = WL_CHANSPEC_BAND_6G;
+	chspec |= bw;
+
+	if (bw == WL_CHANSPEC_BW_40) {
+		center_ch = wf_6g_40m_chans;
+		num_ch = WF_NUM_6G_40M_CHANS;
+		bw = 40;
+	} else if (bw == WL_CHANSPEC_BW_80) {
+		center_ch = wf_6g_80m_chans;
+		num_ch = WF_NUM_6G_80M_CHANS;
+		bw = 80;
+	} else if (bw == WL_CHANSPEC_BW_160) {
+		center_ch = wf_6g_160m_chans;
+		num_ch = WF_NUM_6G_160M_CHANS;
+		bw = 160;
+	} else if (bw == WL_CHANSPEC_BW_20) {
+		chspec |= pri_ch;
+		return chspec;
+	} else {
+		return 0;
+	}
+
+	for (i = 0; i < num_ch; i ++) {
+		sb = channel_to_sb(center_ch[i], pri_ch, bw);
+		if (sb >= 0) {
+			chspec |= center_ch[i];
+			chspec |= (sb << WL_CHANSPEC_CTL_SB_SHIFT);
+			break;
+		}
+	}
+
+	/* check for no matching sb/center */
+	if (sb < 0) {
+		return 0;
+	}
+
+	return chspec;
+}
+#endif /* WL_6E */
+
 /*
  * This function returns the chanspec for the primary 40MHz of an 80MHz or wider channel.
  * The primary 20MHz channel of the returned 40MHz chanspec is the same as the primary 20MHz
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_channels.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_channels.h
index e78878b..f1004f0 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_channels.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_channels.h
@@ -3,9 +3,9 @@
  * This header file housing the define and function prototype use by
  * both the wl driver, tools & Apps.
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -734,6 +734,9 @@
  *
  */
 extern uint16 wf_channel2chspec(uint ctl_ch, uint bw);
+#ifdef WL_6E
+extern uint16 wf_channel2chspec6E(uint pri_ch, uint bw);
+#endif /* WL_6E */
 
 extern uint wf_channel2freq(uint channel);
 extern uint wf_freq2channel(uint freq);
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_rates.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_rates.h
old mode 100644
new mode 100755
index 8603d61..d843770
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_rates.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_rates.h
@@ -1,9 +1,9 @@
 /*
  * Indices for 802.11 a/b/g/n/ac 1-3 chain symmetric transmit rates
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_rspec.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_rspec.h
old mode 100644
new mode 100755
index 76ac971..96cf6f4
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_rspec.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmwifi_rspec.h
@@ -1,9 +1,9 @@
 /*
  * Common OS-independent driver header for rate management.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -52,6 +52,9 @@
 #define WL_RSPEC_BW_MASK	0x00070000	/**< Band width */
 #define WL_RSPEC_BW_SHIFT	16
 #define WL_RSPEC_DCM		0x00080000	/**< Dual Carrier Modulation */
+#define WL_RSPEC_DCM_SHIFT      19
+#define WL_RSPEC_ER_MASK        0x0000C000      /**< Range extension mask */
+#define WL_RSPEC_ER_SHIFT       14
 #define WL_RSPEC_STBC		0x00100000	/**< STBC expansion, Nsts = 2 * Nss */
 #define WL_RSPEC_TXBF		0x00200000
 #define WL_RSPEC_LDPC		0x00400000
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmxtlv.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmxtlv.c
old mode 100644
new mode 100755
index 509fb2f..6802520
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmxtlv.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/bcmxtlv.c
@@ -1,9 +1,9 @@
 /*
  * Driver O/S-independent utility routines
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -33,9 +33,6 @@
 
 #include <typedefs.h>
 #include <bcmdefs.h>
-
-#include <stdarg.h>
-
 #ifdef BCMDRIVER
 #include <osl.h>
 #else /* !BCMDRIVER */
@@ -46,7 +43,7 @@
 #define ASSERT(exp)
 #endif // endif
 #endif /* !BCMDRIVER */
-
+#include <stdarg.h>
 #include <bcmtlv.h>
 #include <bcmendian.h>
 #include <bcmutils.h>
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd.h
index f426c42..3d4c29e 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd.h
@@ -4,9 +4,9 @@
  * Provides type definitions and function prototypes used to link the
  * DHD OS, bus, and protocol modules.
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -41,7 +41,6 @@
 
 #undef CONFIG_PM_WAKELOCKS
 
-
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
@@ -830,8 +829,8 @@
 #define DHD_COMMON_DUMP_PATH	"/data/misc/wifi/"
 #elif defined(OEM_ANDROID) && (defined(BOARD_PANDA) || defined(__ARM_ARCH_7A__))
 #define DHD_COMMON_DUMP_PATH	"/data/vendor/wifi/"
-#elif defined(OEM_ANDROID) /* For Brix Live Image */
-#define DHD_COMMON_DUMP_PATH	"/installmedia/"
+#elif defined(OEM_ANDROID)  	/* For other Android platforms such as Brix Live Image */
+#define DHD_COMMON_DUMP_PATH	"/data/vendor/wifi/wifi_dumps/"
 #else /* Default */
 #define DHD_COMMON_DUMP_PATH	"/root/"
 #endif // endif
@@ -1427,6 +1426,9 @@
 #ifdef REVERSE_AIFSN
 	bool aifsn_reverse;
 #endif /* REVERSE_AIFSN */
+#ifdef WL11AX
+	void *twt_ctx;
+#endif /* WL11AX */
 } dhd_pub_t;
 
 typedef struct {
@@ -2203,7 +2205,8 @@
 
 #ifdef KEEP_ALIVE
 extern int dhd_dev_start_mkeep_alive(dhd_pub_t *dhd_pub, uint8 mkeep_alive_id, uint8 *ip_pkt,
-	uint16 ip_pkt_len, uint8* src_mac_addr, uint8* dst_mac_addr, uint32 period_msec);
+	uint16 ip_pkt_len, uint8* src_mac_addr, uint8* dst_mac_addr, uint32 period_msec,
+	uint16 ether_type);
 extern int dhd_dev_stop_mkeep_alive(dhd_pub_t *dhd_pub, uint8 mkeep_alive_id);
 #endif /* KEEP_ALIVE */
 
@@ -3488,6 +3491,13 @@
 extern uint8 control_he_enab;
 #endif /* DISABLE_HE_ENAB  || CUSTOM_CONTROL_HE_ENAB */
 
+#ifdef CUSTOM_CONTROL_MBO_DISABLE
+extern int dhd_control_mbo_enab(dhd_pub_t * dhd, uint8 mbo_enab);
+#endif /* CUSTOM_CONTROL_MBO_DISABLE */
+#ifdef CUSTOM_CONTROL_OCE_DISABLE
+extern int dhd_control_oce_enab(dhd_pub_t * dhd, uint8 oce_enab);
+#endif /* CUSTOM_CONTROL_OCE_DISABLE */
+
 #if defined(BCMSDIO)
 void dhd_set_role(dhd_pub_t *dhdp, int role, int bssidx);
 #endif /* BCMSDIO */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_bandsteer.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_bandsteer.c
old mode 100644
new mode 100755
index 55395e0..a656cd8
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_bandsteer.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_bandsteer.c
@@ -4,9 +4,9 @@
  * Feature by which dualband capable PEERs will be
  * forced move on 5GHz interface
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_bandsteer.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_bandsteer.h
old mode 100644
new mode 100755
index 94ef3b6..7b2ef3d
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_bandsteer.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_bandsteer.h
@@ -4,9 +4,9 @@
  * Feature by which dualband capable PEERs will be
  * forced move on 5GHz interface
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_bt_interface.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_bt_interface.h
index fda4426..bc33423 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_bt_interface.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_bt_interface.h
@@ -1,9 +1,9 @@
 /*
  *
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_bus.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_bus.h
old mode 100644
new mode 100755
index bcdb19d..78324a9
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_bus.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_bus.h
@@ -4,9 +4,9 @@
  * Provides type definitions and function prototypes used to link the
  * DHD OS, bus, and protocol modules.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -233,8 +233,6 @@
 extern int dhdpcie_get_pcieirq(struct dhd_bus *bus, unsigned int *irq);
 extern void dhd_bus_aer_config(struct dhd_bus *bus);
 
-extern struct device * dhd_bus_to_dev(struct dhd_bus *bus);
-
 extern int dhdpcie_cto_init(struct dhd_bus *bus, bool enable);
 extern int dhdpcie_cto_cfg_init(struct dhd_bus *bus, bool enable);
 
@@ -254,6 +252,8 @@
 extern void dhd_bus_handle_mb_data(struct dhd_bus *bus, uint32 d2h_mb_data);
 #endif /* BCMPCIE */
 
+extern struct device * dhd_bus_to_dev(struct dhd_bus *bus);
+
 /* dump the device trap informtation  */
 extern void dhd_bus_dump_trap_info(struct dhd_bus *bus, struct bcmstrbuf *b);
 extern void dhd_bus_copy_trap_sig(struct dhd_bus *bus,  trap_t *tr);
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_buzzz.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_buzzz.h
old mode 100644
new mode 100755
index 3db6a7f..db7320a
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_buzzz.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_buzzz.h
@@ -3,9 +3,9 @@
 
 /*
  * Broadcom logging system - Empty implementaiton
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_cdc.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_cdc.c
old mode 100644
new mode 100755
index fda0c7e..2f12fdc
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_cdc.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_cdc.c
@@ -1,9 +1,9 @@
 /*
  * DHD Protocol Module for CDC and BDC.
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -153,21 +153,13 @@
 
 #ifdef BCMSPI
 	/* 11bit gSPI bus allows 2048bytes of max-data.  We restrict 'len'
-	 * value which is 8Kbytes for various 'get' commands to 2000.  48 bytes are
+	 * value which is 8Kbytes for various 'get' commands to 1990.  58 bytes are
 	 * left for sw headers and misc.
 	 */
-
-	if (len > 2000) {
-		DHD_ERROR(("dhdcdc_query_ioctl: len is truncated to 2000 bytes\n"));
-		len = 2000;
+	if (len > 1990) {
+		DHD_ERROR(("dhdcdc_query_ioctl: len is truncated from %d to 1990 bytes\n", len));
+		len = 1990;
 	}
-#ifdef BCMQT
-	/* WAR: packet length limited for SPI host issue in FIFO mode on Zebu */
-	if (len > 460) {
-		DHD_ERROR(("len is truncated to 460 bytes on Zebu\n"));
-		len = 460;
-	}
-#endif /* BCMQT */
 #endif /* BCMSPI */
 	msg->cmd = htol32(cmd);
 	msg->len = htol32(len);
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_cfg80211.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_cfg80211.c
old mode 100644
new mode 100755
index 08ccaf5..d29fb9d
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_cfg80211.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_cfg80211.c
@@ -1,9 +1,9 @@
 /*
  * Linux cfg80211 driver - Dongle Host Driver (DHD) related
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_cfg80211.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_cfg80211.h
old mode 100644
new mode 100755
index 2c5d7b9..6528673
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_cfg80211.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_cfg80211.h
@@ -1,9 +1,9 @@
 /*
  * Linux cfg80211 driver - Dongle Host Driver (DHD) related
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_common.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_common.c
index 680bc6d..d56ea16 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_common.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_common.c
@@ -1,9 +1,9 @@
 /*
  * Broadcom Dongle Host Driver (DHD), common DHD core.
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -116,8 +116,7 @@
 #ifdef DHD_LOG_PRINT_RATE_LIMIT
 int log_print_threshold = 0;
 #endif /* DHD_LOG_PRINT_RATE_LIMIT */
-int dhd_msg_level = DHD_ERROR_VAL | DHD_FWLOG_VAL | DHD_EVENT_VAL
-//int dhd_msg_level = DHD_ERROR_VAL | DHD_EVENT_VAL
+uint dhd_msg_level = DHD_ERROR_VAL | DHD_FWLOG_VAL | DHD_EVENT_VAL
 	/* For CUSTOMER_HW4 do not enable DHD_IOVAR_MEM_VAL by default */
 #if !defined(BOARD_HIKEY)
 	| DHD_IOVAR_MEM_VAL
@@ -143,6 +142,12 @@
 #include <linux/pm_runtime.h>
 #endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
 
+#ifdef WL11AX
+#include "wl_twt.h"
+#endif /* WL11AX */
+
+#include <bcmiov.h>
+
 #ifdef SOFTAP
 char fw_path2[MOD_PARAM_PATHLEN];
 extern bool softap_enabled;
@@ -3666,6 +3671,15 @@
 		}
 		break;
 #endif /* BCMSDIO */
+#ifdef WL11AX
+	case WLC_E_TWT_SETUP:
+	case WLC_E_TWT_TEARDOWN:
+		DHD_EVENT(("%s: %u event received\n", __FUNCTION__, type));
+		if (wl_twt_event(dhd_pub, event, event_data)) {
+			DHD_ERROR(("%s: TWT event handling failure\n", __FUNCTION__));
+		}
+		break;
+#endif /* WL11AX */
 	case WLC_E_LINK:
 #ifdef PCIE_FULL_DONGLE
 		if (dhd_update_interface_link_status(dhd_pub, (uint8)dhd_ifname2idx(dhd_pub->info,
@@ -5835,8 +5849,14 @@
 	int32 i = 0;
 	uint8 *pfw_id = NULL;
 	uint32 fwid = 0;
+#ifdef DHD_SUPPORT_REQFW_FOR_EVTLOG
+	const struct firmware *fw = NULL;
+	int err = 0;
+	uint fwid_size = 0;
+#else	/* DHD_SUPPORT_REQFW_FOR_EVTLOG */
 	void *file = NULL;
 	int file_len = 0;
+#endif	/* DHD_SUPPORT_REQFW_FOR_EVTLOG */
 	char fwid_str[FWID_STR_LEN];
 	uint32 hdr_logstrs_size = 0;
 
@@ -5868,7 +5888,20 @@
 			/* For ver. 2 of the header, need to match fwid of
 			 *  both logstrs.bin and fw bin
 			 */
-
+#ifdef DHD_SUPPORT_REQFW_FOR_EVTLOG
+			if (dhd_os_open_reqfw(&fw, st_str_file_path)) {
+				goto error;
+			}
+			memset(fwid_str, 0, sizeof(fwid_str));
+			fwid_size = sizeof(fwid_str) - 1;
+			err = memcpy_s(fwid_str, fwid_size, &(fw->data[fw->size - fwid_size]),
+				fwid_size);
+			if (err) {
+				DHD_ERROR(("%s: failed to copy data, err=%d\n",
+					__FUNCTION__, err));
+				goto error;
+			}
+#else	/* DHD_SUPPORT_REQFW_FOR_EVTLOG */
 			/* read the FWID from fw bin */
 			file = dhd_os_open_image1(NULL, st_str_file_path);
 			if (!file) {
@@ -5891,6 +5924,7 @@
 				DHD_ERROR(("%s: read fw file failed !\n", __FUNCTION__));
 				goto error;
 			}
+#endif	/* DHD_SUPPORT_REQFW_FOR_EVTLOG */
 			pfw_id = (uint8 *)bcmstrnstr(fwid_str, sizeof(fwid_str) - 1,
 					FWID_STR_1, strlen(FWID_STR_1));
 			if (!pfw_id) {
@@ -5928,9 +5962,14 @@
 			hdr_logstrs_size = hdr->logstrs_size;
 
 error:
+#ifdef DHD_SUPPORT_REQFW_FOR_EVTLOG
+			if (fw)
+				release_firmware(fw);
+#else	/* DHD_SUPPORT_REQFW_FOR_EVTLOG */
 			if (file) {
 				dhd_os_close_image1(NULL, file);
 			}
+#endif /* DHD_SUPPORT_REQFW_FOR_EVTLOG */
 			if (match_fail) {
 				return BCME_DECERR;
 			}
@@ -5999,6 +6038,11 @@
 	char * cptr = NULL;
 	char c;
 	uint8 count = 0;
+#ifdef DHD_SUPPORT_REQFW_FOR_EVTLOG
+	const struct firmware *fw = file;
+	uint32 offset = 0;
+	uint32 size = (uint32)fw->size;
+#endif	/* DHD_SUPPORT_REQFW_FOR_EVTLOG */
 
 	*ramstart = 0;
 	*rodata_start = 0;
@@ -6014,12 +6058,25 @@
 	/* read ram start, rodata_start and rodata_end values from map  file */
 	while (count != ALL_MAP_VAL)
 	{
+#ifdef DHD_SUPPORT_REQFW_FOR_EVTLOG
+		if ((offset + read_size) > size) {
+			read_size = size - offset;
+		}
+
+		error = memcpy_s(raw_fmts, read_size, ((char *)(fw->data) + offset), read_size);
+
+		if (error) {
+			DHD_ERROR(("%s: Failed to copy data, err=%d\n", __FUNCTION__, error));
+			goto fail;
+		}
+#else	/* DHD_SUPPORT_REQFW_FOR_EVTLOG */
 		error = dhd_os_read_file(file, raw_fmts, read_size);
 		if (error < 0) {
 			DHD_ERROR(("%s: map file read failed err:%d \n", __FUNCTION__,
 					error));
 			goto fail;
 		}
+#endif	/* DHD_SUPPORT_REQFW_FOR_EVTLOG */
 
 		/* End raw_fmts with NULL as strstr expects NULL terminated strings */
 		raw_fmts[read_size] = '\0';
@@ -6054,6 +6111,13 @@
 			count |= RDEND_BIT;
 		}
 
+#ifdef DHD_SUPPORT_REQFW_FOR_EVTLOG
+		if ((offset + read_size) >= size) {
+			break;
+		}
+		memset(raw_fmts, 0, read_size);
+		offset += (read_size - GO_BACK_FILE_POS_NUM_BYTES);
+#else	/* DHD_SUPPORT_REQFW_FOR_EVTLOG */
 		if (error < (int)read_size) {
 			/*
 			* since we reset file pos back to earlier pos by
@@ -6070,6 +6134,7 @@
 		* the string and  addr even if it comes as splited in next read.
 		*/
 		dhd_os_seek_file(file, -GO_BACK_FILE_POS_NUM_BYTES);
+#endif	/* DHD_SUPPORT_REQFW_FOR_EVTLOG */
 	}
 
 fail:
@@ -7844,3 +7909,87 @@
 	return ret;
 }
 #endif /* DISABLE_HE_ENAB || CUSTOM_CONTROL_HE_ENAB */
+
+#ifdef CUSTOM_CONTROL_MBO_DISABLE
+int
+dhd_control_mbo_enab(dhd_pub_t * dhd, uint8 enable)
+{
+	int ret = BCME_OK;
+	uint8 *pxtlv_data = NULL;
+	bcm_iov_buf_t *iov_buf = NULL;
+	uint8 buf_xtlv[WLC_IOCTL_SMLEN] = {0x0};
+	uint16 buflen = 0, buflen_start = 0;
+
+	iov_buf = (bcm_iov_buf_t *)buf_xtlv;
+	iov_buf->version = WL_MBO_IOV_VERSION;
+	iov_buf->id = WL_MBO_CMD_ENABLE;
+
+	pxtlv_data = (uint8 *)&iov_buf->data[0];
+	buflen = buflen_start = WLC_IOCTL_SMLEN - sizeof(bcm_iov_buf_t);
+
+	ret = bcm_pack_xtlv_entry(&pxtlv_data, &buflen, WL_MBO_XTLV_ENABLE,
+	                sizeof(enable), &enable, BCM_XTLV_OPTION_ALIGN32);
+
+	if (ret != BCME_OK) {
+		ret = -EINVAL;
+		DHD_ERROR(("%s failed to pack mbo enab, err: %s\n",
+		           __FUNCTION__, bcmerrorstr(ret)));
+	        return ret;
+	}
+
+	iov_buf->len = buflen_start - buflen;
+
+	ret = dhd_iovar(dhd, 0, "mbo", (char *)&buf_xtlv, sizeof(buf_xtlv), NULL, 0, TRUE);
+
+	if (ret < 0) {
+		DHD_ERROR(("%s mbo_enab (%d) set failed, err: %s\n",
+		           __FUNCTION__, enable, bcmerrorstr(ret)));
+	} else {
+	        DHD_ERROR(("%s mbo_enab (%d) set successed\n", __FUNCTION__, enable));
+	}
+
+	return ret;
+}
+#endif /* CUSTOM_CONTROL_MBO_DISABLE */
+
+#ifdef CUSTOM_CONTROL_OCE_DISABLE
+int
+dhd_control_oce_enab(dhd_pub_t * dhd, uint8 enable)
+{
+	int ret = BCME_OK;
+	uint8 *pxtlv_data = NULL;
+	bcm_iov_buf_t *iov_buf = NULL;
+	uint8 buf_xtlv[WLC_IOCTL_SMLEN] = {0x0};
+	uint16 buflen = 0, buflen_start = 0;
+
+	iov_buf = (bcm_iov_buf_t *)buf_xtlv;
+	iov_buf->version = WL_OCE_IOV_VERSION;
+	iov_buf->id = WL_OCE_CMD_ENABLE;
+
+	pxtlv_data = (uint8 *)&iov_buf->data[0];
+	buflen = buflen_start = WLC_IOCTL_SMLEN - sizeof(bcm_iov_buf_t);
+
+	ret = bcm_pack_xtlv_entry(&pxtlv_data, &buflen, WL_OCE_XTLV_ENABLE,
+	                sizeof(enable), &enable, BCM_XTLV_OPTION_ALIGN32);
+
+	if (ret != BCME_OK) {
+		ret = -EINVAL;
+		DHD_ERROR(("%s failed to pack oce enab, err: %s\n",
+		           __FUNCTION__, bcmerrorstr(ret)));
+	        return ret;
+	}
+
+	iov_buf->len = buflen_start - buflen;
+
+	ret = dhd_iovar(dhd, 0, "oce", (char *)&buf_xtlv, sizeof(buf_xtlv), NULL, 0, TRUE);
+
+	if (ret < 0) {
+		DHD_ERROR(("%s oce_enab (%d) set failed, err: %s\n",
+		           __FUNCTION__, enable, bcmerrorstr(ret)));
+	} else {
+	        DHD_ERROR(("%s oce_enab (%d) set successed\n", __FUNCTION__, enable));
+	}
+
+	return ret;
+}
+#endif /* CUSTOM_CONTROL_OCE_DISABLE */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c
old mode 100644
new mode 100755
index ebf234c..c05705e
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c
@@ -1,9 +1,9 @@
 /*
  * Customer code to add GPIO control during WLAN start/stop
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_custom_memprealloc.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_custom_memprealloc.c
old mode 100644
new mode 100755
index 810e83c..76a9342
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_custom_memprealloc.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_custom_memprealloc.c
@@ -1,9 +1,9 @@
 /*
  * Platform Dependent file for usage of Preallocted Memory
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_custom_msm.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_custom_msm.c
old mode 100644
new mode 100755
index 453b371..bde5094
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_custom_msm.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_custom_msm.c
@@ -1,9 +1,9 @@
 /*
  * Platform Dependent file for Qualcomm MSM/APQ
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_dbg.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_dbg.h
old mode 100644
new mode 100755
index f6dba15..8a203dc
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_dbg.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_dbg.h
@@ -1,9 +1,9 @@
 /*
  * Debug/trace/assert driver definitions for Dongle Host Driver.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -366,7 +366,7 @@
 #define DHD_BLOG(cp, size)
 
 #define DHD_NONE(args)
-extern int dhd_msg_level;
+extern uint dhd_msg_level;
 #ifdef DHD_LOG_PRINT_RATE_LIMIT
 extern int log_print_threshold;
 #endif /* DHD_LOG_PRINT_RATE_LIMIT */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_dbg_ring.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_dbg_ring.c
old mode 100644
new mode 100755
index 12f9ad8..2cddcb3
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_dbg_ring.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_dbg_ring.c
@@ -3,9 +3,9 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_dbg_ring.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_dbg_ring.h
old mode 100644
new mode 100755
index 26b9f65..c80b05a
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_dbg_ring.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_dbg_ring.h
@@ -3,9 +3,9 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_debug.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_debug.c
index 57317ce..9de2b7d 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_debug.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_debug.c
@@ -3,9 +3,9 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -1601,8 +1601,12 @@
 		alloc_len = sizeof(*tx_report);
 		MFREE(dhdp->osh, tx_report, alloc_len);
 	}
-	dhdp->dbg->pkt_mon.tx_report = NULL;
-	dhdp->dbg->pkt_mon.tx_report->tx_pkts = NULL;
+	if (dhdp->dbg->pkt_mon.tx_report) {
+		if (dhdp->dbg->pkt_mon.tx_report->tx_pkts) {
+			dhdp->dbg->pkt_mon.tx_report->tx_pkts = NULL;
+		}
+		dhdp->dbg->pkt_mon.tx_report = NULL;
+	}
 	dhdp->dbg->pkt_mon.tx_pkt_mon = NULL;
 	dhdp->dbg->pkt_mon.tx_status_mon = NULL;
 	dhdp->dbg->pkt_mon.tx_pkt_state = PKT_MON_DETACHED;
@@ -1617,8 +1621,12 @@
 		alloc_len = sizeof(*rx_report);
 		MFREE(dhdp->osh, rx_report, alloc_len);
 	}
-	dhdp->dbg->pkt_mon.rx_report = NULL;
-	dhdp->dbg->pkt_mon.rx_report->rx_pkts = NULL;
+	if (dhdp->dbg->pkt_mon.rx_report) {
+		if (dhdp->dbg->pkt_mon.rx_report->rx_pkts) {
+			dhdp->dbg->pkt_mon.rx_report->rx_pkts = NULL;
+		}
+		dhdp->dbg->pkt_mon.rx_report = NULL;
+	}
 	dhdp->dbg->pkt_mon.rx_pkt_mon = NULL;
 	dhdp->dbg->pkt_mon.rx_pkt_state = PKT_MON_DETACHED;
 
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_debug.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_debug.h
old mode 100644
new mode 100755
index 2839305..520ad1b
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_debug.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_debug.h
@@ -3,9 +3,9 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_debug_linux.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_debug_linux.c
old mode 100644
new mode 100755
index 70ef894..2b4f2c7
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_debug_linux.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_debug_linux.c
@@ -3,9 +3,9 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_flowring.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_flowring.c
old mode 100644
new mode 100755
index c02095f..872c14b
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_flowring.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_flowring.c
@@ -4,9 +4,9 @@
  * Flow rings are transmit traffic (=propagating towards antenna) related entities
  *
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_flowring.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_flowring.h
old mode 100644
new mode 100755
index dd61e35..2ff9e2c
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_flowring.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_flowring.h
@@ -6,9 +6,9 @@
  * Provides type definitions and function prototypes used to create, delete and manage flow rings at
  * high level.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_ip.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_ip.c
old mode 100644
new mode 100755
index 78aaa38..2a151ae
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_ip.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_ip.c
@@ -1,9 +1,9 @@
 /*
  * IP Packet Parser Module.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_ip.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_ip.h
old mode 100644
new mode 100755
index 640aa93..ba8a13a
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_ip.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_ip.h
@@ -3,9 +3,9 @@
  *
  * Provides type definitions and function prototypes used to parse ip packet.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux.c
index cb9bf49..17fb149 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux.c
@@ -2,9 +2,9 @@
  * Broadcom Dongle Host Driver (DHD), Linux-specific network interface
  * Basically selected code segments from usb-cdc.c and usb-rndis.c
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -172,6 +172,10 @@
 #include <dhd_linux_nfct.h>
 #endif /* WL_NATOE */
 
+#ifdef WL11AX
+#include "wl_twt.h"
+#endif /* WL_11AX */
+
 #if defined(OEM_ANDROID) && defined(SOFTAP)
 extern bool ap_cfg_running;
 extern bool ap_fw_loaded;
@@ -387,6 +391,13 @@
 #endif /* BCMPCIE */
 #endif /* OEM_ANDROID */
 
+#ifdef DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING
+struct dhd_firmware_req {
+	const struct firmware *fw;
+	unsigned long offset;
+};
+#endif /* DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING */
+
 dhd_pub_t	*g_dhd_pub = NULL;
 
 #if defined(BT_OVER_SDIO)
@@ -503,7 +514,7 @@
 #endif /* DHD_WET || DHD_MCAST_REGEN || DHD_L2_FILTER */
 
 /* Error bits */
-module_param(dhd_msg_level, int, 0);
+module_param(dhd_msg_level, uint, 0);
 
 #ifdef ARP_OFFLOAD_SUPPORT
 /* ARP offload enable */
@@ -633,6 +644,12 @@
 uint32 hw_module_variant = 0;
 module_param(hw_module_variant, uint, 0644);
 
+/* Specify pcie device bus name param as shown below
+ * pcie_dev_bus_name='"PCI Bus 0001:01"'
+ */
+char pcie_dev_bus_name[MOD_PARAM_INFOLEN];
+module_param_string(pcie_dev_bus_name, pcie_dev_bus_name, MOD_PARAM_INFOLEN, 0444);
+
 #if defined(DHD_LB_RXP)
 static int dhd_napi_weight = 32;
 module_param(dhd_napi_weight, int, 0644);
@@ -666,7 +683,13 @@
 #endif /* FORCE_TPOWERON */
 
 #ifdef SHOW_LOGTRACE
-#if defined(CUSTOMER_HW4_DEBUG)
+#if defined(DHD_SUPPORT_REQFW_FOR_EVTLOG)
+static char *logstrs_path = "logstrs.bin";
+char *st_str_file_path = "rtecdc.bin";
+static char *map_file_path = "rtecdc.map";
+static char *rom_st_str_file_path = "roml.bin";
+static char *rom_map_file_path = "roml.map";
+#elif defined(CUSTOMER_HW4_DEBUG)
 static char *logstrs_path = PLATFORM_PATH"logstrs.bin";
 char *st_str_file_path = PLATFORM_PATH"rtecdc.bin";
 static char *map_file_path = PLATFORM_PATH"rtecdc.map";
@@ -2454,13 +2477,17 @@
 dhd_net2idx(dhd_info_t *dhd, struct net_device *net)
 {
 	int i = 0;
-
+#ifdef WL_STATIC_IF
+	int max_ifs = DHD_MAX_IFS + DHD_MAX_STATIC_IFS;
+#else
+	int max_ifs = DHD_MAX_IFS;
+#endif // endif
 	if (!dhd) {
 		DHD_ERROR(("%s : DHD_BAD_IF return\n", __FUNCTION__));
 		return DHD_BAD_IF;
 	}
 
-	while (i < DHD_MAX_IFS) {
+	while (i < max_ifs) {
 		if (dhd->iflist[i] && dhd->iflist[i]->net && (dhd->iflist[i]->net == net))
 			return i;
 		i++;
@@ -2717,6 +2744,11 @@
 _dhd_set_mac_address(dhd_info_t *dhd, int ifidx, uint8 *addr)
 {
 	int ret;
+#ifdef P2P_RAND
+	struct bcm_cfg80211 *cfg = NULL;
+	s16 bssidx = 0;
+	s32 cfg_type = BCME_ERROR;
+#endif /* P2P_RAND */
 
 	ret = dhd_iovar(&dhd->pub, ifidx, "cur_etheraddr", (char *)addr,
 			ETHER_ADDR_LEN, NULL, 0, TRUE);
@@ -2726,6 +2758,25 @@
 		memcpy(dhd->iflist[ifidx]->net->dev_addr, addr, ETHER_ADDR_LEN);
 		if (ifidx == 0)
 			memcpy(dhd->pub.mac.octet, addr, ETHER_ADDR_LEN);
+#ifdef P2P_RAND
+		//Update p2p mac in cfg bss
+		cfg = wl_get_cfg(dhd->iflist[ifidx]->net);
+		if (!cfg) {
+			DHD_ERROR(("%s: Cannot find cfg\n", __FUNCTION__));
+			return ret;
+		}
+		bssidx = wl_get_bssidx_by_wdev(cfg, ndev_to_wdev(dhd->iflist[ifidx]->net));
+		if (bssidx > 0) {
+			if (wl_cfgp2p_find_type(cfg, bssidx, &cfg_type) == BCME_OK) {
+				ret = memcpy_s(wl_to_p2p_bss_macaddr(cfg, cfg_type),
+						ETHER_ADDR_LEN, addr, ETHER_ADDR_LEN);
+				if (ret) {
+					DHD_ERROR(("%s: P2P CFG MAC copy fail\n", __FUNCTION__));
+					return ret;
+				}
+			}
+		}
+#endif /* P2P_RAND */
 	}
 
 	return ret;
@@ -3098,10 +3149,19 @@
 	int ret = 0;
 
 	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+#if defined(WL_STATIC_IF) && defined(SOFTAP_RAND)
+	struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
+#endif /* WL_STATIC_IF && SOFTAP_RAND */
 	struct sockaddr *sa = (struct sockaddr *)addr;
 	int ifidx;
 	dhd_if_t *dhdif;
-
+#if defined(SOFTAP_RAND)
+	if (!ETHER_IS_LOCALADDR(sa->sa_data)) {
+		DHD_ERROR(("%s: locally administered not set" MACDBG "\n", __FUNCTION__,
+			MAC2STRDBG(sa->sa_data)));
+		return -1;
+	}
+#endif /* SOFTAP_RAND */
 	ifidx = dhd_net2idx(dhd, dev);
 	if (ifidx == DHD_BAD_IF)
 		return -1;
@@ -3112,6 +3172,16 @@
 	memcpy(dhdif->mac_addr, sa->sa_data, ETHER_ADDR_LEN);
 	dhdif->set_macaddress = TRUE;
 	dhd_net_if_unlock_local(dhd);
+
+#if defined(WL_STATIC_IF) && defined(SOFTAP_RAND)
+	if (dhd_is_static_ndev(&dhd->pub, dev) &&
+		static_if_ndev_get_state(cfg, dev) == NDEV_STATE_OS_IF_CREATED) {
+		/* In case of SoftAP, save random MAC as FW interface is not created in ndev.
+		 */
+		(void)memcpy_s(dev->dev_addr, ETH_ALEN, dhdif->mac_addr, ETH_ALEN);
+		return ret;
+	}
+#endif /* WL_STATIC_IF && SOFTAP_RAND */
 #ifdef DHD_DIRECT_SET_MAC
 	/* It needs to update new mac address on this context */
 	ret = _dhd_set_mac_address(dhd, ifidx, dhdif->mac_addr);
@@ -5651,7 +5721,7 @@
 		/* Copy out any request driver name */
 		if (copy_from_user(&info, uaddr, sizeof(info)))
 			return -EFAULT;
-		strncpy(drvname, info.driver, sizeof(info.driver));
+		strncpy(drvname, info.driver, sizeof(drvname));
 		drvname[sizeof(info.driver)-1] = '\0';
 
 		/* clear struct for return */
@@ -6381,6 +6451,14 @@
 	return OSL_ERROR(bcmerror);
 }
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
+static int
+dhd_ioctl_private(struct net_device *net, struct ifreq *ifr,
+                  void __user *data, int cmd) {
+	return dhd_ioctl_entry(net, ifr, cmd);
+}
+#endif // endif
+
 #if defined(WL_CFG80211) && defined(SUPPORT_DEEP_SLEEP)
 /* Flags to indicate if we distingish power off policy when
  * user set the memu "Keep Wi-Fi on during sleep" to "Never"
@@ -6582,6 +6660,11 @@
 			dhd_rtt_deinit(&dhd->pub);
 		}
 #endif /* RTT_SUPPORT */
+#ifdef WL11AX
+		if (dhd->pub.twt_ctx) {
+			dhd_twt_deinit(&dhd->pub);
+		}
+#endif /* WL11AX */
 		ret = dhd_bus_devreset(dhdp, TRUE);
 		if (!ret) {
 			dhd_bus_suspend(dhdp);
@@ -6699,6 +6782,7 @@
 	unsigned long flags = 0;
 #ifdef WL_STATIC_IF
 	struct bcm_cfg80211 *cfg = wl_get_cfg(net);
+	int i = 0;
 #endif /* WL_STATIC_IF */
 #endif /* WL_CFG80211 */
 	dhd_info_t *dhd = DHD_DEV_INFO(net);
@@ -6739,12 +6823,15 @@
 
 #if defined(WL_STATIC_IF) && defined(WL_CFG80211)
 	/* If static if is operational, don't reset the chip */
-	if (static_if_ndev_get_state(cfg, net) == NDEV_STATE_FW_IF_CREATED) {
-		DHD_ERROR(("static if operational. skip chip reset.\n"));
-		skip_reset = true;
-		wl_cfg80211_sta_ifdown(net);
-		goto exit;
+	for (i = 0; i < DHD_NUM_STATIC_IFACES; i++) {
+		if ((cfg && (cfg->static_ndev_state[i] == NDEV_STATE_FW_IF_CREATED))) {
+			DHD_ERROR(("static if operational. skip chip reset.\n"));
+			skip_reset = true;
+			wl_cfg80211_sta_ifdown(net);
+			goto exit;
+		}
 	}
+
 #endif /* WL_STATIC_IF && WL_CFG80211 */
 
 #if defined(WL_VIF_SUPPORT)
@@ -7349,11 +7436,17 @@
 	struct bcm_cfg80211 *cfg;
 	struct net_device *primary_netdev = NULL;
 
+#if defined(SOFTAP_RAND)
+	dhd_info_t *dhd = DHD_DEV_INFO(net);
+	dhd_if_t *ifp;
+#endif /* SOFTAP_RAND */
 	cfg = wl_get_cfg(net);
 	primary_netdev = bcmcfg_to_prmry_ndev(cfg);
 
 	if (!is_static_iface(cfg, net)) {
 		DHD_TRACE(("non-static interface (%s)..do nothing \n", net->name));
+		/* Allow transmit calls for non-static iface */
+		netif_start_queue(net);
 		ret = BCME_OK;
 		goto done;
 	}
@@ -7367,8 +7460,17 @@
 		DHD_ERROR(("Failed to open primary dev ret %d\n", ret));
 		goto done;
 	}
-
-	ret = wl_cfg80211_static_if_open(net);
+#if defined(SOFTAP_RAND)
+	ifp = dhd_get_ifp_by_ndev(&dhd->pub, net);
+	if (ifp && ifp->set_macaddress) {
+		ret = wl_cfg80211_static_if_open(net, net->dev_addr);
+		ifp->set_macaddress = FALSE;
+	} else {
+		ret = wl_cfg80211_static_if_open(net, NULL);
+	}
+#else
+	ret = wl_cfg80211_static_if_open(net, NULL);
+#endif /* SOFTAP_RAND */
 	if (!ret) {
 		/* Allow transmit calls */
 		netif_start_queue(net);
@@ -8047,6 +8149,10 @@
 #else
 	.ndo_set_multicast_list = dhd_set_multicast_list,
 #endif // endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
+	.ndo_siocdevprivate = dhd_ioctl_private,
+#endif // endif
+
 };
 
 static struct net_device_ops dhd_ops_virt = {
@@ -8068,6 +8174,9 @@
 #else
 	.ndo_set_multicast_list = dhd_set_multicast_list,
 #endif // endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
+	.ndo_siocdevprivate = dhd_ioctl_private,
+#endif // endif
 };
 
 int
@@ -8111,6 +8220,177 @@
 	return 0;
 }
 
+#ifdef DHD_SUPPORT_REQFW_FOR_EVTLOG
+static int
+dhd_init_logstrs_array(osl_t *osh, dhd_event_log_t *temp)
+{
+	const struct firmware *fw = NULL;
+	int ret = BCME_ERROR;
+	char *raw_fmts =  NULL;
+	int logstrs_size = 0;
+
+	ret = dhd_os_open_reqfw(&fw, logstrs_path);
+	if (ret) {
+		goto exit;
+	}
+
+	logstrs_size = (int)fw->size;
+
+	if (logstrs_size == 0) {
+		DHD_ERROR(("%s: return as logstrs_size is 0\n", __FUNCTION__));
+		goto exit;
+	}
+
+	raw_fmts = MALLOC(osh, logstrs_size);
+	if (raw_fmts == NULL) {
+		DHD_ERROR(("%s: Failed to allocate memory \n", __FUNCTION__));
+		ret = BCME_NOMEM;
+		goto exit;
+	}
+
+	ret = memcpy_s(raw_fmts, logstrs_size, (char *)(fw->data), logstrs_size);
+	if (ret) {
+		DHD_ERROR(("%s: Failed to copy fw data, err=%d\n", __FUNCTION__, ret));
+		ret = BCME_ERROR;
+		goto exit;
+	}
+
+	ret = dhd_parse_logstrs_file(osh, raw_fmts, logstrs_size, temp);
+
+exit:
+	if (fw)
+		release_firmware(fw);
+
+	if (ret != BCME_OK) {
+		if (raw_fmts) {
+			MFREE(osh, raw_fmts, logstrs_size);
+			raw_fmts = NULL;
+		}
+
+		temp->fmts = NULL;
+	}
+
+	return ret;
+}
+
+static int
+dhd_read_map(osl_t *osh, char *fname, uint32 *ramstart, uint32 *rodata_start,
+		uint32 *rodata_end)
+{
+	const struct firmware *fw = NULL;
+	int ret = BCME_ERROR;
+
+	if (fname == NULL) {
+		DHD_ERROR(("%s: ERROR fname is NULL \n", __FUNCTION__));
+		goto fail;
+	}
+
+	ret = dhd_os_open_reqfw(&fw, fname);
+	if (ret) {
+		goto fail;
+	}
+
+	if ((ret = dhd_parse_map_file(osh, (struct firmware *)fw, ramstart,
+		rodata_start, rodata_end)) < 0)
+	goto fail;
+
+fail:
+	if (fw) {
+		release_firmware(fw);
+	}
+
+	return ret;
+}
+
+static int
+dhd_init_static_strs_array(osl_t *osh, dhd_event_log_t *temp, char *str_file, char *map_file)
+{
+	const struct firmware *fw = NULL;
+	char *raw_fmts =  NULL;
+	uint32 logstrs_size = 0;
+	int ret = BCME_OK;
+	uint32 ramstart = 0;
+	uint32 rodata_start = 0;
+	uint32 rodata_end = 0;
+	uint32 logfilebase = 0;
+
+	ret = dhd_read_map(osh, map_file, &ramstart, &rodata_start, &rodata_end);
+	if (ret != BCME_OK) {
+		DHD_ERROR(("readmap Error!! \n"));
+		/* don't do event log parsing in actual case */
+		if (strstr(str_file, ram_file_str) != NULL) {
+			temp->raw_sstr = NULL;
+		} else if (strstr(str_file, rom_file_str) != NULL) {
+			temp->rom_raw_sstr = NULL;
+		}
+		goto exit;
+	}
+	DHD_ERROR(("ramstart: 0x%x, rodata_start: 0x%x, rodata_end:0x%x\n",
+		ramstart, rodata_start, rodata_end));
+
+	ret = dhd_os_open_reqfw(&fw, str_file);
+	if (ret) {
+		goto exit;
+	}
+
+	/* Full file size is huge. Just read required part */
+	logstrs_size = rodata_end - rodata_start;
+	logfilebase = rodata_start - ramstart;
+
+	if (logstrs_size == 0) {
+		DHD_ERROR(("%s: return as logstrs_size is 0\n", __FUNCTION__));
+		ret = BCME_ERROR;
+		goto exit;
+	}
+
+	raw_fmts = MALLOC(osh, logstrs_size);
+	if (raw_fmts == NULL) {
+		DHD_ERROR(("%s: Failed to allocate raw_fmts memory \n", __FUNCTION__));
+		ret = BCME_NOMEM;
+		goto exit;
+	}
+
+	ret = memcpy_s(raw_fmts, logstrs_size, (char *)((fw->data) + logfilebase),
+		logstrs_size);
+
+	if (ret) {
+		DHD_ERROR(("%s: Failed to copy data, err=%d\n", __FUNCTION__, ret));
+		ret = BCME_ERROR;
+		goto exit;
+	}
+
+	if (strstr(str_file, ram_file_str) != NULL) {
+		temp->raw_sstr = raw_fmts;
+		temp->raw_sstr_size = logstrs_size;
+		temp->rodata_start = rodata_start;
+		temp->rodata_end = rodata_end;
+	} else if (strstr(str_file, rom_file_str) != NULL) {
+		temp->rom_raw_sstr = raw_fmts;
+		temp->rom_raw_sstr_size = logstrs_size;
+		temp->rom_rodata_start = rodata_start;
+		temp->rom_rodata_end = rodata_end;
+	}
+
+exit:
+	if (fw)
+		release_firmware(fw);
+
+	if (ret != BCME_OK) {
+		if (raw_fmts) {
+			MFREE(osh, raw_fmts, logstrs_size);
+			raw_fmts = NULL;
+		}
+
+		if (strstr(str_file, ram_file_str) != NULL) {
+			temp->raw_sstr = NULL;
+		} else if (strstr(str_file, rom_file_str) != NULL) {
+			temp->rom_raw_sstr = NULL;
+		}
+	}
+
+	return ret;
+}
+#else	/* DHD_SUPPORT_REQFW_FOR_EVTLOG */
 static int
 dhd_init_logstrs_array(osl_t *osh, dhd_event_log_t *temp)
 {
@@ -8343,7 +8623,7 @@
 
 	return error;
 } /* dhd_init_static_strs_array */
-
+#endif	/* DHD_SUPPORT_REQFW_FOR_EVTLOG */
 #endif /* SHOW_LOGTRACE */
 
 #ifdef DHD_ERPOM
@@ -8423,7 +8703,7 @@
 
 #ifdef DHD_DISABLE_FWLOG_IN_CHIPBOOT
 	dhd_msg_level = (dhd_msg_level & (~DHD_FWLOG_VAL));
-	DHD_ERROR(("%s , dhd_msg_level: 0x%x\n",__FUNCTION__,dhd_msg_level));
+	DHD_ERROR(("%s , dhd_msg_level: 0x%x\n", __FUNCTION__, dhd_msg_level));
 #endif
 #ifdef PCIE_FULL_DONGLE
 	ASSERT(sizeof(dhd_pkttag_fd_t) <= OSL_PKTTAG_SZ);
@@ -9254,6 +9534,8 @@
 	config_chipid = BCM4335_CHIP_ID;
 #elif defined(BCM43430_CHIP)
 	config_chipid = BCM43430_CHIP_ID;
+#elif defined(BCM43439_CHIP)
+	config_chipid = BCM43439_CHIP_ID;
 #elif defined(BCM43018_CHIP)
 	config_chipid = BCM43018_CHIP_ID;
 #elif defined(BCM43455_CHIP)
@@ -10091,6 +10373,10 @@
 	uint32 okc = 1;
 #endif // endif
 
+#ifdef OCE_SUPPORT
+	uint8 oce_enable = 0;
+#endif //endif
+
 #ifdef DISABLE_11N
 	uint32 nmode = 0;
 #endif /* DISABLE_11N */
@@ -10542,6 +10828,44 @@
 		DHD_ERROR(("%s set const_awake_thresh failed %d\n", __FUNCTION__, ret));
 	}
 #endif	/* CUSTOM_EVENT_PM_WAKE */
+
+#ifdef OCE_SUPPORT
+	{
+		uint8 ioctl_buf[WLC_IOCTL_SMLEN] = {0};
+		uint8 oce_xtlv[WLC_IOCTL_SMLEN] = {0};
+		bcm_iov_buf_t *iov_buf = NULL;
+		uint8 *pxtlv_data = NULL;
+		uint16 buflen = 0, buflen_start = 0, iovlen = 0;
+		s32 iovar_len = 0;
+		struct wl_ioctl ioc;
+		
+		memset(&ioc, 0, sizeof(ioc));
+		iov_buf = (bcm_iov_buf_t *)oce_xtlv;
+		iov_buf->version = WL_OCE_IOV_VERSION;
+		iov_buf->id = WL_OCE_CMD_ENABLE;
+		pxtlv_data = (uint8 *)&iov_buf->data[0];
+		buflen = buflen_start = WLC_IOCTL_SMLEN - sizeof(bcm_iov_buf_t);
+		ret = bcm_pack_xtlv_entry(&pxtlv_data, &buflen, WL_OCE_XTLV_ENABLE,
+				sizeof(oce_enable), &oce_enable, BCM_XTLV_OPTION_ALIGN32);
+		if (ret != BCME_OK) {
+			DHD_ERROR(("Failed to enable oce: %d\n", ret));
+		} else {
+			iov_buf->len = buflen_start - buflen;
+			iovlen = sizeof(bcm_iov_buf_t) + iov_buf->len;
+			iovar_len = wldev_mkiovar_bsscfg("oce", (void *)iov_buf, iovlen,  ioctl_buf, WLC_IOCTL_SMLEN, 0);
+			if (iovar_len > 0) {
+				ioc.cmd = WLC_SET_VAR;
+				ioc.buf = (void *)ioctl_buf;
+				ioc.len = iovar_len;
+				ioc.set = 1;
+				ret = dhd_wl_ioctl(dhd, 0, (wl_ioctl_t *)&ioc, ioc.buf, ioc.len);
+				if (ret < 0)
+					DHD_ERROR(("%s set oce failed %d\n", __FUNCTION__, ret));
+			}
+		}
+	}
+#endif
+	
 #ifdef OKC_SUPPORT
 	ret = dhd_iovar(dhd, 0, "okc_enable", (char *)&okc, sizeof(okc), NULL, 0, TRUE);
 #endif // endif
@@ -10892,7 +11216,14 @@
 	control_he_enab = 0;
 #endif /* DISABLE_HE_ENAB */
 	dhd_control_he_enab(dhd, control_he_enab);
+#ifdef CUSTOM_CONTROL_MBO_DISABLE
+	if (!control_he_enab)
+		dhd_control_mbo_enab(dhd, FALSE);
+#endif /* CUSTOM_CONTROL_MBO_DISABLE */
 #endif /* DISABLE_HE_ENAB || CUSTOM_CONTROL_HE_ENAB */
+#ifdef CUSTOM_CONTROL_OCE_DISABLE
+	dhd_control_oce_enab(dhd, FALSE);
+#endif /* CUSTOM_CONTROL_OCE_DISABLE */
 
 #ifdef CUSTOM_PSPRETEND_THR
 	/* Turn off MPC in AP mode */
@@ -11064,6 +11395,12 @@
 		setbit(eventmask_msg->mask, WLC_E_ROAM_EXP_EVENT);
 #endif /* GSCAN_SUPPORT */
 		setbit(eventmask_msg->mask, WLC_E_RSSI_LQM);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+		setbit(eventmask_msg->mask, WLC_E_RSSI);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
+		setbit(eventmask_msg->mask, WLC_E_BCNLOST_MSG);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) */
 #ifdef BT_WIFI_HANDOVER
 		setbit(eventmask_msg->mask, WLC_E_BT_WIFI_HANDOVER_REQ);
 #endif /* BT_WIFI_HANDOVER */
@@ -11105,6 +11442,17 @@
 		setbit(eventmask_msg->mask, WLC_E_LDF_HOGGER);
 #endif /* ENABLE_HOGSQS */
 
+#ifdef WL11AX
+		/* TWT Setup Complete Event */
+		setbit(eventmask_msg->mask, WLC_E_TWT_SETUP);
+
+		/* TWT Teardown Complete Event */
+		setbit(eventmask_msg->mask, WLC_E_TWT_TEARDOWN);
+#endif /* WL11AX */
+#if defined(WL_OWE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0))
+		setbit(eventmask_msg->mask, WLC_E_EXT_ASSOC_FRAME_RX);
+#endif /* WL_OWE && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) */
+
 		/* over temp event */
 		setbit(eventmask_msg->mask, WLC_E_OVERTEMP);
 
@@ -11414,6 +11762,14 @@
 		}
 	}
 #endif // endif
+#ifdef WL11AX
+	if (!dhd->twt_ctx) {
+		ret = wl_twt_init(dhd);
+		if (ret < 0) {
+			DHD_ERROR(("%s failed to initialize TWT\n", __FUNCTION__));
+		}
+	}
+#endif /* WL11AX */
 #ifdef FILTER_IE
 	/* Failure to configure filter IE is not a fatal error, ignore it. */
 	if (!(dhd->op_mode & (DHD_FLAG_HOSTAP_MODE | DHD_FLAG_MFG_MODE)))
@@ -12056,9 +12412,11 @@
 		 * device functions for the primary interface only
 		 */
 #ifdef DHD_DISABLE_FWLOG_IN_CHIPBOOT
-		dhd_msg_level = (dhd_msg_level | (DHD_FWLOG_VAL));
-		DHD_ERROR(("%s , dhd_msg_level: 0x%x\n", __FUNCTION__, dhd_msg_level));
+       dhd_msg_level = (dhd_msg_level | (DHD_FWLOG_VAL));
+       DHD_ERROR(("%s , dhd_msg_level: 0x%x\n", __FUNCTION__, dhd_msg_level));
 #endif
+
+
 		net->netdev_ops = &dhd_ops_pri;
 		if (!ETHER_ISNULLADDR(dhd->pub.mac.octet))
 			memcpy(temp_addr, dhd->pub.mac.octet, ETHER_ADDR_LEN);
@@ -12587,6 +12945,11 @@
 		dhd_rtt_deinit(dhdp);
 	}
 #endif // endif
+#ifdef WL11AX
+	if (dhdp->twt_ctx) {
+		wl_twt_deinit(dhdp);
+	}
+#endif /*  WL11AX */
 #if defined(CONFIG_PM_SLEEP)
 	if (dhd_pm_notifier_registered) {
 		unregister_pm_notifier(&dhd->pm_notifier);
@@ -12641,7 +13004,9 @@
 	}
 #endif /* DHD_ERPOM */
 
+#if defined(OEM_ANDROID)
 	cancel_work_sync(&dhd->dhd_hang_process_work);
+#endif /* OEM_ANDROID */
 
 	/* Prefer adding de-init code above this comment unless necessary.
 	 * The idea is to cancel work queue, sysfs and flags at the end.
@@ -13268,9 +13633,44 @@
 
 #endif /* DHD_PCIE_RUNTIMEPM */
 
+#if defined(DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING) || \
+	defined(DHD_SUPPORT_REQFW_FOR_EVTLOG)
+int
+dhd_os_open_reqfw(const struct firmware **fw, char *filename)
+{
+	int ret = BCME_OK;
+
+	ret = request_firmware(fw, filename, dhd_bus_to_dev(g_dhd_pub->bus));
+
+	if (ret) {
+		DHD_ERROR(("%s] request_firmware error : %d\n", __FUNCTION__, ret));
+		ret = BCME_ERROR;
+	}
+
+	return ret;
+}
+#endif  /* DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING || DHD_SUPPORT_REQFW_FOR_EVTLOG */
 void *
 dhd_os_open_image1(dhd_pub_t *pub, char *filename)
 {
+#ifdef DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING
+	int ret = BCME_OK;
+	struct dhd_firmware_req *fw;
+
+	fw = kmalloc(sizeof(struct dhd_firmware_req), GFP_ATOMIC);
+	if (fw) {
+		ret = dhd_os_open_reqfw(&fw->fw, filename);
+		if (!ret) {
+			fw->offset = 0;
+		}
+		else {
+			kfree(fw);
+			fw = NULL;
+		}
+	}
+
+	return (void *)fw;
+#else
 	struct file *fp;
 	int size;
 
@@ -13303,11 +13703,35 @@
 
 err:
 	 return fp;
+#endif  /* DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING */
 }
 
 int
 dhd_os_get_image_block(char *buf, int len, void *image)
 {
+#ifdef DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING
+	struct dhd_firmware_req *dhd_fw = (struct dhd_firmware_req *)image;
+	const struct firmware *fw;
+	unsigned long length;
+
+	if (!dhd_fw)
+		return 0;
+
+	fw = dhd_fw->fw;
+	if (!fw)
+		return 0;
+
+	if (dhd_fw->offset + len < fw->size) {
+		length = len;
+	}
+	else {
+		length = fw->size - dhd_fw->offset;
+	}
+	memcpy(buf, &fw->data[dhd_fw->offset], length);
+	dhd_fw->offset += length;
+
+	return length;
+#else
 	struct file *fp = (struct file *)image;
 	int rdlen;
 	int size;
@@ -13328,6 +13752,7 @@
 	}
 
 	return rdlen;
+#endif /* DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING */
 }
 
 #if defined(BT_OVER_SDIO)
@@ -13361,6 +13786,19 @@
 int
 dhd_os_get_image_size(void *image)
 {
+#ifdef DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING
+	struct dhd_firmware_req *dhd_fw = (struct dhd_firmware_req *)image;
+	const struct firmware *fw;
+
+	if (!dhd_fw)
+		return 0;
+
+	fw = dhd_fw->fw;
+	if (!fw)
+		return 0;
+
+	return fw->size;
+#else
 	struct file *fp = (struct file *)image;
 	int size;
 	if (!image) {
@@ -13370,14 +13808,26 @@
 	size = i_size_read(file_inode(fp));
 
 	return size;
+#endif  /* DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING */
 }
 
 void
 dhd_os_close_image1(dhd_pub_t *pub, void *image)
 {
+#ifdef DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING
+	struct dhd_firmware_req *dhd_fw = (struct dhd_firmware_req *)image;
+
+	if (dhd_fw) {
+		if (dhd_fw->fw) {
+			release_firmware(dhd_fw->fw);
+		}
+		kfree(dhd_fw);
+	}
+#else
 	if (image) {
 		filp_close((struct file *)image, NULL);
 	}
+#endif  /* DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING */
 }
 
 void
@@ -14828,7 +15278,7 @@
 
 int
 dhd_dev_start_mkeep_alive(dhd_pub_t *dhd_pub, uint8 mkeep_alive_id, uint8 *ip_pkt,
-	uint16 ip_pkt_len, uint8* src_mac, uint8* dst_mac, uint32 period_msec)
+	uint16 ip_pkt_len, uint8* src_mac, uint8* dst_mac, uint32 period_msec, uint16 ether_type)
 {
 	const int		ETHERTYPE_LEN = 2;
 	char			*pbuf = NULL;
@@ -14933,9 +15383,10 @@
 	memcpy(pmac_frame, src_mac, ETHER_ADDR_LEN);
 	pmac_frame += ETHER_ADDR_LEN;
 
-	/* Mapping Ethernet type (ETHERTYPE_IP: 0x0800) */
-	*(pmac_frame++) = 0x08;
-	*(pmac_frame++) = 0x00;
+	/* Mapping Ethernet type */
+	ether_type = hton16(ether_type);
+	memcpy(pmac_frame, &ether_type, ETHERTYPE_LEN);
+	pmac_frame += ETHERTYPE_LEN;
 
 	/* Mapping IP pkt */
 	memcpy(pmac_frame, ip_pkt, ip_pkt_len);
@@ -22327,8 +22778,11 @@
 
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
 #define DHD_VFS_UNLINK(dir, b, c) vfs_unlink(DHD_VFS_INODE(dir), b)
-#else
+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0))
 #define DHD_VFS_UNLINK(dir, b, c) vfs_unlink(DHD_VFS_INODE(dir), b, c)
+#else
+#define DHD_VFS_UNLINK(dir, b, c) vfs_unlink(mnt_user_ns(file_path.mnt), \
+		DHD_VFS_INODE(dir), b, c)
 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) */
 int
 dhd_file_delete(char *path)
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux.h
index 53a727a..8cc1020 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux.h
@@ -1,9 +1,9 @@
 /*
  * DHD Linux header file (dhd_linux exports for cfg80211 and other components)
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_exportfs.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_exportfs.c
index 9e96728..d0f69b9 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_exportfs.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_exportfs.c
@@ -2,9 +2,9 @@
  * Broadcom Dongle Host Driver (DHD), Linux-specific network interface
  * Basically selected code segments from usb-cdc.c and usb-rndis.c
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_lb.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_lb.c
index f3ff91d..68b6199 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_lb.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_lb.c
@@ -2,9 +2,9 @@
  * Broadcom Dongle Host Driver (DHD), Linux-specific network interface
  * Basically selected code segments from usb-cdc.c and usb-rndis.c
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -828,13 +828,21 @@
 		container_of(work, struct dhd_info, tx_compl_dispatcher_work);
 	int cpu;
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
 	get_online_cpus();
+#else
+	cpus_read_lock();
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) */
 	cpu = atomic_read(&dhd->tx_compl_cpu);
 	if (!cpu_online(cpu))
 		dhd_tasklet_schedule(&dhd->tx_compl_tasklet);
 	else
 		dhd_tasklet_schedule_on(&dhd->tx_compl_tasklet, cpu);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
 	put_online_cpus();
+#else
+	cpus_read_unlock();
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) */
 }
 #endif /* DHD_LB_TXC */
 
@@ -880,14 +888,22 @@
 		container_of(work, struct dhd_info, rx_compl_dispatcher_work);
 	int cpu;
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
 	get_online_cpus();
+#else
+	cpus_read_lock();
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) */
 	cpu = atomic_read(&dhd->rx_compl_cpu);
 	if (!cpu_online(cpu))
 		dhd_tasklet_schedule(&dhd->rx_compl_tasklet);
 	else {
 		dhd_tasklet_schedule_on(&dhd->rx_compl_tasklet, cpu);
 	}
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
 	put_online_cpus();
+#else
+	cpus_read_unlock();
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) */
 }
 #endif /* DHD_LB_RXC */
 
@@ -1124,7 +1140,11 @@
 #endif // endif
 	int cpu;
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
 	get_online_cpus();
+#else
+	cpus_read_lock();
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) */
 	cpu = atomic_read(&dhd->rx_napi_cpu);
 
 	if (!cpu_online(cpu))
@@ -1132,7 +1152,11 @@
 	else
 		dhd_napi_schedule_on(dhd, cpu);
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
 	put_online_cpus();
+#else
+	cpus_read_unlock();
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) */
 }
 
 /**
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_pktdump.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_pktdump.c
old mode 100644
new mode 100755
index 50c61f6..5240d0e
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_pktdump.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_pktdump.c
@@ -1,9 +1,9 @@
 /*
  * Packet dump helper functions
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_pktdump.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_pktdump.h
old mode 100644
new mode 100755
index e06487f..d5f35fa
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_pktdump.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_pktdump.h
@@ -1,9 +1,9 @@
 /*
  * Header file for the Packet dump helper functions
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_platdev.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_platdev.c
old mode 100644
new mode 100755
index ee49f34..bdd0b5b
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_platdev.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_platdev.c
@@ -1,9 +1,9 @@
 /*
  * Linux platform device for DHD WLAN adapter
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_priv.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_priv.h
index 7c0e53e..8ce97fc 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_priv.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_priv.h
@@ -1,9 +1,9 @@
 /*
  * DHD Linux header file - contains private structure definition of the Linux specific layer
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -52,6 +52,11 @@
 #include <dhd_flowring.h>
 #endif /* PCIE_FULL_DONGLE */
 
+#if defined(DHD_SUPPORT_REQFW_FOR_EVTLOG) || \
+	defined(DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING)
+#include <linux/firmware.h>
+#endif	/* DHD_SUPPORT_REQFW_FOR_EVTLOG || DHD_SUPPORT_REQFW_FOR_FIRMWARE_DOWNLOADING */
+
 /*
  * Do not include this header except for the dhd_linux.c dhd_linux_sysfs.c
  * Local private structure (extension of pub)
@@ -427,4 +432,7 @@
 void dhd_irq_set_affinity(dhd_pub_t *dhdp, const struct cpumask *cpumask);
 #endif /* DHD_LB_IRQSET || DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON */
 
+#ifdef DHD_SUPPORT_REQFW_FOR_EVTLOG
+int dhd_os_open_reqfw(const struct firmware **fw, char *filename);
+#endif /* DHD_SUPPORT_REQFW_FOR_EVTLOG */
 #endif /* __DHD_LINUX_PRIV_H__ */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_sched.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_sched.c
index 6cc377d..9e7b5ba 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_sched.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_sched.c
@@ -1,9 +1,9 @@
 /*
  * Expose some of the kernel scheduler routines
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_wq.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_wq.c
old mode 100644
new mode 100755
index 54de6a7..d35b47b
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_wq.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_wq.c
@@ -2,9 +2,9 @@
  * Broadcom Dongle Host Driver (DHD), Generic work queue framework
  * Generic interface to handle dhd deferred work events
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_wq.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_wq.h
old mode 100644
new mode 100755
index ddbdd42..6874ada
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_wq.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_linux_wq.h
@@ -2,9 +2,9 @@
  * Broadcom Dongle Host Driver (DHD), Generic work queue framework
  * Generic interface to handle dhd deferred work events
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_mschdbg.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_mschdbg.c
old mode 100644
new mode 100755
index 71f77a4..95738de
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_mschdbg.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_mschdbg.c
@@ -3,9 +3,9 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_mschdbg.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_mschdbg.h
old mode 100644
new mode 100755
index 76e32f5..2a0b36f
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_mschdbg.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_mschdbg.h
@@ -3,9 +3,9 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_msgbuf.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_msgbuf.c
index 26638d4..3e0a0d4 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_msgbuf.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_msgbuf.c
@@ -3,9 +3,9 @@
  * Provides type definitions and function prototypes used to link the
  * DHD OS, bus, and protocol modules.
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pcie.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pcie.c
index 3cf7267..b4e14ce 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pcie.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pcie.c
@@ -1,9 +1,9 @@
 /*
  * DHD Bus Module for PCIE
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -682,8 +682,7 @@
 		si_chipid(bus->sih) == BCM4375_CHIP_ID ||
 		si_chipid(bus->sih) == BCM4362_CHIP_ID ||
 		si_chipid(bus->sih) == BCM43751_CHIP_ID ||
-		si_chipid(bus->sih) == BCM4361_CHIP_ID ||
-		si_chipid(bus->sih) == CYW55560_CHIP_ID) {
+		si_chipid(bus->sih) == BCM4361_CHIP_ID) {
 		return FALSE;
 	} else {
 		return TRUE;
@@ -3459,7 +3458,6 @@
 	uint readlen = 0;
 	uint i = 0;
 
-	DHD_ERROR(("dhdpcie_bus_readconsole\n"));
 	if (!DHD_FWLOG_ON())
 		return 0;
 
@@ -3512,7 +3510,6 @@
 	 * important to handle wrap-around.
 	 */
 	addr = ltoh32(c->log.buf);
-	DHD_ERROR(("addr 0x%x\n", addr));
 
 	/* wrap around case - write ptr < read ptr */
 	if (idx < c->last) {
@@ -3543,7 +3540,6 @@
 	/* update read ptr */
 	c->last = idx;
 
-	DHD_ERROR(("last 0x%x\n", idx));
 	/* now output the read data from the local buffer to the host console */
 	while (i < readlen) {
 		for (n = 0; n < CONSOLE_LINE_MAX - 2 && i < readlen; n++) {
@@ -3562,7 +3558,6 @@
 		}
 	}
 
-	DHD_ERROR(("read console finish\n"));
 	return BCME_OK;
 
 } /* dhdpcie_bus_readconsole */
@@ -7329,7 +7324,6 @@
 	bool do_flr;
 	hs_addrs_t bl_hs_addrs = {NULL, NULL};
 
-	DHD_ERROR(("dhdpcie_bus_download_state\n"));
 	if (bus->sih->chip == CYW55560_CHIP_ID) {
 		/* Host bootloader handshake TCM/REGS addresses init */
 		bcmerror = dhdpcie_dongle_host_get_handshake_address(bus->sih, bus->osh,
@@ -7359,7 +7353,6 @@
 #ifndef BCMQT	/* for performance reasons, skip the FLR for QT */
 #endif /* !BCMQT */
 
-	DHD_ERROR(("dhdpcie_bus_download_state enter\n"));
 		/* Make sure BAR1 maps to backplane address 0 */
 		dhdpcie_setbar1win(bus, 0x00000000);
 		bus->alp_only = TRUE;
@@ -7437,7 +7430,6 @@
 						__FUNCTION__));
 				}
 
-				DHD_ERROR(("dhdpcie_bus_download_state 1\n"));
 				/* Console buffer read - First pass */
 				if ((bcmerror = dhdpcie_bus_readconsole(bus)) < 0) {
 					DHD_ERROR(("%s: First pass console buffer read failed\n",
@@ -7461,10 +7453,8 @@
 			}
 		}
 	} else {
-		DHD_ERROR(("dhdpcie_bus_download_state not enter\n"));
 		if (si_setcore(bus->sih, ARMCA7_CORE_ID, 0)) {
 			/* write vars */
-			DHD_ERROR(("dhdpcie_bus_download_state ca7\n"));
 			if ((bcmerror = dhdpcie_bus_write_vars(bus))) {
 				DHD_ERROR(("%s: could not write vars to RAM\n", __FUNCTION__));
 				goto fail;
@@ -7488,7 +7478,6 @@
 				(uint8 *)&bus->resetinstr, sizeof(bus->resetinstr));
 			/* now remove reset and halt and continue to run CA7 */
 		} else if (!si_setcore(bus->sih, ARMCR4_CORE_ID, 0)) {
-			DHD_ERROR(("dhdpcie_bus_download_state cr4\n"));
 			if (!(si_setcore(bus->sih, SOCRAM_CORE_ID, 0))) {
 				DHD_ERROR(("%s: Failed to find SOCRAM core!\n", __FUNCTION__));
 				bcmerror = BCME_ERROR;
@@ -7518,7 +7507,6 @@
 				goto fail;
 			}
 		} else {
-			DHD_ERROR(("dhdpcie_bus_download_state oth\n"));
 			if (BCM43602_CHIP(bus->sih->chip)) {
 				/* Firmware crashes on SOCSRAM access when core is in reset */
 				if (!(si_setcore(bus->sih, SOCRAM_CORE_ID, 0))) {
@@ -7533,7 +7521,6 @@
 
 			if (bus->sih->chip == CYW55560_CHIP_ID) {
 				/* Console buffer read - Second pass */
-				DHD_ERROR(("dhdpcie_bus_download_state 2\n"));
 				if ((bcmerror = dhdpcie_bus_readconsole(bus)) < 0) {
 					DHD_ERROR(("%s: Second pass console buffer read failed\n",
 						__FUNCTION__));
@@ -7612,7 +7599,6 @@
 			/* now remove reset and halt and continue to run CR4 */
 		}
 
-		DHD_ERROR(("dhdpcie_bus_download_state 55560\n"));
 		if (bus->sih->chip == CYW55560_CHIP_ID) {
 			/* Console buffer read - Final pass */
 			if ((bcmerror = dhdpcie_bus_readconsole(bus)) < 0) {
@@ -7647,7 +7633,6 @@
 					__FUNCTION__));
 			} else {
 				/* Console buffer read */
-				DHD_ERROR(("dhdpcie_bus_download_state 4\n"));
 				if (dhdpcie_bus_readconsole(bus) < 0) {
 					DHD_ERROR(("%s: Failure case console buffer read failed\n",
 						__FUNCTION__));
@@ -7663,7 +7648,6 @@
 		dhd_bus_pcie_pwr_req_clear(bus);
 	}
 
-	DHD_ERROR(("dhdpcie_bus_download_state exit\n"));
 	return bcmerror;
 } /* dhdpcie_bus_download_state */
 
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pcie.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pcie.h
old mode 100644
new mode 100755
index d2e00f4..23e2aa2
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pcie.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pcie.h
@@ -1,9 +1,9 @@
 /*
  * Linux DHD Bus Module for PCIE
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pcie_linux.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pcie_linux.c
old mode 100644
new mode 100755
index 426afe7..32be7b1
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pcie_linux.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pcie_linux.c
@@ -1,9 +1,9 @@
 /*
  * Linux DHD Bus Module for PCIE
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -267,6 +267,7 @@
 #endif /* DHD_PCIE_RUNTIMEPM || DHD_PCIE_NATIVE_RUNTIMEPM */
 };
 
+extern char pcie_dev_bus_name[MOD_PARAM_INFOLEN];
 int dhdpcie_init_succeeded = FALSE;
 
 #ifdef USE_SMMU_ARCH_MSM
@@ -1042,10 +1043,23 @@
 {
 	int err = 0;
 	dhdpcie_info_t *pch = pci_get_drvdata(dev);
+
+	DHD_ERROR(("%s: Enter\n", __FUNCTION__));
+
+	err = pci_set_power_state(dev, PCI_D0);
+	if (err) {
+		printf("%s:pci_set_power_state error %d \n", __FUNCTION__, err);
+		goto out;
+	}
+	err = pci_enable_device(dev);
+	if (err) {
+		printf("%s:pci_enable_device error %d \n", __FUNCTION__, err);
+		goto out;
+	}
+	pci_set_master(dev);
 #if defined(OEM_ANDROID) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
 	pci_load_and_free_saved_state(dev, &pch->state);
 #endif /* OEM_ANDROID && LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) */
-	DHD_ERROR(("%s: Enter\n", __FUNCTION__));
 #ifdef OEM_ANDROID
 	dev->state_saved = TRUE;
 #endif /* OEM_ANDROID */
@@ -1055,17 +1069,6 @@
 		dhd_bus_set_tpoweron(pch->bus, tpoweron_scale);
 	}
 #endif /* FORCE_TPOWERON */
-	err = pci_enable_device(dev);
-	if (err) {
-		printf("%s:pci_enable_device error %d \n", __FUNCTION__, err);
-		goto out;
-	}
-	pci_set_master(dev);
-	err = pci_set_power_state(dev, PCI_D0);
-	if (err) {
-		printf("%s:pci_set_power_state error %d \n", __FUNCTION__, err);
-		goto out;
-	}
 	BCM_REFERENCE(pch);
 	dhdpcie_suspend_dump_cfgregs(pch->bus, "AFTER_EP_RESUME");
 out:
@@ -1510,9 +1513,21 @@
 			return -ENODEV;
 	}
 
-	printf("PCI_PROBE:  bus %X, slot %X,vendor %X, device %X"
-		"(good PCI location)\n", pdev->bus->number,
-		PCI_SLOT(pdev->devfn), pdev->vendor, pdev->device);
+	DHD_ERROR(("%s: PCI_PROBE: bus %X, slot %X,vendor %X, device %X"
+			"(good PCI location), name %s\n", dhdpcie_driver.name, pdev->bus->number,
+			PCI_SLOT(pdev->devfn), pdev->vendor, pdev->device, pdev->bus->name));
+
+	if (strlen(pcie_dev_bus_name)) {
+		if (!strncmp(pdev->bus->name,
+			pcie_dev_bus_name, strlen(pcie_dev_bus_name))) {
+			DHD_ERROR(("%s: PCI_PROBE: bus name (%s) matched (%s)\n",
+					dhdpcie_driver.name, pcie_dev_bus_name, pdev->bus->name));
+		} else {
+			DHD_ERROR(("%s: PCI_PROBE: bus name (%s) did not match (%s)\n",
+					dhdpcie_driver.name, pcie_dev_bus_name, pdev->bus->name));
+			return -ENODEV;
+		}
+	}
 
 	if (dhdpcie_init_succeeded == TRUE) {
 		DHD_ERROR(("%s(): === Driver Already attached to a BRCM device === \r\n",
@@ -1797,10 +1812,11 @@
 			goto err;
 		}
 
-		dhdpcie_info->regs = (volatile char *) REG_MAP(bar0_addr, DONGLE_REG_MAP_SIZE);
+		dhdpcie_info->regs = (volatile char *) REG_MAP_XBIT(bar0_addr, DONGLE_REG_MAP_SIZE);
 		dhdpcie_info->bar1_size =
 			(bar1_size > DONGLE_TCM_MAP_SIZE) ? bar1_size : DONGLE_TCM_MAP_SIZE;
-		dhdpcie_info->tcm = (volatile char *) REG_MAP(bar1_addr, dhdpcie_info->bar1_size);
+		dhdpcie_info->tcm = (volatile char *) REG_MAP_XBIT(bar1_addr,
+			dhdpcie_info->bar1_size);
 
 		if (!dhdpcie_info->regs || !dhdpcie_info->tcm) {
 			DHD_ERROR(("%s:ioremap() failed\n", __FUNCTION__));
@@ -2528,7 +2544,7 @@
 			break;
 		}
 
-		dhdpcie_info->regs = (volatile char *) REG_MAP(bar0_addr, DONGLE_REG_MAP_SIZE);
+		dhdpcie_info->regs = (volatile char *) REG_MAP_XBIT(bar0_addr, DONGLE_REG_MAP_SIZE);
 		if (!dhdpcie_info->regs) {
 			DHD_ERROR(("%s: ioremap() for regs is failed\n", __FUNCTION__));
 			break;
@@ -2537,7 +2553,8 @@
 		bus->regs = dhdpcie_info->regs;
 		dhdpcie_info->bar1_size =
 			(bar1_size > DONGLE_TCM_MAP_SIZE) ? bar1_size : DONGLE_TCM_MAP_SIZE;
-		dhdpcie_info->tcm = (volatile char *) REG_MAP(bar1_addr, dhdpcie_info->bar1_size);
+		dhdpcie_info->tcm = (volatile char *) REG_MAP_XBIT(bar1_addr,
+			dhdpcie_info->bar1_size);
 		if (!dhdpcie_info->tcm) {
 			DHD_ERROR(("%s: ioremap() for regs is failed\n", __FUNCTION__));
 			REG_UNMAP(dhdpcie_info->regs);
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pno.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pno.c
index 37f88d4..afbbcc7 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pno.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pno.c
@@ -2,9 +2,9 @@
  * Broadcom Dongle Host Driver (DHD)
  * Prefered Network Offload and Wi-Fi Location Service(WLS) code.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pno.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pno.h
old mode 100644
new mode 100755
index 2c5b4f3..ecb560e
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pno.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pno.h
@@ -2,9 +2,9 @@
  * Header file of Broadcom Dongle Host Driver (DHD)
  * Prefered Network Offload code and Wi-Fi Location Service(WLS) code.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_proto.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_proto.h
old mode 100644
new mode 100755
index a339232..3311a0f
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_proto.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_proto.h
@@ -4,9 +4,9 @@
  * Provides type definitions and function prototypes used to link the
  * DHD OS, bus, and protocol modules.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_rtt.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_rtt.c
old mode 100644
new mode 100755
index 87f2f97..67b81bd
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_rtt.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_rtt.c
@@ -1,9 +1,9 @@
 /*
  * Broadcom Dongle Host Driver (DHD), RTT
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_rtt.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_rtt.h
old mode 100644
new mode 100755
index 0e2d0e6..a1a665f
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_rtt.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_rtt.h
@@ -1,9 +1,9 @@
 /*
  * Broadcom Dongle Host Driver (DHD), RTT
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_sdio.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_sdio.c
index c8a0d5a..a9555ef 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_sdio.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_sdio.c
@@ -1,9 +1,9 @@
 /*
  * DHD Bus Module for SDIO
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -163,6 +163,11 @@
 #define DHD_WAIT_HTAVAIL	10000
 #endif /* BCMQT */
 
+/* Maximum read shared console retry */
+#ifdef BCMSPI
+#define MAX_READSHARED_RETRY	1000
+#endif /* BCMSPI */
+
 /* Bump up limit on waiting for HT to account for first startup;
  * if the image is doing a CRC calculation before programming the PMU
  * for HT availability, it could take a couple hundred ms more, so
@@ -941,6 +946,7 @@
 	}
 
 	if (bus->sih->chip == BCM43430_CHIP_ID ||
+		bus->sih->chip == BCM43439_CHIP_ID ||
 		bus->sih->chip == BCM43018_CHIP_ID) {
 		/* check if fw initialized sr engine */
 		addr = SI_ENUM_BASE(bus->sih) + OFFSETOF(chipcregs_t, sr_control1);
@@ -1037,6 +1043,7 @@
 #endif /* USE_CMD14 */
 
 	if (CHIPID(bus->sih->chip) == BCM43430_CHIP_ID ||
+		CHIPID(bus->sih->chip) == BCM43439_CHIP_ID ||
 		CHIPID(bus->sih->chip) == BCM43018_CHIP_ID ||
 		CHIPID(bus->sih->chip) == BCM4339_CHIP_ID ||
 		CHIPID(bus->sih->chip) == BCM43012_CHIP_ID ||
@@ -3457,6 +3464,7 @@
 		}
 	}
 	if ((CHIPID(bus->sih->chip) == BCM43430_CHIP_ID ||
+		CHIPID(bus->sih->chip) == BCM43439_CHIP_ID ||
 		CHIPID(bus->sih->chip) == BCM43018_CHIP_ID) && !dhdsdio_sr_cap(bus))
 		bus->srmemsize = 0;
 
@@ -3522,7 +3530,9 @@
 	uint32 shaddr = 0;
 	sdpcm_shared_t sh_info;
 	sdpcm_shared_t *sh = &sh_info;
+#ifndef BCMSPI
 	int retry = 10;
+#endif /* BCMSPI */
 
 	shaddr = bus->dongle_ram_base + bus->ramsize - 4;
 	i = 0;
@@ -3550,10 +3560,19 @@
 			}
 		} else
 			break;
+#ifndef BCMSPI
 	} while (i < retry);
+#else
+	} while (++i < MAX_READSHARED_RETRY);
+#endif /* BCMSPI */
 
+#ifndef BCMSPI
 	if (i == retry)
 		return BCME_ERROR;
+#else
+	if (i == MAX_READSHARED_RETRY)
+		return BCME_ERROR;
+#endif /* BCMSPI */
 
 	/* Read hndrte_shared structure */
 	if ((rv = dhdsdio_membytes(bus, FALSE, addr, (uint8 *)sh, sizeof(sdpcm_shared_t))) < 0)
@@ -3630,7 +3649,6 @@
 
 	/* Read the console buffer */
 	addr = ltoh32(c->log.buf);
-	DHD_ERROR(("read addr finish\n"));
 	if ((rv = dhdsdio_membytes(bus, FALSE, addr, c->buf, c->bufsize)) < 0)
 		return rv;
 
@@ -4842,6 +4860,7 @@
 				dhdsdio_devram_remap(bus, FALSE);
 
 			if (CHIPID(bus->sih->chip) == BCM43430_CHIP_ID ||
+				CHIPID(bus->sih->chip) == BCM43439_CHIP_ID ||
 				CHIPID(bus->sih->chip) == BCM43018_CHIP_ID) {
 				/* Disabling Remap for SRAM_3 */
 				si_socram_set_bankpda(bus->sih, 0x3, 0x0);
@@ -5610,6 +5629,17 @@
 #endif /* DHD_DEBUG */
 	}
 
+#if defined(PLATFORM_IMX)
+	/* dhdsdio_readshared_console is failed sometimes in i.MX platform
+	 * unless wait the time with specific chips so it treat as fine.
+	 */
+	if ((ret < 0) &&
+		((CHIPID(bus->sih->chip) == BCM43430_CHIP_ID) ||
+		(CHIPID(bus->sih->chip) == BCM43439_CHIP_ID))) {
+			ret = BCME_OK;
+	}
+#endif /* defined(PLATFORM_IMX) */
+
 	if (enforce_mutex)
 		dhd_os_sdlock(bus->dhd);
 
@@ -7079,7 +7109,8 @@
 #endif /* SDTEST */
 
 #if defined(BCMSPI)
-	if ((chan == SDPCM_EVENT_CHANNEL) && (bus->sdpcmrev >= 17 && bus->sdpcmrev <= 22)) {
+	if (((chan == SDPCM_EVENT_CHANNEL) && (bus->sdpcmrev >= 17 && bus->sdpcmrev <= 22))||
+			PKTLEN(osh, pkt) == 0) {
 #else
 	if (PKTLEN(osh, pkt) == 0) {
 #endif /* BCMSPI */
@@ -7522,8 +7553,10 @@
 #endif /* DHD_ULP */
 	}
 	/* Resched the DPC if ctrl cmd is pending on bus credit */
-	if (bus->ctrl_frame_stat)
+	if (bus->ctrl_frame_stat) {
 		resched = TRUE;
+		bus->ipend = TRUE;
+	}
 
 	/* Resched if events or tx frames are pending, else await next interrupt */
 	/* On failed register access, all bets are off: no resched or interrupts */
@@ -7988,6 +8021,11 @@
 #endif // endif
 }
 
+struct device * dhd_bus_to_dev(struct dhd_bus *bus)
+{
+	return (struct device *)bcmsdh_get_dev(bus->sdh);
+}
+
 void dhd_bus_dev_pm_stay_awake(dhd_pub_t *dhdpub)
 {
 	bcmsdh_dev_pm_stay_awake(dhdpub->bus->sdh);
@@ -8287,6 +8325,8 @@
 		return TRUE;
 	if (chipid == BCM43430_CHIP_ID)
 		return TRUE;
+	if (chipid == BCM43439_CHIP_ID)
+		return TRUE;
 	if (chipid == BCM43018_CHIP_ID)
 		return TRUE;
 	if (BCM4349_CHIP(chipid))
@@ -9092,7 +9132,7 @@
 #if defined(BCMSPI) && defined(GSPI_DWORD_MODE)
 	/* Enable the dwordmode in gSPI before first F2 transaction */
 	if (((bus->sih->chip == BCM4329_CHIP_ID) && (bus->sih->chiprev > 1)) ||
-		(bus->sih->chip == BCM43430_CHIP_ID)) {
+		(bus->sih->chip == BCM43430_CHIP_ID || bus->sih->chip == BCM43439_CHIP_ID)) {
 			bcmsdh_dwordmode(bus->sdh, TRUE);
 			bus->dwordmode = TRUE;
 			DHD_INFO(("DHD:SPI DWORD mode enabled\n"));
@@ -9253,6 +9293,10 @@
 				 * well as WLAN reset (instead of using PMU/CC Watchdog register)
 				 */
 				uint8 cardctl;
+#ifdef BCMSPI
+				int bcmspierr;
+				uint32 regdata;
+#endif /* BCMSPI */
 				cardctl = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0,
 						SDIOD_CCCR_BRCM_CARDCTL, &bcmerror);
 				cardctl |= SDIOD_CCCR_BRCM_WLANRST_ONF0ABORT;
@@ -9266,6 +9310,26 @@
 					DHD_ERROR(("%s: Set WLANRST in cardctl error %d\n",
 							__FUNCTION__, bcmerror));
 				}
+
+#ifdef BCMSPI
+
+				regdata = bcmsdh_cfg_read_word(bus->sdh,
+						SDIO_FUNC_0, SPID_RESET_BP, &bcmspierr);
+
+				regdata |= (RESET_ON_WLAN_BP_RESET | RESET_SPI);
+
+				if (!bcmspierr) {
+					bcmsdh_cfg_write_word(bus->sdh, SDIO_FUNC_0,
+							SPID_RESET_BP, regdata, &bcmspierr);
+				}
+
+				if (bcmspierr) {
+					DHD_ERROR(("%s : SPI RESET Returns Error 0x%x\n",
+							__FUNCTION__, bcmspierr));
+				}
+
+#endif /* BCMSPI */
+
 			} else {
 				si_watchdog(bus->sih, 4);
 			}
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_wlfc.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_wlfc.c
old mode 100644
new mode 100755
index 0005403..5032485
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_wlfc.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_wlfc.c
@@ -1,9 +1,9 @@
 /*
  * DHD PROP_TXSTATUS Module.
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_wlfc.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_wlfc.h
old mode 100644
new mode 100755
index 5a223f5..12533ee
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_wlfc.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_wlfc.h
@@ -1,7 +1,7 @@
 /*
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dngl_stats.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dngl_stats.h
old mode 100644
new mode 100755
index faad142..7bc8feb
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dngl_stats.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dngl_stats.h
@@ -2,9 +2,9 @@
  * Common stats definitions for clients of dongle
  * ports
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dngl_wlhdr.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dngl_wlhdr.h
old mode 100644
new mode 100755
index a6b5c0a..e15b397
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dngl_wlhdr.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dngl_wlhdr.h
@@ -1,9 +1,9 @@
 /*
  * Dongle WL Header definitions
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/frag.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/frag.c
old mode 100644
new mode 100755
index 3615cff..0e5b5af
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/frag.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/frag.c
@@ -2,9 +2,9 @@
  * IE/TLV fragmentation/defragmentation support for
  * Broadcom 802.11bang Networking Device Driver
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/frag.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/frag.h
old mode 100644
new mode 100755
index aa5d7fc..730dfc7
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/frag.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/frag.h
@@ -2,9 +2,9 @@
  * IE/TLV (de)fragmentation declarations/definitions for
  * Broadcom 802.11abgn Networking Device Driver
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/hnd_pktpool.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/hnd_pktpool.c
old mode 100644
new mode 100755
index f54c7c2..e95a89d
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/hnd_pktpool.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/hnd_pktpool.c
@@ -1,9 +1,9 @@
 /*
  * HND generic packet pool operation primitives
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/hnd_pktq.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/hnd_pktq.c
old mode 100644
new mode 100755
index c325a37..2969e86
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/hnd_pktq.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/hnd_pktq.c
@@ -1,9 +1,9 @@
 /*
  * HND generic pktq operation primitives
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/hndlhl.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/hndlhl.c
old mode 100644
new mode 100755
index f220e84..926fff5
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/hndlhl.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/hndlhl.c
@@ -2,9 +2,9 @@
  * Misc utility routines for accessing lhl specific features
  * of the SiliconBackplane-based Broadcom chips.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/hndmem.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/hndmem.c
old mode 100644
new mode 100755
index d6213f4..a698caa
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/hndmem.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/hndmem.c
@@ -1,9 +1,9 @@
 /*
  * Utility routines for configuring different memories in Broadcom chips.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/hndpmu.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/hndpmu.c
old mode 100644
new mode 100755
index 7a4fd28..0e12c9d
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/hndpmu.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/hndpmu.c
@@ -2,9 +2,9 @@
  * Misc utility routines for accessing PMU corerev specific features
  * of the SiliconBackplane-based Broadcom chips.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git "a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/20230329_updated_nl80211 \0501\051.h" "b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/20230329_updated_nl80211 \0501\051.h"
new file mode 100755
index 0000000..1e47749
--- /dev/null
+++ "b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/20230329_updated_nl80211 \0501\051.h"
@@ -0,0 +1,6127 @@
+#ifndef __LINUX_NL80211_H
+#define __LINUX_NL80211_H
+/*
+ * 802.11 netlink interface public header
+ *
+ * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2008 Michael Wu <flamingice@sourmilk.net>
+ * Copyright 2008 Luis Carlos Cobo <luisca@cozybit.com>
+ * Copyright 2008 Michael Buesch <m@bues.ch>
+ * Copyright 2008, 2009 Luis R. Rodriguez <lrodriguez@atheros.com>
+ * Copyright 2008 Jouni Malinen <jouni.malinen@atheros.com>
+ * Copyright 2008 Colin McCabe <colin@cozybit.com>
+ * Copyright 2015-2017	Intel Deutschland GmbH
+ * Copyright (C) 2018 Intel Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/*
+ * This header file defines the userspace API to the wireless stack. Please
+ * be careful not to break things - i.e. don't move anything around or so
+ * unless you can demonstrate that it breaks neither API nor ABI.
+ *
+ * Additions to the API should be accompanied by actual implementations in
+ * an upstream driver, so that example implementations exist in case there
+ * are ever concerns about the precise semantics of the API or changes are
+ * needed, and to ensure that code for dead (no longer implemented) API
+ * can actually be identified and removed.
+ * Nonetheless, semantics should also be documented carefully in this file.
+ */
+
+#include <linux/types.h>
+
+#define NL80211_GENL_NAME "nl80211"
+
+#define NL80211_MULTICAST_GROUP_CONFIG		"config"
+#define NL80211_MULTICAST_GROUP_SCAN		"scan"
+#define NL80211_MULTICAST_GROUP_REG		"regulatory"
+#define NL80211_MULTICAST_GROUP_MLME		"mlme"
+#define NL80211_MULTICAST_GROUP_VENDOR		"vendor"
+#define NL80211_MULTICAST_GROUP_NAN		"nan"
+#define NL80211_MULTICAST_GROUP_TESTMODE	"testmode"
+
+/**
+ * DOC: Station handling
+ *
+ * Stations are added per interface, but a special case exists with VLAN
+ * interfaces. When a station is bound to an AP interface, it may be moved
+ * into a VLAN identified by a VLAN interface index (%NL80211_ATTR_STA_VLAN).
+ * The station is still assumed to belong to the AP interface it was added
+ * to.
+ *
+ * Station handling varies per interface type and depending on the driver's
+ * capabilities.
+ *
+ * For drivers supporting TDLS with external setup (WIPHY_FLAG_SUPPORTS_TDLS
+ * and WIPHY_FLAG_TDLS_EXTERNAL_SETUP), the station lifetime is as follows:
+ *  - a setup station entry is added, not yet authorized, without any rate
+ *    or capability information, this just exists to avoid race conditions
+ *  - when the TDLS setup is done, a single NL80211_CMD_SET_STATION is valid
+ *    to add rate and capability information to the station and at the same
+ *    time mark it authorized.
+ *  - %NL80211_TDLS_ENABLE_LINK is then used
+ *  - after this, the only valid operation is to remove it by tearing down
+ *    the TDLS link (%NL80211_TDLS_DISABLE_LINK)
+ *
+ * TODO: need more info for other interface types
+ */
+
+/**
+ * DOC: Frame transmission/registration support
+ *
+ * Frame transmission and registration support exists to allow userspace
+ * management entities such as wpa_supplicant react to management frames
+ * that are not being handled by the kernel. This includes, for example,
+ * certain classes of action frames that cannot be handled in the kernel
+ * for various reasons.
+ *
+ * Frame registration is done on a per-interface basis and registrations
+ * cannot be removed other than by closing the socket. It is possible to
+ * specify a registration filter to register, for example, only for a
+ * certain type of action frame. In particular with action frames, those
+ * that userspace registers for will not be returned as unhandled by the
+ * driver, so that the registered application has to take responsibility
+ * for doing that.
+ *
+ * The type of frame that can be registered for is also dependent on the
+ * driver and interface type. The frame types are advertised in wiphy
+ * attributes so applications know what to expect.
+ *
+ * NOTE: When an interface changes type while registrations are active,
+ *       these registrations are ignored until the interface type is
+ *       changed again. This means that changing the interface type can
+ *       lead to a situation that couldn't otherwise be produced, but
+ *       any such registrations will be dormant in the sense that they
+ *       will not be serviced, i.e. they will not receive any frames.
+ *
+ * Frame transmission allows userspace to send for example the required
+ * responses to action frames. It is subject to some sanity checking,
+ * but many frames can be transmitted. When a frame was transmitted, its
+ * status is indicated to the sending socket.
+ *
+ * For more technical details, see the corresponding command descriptions
+ * below.
+ */
+
+/**
+ * DOC: Virtual interface / concurrency capabilities
+ *
+ * Some devices are able to operate with virtual MACs, they can have
+ * more than one virtual interface. The capability handling for this
+ * is a bit complex though, as there may be a number of restrictions
+ * on the types of concurrency that are supported.
+ *
+ * To start with, each device supports the interface types listed in
+ * the %NL80211_ATTR_SUPPORTED_IFTYPES attribute, but by listing the
+ * types there no concurrency is implied.
+ *
+ * Once concurrency is desired, more attributes must be observed:
+ * To start with, since some interface types are purely managed in
+ * software, like the AP-VLAN type in mac80211 for example, there's
+ * an additional list of these, they can be added at any time and
+ * are only restricted by some semantic restrictions (e.g. AP-VLAN
+ * cannot be added without a corresponding AP interface). This list
+ * is exported in the %NL80211_ATTR_SOFTWARE_IFTYPES attribute.
+ *
+ * Further, the list of supported combinations is exported. This is
+ * in the %NL80211_ATTR_INTERFACE_COMBINATIONS attribute. Basically,
+ * it exports a list of "groups", and at any point in time the
+ * interfaces that are currently active must fall into any one of
+ * the advertised groups. Within each group, there are restrictions
+ * on the number of interfaces of different types that are supported
+ * and also the number of different channels, along with potentially
+ * some other restrictions. See &enum nl80211_if_combination_attrs.
+ *
+ * All together, these attributes define the concurrency of virtual
+ * interfaces that a given device supports.
+ */
+
+/**
+ * DOC: packet coalesce support
+ *
+ * In most cases, host that receives IPv4 and IPv6 multicast/broadcast
+ * packets does not do anything with these packets. Therefore the
+ * reception of these unwanted packets causes unnecessary processing
+ * and power consumption.
+ *
+ * Packet coalesce feature helps to reduce number of received interrupts
+ * to host by buffering these packets in firmware/hardware for some
+ * predefined time. Received interrupt will be generated when one of the
+ * following events occur.
+ * a) Expiration of hardware timer whose expiration time is set to maximum
+ * coalescing delay of matching coalesce rule.
+ * b) Coalescing buffer in hardware reaches it's limit.
+ * c) Packet doesn't match any of the configured coalesce rules.
+ *
+ * User needs to configure following parameters for creating a coalesce
+ * rule.
+ * a) Maximum coalescing delay
+ * b) List of packet patterns which needs to be matched
+ * c) Condition for coalescence. pattern 'match' or 'no match'
+ * Multiple such rules can be created.
+ */
+
+/**
+ * DOC: WPA/WPA2 EAPOL handshake offload
+ *
+ * By setting @NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK flag drivers
+ * can indicate they support offloading EAPOL handshakes for WPA/WPA2
+ * preshared key authentication. In %NL80211_CMD_CONNECT the preshared
+ * key should be specified using %NL80211_ATTR_PMK. Drivers supporting
+ * this offload may reject the %NL80211_CMD_CONNECT when no preshared
+ * key material is provided, for example when that driver does not
+ * support setting the temporal keys through %CMD_NEW_KEY.
+ *
+ * Similarly @NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X flag can be
+ * set by drivers indicating offload support of the PTK/GTK EAPOL
+ * handshakes during 802.1X authentication. In order to use the offload
+ * the %NL80211_CMD_CONNECT should have %NL80211_ATTR_WANT_1X_4WAY_HS
+ * attribute flag. Drivers supporting this offload may reject the
+ * %NL80211_CMD_CONNECT when the attribute flag is not present.
+ *
+ * For 802.1X the PMK or PMK-R0 are set by providing %NL80211_ATTR_PMK
+ * using %NL80211_CMD_SET_PMK. For offloaded FT support also
+ * %NL80211_ATTR_PMKR0_NAME must be provided.
+ */
+
+/**
+ * DOC: FILS shared key authentication offload
+ *
+ * FILS shared key authentication offload can be advertized by drivers by
+ * setting @NL80211_EXT_FEATURE_FILS_SK_OFFLOAD flag. The drivers that support
+ * FILS shared key authentication offload should be able to construct the
+ * authentication and association frames for FILS shared key authentication and
+ * eventually do a key derivation as per IEEE 802.11ai. The below additional
+ * parameters should be given to driver in %NL80211_CMD_CONNECT and/or in
+ * %NL80211_CMD_UPDATE_CONNECT_PARAMS.
+ *	%NL80211_ATTR_FILS_ERP_USERNAME - used to construct keyname_nai
+ *	%NL80211_ATTR_FILS_ERP_REALM - used to construct keyname_nai
+ *	%NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM - used to construct erp message
+ *	%NL80211_ATTR_FILS_ERP_RRK - used to generate the rIK and rMSK
+ * rIK should be used to generate an authentication tag on the ERP message and
+ * rMSK should be used to derive a PMKSA.
+ * rIK, rMSK should be generated and keyname_nai, sequence number should be used
+ * as specified in IETF RFC 6696.
+ *
+ * When FILS shared key authentication is completed, driver needs to provide the
+ * below additional parameters to userspace, which can be either after setting
+ * up a connection or after roaming.
+ *	%NL80211_ATTR_FILS_KEK - used for key renewal
+ *	%NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM - used in further EAP-RP exchanges
+ *	%NL80211_ATTR_PMKID - used to identify the PMKSA used/generated
+ *	%Nl80211_ATTR_PMK - used to update PMKSA cache in userspace
+ * The PMKSA can be maintained in userspace persistently so that it can be used
+ * later after reboots or wifi turn off/on also.
+ *
+ * %NL80211_ATTR_FILS_CACHE_ID is the cache identifier advertized by a FILS
+ * capable AP supporting PMK caching. It specifies the scope within which the
+ * PMKSAs are cached in an ESS. %NL80211_CMD_SET_PMKSA and
+ * %NL80211_CMD_DEL_PMKSA are enhanced to allow support for PMKSA caching based
+ * on FILS cache identifier. Additionally %NL80211_ATTR_PMK is used with
+ * %NL80211_SET_PMKSA to specify the PMK corresponding to a PMKSA for driver to
+ * use in a FILS shared key connection with PMKSA caching.
+ */
+
+/**
+ * enum nl80211_commands - supported nl80211 commands
+ *
+ * @NL80211_CMD_UNSPEC: unspecified command to catch errors
+ *
+ * @NL80211_CMD_GET_WIPHY: request information about a wiphy or dump request
+ *	to get a list of all present wiphys.
+ * @NL80211_CMD_SET_WIPHY: set wiphy parameters, needs %NL80211_ATTR_WIPHY or
+ *	%NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME,
+ *	%NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ (and the
+ *	attributes determining the channel width; this is used for setting
+ *	monitor mode channel),  %NL80211_ATTR_WIPHY_RETRY_SHORT,
+ *	%NL80211_ATTR_WIPHY_RETRY_LONG, %NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
+ *	and/or %NL80211_ATTR_WIPHY_RTS_THRESHOLD.
+ *	However, for setting the channel, see %NL80211_CMD_SET_CHANNEL
+ *	instead, the support here is for backward compatibility only.
+ * @NL80211_CMD_NEW_WIPHY: Newly created wiphy, response to get request
+ *	or rename notification. Has attributes %NL80211_ATTR_WIPHY and
+ *	%NL80211_ATTR_WIPHY_NAME.
+ * @NL80211_CMD_DEL_WIPHY: Wiphy deleted. Has attributes
+ *	%NL80211_ATTR_WIPHY and %NL80211_ATTR_WIPHY_NAME.
+ *
+ * @NL80211_CMD_GET_INTERFACE: Request an interface's configuration;
+ *	either a dump request for all interfaces or a specific get with a
+ *	single %NL80211_ATTR_IFINDEX is supported.
+ * @NL80211_CMD_SET_INTERFACE: Set type of a virtual interface, requires
+ *	%NL80211_ATTR_IFINDEX and %NL80211_ATTR_IFTYPE.
+ * @NL80211_CMD_NEW_INTERFACE: Newly created virtual interface or response
+ *	to %NL80211_CMD_GET_INTERFACE. Has %NL80211_ATTR_IFINDEX,
+ *	%NL80211_ATTR_WIPHY and %NL80211_ATTR_IFTYPE attributes. Can also
+ *	be sent from userspace to request creation of a new virtual interface,
+ *	then requires attributes %NL80211_ATTR_WIPHY, %NL80211_ATTR_IFTYPE and
+ *	%NL80211_ATTR_IFNAME.
+ * @NL80211_CMD_DEL_INTERFACE: Virtual interface was deleted, has attributes
+ *	%NL80211_ATTR_IFINDEX and %NL80211_ATTR_WIPHY. Can also be sent from
+ *	userspace to request deletion of a virtual interface, then requires
+ *	attribute %NL80211_ATTR_IFINDEX.
+ *
+ * @NL80211_CMD_GET_KEY: Get sequence counter information for a key specified
+ *	by %NL80211_ATTR_KEY_IDX and/or %NL80211_ATTR_MAC.
+ * @NL80211_CMD_SET_KEY: Set key attributes %NL80211_ATTR_KEY_DEFAULT,
+ *	%NL80211_ATTR_KEY_DEFAULT_MGMT, or %NL80211_ATTR_KEY_THRESHOLD.
+ * @NL80211_CMD_NEW_KEY: add a key with given %NL80211_ATTR_KEY_DATA,
+ *	%NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC, %NL80211_ATTR_KEY_CIPHER,
+ *	and %NL80211_ATTR_KEY_SEQ attributes.
+ * @NL80211_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_IDX
+ *	or %NL80211_ATTR_MAC.
+ *
+ * @NL80211_CMD_GET_BEACON: (not used)
+ * @NL80211_CMD_SET_BEACON: change the beacon on an access point interface
+ *	using the %NL80211_ATTR_BEACON_HEAD and %NL80211_ATTR_BEACON_TAIL
+ *	attributes. For drivers that generate the beacon and probe responses
+ *	internally, the following attributes must be provided: %NL80211_ATTR_IE,
+ *	%NL80211_ATTR_IE_PROBE_RESP and %NL80211_ATTR_IE_ASSOC_RESP.
+ * @NL80211_CMD_START_AP: Start AP operation on an AP interface, parameters
+ *	are like for %NL80211_CMD_SET_BEACON, and additionally parameters that
+ *	do not change are used, these include %NL80211_ATTR_BEACON_INTERVAL,
+ *	%NL80211_ATTR_DTIM_PERIOD, %NL80211_ATTR_SSID,
+ *	%NL80211_ATTR_HIDDEN_SSID, %NL80211_ATTR_CIPHERS_PAIRWISE,
+ *	%NL80211_ATTR_CIPHER_GROUP, %NL80211_ATTR_WPA_VERSIONS,
+ *	%NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY,
+ *	%NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_INACTIVITY_TIMEOUT,
+ *	%NL80211_ATTR_ACL_POLICY and %NL80211_ATTR_MAC_ADDRS.
+ *	The channel to use can be set on the interface or be given using the
+ *	%NL80211_ATTR_WIPHY_FREQ and the attributes determining channel width.
+ * @NL80211_CMD_NEW_BEACON: old alias for %NL80211_CMD_START_AP
+ * @NL80211_CMD_STOP_AP: Stop AP operation on the given interface
+ * @NL80211_CMD_DEL_BEACON: old alias for %NL80211_CMD_STOP_AP
+ *
+ * @NL80211_CMD_GET_STATION: Get station attributes for station identified by
+ *	%NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_SET_STATION: Set station attributes for station identified by
+ *	%NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_NEW_STATION: Add a station with given attributes to the
+ *	the interface identified by %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_DEL_STATION: Remove a station identified by %NL80211_ATTR_MAC
+ *	or, if no MAC address given, all stations, on the interface identified
+ *	by %NL80211_ATTR_IFINDEX. %NL80211_ATTR_MGMT_SUBTYPE and
+ *	%NL80211_ATTR_REASON_CODE can optionally be used to specify which type
+ *	of disconnection indication should be sent to the station
+ *	(Deauthentication or Disassociation frame and reason code for that
+ *	frame).
+ *
+ * @NL80211_CMD_GET_MPATH: Get mesh path attributes for mesh path to
+ * 	destination %NL80211_ATTR_MAC on the interface identified by
+ * 	%NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_SET_MPATH:  Set mesh path attributes for mesh path to
+ * 	destination %NL80211_ATTR_MAC on the interface identified by
+ * 	%NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_NEW_MPATH: Create a new mesh path for the destination given by
+ *	%NL80211_ATTR_MAC via %NL80211_ATTR_MPATH_NEXT_HOP.
+ * @NL80211_CMD_DEL_MPATH: Delete a mesh path to the destination given by
+ *	%NL80211_ATTR_MAC.
+ * @NL80211_CMD_NEW_PATH: Add a mesh path with given attributes to the
+ *	the interface identified by %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_DEL_PATH: Remove a mesh path identified by %NL80211_ATTR_MAC
+ *	or, if no MAC address given, all mesh paths, on the interface identified
+ *	by %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_SET_BSS: Set BSS attributes for BSS identified by
+ *	%NL80211_ATTR_IFINDEX.
+ *
+ * @NL80211_CMD_GET_REG: ask the wireless core to send us its currently set
+ *	regulatory domain. If %NL80211_ATTR_WIPHY is specified and the device
+ *	has a private regulatory domain, it will be returned. Otherwise, the
+ *	global regdomain will be returned.
+ *	A device will have a private regulatory domain if it uses the
+ *	regulatory_hint() API. Even when a private regdomain is used the channel
+ *	information will still be mended according to further hints from
+ *	the regulatory core to help with compliance. A dump version of this API
+ *	is now available which will returns the global regdomain as well as
+ *	all private regdomains of present wiphys (for those that have it).
+ *	If a wiphy is self-managed (%NL80211_ATTR_WIPHY_SELF_MANAGED_REG), then
+ *	its private regdomain is the only valid one for it. The regulatory
+ *	core is not used to help with compliance in this case.
+ * @NL80211_CMD_SET_REG: Set current regulatory domain. CRDA sends this command
+ *	after being queried by the kernel. CRDA replies by sending a regulatory
+ *	domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our
+ *	current alpha2 if it found a match. It also provides
+ * 	NL80211_ATTR_REG_RULE_FLAGS, and a set of regulatory rules. Each
+ * 	regulatory rule is a nested set of attributes  given by
+ * 	%NL80211_ATTR_REG_RULE_FREQ_[START|END] and
+ * 	%NL80211_ATTR_FREQ_RANGE_MAX_BW with an attached power rule given by
+ * 	%NL80211_ATTR_REG_RULE_POWER_MAX_ANT_GAIN and
+ * 	%NL80211_ATTR_REG_RULE_POWER_MAX_EIRP.
+ * @NL80211_CMD_REQ_SET_REG: ask the wireless core to set the regulatory domain
+ * 	to the specified ISO/IEC 3166-1 alpha2 country code. The core will
+ * 	store this as a valid request and then query userspace for it.
+ *
+ * @NL80211_CMD_GET_MESH_CONFIG: Get mesh networking properties for the
+ *	interface identified by %NL80211_ATTR_IFINDEX
+ *
+ * @NL80211_CMD_SET_MESH_CONFIG: Set mesh networking properties for the
+ *      interface identified by %NL80211_ATTR_IFINDEX
+ *
+ * @NL80211_CMD_SET_MGMT_EXTRA_IE: Set extra IEs for management frames. The
+ *	interface is identified with %NL80211_ATTR_IFINDEX and the management
+ *	frame subtype with %NL80211_ATTR_MGMT_SUBTYPE. The extra IE data to be
+ *	added to the end of the specified management frame is specified with
+ *	%NL80211_ATTR_IE. If the command succeeds, the requested data will be
+ *	added to all specified management frames generated by
+ *	kernel/firmware/driver.
+ *	Note: This command has been removed and it is only reserved at this
+ *	point to avoid re-using existing command number. The functionality this
+ *	command was planned for has been provided with cleaner design with the
+ *	option to specify additional IEs in NL80211_CMD_TRIGGER_SCAN,
+ *	NL80211_CMD_AUTHENTICATE, NL80211_CMD_ASSOCIATE,
+ *	NL80211_CMD_DEAUTHENTICATE, and NL80211_CMD_DISASSOCIATE.
+ *
+ * @NL80211_CMD_GET_SCAN: get scan results
+ * @NL80211_CMD_TRIGGER_SCAN: trigger a new scan with the given parameters
+ *	%NL80211_ATTR_TX_NO_CCK_RATE is used to decide whether to send the
+ *	probe requests at CCK rate or not. %NL80211_ATTR_BSSID can be used to
+ *	specify a BSSID to scan for; if not included, the wildcard BSSID will
+ *	be used.
+ * @NL80211_CMD_NEW_SCAN_RESULTS: scan notification (as a reply to
+ *	NL80211_CMD_GET_SCAN and on the "scan" multicast group)
+ * @NL80211_CMD_SCAN_ABORTED: scan was aborted, for unspecified reasons,
+ *	partial scan results may be available
+ *
+ * @NL80211_CMD_START_SCHED_SCAN: start a scheduled scan at certain
+ *	intervals and certain number of cycles, as specified by
+ *	%NL80211_ATTR_SCHED_SCAN_PLANS. If %NL80211_ATTR_SCHED_SCAN_PLANS is
+ *	not specified and only %NL80211_ATTR_SCHED_SCAN_INTERVAL is specified,
+ *	scheduled scan will run in an infinite loop with the specified interval.
+ *	These attributes are mutually exculsive,
+ *	i.e. NL80211_ATTR_SCHED_SCAN_INTERVAL must not be passed if
+ *	NL80211_ATTR_SCHED_SCAN_PLANS is defined.
+ *	If for some reason scheduled scan is aborted by the driver, all scan
+ *	plans are canceled (including scan plans that did not start yet).
+ *	Like with normal scans, if SSIDs (%NL80211_ATTR_SCAN_SSIDS)
+ *	are passed, they are used in the probe requests.  For
+ *	broadcast, a broadcast SSID must be passed (ie. an empty
+ *	string).  If no SSID is passed, no probe requests are sent and
+ *	a passive scan is performed.  %NL80211_ATTR_SCAN_FREQUENCIES,
+ *	if passed, define which channels should be scanned; if not
+ *	passed, all channels allowed for the current regulatory domain
+ *	are used.  Extra IEs can also be passed from the userspace by
+ *	using the %NL80211_ATTR_IE attribute.  The first cycle of the
+ *	scheduled scan can be delayed by %NL80211_ATTR_SCHED_SCAN_DELAY
+ *	is supplied. If the device supports multiple concurrent scheduled
+ *	scans, it will allow such when the caller provides the flag attribute
+ *	%NL80211_ATTR_SCHED_SCAN_MULTI to indicate user-space support for it.
+ * @NL80211_CMD_STOP_SCHED_SCAN: stop a scheduled scan. Returns -ENOENT if
+ *	scheduled scan is not running. The caller may assume that as soon
+ *	as the call returns, it is safe to start a new scheduled scan again.
+ * @NL80211_CMD_SCHED_SCAN_RESULTS: indicates that there are scheduled scan
+ *	results available.
+ * @NL80211_CMD_SCHED_SCAN_STOPPED: indicates that the scheduled scan has
+ *	stopped.  The driver may issue this event at any time during a
+ *	scheduled scan.  One reason for stopping the scan is if the hardware
+ *	does not support starting an association or a normal scan while running
+ *	a scheduled scan.  This event is also sent when the
+ *	%NL80211_CMD_STOP_SCHED_SCAN command is received or when the interface
+ *	is brought down while a scheduled scan was running.
+ *
+ * @NL80211_CMD_GET_SURVEY: get survey resuls, e.g. channel occupation
+ *      or noise level
+ * @NL80211_CMD_NEW_SURVEY_RESULTS: survey data notification (as a reply to
+ *	NL80211_CMD_GET_SURVEY and on the "scan" multicast group)
+ *
+ * @NL80211_CMD_SET_PMKSA: Add a PMKSA cache entry using %NL80211_ATTR_MAC
+ *	(for the BSSID), %NL80211_ATTR_PMKID, and optionally %NL80211_ATTR_PMK
+ *	(PMK is used for PTKSA derivation in case of FILS shared key offload) or
+ *	using %NL80211_ATTR_SSID, %NL80211_ATTR_FILS_CACHE_ID,
+ *	%NL80211_ATTR_PMKID, and %NL80211_ATTR_PMK in case of FILS
+ *	authentication where %NL80211_ATTR_FILS_CACHE_ID is the identifier
+ *	advertized by a FILS capable AP identifying the scope of PMKSA in an
+ *	ESS.
+ * @NL80211_CMD_DEL_PMKSA: Delete a PMKSA cache entry, using %NL80211_ATTR_MAC
+ *	(for the BSSID) and %NL80211_ATTR_PMKID or using %NL80211_ATTR_SSID,
+ *	%NL80211_ATTR_FILS_CACHE_ID, and %NL80211_ATTR_PMKID in case of FILS
+ *	authentication.
+ * @NL80211_CMD_FLUSH_PMKSA: Flush all PMKSA cache entries.
+ *
+ * @NL80211_CMD_REG_CHANGE: indicates to userspace the regulatory domain
+ * 	has been changed and provides details of the request information
+ * 	that caused the change such as who initiated the regulatory request
+ * 	(%NL80211_ATTR_REG_INITIATOR), the wiphy_idx
+ * 	(%NL80211_ATTR_REG_ALPHA2) on which the request was made from if
+ * 	the initiator was %NL80211_REGDOM_SET_BY_COUNTRY_IE or
+ * 	%NL80211_REGDOM_SET_BY_DRIVER, the type of regulatory domain
+ * 	set (%NL80211_ATTR_REG_TYPE), if the type of regulatory domain is
+ * 	%NL80211_REG_TYPE_COUNTRY the alpha2 to which we have moved on
+ * 	to (%NL80211_ATTR_REG_ALPHA2).
+ * @NL80211_CMD_REG_BEACON_HINT: indicates to userspace that an AP beacon
+ * 	has been found while world roaming thus enabling active scan or
+ * 	any mode of operation that initiates TX (beacons) on a channel
+ * 	where we would not have been able to do either before. As an example
+ * 	if you are world roaming (regulatory domain set to world or if your
+ * 	driver is using a custom world roaming regulatory domain) and while
+ * 	doing a passive scan on the 5 GHz band you find an AP there (if not
+ * 	on a DFS channel) you will now be able to actively scan for that AP
+ * 	or use AP mode on your card on that same channel. Note that this will
+ * 	never be used for channels 1-11 on the 2 GHz band as they are always
+ * 	enabled world wide. This beacon hint is only sent if your device had
+ * 	either disabled active scanning or beaconing on a channel. We send to
+ * 	userspace the wiphy on which we removed a restriction from
+ * 	(%NL80211_ATTR_WIPHY) and the channel on which this occurred
+ * 	before (%NL80211_ATTR_FREQ_BEFORE) and after (%NL80211_ATTR_FREQ_AFTER)
+ * 	the beacon hint was processed.
+ *
+ * @NL80211_CMD_AUTHENTICATE: authentication request and notification.
+ *	This command is used both as a command (request to authenticate) and
+ *	as an event on the "mlme" multicast group indicating completion of the
+ *	authentication process.
+ *	When used as a command, %NL80211_ATTR_IFINDEX is used to identify the
+ *	interface. %NL80211_ATTR_MAC is used to specify PeerSTAAddress (and
+ *	BSSID in case of station mode). %NL80211_ATTR_SSID is used to specify
+ *	the SSID (mainly for association, but is included in authentication
+ *	request, too, to help BSS selection. %NL80211_ATTR_WIPHY_FREQ is used
+ *	to specify the frequence of the channel in MHz. %NL80211_ATTR_AUTH_TYPE
+ *	is used to specify the authentication type. %NL80211_ATTR_IE is used to
+ *	define IEs (VendorSpecificInfo, but also including RSN IE and FT IEs)
+ *	to be added to the frame.
+ *	When used as an event, this reports reception of an Authentication
+ *	frame in station and IBSS modes when the local MLME processed the
+ *	frame, i.e., it was for the local STA and was received in correct
+ *	state. This is similar to MLME-AUTHENTICATE.confirm primitive in the
+ *	MLME SAP interface (kernel providing MLME, userspace SME). The
+ *	included %NL80211_ATTR_FRAME attribute contains the management frame
+ *	(including both the header and frame body, but not FCS). This event is
+ *	also used to indicate if the authentication attempt timed out. In that
+ *	case the %NL80211_ATTR_FRAME attribute is replaced with a
+ *	%NL80211_ATTR_TIMED_OUT flag (and %NL80211_ATTR_MAC to indicate which
+ *	pending authentication timed out).
+ * @NL80211_CMD_ASSOCIATE: association request and notification; like
+ *	NL80211_CMD_AUTHENTICATE but for Association and Reassociation
+ *	(similar to MLME-ASSOCIATE.request, MLME-REASSOCIATE.request,
+ *	MLME-ASSOCIATE.confirm or MLME-REASSOCIATE.confirm primitives). The
+ *	%NL80211_ATTR_PREV_BSSID attribute is used to specify whether the
+ *	request is for the initial association to an ESS (that attribute not
+ *	included) or for reassociation within the ESS (that attribute is
+ *	included).
+ * @NL80211_CMD_DEAUTHENTICATE: deauthentication request and notification; like
+ *	NL80211_CMD_AUTHENTICATE but for Deauthentication frames (similar to
+ *	MLME-DEAUTHENTICATION.request and MLME-DEAUTHENTICATE.indication
+ *	primitives).
+ * @NL80211_CMD_DISASSOCIATE: disassociation request and notification; like
+ *	NL80211_CMD_AUTHENTICATE but for Disassociation frames (similar to
+ *	MLME-DISASSOCIATE.request and MLME-DISASSOCIATE.indication primitives).
+ *
+ * @NL80211_CMD_MICHAEL_MIC_FAILURE: notification of a locally detected Michael
+ *	MIC (part of TKIP) failure; sent on the "mlme" multicast group; the
+ *	event includes %NL80211_ATTR_MAC to describe the source MAC address of
+ *	the frame with invalid MIC, %NL80211_ATTR_KEY_TYPE to show the key
+ *	type, %NL80211_ATTR_KEY_IDX to indicate the key identifier, and
+ *	%NL80211_ATTR_KEY_SEQ to indicate the TSC value of the frame; this
+ *	event matches with MLME-MICHAELMICFAILURE.indication() primitive
+ *
+ * @NL80211_CMD_JOIN_IBSS: Join a new IBSS -- given at least an SSID and a
+ *	FREQ attribute (for the initial frequency if no peer can be found)
+ *	and optionally a MAC (as BSSID) and FREQ_FIXED attribute if those
+ *	should be fixed rather than automatically determined. Can only be
+ *	executed on a network interface that is UP, and fixed BSSID/FREQ
+ *	may be rejected. Another optional parameter is the beacon interval,
+ *	given in the %NL80211_ATTR_BEACON_INTERVAL attribute, which if not
+ *	given defaults to 100 TU (102.4ms).
+ * @NL80211_CMD_LEAVE_IBSS: Leave the IBSS -- no special arguments, the IBSS is
+ *	determined by the network interface.
+ *
+ * @NL80211_CMD_TESTMODE: testmode command, takes a wiphy (or ifindex) attribute
+ *	to identify the device, and the TESTDATA blob attribute to pass through
+ *	to the driver.
+ *
+ * @NL80211_CMD_CONNECT: connection request and notification; this command
+ *	requests to connect to a specified network but without separating
+ *	auth and assoc steps. For this, you need to specify the SSID in a
+ *	%NL80211_ATTR_SSID attribute, and can optionally specify the association
+ *	IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_USE_MFP,
+ *	%NL80211_ATTR_MAC, %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT,
+ *	%NL80211_ATTR_CONTROL_PORT_ETHERTYPE,
+ *	%NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT,
+ *	%NL80211_ATTR_CONTROL_PORT_OVER_NL80211, %NL80211_ATTR_MAC_HINT, and
+ *	%NL80211_ATTR_WIPHY_FREQ_HINT.
+ *	If included, %NL80211_ATTR_MAC and %NL80211_ATTR_WIPHY_FREQ are
+ *	restrictions on BSS selection, i.e., they effectively prevent roaming
+ *	within the ESS. %NL80211_ATTR_MAC_HINT and %NL80211_ATTR_WIPHY_FREQ_HINT
+ *	can be included to provide a recommendation of the initial BSS while
+ *	allowing the driver to roam to other BSSes within the ESS and also to
+ *	ignore this recommendation if the indicated BSS is not ideal. Only one
+ *	set of BSSID,frequency parameters is used (i.e., either the enforcing
+ *	%NL80211_ATTR_MAC,%NL80211_ATTR_WIPHY_FREQ or the less strict
+ *	%NL80211_ATTR_MAC_HINT and %NL80211_ATTR_WIPHY_FREQ_HINT).
+ *	%NL80211_ATTR_PREV_BSSID can be used to request a reassociation within
+ *	the ESS in case the device is already associated and an association with
+ *	a different BSS is desired.
+ *	Background scan period can optionally be
+ *	specified in %NL80211_ATTR_BG_SCAN_PERIOD,
+ *	if not specified default background scan configuration
+ *	in driver is used and if period value is 0, bg scan will be disabled.
+ *	This attribute is ignored if driver does not support roam scan.
+ *	It is also sent as an event, with the BSSID and response IEs when the
+ *	connection is established or failed to be established. This can be
+ *	determined by the %NL80211_ATTR_STATUS_CODE attribute (0 = success,
+ *	non-zero = failure). If %NL80211_ATTR_TIMED_OUT is included in the
+ *	event, the connection attempt failed due to not being able to initiate
+ *	authentication/association or not receiving a response from the AP.
+ *	Non-zero %NL80211_ATTR_STATUS_CODE value is indicated in that case as
+ *	well to remain backwards compatible.
+ *	When establishing a security association, drivers that support 4 way
+ *	handshake offload should send %NL80211_CMD_PORT_AUTHORIZED event when
+ *	the 4 way handshake is completed successfully.
+ * @NL80211_CMD_ROAM: Notification indicating the card/driver roamed by itself.
+ *	When a security association was established with the new AP (e.g. if
+ *	the FT protocol was used for roaming or the driver completed the 4 way
+ *	handshake), this event should be followed by an
+ *	%NL80211_CMD_PORT_AUTHORIZED event.
+ * @NL80211_CMD_DISCONNECT: drop a given connection; also used to notify
+ *	userspace that a connection was dropped by the AP or due to other
+ *	reasons, for this the %NL80211_ATTR_DISCONNECTED_BY_AP and
+ *	%NL80211_ATTR_REASON_CODE attributes are used.
+ *
+ * @NL80211_CMD_SET_WIPHY_NETNS: Set a wiphy's netns. Note that all devices
+ *	associated with this wiphy must be down and will follow.
+ *
+ * @NL80211_CMD_REMAIN_ON_CHANNEL: Request to remain awake on the specified
+ *	channel for the specified amount of time. This can be used to do
+ *	off-channel operations like transmit a Public Action frame and wait for
+ *	a response while being associated to an AP on another channel.
+ *	%NL80211_ATTR_IFINDEX is used to specify which interface (and thus
+ *	radio) is used. %NL80211_ATTR_WIPHY_FREQ is used to specify the
+ *	frequency for the operation.
+ *	%NL80211_ATTR_DURATION is used to specify the duration in milliseconds
+ *	to remain on the channel. This command is also used as an event to
+ *	notify when the requested duration starts (it may take a while for the
+ *	driver to schedule this time due to other concurrent needs for the
+ *	radio).
+ *	When called, this operation returns a cookie (%NL80211_ATTR_COOKIE)
+ *	that will be included with any events pertaining to this request;
+ *	the cookie is also used to cancel the request.
+ * @NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL: This command can be used to cancel a
+ *	pending remain-on-channel duration if the desired operation has been
+ *	completed prior to expiration of the originally requested duration.
+ *	%NL80211_ATTR_WIPHY or %NL80211_ATTR_IFINDEX is used to specify the
+ *	radio. The %NL80211_ATTR_COOKIE attribute must be given as well to
+ *	uniquely identify the request.
+ *	This command is also used as an event to notify when a requested
+ *	remain-on-channel duration has expired.
+ *
+ * @NL80211_CMD_SET_TX_BITRATE_MASK: Set the mask of rates to be used in TX
+ *	rate selection. %NL80211_ATTR_IFINDEX is used to specify the interface
+ *	and @NL80211_ATTR_TX_RATES the set of allowed rates.
+ *
+ * @NL80211_CMD_REGISTER_FRAME: Register for receiving certain mgmt frames
+ *	(via @NL80211_CMD_FRAME) for processing in userspace. This command
+ *	requires an interface index, a frame type attribute (optional for
+ *	backward compatibility reasons, if not given assumes action frames)
+ *	and a match attribute containing the first few bytes of the frame
+ *	that should match, e.g. a single byte for only a category match or
+ *	four bytes for vendor frames including the OUI. The registration
+ *	cannot be dropped, but is removed automatically when the netlink
+ *	socket is closed. Multiple registrations can be made.
+ * @NL80211_CMD_REGISTER_ACTION: Alias for @NL80211_CMD_REGISTER_FRAME for
+ *	backward compatibility
+ * @NL80211_CMD_FRAME: Management frame TX request and RX notification. This
+ *	command is used both as a request to transmit a management frame and
+ *	as an event indicating reception of a frame that was not processed in
+ *	kernel code, but is for us (i.e., which may need to be processed in a
+ *	user space application). %NL80211_ATTR_FRAME is used to specify the
+ *	frame contents (including header). %NL80211_ATTR_WIPHY_FREQ is used
+ *	to indicate on which channel the frame is to be transmitted or was
+ *	received. If this channel is not the current channel (remain-on-channel
+ *	or the operational channel) the device will switch to the given channel
+ *	and transmit the frame, optionally waiting for a response for the time
+ *	specified using %NL80211_ATTR_DURATION. When called, this operation
+ *	returns a cookie (%NL80211_ATTR_COOKIE) that will be included with the
+ *	TX status event pertaining to the TX request.
+ *	%NL80211_ATTR_TX_NO_CCK_RATE is used to decide whether to send the
+ *	management frames at CCK rate or not in 2GHz band.
+ *	%NL80211_ATTR_CSA_C_OFFSETS_TX is an array of offsets to CSA
+ *	counters which will be updated to the current value. This attribute
+ *	is used during CSA period.
+ * @NL80211_CMD_FRAME_WAIT_CANCEL: When an off-channel TX was requested, this
+ *	command may be used with the corresponding cookie to cancel the wait
+ *	time if it is known that it is no longer necessary.
+ * @NL80211_CMD_ACTION: Alias for @NL80211_CMD_FRAME for backward compatibility.
+ * @NL80211_CMD_FRAME_TX_STATUS: Report TX status of a management frame
+ *	transmitted with %NL80211_CMD_FRAME. %NL80211_ATTR_COOKIE identifies
+ *	the TX command and %NL80211_ATTR_FRAME includes the contents of the
+ *	frame. %NL80211_ATTR_ACK flag is included if the recipient acknowledged
+ *	the frame.
+ * @NL80211_CMD_ACTION_TX_STATUS: Alias for @NL80211_CMD_FRAME_TX_STATUS for
+ *	backward compatibility.
+ *
+ * @NL80211_CMD_SET_POWER_SAVE: Set powersave, using %NL80211_ATTR_PS_STATE
+ * @NL80211_CMD_GET_POWER_SAVE: Get powersave status in %NL80211_ATTR_PS_STATE
+ *
+ * @NL80211_CMD_SET_CQM: Connection quality monitor configuration. This command
+ *	is used to configure connection quality monitoring notification trigger
+ *	levels.
+ * @NL80211_CMD_NOTIFY_CQM: Connection quality monitor notification. This
+ *	command is used as an event to indicate the that a trigger level was
+ *	reached.
+ * @NL80211_CMD_SET_CHANNEL: Set the channel (using %NL80211_ATTR_WIPHY_FREQ
+ *	and the attributes determining channel width) the given interface
+ *	(identifed by %NL80211_ATTR_IFINDEX) shall operate on.
+ *	In case multiple channels are supported by the device, the mechanism
+ *	with which it switches channels is implementation-defined.
+ *	When a monitor interface is given, it can only switch channel while
+ *	no other interfaces are operating to avoid disturbing the operation
+ *	of any other interfaces, and other interfaces will again take
+ *	precedence when they are used.
+ *
+ * @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface.
+ *
+ * @NL80211_CMD_SET_MULTICAST_TO_UNICAST: Configure if this AP should perform
+ *	multicast to unicast conversion. When enabled, all multicast packets
+ *	with ethertype ARP, IPv4 or IPv6 (possibly within an 802.1Q header)
+ *	will be sent out to each station once with the destination (multicast)
+ *	MAC address replaced by the station's MAC address. Note that this may
+ *	break certain expectations of the receiver, e.g. the ability to drop
+ *	unicast IP packets encapsulated in multicast L2 frames, or the ability
+ *	to not send destination unreachable messages in such cases.
+ *	This can only be toggled per BSS. Configure this on an interface of
+ *	type %NL80211_IFTYPE_AP. It applies to all its VLAN interfaces
+ *	(%NL80211_IFTYPE_AP_VLAN), except for those in 4addr (WDS) mode.
+ *	If %NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED is not present with this
+ *	command, the feature is disabled.
+ *
+ * @NL80211_CMD_JOIN_MESH: Join a mesh. The mesh ID must be given, and initial
+ *	mesh config parameters may be given.
+ * @NL80211_CMD_LEAVE_MESH: Leave the mesh network -- no special arguments, the
+ *	network is determined by the network interface.
+ *
+ * @NL80211_CMD_UNPROT_DEAUTHENTICATE: Unprotected deauthentication frame
+ *	notification. This event is used to indicate that an unprotected
+ *	deauthentication frame was dropped when MFP is in use.
+ * @NL80211_CMD_UNPROT_DISASSOCIATE: Unprotected disassociation frame
+ *	notification. This event is used to indicate that an unprotected
+ *	disassociation frame was dropped when MFP is in use.
+ *
+ * @NL80211_CMD_NEW_PEER_CANDIDATE: Notification on the reception of a
+ *      beacon or probe response from a compatible mesh peer.  This is only
+ *      sent while no station information (sta_info) exists for the new peer
+ *      candidate and when @NL80211_MESH_SETUP_USERSPACE_AUTH,
+ *      @NL80211_MESH_SETUP_USERSPACE_AMPE, or
+ *      @NL80211_MESH_SETUP_USERSPACE_MPM is set.  On reception of this
+ *      notification, userspace may decide to create a new station
+ *      (@NL80211_CMD_NEW_STATION).  To stop this notification from
+ *      reoccurring, the userspace authentication daemon may want to create the
+ *      new station with the AUTHENTICATED flag unset and maybe change it later
+ *      depending on the authentication result.
+ *
+ * @NL80211_CMD_GET_WOWLAN: get Wake-on-Wireless-LAN (WoWLAN) settings.
+ * @NL80211_CMD_SET_WOWLAN: set Wake-on-Wireless-LAN (WoWLAN) settings.
+ *	Since wireless is more complex than wired ethernet, it supports
+ *	various triggers. These triggers can be configured through this
+ *	command with the %NL80211_ATTR_WOWLAN_TRIGGERS attribute. For
+ *	more background information, see
+ *	http://wireless.kernel.org/en/users/Documentation/WoWLAN.
+ *	The @NL80211_CMD_SET_WOWLAN command can also be used as a notification
+ *	from the driver reporting the wakeup reason. In this case, the
+ *	@NL80211_ATTR_WOWLAN_TRIGGERS attribute will contain the reason
+ *	for the wakeup, if it was caused by wireless. If it is not present
+ *	in the wakeup notification, the wireless device didn't cause the
+ *	wakeup but reports that it was woken up.
+ *
+ * @NL80211_CMD_SET_REKEY_OFFLOAD: This command is used give the driver
+ *	the necessary information for supporting GTK rekey offload. This
+ *	feature is typically used during WoWLAN. The configuration data
+ *	is contained in %NL80211_ATTR_REKEY_DATA (which is nested and
+ *	contains the data in sub-attributes). After rekeying happened,
+ *	this command may also be sent by the driver as an MLME event to
+ *	inform userspace of the new replay counter.
+ *
+ * @NL80211_CMD_PMKSA_CANDIDATE: This is used as an event to inform userspace
+ *	of PMKSA caching dandidates.
+ *
+ * @NL80211_CMD_TDLS_OPER: Perform a high-level TDLS command (e.g. link setup).
+ *	In addition, this can be used as an event to request userspace to take
+ *	actions on TDLS links (set up a new link or tear down an existing one).
+ *	In such events, %NL80211_ATTR_TDLS_OPERATION indicates the requested
+ *	operation, %NL80211_ATTR_MAC contains the peer MAC address, and
+ *	%NL80211_ATTR_REASON_CODE the reason code to be used (only with
+ *	%NL80211_TDLS_TEARDOWN).
+ * @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame. The
+ *	%NL80211_ATTR_TDLS_ACTION attribute determines the type of frame to be
+ *	sent. Public Action codes (802.11-2012 8.1.5.1) will be sent as
+ *	802.11 management frames, while TDLS action codes (802.11-2012
+ *	8.5.13.1) will be encapsulated and sent as data frames. The currently
+ *	supported Public Action code is %WLAN_PUB_ACTION_TDLS_DISCOVER_RES
+ *	and the currently supported TDLS actions codes are given in
+ *	&enum ieee80211_tdls_actioncode.
+ *
+ * @NL80211_CMD_UNEXPECTED_FRAME: Used by an application controlling an AP
+ *	(or GO) interface (i.e. hostapd) to ask for unexpected frames to
+ *	implement sending deauth to stations that send unexpected class 3
+ *	frames. Also used as the event sent by the kernel when such a frame
+ *	is received.
+ *	For the event, the %NL80211_ATTR_MAC attribute carries the TA and
+ *	other attributes like the interface index are present.
+ *	If used as the command it must have an interface index and you can
+ *	only unsubscribe from the event by closing the socket. Subscription
+ *	is also for %NL80211_CMD_UNEXPECTED_4ADDR_FRAME events.
+ *
+ * @NL80211_CMD_UNEXPECTED_4ADDR_FRAME: Sent as an event indicating that the
+ *	associated station identified by %NL80211_ATTR_MAC sent a 4addr frame
+ *	and wasn't already in a 4-addr VLAN. The event will be sent similarly
+ *	to the %NL80211_CMD_UNEXPECTED_FRAME event, to the same listener.
+ *
+ * @NL80211_CMD_PROBE_CLIENT: Probe an associated station on an AP interface
+ *	by sending a null data frame to it and reporting when the frame is
+ *	acknowleged. This is used to allow timing out inactive clients. Uses
+ *	%NL80211_ATTR_IFINDEX and %NL80211_ATTR_MAC. The command returns a
+ *	direct reply with an %NL80211_ATTR_COOKIE that is later used to match
+ *	up the event with the request. The event includes the same data and
+ *	has %NL80211_ATTR_ACK set if the frame was ACKed.
+ *
+ * @NL80211_CMD_REGISTER_BEACONS: Register this socket to receive beacons from
+ *	other BSSes when any interfaces are in AP mode. This helps implement
+ *	OLBC handling in hostapd. Beacons are reported in %NL80211_CMD_FRAME
+ *	messages. Note that per PHY only one application may register.
+ *
+ * @NL80211_CMD_SET_NOACK_MAP: sets a bitmap for the individual TIDs whether
+ *      No Acknowledgement Policy should be applied.
+ *
+ * @NL80211_CMD_CH_SWITCH_NOTIFY: An AP or GO may decide to switch channels
+ *	independently of the userspace SME, send this event indicating
+ *	%NL80211_ATTR_IFINDEX is now on %NL80211_ATTR_WIPHY_FREQ and the
+ *	attributes determining channel width.  This indication may also be
+ *	sent when a remotely-initiated switch (e.g., when a STA receives a CSA
+ *	from the remote AP) is completed;
+ *
+ * @NL80211_CMD_CH_SWITCH_STARTED_NOTIFY: Notify that a channel switch
+ *	has been started on an interface, regardless of the initiator
+ *	(ie. whether it was requested from a remote device or
+ *	initiated on our own).  It indicates that
+ *	%NL80211_ATTR_IFINDEX will be on %NL80211_ATTR_WIPHY_FREQ
+ *	after %NL80211_ATTR_CH_SWITCH_COUNT TBTT's.  The userspace may
+ *	decide to react to this indication by requesting other
+ *	interfaces to change channel as well.
+ *
+ * @NL80211_CMD_START_P2P_DEVICE: Start the given P2P Device, identified by
+ *	its %NL80211_ATTR_WDEV identifier. It must have been created with
+ *	%NL80211_CMD_NEW_INTERFACE previously. After it has been started, the
+ *	P2P Device can be used for P2P operations, e.g. remain-on-channel and
+ *	public action frame TX.
+ * @NL80211_CMD_STOP_P2P_DEVICE: Stop the given P2P Device, identified by
+ *	its %NL80211_ATTR_WDEV identifier.
+ *
+ * @NL80211_CMD_CONN_FAILED: connection request to an AP failed; used to
+ *	notify userspace that AP has rejected the connection request from a
+ *	station, due to particular reason. %NL80211_ATTR_CONN_FAILED_REASON
+ *	is used for this.
+ *
+ * @NL80211_CMD_SET_MCAST_RATE: Change the rate used to send multicast frames
+ *	for IBSS or MESH vif.
+ *
+ * @NL80211_CMD_SET_MAC_ACL: sets ACL for MAC address based access control.
+ *	This is to be used with the drivers advertising the support of MAC
+ *	address based access control. List of MAC addresses is passed in
+ *	%NL80211_ATTR_MAC_ADDRS and ACL policy is passed in
+ *	%NL80211_ATTR_ACL_POLICY. Driver will enable ACL with this list, if it
+ *	is not already done. The new list will replace any existing list. Driver
+ *	will clear its ACL when the list of MAC addresses passed is empty. This
+ *	command is used in AP/P2P GO mode. Driver has to make sure to clear its
+ *	ACL list during %NL80211_CMD_STOP_AP.
+ *
+ * @NL80211_CMD_RADAR_DETECT: Start a Channel availability check (CAC). Once
+ *	a radar is detected or the channel availability scan (CAC) has finished
+ *	or was aborted, or a radar was detected, usermode will be notified with
+ *	this event. This command is also used to notify userspace about radars
+ *	while operating on this channel.
+ *	%NL80211_ATTR_RADAR_EVENT is used to inform about the type of the
+ *	event.
+ *
+ * @NL80211_CMD_GET_PROTOCOL_FEATURES: Get global nl80211 protocol features,
+ *	i.e. features for the nl80211 protocol rather than device features.
+ *	Returns the features in the %NL80211_ATTR_PROTOCOL_FEATURES bitmap.
+ *
+ * @NL80211_CMD_UPDATE_FT_IES: Pass down the most up-to-date Fast Transition
+ *	Information Element to the WLAN driver
+ *
+ * @NL80211_CMD_FT_EVENT: Send a Fast transition event from the WLAN driver
+ *	to the supplicant. This will carry the target AP's MAC address along
+ *	with the relevant Information Elements. This event is used to report
+ *	received FT IEs (MDIE, FTIE, RSN IE, TIE, RICIE).
+ *
+ * @NL80211_CMD_CRIT_PROTOCOL_START: Indicates user-space will start running
+ *	a critical protocol that needs more reliability in the connection to
+ *	complete.
+ *
+ * @NL80211_CMD_CRIT_PROTOCOL_STOP: Indicates the connection reliability can
+ *	return back to normal.
+ *
+ * @NL80211_CMD_GET_COALESCE: Get currently supported coalesce rules.
+ * @NL80211_CMD_SET_COALESCE: Configure coalesce rules or clear existing rules.
+ *
+ * @NL80211_CMD_CHANNEL_SWITCH: Perform a channel switch by announcing the
+ *	the new channel information (Channel Switch Announcement - CSA)
+ *	in the beacon for some time (as defined in the
+ *	%NL80211_ATTR_CH_SWITCH_COUNT parameter) and then change to the
+ *	new channel. Userspace provides the new channel information (using
+ *	%NL80211_ATTR_WIPHY_FREQ and the attributes determining channel
+ *	width). %NL80211_ATTR_CH_SWITCH_BLOCK_TX may be supplied to inform
+ *	other station that transmission must be blocked until the channel
+ *	switch is complete.
+ *
+ * @NL80211_CMD_VENDOR: Vendor-specified command/event. The command is specified
+ *	by the %NL80211_ATTR_VENDOR_ID attribute and a sub-command in
+ *	%NL80211_ATTR_VENDOR_SUBCMD. Parameter(s) can be transported in
+ *	%NL80211_ATTR_VENDOR_DATA.
+ *	For feature advertisement, the %NL80211_ATTR_VENDOR_DATA attribute is
+ *	used in the wiphy data as a nested attribute containing descriptions
+ *	(&struct nl80211_vendor_cmd_info) of the supported vendor commands.
+ *	This may also be sent as an event with the same attributes.
+ *
+ * @NL80211_CMD_SET_QOS_MAP: Set Interworking QoS mapping for IP DSCP values.
+ *	The QoS mapping information is included in %NL80211_ATTR_QOS_MAP. If
+ *	that attribute is not included, QoS mapping is disabled. Since this
+ *	QoS mapping is relevant for IP packets, it is only valid during an
+ *	association. This is cleared on disassociation and AP restart.
+ *
+ * @NL80211_CMD_ADD_TX_TS: Ask the kernel to add a traffic stream for the given
+ *	%NL80211_ATTR_TSID and %NL80211_ATTR_MAC with %NL80211_ATTR_USER_PRIO
+ *	and %NL80211_ATTR_ADMITTED_TIME parameters.
+ *	Note that the action frame handshake with the AP shall be handled by
+ *	userspace via the normal management RX/TX framework, this only sets
+ *	up the TX TS in the driver/device.
+ *	If the admitted time attribute is not added then the request just checks
+ *	if a subsequent setup could be successful, the intent is to use this to
+ *	avoid setting up a session with the AP when local restrictions would
+ *	make that impossible. However, the subsequent "real" setup may still
+ *	fail even if the check was successful.
+ * @NL80211_CMD_DEL_TX_TS: Remove an existing TS with the %NL80211_ATTR_TSID
+ *	and %NL80211_ATTR_MAC parameters. It isn't necessary to call this
+ *	before removing a station entry entirely, or before disassociating
+ *	or similar, cleanup will happen in the driver/device in this case.
+ *
+ * @NL80211_CMD_GET_MPP: Get mesh path attributes for mesh proxy path to
+ *	destination %NL80211_ATTR_MAC on the interface identified by
+ *	%NL80211_ATTR_IFINDEX.
+ *
+ * @NL80211_CMD_JOIN_OCB: Join the OCB network. The center frequency and
+ *	bandwidth of a channel must be given.
+ * @NL80211_CMD_LEAVE_OCB: Leave the OCB network -- no special arguments, the
+ *	network is determined by the network interface.
+ *
+ * @NL80211_CMD_TDLS_CHANNEL_SWITCH: Start channel-switching with a TDLS peer,
+ *	identified by the %NL80211_ATTR_MAC parameter. A target channel is
+ *	provided via %NL80211_ATTR_WIPHY_FREQ and other attributes determining
+ *	channel width/type. The target operating class is given via
+ *	%NL80211_ATTR_OPER_CLASS.
+ *	The driver is responsible for continually initiating channel-switching
+ *	operations and returning to the base channel for communication with the
+ *	AP.
+ * @NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH: Stop channel-switching with a TDLS
+ *	peer given by %NL80211_ATTR_MAC. Both peers must be on the base channel
+ *	when this command completes.
+ *
+ * @NL80211_CMD_WIPHY_REG_CHANGE: Similar to %NL80211_CMD_REG_CHANGE, but used
+ *	as an event to indicate changes for devices with wiphy-specific regdom
+ *	management.
+ *
+ * @NL80211_CMD_ABORT_SCAN: Stop an ongoing scan. Returns -ENOENT if a scan is
+ *	not running. The driver indicates the status of the scan through
+ *	cfg80211_scan_done().
+ *
+ * @NL80211_CMD_START_NAN: Start NAN operation, identified by its
+ *	%NL80211_ATTR_WDEV interface. This interface must have been
+ *	previously created with %NL80211_CMD_NEW_INTERFACE. After it
+ *	has been started, the NAN interface will create or join a
+ *	cluster. This command must have a valid
+ *	%NL80211_ATTR_NAN_MASTER_PREF attribute and optional
+ *	%NL80211_ATTR_BANDS attributes.  If %NL80211_ATTR_BANDS is
+ *	omitted or set to 0, it means don't-care and the device will
+ *	decide what to use.  After this command NAN functions can be
+ *	added.
+ * @NL80211_CMD_STOP_NAN: Stop the NAN operation, identified by
+ *	its %NL80211_ATTR_WDEV interface.
+ * @NL80211_CMD_ADD_NAN_FUNCTION: Add a NAN function. The function is defined
+ *	with %NL80211_ATTR_NAN_FUNC nested attribute. When called, this
+ *	operation returns the strictly positive and unique instance id
+ *	(%NL80211_ATTR_NAN_FUNC_INST_ID) and a cookie (%NL80211_ATTR_COOKIE)
+ *	of the function upon success.
+ *	Since instance ID's can be re-used, this cookie is the right
+ *	way to identify the function. This will avoid races when a termination
+ *	event is handled by the user space after it has already added a new
+ *	function that got the same instance id from the kernel as the one
+ *	which just terminated.
+ *	This cookie may be used in NAN events even before the command
+ *	returns, so userspace shouldn't process NAN events until it processes
+ *	the response to this command.
+ *	Look at %NL80211_ATTR_SOCKET_OWNER as well.
+ * @NL80211_CMD_DEL_NAN_FUNCTION: Delete a NAN function by cookie.
+ *	This command is also used as a notification sent when a NAN function is
+ *	terminated. This will contain a %NL80211_ATTR_NAN_FUNC_INST_ID
+ *	and %NL80211_ATTR_COOKIE attributes.
+ * @NL80211_CMD_CHANGE_NAN_CONFIG: Change current NAN
+ *	configuration. NAN must be operational (%NL80211_CMD_START_NAN
+ *	was executed).  It must contain at least one of the following
+ *	attributes: %NL80211_ATTR_NAN_MASTER_PREF,
+ *	%NL80211_ATTR_BANDS.  If %NL80211_ATTR_BANDS is omitted, the
+ *	current configuration is not changed.  If it is present but
+ *	set to zero, the configuration is changed to don't-care
+ *	(i.e. the device can decide what to do).
+ * @NL80211_CMD_NAN_FUNC_MATCH: Notification sent when a match is reported.
+ *	This will contain a %NL80211_ATTR_NAN_MATCH nested attribute and
+ *	%NL80211_ATTR_COOKIE.
+ *
+ * @NL80211_CMD_UPDATE_CONNECT_PARAMS: Update one or more connect parameters
+ *	for subsequent roaming cases if the driver or firmware uses internal
+ *	BSS selection. This command can be issued only while connected and it
+ *	does not result in a change for the current association. Currently,
+ *	only the %NL80211_ATTR_IE data is used and updated with this command.
+ *
+ * @NL80211_CMD_SET_PMK: For offloaded 4-Way handshake, set the PMK or PMK-R0
+ *	for the given authenticator address (specified with %NL80211_ATTR_MAC).
+ *	When %NL80211_ATTR_PMKR0_NAME is set, %NL80211_ATTR_PMK specifies the
+ *	PMK-R0, otherwise it specifies the PMK.
+ * @NL80211_CMD_DEL_PMK: For offloaded 4-Way handshake, delete the previously
+ *	configured PMK for the authenticator address identified by
+ *	%NL80211_ATTR_MAC.
+ * @NL80211_CMD_PORT_AUTHORIZED: An event that indicates that the 4 way
+ *	handshake was completed successfully by the driver. The BSSID is
+ *	specified with %NL80211_ATTR_MAC. Drivers that support 4 way handshake
+ *	offload should send this event after indicating 802.11 association with
+ *	%NL80211_CMD_CONNECT or %NL80211_CMD_ROAM. If the 4 way handshake failed
+ *	%NL80211_CMD_DISCONNECT should be indicated instead.
+ *
+ * @NL80211_CMD_CONTROL_PORT_FRAME: Control Port (e.g. PAE) frame TX request
+ *	and RX notification.  This command is used both as a request to transmit
+ *	a control port frame and as a notification that a control port frame
+ *	has been received. %NL80211_ATTR_FRAME is used to specify the
+ *	frame contents.  The frame is the raw EAPoL data, without ethernet or
+ *	802.11 headers.
+ *	When used as an event indication %NL80211_ATTR_CONTROL_PORT_ETHERTYPE,
+ *	%NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT and %NL80211_ATTR_MAC are added
+ *	indicating the protocol type of the received frame; whether the frame
+ *	was received unencrypted and the MAC address of the peer respectively.
+ *
+ * @NL80211_CMD_RELOAD_REGDB: Request that the regdb firmware file is reloaded.
+ *
+ * @NL80211_CMD_EXTERNAL_AUTH: This interface is exclusively defined for host
+ *	drivers that do not define separate commands for authentication and
+ *	association, but rely on user space for the authentication to happen.
+ *	This interface acts both as the event request (driver to user space)
+ *	to trigger the authentication and command response (userspace to
+ *	driver) to indicate the authentication status.
+ *
+ *	User space uses the %NL80211_CMD_CONNECT command to the host driver to
+ *	trigger a connection. The host driver selects a BSS and further uses
+ *	this interface to offload only the authentication part to the user
+ *	space. Authentication frames are passed between the driver and user
+ *	space through the %NL80211_CMD_FRAME interface. Host driver proceeds
+ *	further with the association after getting successful authentication
+ *	status. User space indicates the authentication status through
+ *	%NL80211_ATTR_STATUS_CODE attribute in %NL80211_CMD_EXTERNAL_AUTH
+ *	command interface.
+ *
+ *	Host driver reports this status on an authentication failure to the
+ *	user space through the connect result as the user space would have
+ *	initiated the connection through the connect request.
+ *
+ * @NL80211_CMD_STA_OPMODE_CHANGED: An event that notify station's
+ *	ht opmode or vht opmode changes using any of %NL80211_ATTR_SMPS_MODE,
+ *	%NL80211_ATTR_CHANNEL_WIDTH,%NL80211_ATTR_NSS attributes with its
+ *	address(specified in %NL80211_ATTR_MAC).
+ *
+ * @NL80211_CMD_MAX: highest used command number
+ * @__NL80211_CMD_AFTER_LAST: internal use
+ */
+enum nl80211_commands {
+/* don't change the order or add anything between, this is ABI! */
+	NL80211_CMD_UNSPEC,
+
+	NL80211_CMD_GET_WIPHY,		/* can dump */
+	NL80211_CMD_SET_WIPHY,
+	NL80211_CMD_NEW_WIPHY,
+	NL80211_CMD_DEL_WIPHY,
+
+	NL80211_CMD_GET_INTERFACE,	/* can dump */
+	NL80211_CMD_SET_INTERFACE,
+	NL80211_CMD_NEW_INTERFACE,
+	NL80211_CMD_DEL_INTERFACE,
+
+	NL80211_CMD_GET_KEY,
+	NL80211_CMD_SET_KEY,
+	NL80211_CMD_NEW_KEY,
+	NL80211_CMD_DEL_KEY,
+
+	NL80211_CMD_GET_BEACON,
+	NL80211_CMD_SET_BEACON,
+	NL80211_CMD_START_AP,
+	NL80211_CMD_NEW_BEACON = NL80211_CMD_START_AP,
+	NL80211_CMD_STOP_AP,
+	NL80211_CMD_DEL_BEACON = NL80211_CMD_STOP_AP,
+
+	NL80211_CMD_GET_STATION,
+	NL80211_CMD_SET_STATION,
+	NL80211_CMD_NEW_STATION,
+	NL80211_CMD_DEL_STATION,
+
+	NL80211_CMD_GET_MPATH,
+	NL80211_CMD_SET_MPATH,
+	NL80211_CMD_NEW_MPATH,
+	NL80211_CMD_DEL_MPATH,
+
+	NL80211_CMD_SET_BSS,
+
+	NL80211_CMD_SET_REG,
+	NL80211_CMD_REQ_SET_REG,
+
+	NL80211_CMD_GET_MESH_CONFIG,
+	NL80211_CMD_SET_MESH_CONFIG,
+
+	NL80211_CMD_SET_MGMT_EXTRA_IE /* reserved; not used */,
+
+	NL80211_CMD_GET_REG,
+
+	NL80211_CMD_GET_SCAN,
+	NL80211_CMD_TRIGGER_SCAN,
+	NL80211_CMD_NEW_SCAN_RESULTS,
+	NL80211_CMD_SCAN_ABORTED,
+
+	NL80211_CMD_REG_CHANGE,
+
+	NL80211_CMD_AUTHENTICATE,
+	NL80211_CMD_ASSOCIATE,
+	NL80211_CMD_DEAUTHENTICATE,
+	NL80211_CMD_DISASSOCIATE,
+
+	NL80211_CMD_MICHAEL_MIC_FAILURE,
+
+	NL80211_CMD_REG_BEACON_HINT,
+
+	NL80211_CMD_JOIN_IBSS,
+	NL80211_CMD_LEAVE_IBSS,
+
+	NL80211_CMD_TESTMODE,
+
+	NL80211_CMD_CONNECT,
+	NL80211_CMD_ROAM,
+	NL80211_CMD_DISCONNECT,
+
+	NL80211_CMD_SET_WIPHY_NETNS,
+
+	NL80211_CMD_GET_SURVEY,
+	NL80211_CMD_NEW_SURVEY_RESULTS,
+
+	NL80211_CMD_SET_PMKSA,
+	NL80211_CMD_DEL_PMKSA,
+	NL80211_CMD_FLUSH_PMKSA,
+
+	NL80211_CMD_REMAIN_ON_CHANNEL,
+	NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
+
+	NL80211_CMD_SET_TX_BITRATE_MASK,
+
+	NL80211_CMD_REGISTER_FRAME,
+	NL80211_CMD_REGISTER_ACTION = NL80211_CMD_REGISTER_FRAME,
+	NL80211_CMD_FRAME,
+	NL80211_CMD_ACTION = NL80211_CMD_FRAME,
+	NL80211_CMD_FRAME_TX_STATUS,
+	NL80211_CMD_ACTION_TX_STATUS = NL80211_CMD_FRAME_TX_STATUS,
+
+	NL80211_CMD_SET_POWER_SAVE,
+	NL80211_CMD_GET_POWER_SAVE,
+
+	NL80211_CMD_SET_CQM,
+	NL80211_CMD_NOTIFY_CQM,
+
+	NL80211_CMD_SET_CHANNEL,
+	NL80211_CMD_SET_WDS_PEER,
+
+	NL80211_CMD_FRAME_WAIT_CANCEL,
+
+	NL80211_CMD_JOIN_MESH,
+	NL80211_CMD_LEAVE_MESH,
+
+	NL80211_CMD_UNPROT_DEAUTHENTICATE,
+	NL80211_CMD_UNPROT_DISASSOCIATE,
+
+	NL80211_CMD_NEW_PEER_CANDIDATE,
+
+	NL80211_CMD_GET_WOWLAN,
+	NL80211_CMD_SET_WOWLAN,
+
+	NL80211_CMD_START_SCHED_SCAN,
+	NL80211_CMD_STOP_SCHED_SCAN,
+	NL80211_CMD_SCHED_SCAN_RESULTS,
+	NL80211_CMD_SCHED_SCAN_STOPPED,
+
+	NL80211_CMD_SET_REKEY_OFFLOAD,
+
+	NL80211_CMD_PMKSA_CANDIDATE,
+
+	NL80211_CMD_TDLS_OPER,
+	NL80211_CMD_TDLS_MGMT,
+
+	NL80211_CMD_UNEXPECTED_FRAME,
+
+	NL80211_CMD_PROBE_CLIENT,
+
+	NL80211_CMD_REGISTER_BEACONS,
+
+	NL80211_CMD_UNEXPECTED_4ADDR_FRAME,
+
+	NL80211_CMD_SET_NOACK_MAP,
+
+	NL80211_CMD_CH_SWITCH_NOTIFY,
+
+	NL80211_CMD_START_P2P_DEVICE,
+	NL80211_CMD_STOP_P2P_DEVICE,
+
+	NL80211_CMD_CONN_FAILED,
+
+	NL80211_CMD_SET_MCAST_RATE,
+
+	NL80211_CMD_SET_MAC_ACL,
+
+	NL80211_CMD_RADAR_DETECT,
+
+	NL80211_CMD_GET_PROTOCOL_FEATURES,
+
+	NL80211_CMD_UPDATE_FT_IES,
+	NL80211_CMD_FT_EVENT,
+
+	NL80211_CMD_CRIT_PROTOCOL_START,
+	NL80211_CMD_CRIT_PROTOCOL_STOP,
+
+	NL80211_CMD_GET_COALESCE,
+	NL80211_CMD_SET_COALESCE,
+
+	NL80211_CMD_CHANNEL_SWITCH,
+
+	NL80211_CMD_VENDOR,
+
+	NL80211_CMD_SET_QOS_MAP,
+
+	NL80211_CMD_ADD_TX_TS,
+	NL80211_CMD_DEL_TX_TS,
+
+	NL80211_CMD_GET_MPP,
+
+	NL80211_CMD_JOIN_OCB,
+	NL80211_CMD_LEAVE_OCB,
+
+	NL80211_CMD_CH_SWITCH_STARTED_NOTIFY,
+
+	NL80211_CMD_TDLS_CHANNEL_SWITCH,
+	NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH,
+
+	NL80211_CMD_WIPHY_REG_CHANGE,
+
+	NL80211_CMD_ABORT_SCAN,
+
+	NL80211_CMD_START_NAN,
+	NL80211_CMD_STOP_NAN,
+	NL80211_CMD_ADD_NAN_FUNCTION,
+	NL80211_CMD_DEL_NAN_FUNCTION,
+	NL80211_CMD_CHANGE_NAN_CONFIG,
+	NL80211_CMD_NAN_MATCH,
+
+	NL80211_CMD_SET_MULTICAST_TO_UNICAST,
+
+	NL80211_CMD_UPDATE_CONNECT_PARAMS,
+
+	NL80211_CMD_SET_PMK,
+	NL80211_CMD_DEL_PMK,
+
+	NL80211_CMD_PORT_AUTHORIZED,
+
+	NL80211_CMD_RELOAD_REGDB,
+
+	NL80211_CMD_EXTERNAL_AUTH,
+
+	NL80211_CMD_STA_OPMODE_CHANGED,
+
+	NL80211_CMD_CONTROL_PORT_FRAME,
+
+	/* add new commands above here */
+
+	/* used to define NL80211_CMD_MAX below */
+	__NL80211_CMD_AFTER_LAST,
+	NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1
+};
+
+/*
+ * Allow user space programs to use #ifdef on new commands by defining them
+ * here
+ */
+#define NL80211_CMD_SET_BSS NL80211_CMD_SET_BSS
+#define NL80211_CMD_SET_MGMT_EXTRA_IE NL80211_CMD_SET_MGMT_EXTRA_IE
+#define NL80211_CMD_REG_CHANGE NL80211_CMD_REG_CHANGE
+#define NL80211_CMD_AUTHENTICATE NL80211_CMD_AUTHENTICATE
+#define NL80211_CMD_ASSOCIATE NL80211_CMD_ASSOCIATE
+#define NL80211_CMD_DEAUTHENTICATE NL80211_CMD_DEAUTHENTICATE
+#define NL80211_CMD_DISASSOCIATE NL80211_CMD_DISASSOCIATE
+#define NL80211_CMD_REG_BEACON_HINT NL80211_CMD_REG_BEACON_HINT
+
+#define NL80211_ATTR_FEATURE_FLAGS NL80211_ATTR_FEATURE_FLAGS
+
+/* source-level API compatibility */
+#define NL80211_CMD_GET_MESH_PARAMS NL80211_CMD_GET_MESH_CONFIG
+#define NL80211_CMD_SET_MESH_PARAMS NL80211_CMD_SET_MESH_CONFIG
+#define NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE NL80211_MESH_SETUP_IE
+
+ /**
+ * DOC: SAE authentication offload
+ *
+ * By setting @NL80211_EXT_FEATURE_SAE_OFFLOAD flag drivers can indicate they
+ * support offloading SAE authentication for WPA3-Personal networks. In
+ * %NL80211_CMD_CONNECT the password for SAE should be specified using
+ * %NL80211_ATTR_SAE_PASSWORD.
+ */
+
+/**
+ * enum nl80211_attrs - nl80211 netlink attributes
+ *
+ * @NL80211_ATTR_UNSPEC: unspecified attribute to catch errors
+ *
+ * @NL80211_ATTR_WIPHY: index of wiphy to operate on, cf.
+ *	/sys/class/ieee80211/<phyname>/index
+ * @NL80211_ATTR_WIPHY_NAME: wiphy name (used for renaming)
+ * @NL80211_ATTR_WIPHY_TXQ_PARAMS: a nested array of TX queue parameters
+ * @NL80211_ATTR_WIPHY_FREQ: frequency of the selected channel in MHz,
+ *	defines the channel together with the (deprecated)
+ *	%NL80211_ATTR_WIPHY_CHANNEL_TYPE attribute or the attributes
+ *	%NL80211_ATTR_CHANNEL_WIDTH and if needed %NL80211_ATTR_CENTER_FREQ1
+ *	and %NL80211_ATTR_CENTER_FREQ2
+ * @NL80211_ATTR_CHANNEL_WIDTH: u32 attribute containing one of the values
+ *	of &enum nl80211_chan_width, describing the channel width. See the
+ *	documentation of the enum for more information.
+ * @NL80211_ATTR_CENTER_FREQ1: Center frequency of the first part of the
+ *	channel, used for anything but 20 MHz bandwidth
+ * @NL80211_ATTR_CENTER_FREQ2: Center frequency of the second part of the
+ *	channel, used only for 80+80 MHz bandwidth
+ * @NL80211_ATTR_WIPHY_CHANNEL_TYPE: included with NL80211_ATTR_WIPHY_FREQ
+ *	if HT20 or HT40 are to be used (i.e., HT disabled if not included):
+ *	NL80211_CHAN_NO_HT = HT not allowed (i.e., same as not including
+ *		this attribute)
+ *	NL80211_CHAN_HT20 = HT20 only
+ *	NL80211_CHAN_HT40MINUS = secondary channel is below the primary channel
+ *	NL80211_CHAN_HT40PLUS = secondary channel is above the primary channel
+ *	This attribute is now deprecated.
+ * @NL80211_ATTR_WIPHY_RETRY_SHORT: TX retry limit for frames whose length is
+ *	less than or equal to the RTS threshold; allowed range: 1..255;
+ *	dot11ShortRetryLimit; u8
+ * @NL80211_ATTR_WIPHY_RETRY_LONG: TX retry limit for frames whose length is
+ *	greater than the RTS threshold; allowed range: 1..255;
+ *	dot11ShortLongLimit; u8
+ * @NL80211_ATTR_WIPHY_FRAG_THRESHOLD: fragmentation threshold, i.e., maximum
+ *	length in octets for frames; allowed range: 256..8000, disable
+ *	fragmentation with (u32)-1; dot11FragmentationThreshold; u32
+ * @NL80211_ATTR_WIPHY_RTS_THRESHOLD: RTS threshold (TX frames with length
+ *	larger than or equal to this use RTS/CTS handshake); allowed range:
+ *	0..65536, disable with (u32)-1; dot11RTSThreshold; u32
+ * @NL80211_ATTR_WIPHY_COVERAGE_CLASS: Coverage Class as defined by IEEE 802.11
+ *	section 7.3.2.9; dot11CoverageClass; u8
+ *
+ * @NL80211_ATTR_IFINDEX: network interface index of the device to operate on
+ * @NL80211_ATTR_IFNAME: network interface name
+ * @NL80211_ATTR_IFTYPE: type of virtual interface, see &enum nl80211_iftype
+ *
+ * @NL80211_ATTR_WDEV: wireless device identifier, used for pseudo-devices
+ *	that don't have a netdev (u64)
+ *
+ * @NL80211_ATTR_MAC: MAC address (various uses)
+ *
+ * @NL80211_ATTR_KEY_DATA: (temporal) key data; for TKIP this consists of
+ *	16 bytes encryption key followed by 8 bytes each for TX and RX MIC
+ *	keys
+ * @NL80211_ATTR_KEY_IDX: key ID (u8, 0-3)
+ * @NL80211_ATTR_KEY_CIPHER: key cipher suite (u32, as defined by IEEE 802.11
+ *	section 7.3.2.25.1, e.g. 0x000FAC04)
+ * @NL80211_ATTR_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and
+ *	CCMP keys, each six bytes in little endian
+ * @NL80211_ATTR_KEY_DEFAULT: Flag attribute indicating the key is default key
+ * @NL80211_ATTR_KEY_DEFAULT_MGMT: Flag attribute indicating the key is the
+ *	default management key
+ * @NL80211_ATTR_CIPHER_SUITES_PAIRWISE: For crypto settings for connect or
+ *	other commands, indicates which pairwise cipher suites are used
+ * @NL80211_ATTR_CIPHER_SUITE_GROUP: For crypto settings for connect or
+ *	other commands, indicates which group cipher suite is used
+ *
+ * @NL80211_ATTR_BEACON_INTERVAL: beacon interval in TU
+ * @NL80211_ATTR_DTIM_PERIOD: DTIM period for beaconing
+ * @NL80211_ATTR_BEACON_HEAD: portion of the beacon before the TIM IE
+ * @NL80211_ATTR_BEACON_TAIL: portion of the beacon after the TIM IE
+ *
+ * @NL80211_ATTR_STA_AID: Association ID for the station (u16)
+ * @NL80211_ATTR_STA_FLAGS: flags, nested element with NLA_FLAG attributes of
+ *	&enum nl80211_sta_flags (deprecated, use %NL80211_ATTR_STA_FLAGS2)
+ * @NL80211_ATTR_STA_LISTEN_INTERVAL: listen interval as defined by
+ *	IEEE 802.11 7.3.1.6 (u16).
+ * @NL80211_ATTR_STA_SUPPORTED_RATES: supported rates, array of supported
+ *	rates as defined by IEEE 802.11 7.3.2.2 but without the length
+ *	restriction (at most %NL80211_MAX_SUPP_RATES).
+ * @NL80211_ATTR_STA_VLAN: interface index of VLAN interface to move station
+ *	to, or the AP interface the station was originally added to to.
+ * @NL80211_ATTR_STA_INFO: information about a station, part of station info
+ *	given for %NL80211_CMD_GET_STATION, nested attribute containing
+ *	info as possible, see &enum nl80211_sta_info.
+ *
+ * @NL80211_ATTR_WIPHY_BANDS: Information about an operating bands,
+ *	consisting of a nested array.
+ *
+ * @NL80211_ATTR_MESH_ID: mesh id (1-32 bytes).
+ * @NL80211_ATTR_STA_PLINK_ACTION: action to perform on the mesh peer link
+ *	(see &enum nl80211_plink_action).
+ * @NL80211_ATTR_MPATH_NEXT_HOP: MAC address of the next hop for a mesh path.
+ * @NL80211_ATTR_MPATH_INFO: information about a mesh_path, part of mesh path
+ * 	info given for %NL80211_CMD_GET_MPATH, nested attribute described at
+ *	&enum nl80211_mpath_info.
+ *
+ * @NL80211_ATTR_MNTR_FLAGS: flags, nested element with NLA_FLAG attributes of
+ *      &enum nl80211_mntr_flags.
+ *
+ * @NL80211_ATTR_REG_ALPHA2: an ISO-3166-alpha2 country code for which the
+ * 	current regulatory domain should be set to or is already set to.
+ * 	For example, 'CR', for Costa Rica. This attribute is used by the kernel
+ * 	to query the CRDA to retrieve one regulatory domain. This attribute can
+ * 	also be used by userspace to query the kernel for the currently set
+ * 	regulatory domain. We chose an alpha2 as that is also used by the
+ * 	IEEE-802.11 country information element to identify a country.
+ * 	Users can also simply ask the wireless core to set regulatory domain
+ * 	to a specific alpha2.
+ * @NL80211_ATTR_REG_RULES: a nested array of regulatory domain regulatory
+ *	rules.
+ *
+ * @NL80211_ATTR_BSS_CTS_PROT: whether CTS protection is enabled (u8, 0 or 1)
+ * @NL80211_ATTR_BSS_SHORT_PREAMBLE: whether short preamble is enabled
+ *	(u8, 0 or 1)
+ * @NL80211_ATTR_BSS_SHORT_SLOT_TIME: whether short slot time enabled
+ *	(u8, 0 or 1)
+ * @NL80211_ATTR_BSS_BASIC_RATES: basic rates, array of basic
+ *	rates in format defined by IEEE 802.11 7.3.2.2 but without the length
+ *	restriction (at most %NL80211_MAX_SUPP_RATES).
+ *
+ * @NL80211_ATTR_HT_CAPABILITY: HT Capability information element (from
+ *	association request when used with NL80211_CMD_NEW_STATION)
+ *
+ * @NL80211_ATTR_SUPPORTED_IFTYPES: nested attribute containing all
+ *	supported interface types, each a flag attribute with the number
+ *	of the interface mode.
+ *
+ * @NL80211_ATTR_MGMT_SUBTYPE: Management frame subtype for
+ *	%NL80211_CMD_SET_MGMT_EXTRA_IE.
+ *
+ * @NL80211_ATTR_IE: Information element(s) data (used, e.g., with
+ *	%NL80211_CMD_SET_MGMT_EXTRA_IE).
+ *
+ * @NL80211_ATTR_MAX_NUM_SCAN_SSIDS: number of SSIDs you can scan with
+ *	a single scan request, a wiphy attribute.
+ * @NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS: number of SSIDs you can
+ *	scan with a single scheduled scan request, a wiphy attribute.
+ * @NL80211_ATTR_MAX_SCAN_IE_LEN: maximum length of information elements
+ *	that can be added to a scan request
+ * @NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN: maximum length of information
+ *	elements that can be added to a scheduled scan request
+ * @NL80211_ATTR_MAX_MATCH_SETS: maximum number of sets that can be
+ *	used with @NL80211_ATTR_SCHED_SCAN_MATCH, a wiphy attribute.
+ *
+ * @NL80211_ATTR_SCAN_FREQUENCIES: nested attribute with frequencies (in MHz)
+ * @NL80211_ATTR_SCAN_SSIDS: nested attribute with SSIDs, leave out for passive
+ *	scanning and include a zero-length SSID (wildcard) for wildcard scan
+ * @NL80211_ATTR_BSS: scan result BSS
+ *
+ * @NL80211_ATTR_REG_INITIATOR: indicates who requested the regulatory domain
+ * 	currently in effect. This could be any of the %NL80211_REGDOM_SET_BY_*
+ * @NL80211_ATTR_REG_TYPE: indicates the type of the regulatory domain currently
+ * 	set. This can be one of the nl80211_reg_type (%NL80211_REGDOM_TYPE_*)
+ *
+ * @NL80211_ATTR_SUPPORTED_COMMANDS: wiphy attribute that specifies
+ *	an array of command numbers (i.e. a mapping index to command number)
+ *	that the driver for the given wiphy supports.
+ *
+ * @NL80211_ATTR_FRAME: frame data (binary attribute), including frame header
+ *	and body, but not FCS; used, e.g., with NL80211_CMD_AUTHENTICATE and
+ *	NL80211_CMD_ASSOCIATE events
+ * @NL80211_ATTR_SSID: SSID (binary attribute, 0..32 octets)
+ * @NL80211_ATTR_AUTH_TYPE: AuthenticationType, see &enum nl80211_auth_type,
+ *	represented as a u32
+ * @NL80211_ATTR_REASON_CODE: ReasonCode for %NL80211_CMD_DEAUTHENTICATE and
+ *	%NL80211_CMD_DISASSOCIATE, u16
+ *
+ * @NL80211_ATTR_KEY_TYPE: Key Type, see &enum nl80211_key_type, represented as
+ *	a u32
+ *
+ * @NL80211_ATTR_FREQ_BEFORE: A channel which has suffered a regulatory change
+ * 	due to considerations from a beacon hint. This attribute reflects
+ * 	the state of the channel _before_ the beacon hint processing. This
+ * 	attributes consists of a nested attribute containing
+ * 	NL80211_FREQUENCY_ATTR_*
+ * @NL80211_ATTR_FREQ_AFTER: A channel which has suffered a regulatory change
+ * 	due to considerations from a beacon hint. This attribute reflects
+ * 	the state of the channel _after_ the beacon hint processing. This
+ * 	attributes consists of a nested attribute containing
+ * 	NL80211_FREQUENCY_ATTR_*
+ *
+ * @NL80211_ATTR_CIPHER_SUITES: a set of u32 values indicating the supported
+ *	cipher suites
+ *
+ * @NL80211_ATTR_FREQ_FIXED: a flag indicating the IBSS should not try to look
+ *	for other networks on different channels
+ *
+ * @NL80211_ATTR_TIMED_OUT: a flag indicating than an operation timed out; this
+ *	is used, e.g., with %NL80211_CMD_AUTHENTICATE event
+ *
+ * @NL80211_ATTR_USE_MFP: Whether management frame protection (IEEE 802.11w) is
+ *	used for the association (&enum nl80211_mfp, represented as a u32);
+ *	this attribute can be used with %NL80211_CMD_ASSOCIATE and
+ *	%NL80211_CMD_CONNECT requests. %NL80211_MFP_OPTIONAL is not allowed for
+ *	%NL80211_CMD_ASSOCIATE since user space SME is expected and hence, it
+ *	must have decided whether to use management frame protection or not.
+ *	Setting %NL80211_MFP_OPTIONAL with a %NL80211_CMD_CONNECT request will
+ *	let the driver (or the firmware) decide whether to use MFP or not.
+ *
+ * @NL80211_ATTR_STA_FLAGS2: Attribute containing a
+ *	&struct nl80211_sta_flag_update.
+ *
+ * @NL80211_ATTR_CONTROL_PORT: A flag indicating whether user space controls
+ *	IEEE 802.1X port, i.e., sets/clears %NL80211_STA_FLAG_AUTHORIZED, in
+ *	station mode. If the flag is included in %NL80211_CMD_ASSOCIATE
+ *	request, the driver will assume that the port is unauthorized until
+ *	authorized by user space. Otherwise, port is marked authorized by
+ *	default in station mode.
+ * @NL80211_ATTR_CONTROL_PORT_ETHERTYPE: A 16-bit value indicating the
+ *	ethertype that will be used for key negotiation. It can be
+ *	specified with the associate and connect commands. If it is not
+ *	specified, the value defaults to 0x888E (PAE, 802.1X). This
+ *	attribute is also used as a flag in the wiphy information to
+ *	indicate that protocols other than PAE are supported.
+ * @NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT: When included along with
+ *	%NL80211_ATTR_CONTROL_PORT_ETHERTYPE, indicates that the custom
+ *	ethertype frames used for key negotiation must not be encrypted.
+ * @NL80211_ATTR_CONTROL_PORT_OVER_NL80211: A flag indicating whether control
+ *	port frames (e.g. of type given in %NL80211_ATTR_CONTROL_PORT_ETHERTYPE)
+ *	will be sent directly to the network interface or sent via the NL80211
+ *	socket.  If this attribute is missing, then legacy behavior of sending
+ *	control port frames directly to the network interface is used.  If the
+ *	flag is included, then control port frames are sent over NL80211 instead
+ *	using %CMD_CONTROL_PORT_FRAME.  If control port routing over NL80211 is
+ *	to be used then userspace must also use the %NL80211_ATTR_SOCKET_OWNER
+ *	flag.
+ *
+ * @NL80211_ATTR_TESTDATA: Testmode data blob, passed through to the driver.
+ *	We recommend using nested, driver-specific attributes within this.
+ *
+ * @NL80211_ATTR_DISCONNECTED_BY_AP: A flag indicating that the DISCONNECT
+ *	event was due to the AP disconnecting the station, and not due to
+ *	a local disconnect request.
+ * @NL80211_ATTR_STATUS_CODE: StatusCode for the %NL80211_CMD_CONNECT
+ *	event (u16)
+ * @NL80211_ATTR_PRIVACY: Flag attribute, used with connect(), indicating
+ *	that protected APs should be used. This is also used with NEW_BEACON to
+ *	indicate that the BSS is to use protection.
+ *
+ * @NL80211_ATTR_CIPHERS_PAIRWISE: Used with CONNECT, ASSOCIATE, and NEW_BEACON
+ *	to indicate which unicast key ciphers will be used with the connection
+ *	(an array of u32).
+ * @NL80211_ATTR_CIPHER_GROUP: Used with CONNECT, ASSOCIATE, and NEW_BEACON to
+ *	indicate which group key cipher will be used with the connection (a
+ *	u32).
+ * @NL80211_ATTR_WPA_VERSIONS: Used with CONNECT, ASSOCIATE, and NEW_BEACON to
+ *	indicate which WPA version(s) the AP we want to associate with is using
+ *	(a u32 with flags from &enum nl80211_wpa_versions).
+ * @NL80211_ATTR_AKM_SUITES: Used with CONNECT, ASSOCIATE, and NEW_BEACON to
+ *	indicate which key management algorithm(s) to use (an array of u32).
+ *
+ * @NL80211_ATTR_REQ_IE: (Re)association request information elements as
+ *	sent out by the card, for ROAM and successful CONNECT events.
+ * @NL80211_ATTR_RESP_IE: (Re)association response information elements as
+ *	sent by peer, for ROAM and successful CONNECT events.
+ *
+ * @NL80211_ATTR_PREV_BSSID: previous BSSID, to be used in ASSOCIATE and CONNECT
+ *	commands to specify a request to reassociate within an ESS, i.e., to use
+ *	Reassociate Request frame (with the value of this attribute in the
+ *	Current AP address field) instead of Association Request frame which is
+ *	used for the initial association to an ESS.
+ *
+ * @NL80211_ATTR_KEY: key information in a nested attribute with
+ *	%NL80211_KEY_* sub-attributes
+ * @NL80211_ATTR_KEYS: array of keys for static WEP keys for connect()
+ *	and join_ibss(), key information is in a nested attribute each
+ *	with %NL80211_KEY_* sub-attributes
+ *
+ * @NL80211_ATTR_PID: Process ID of a network namespace.
+ *
+ * @NL80211_ATTR_GENERATION: Used to indicate consistent snapshots for
+ *	dumps. This number increases whenever the object list being
+ *	dumped changes, and as such userspace can verify that it has
+ *	obtained a complete and consistent snapshot by verifying that
+ *	all dump messages contain the same generation number. If it
+ *	changed then the list changed and the dump should be repeated
+ *	completely from scratch.
+ *
+ * @NL80211_ATTR_4ADDR: Use 4-address frames on a virtual interface
+ *
+ * @NL80211_ATTR_SURVEY_INFO: survey information about a channel, part of
+ *      the survey response for %NL80211_CMD_GET_SURVEY, nested attribute
+ *      containing info as possible, see &enum survey_info.
+ *
+ * @NL80211_ATTR_PMKID: PMK material for PMKSA caching.
+ * @NL80211_ATTR_MAX_NUM_PMKIDS: maximum number of PMKIDs a firmware can
+ *	cache, a wiphy attribute.
+ *
+ * @NL80211_ATTR_DURATION: Duration of an operation in milliseconds, u32.
+ * @NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION: Device attribute that
+ *	specifies the maximum duration that can be requested with the
+ *	remain-on-channel operation, in milliseconds, u32.
+ *
+ * @NL80211_ATTR_COOKIE: Generic 64-bit cookie to identify objects.
+ *
+ * @NL80211_ATTR_TX_RATES: Nested set of attributes
+ *	(enum nl80211_tx_rate_attributes) describing TX rates per band. The
+ *	enum nl80211_band value is used as the index (nla_type() of the nested
+ *	data. If a band is not included, it will be configured to allow all
+ *	rates based on negotiated supported rates information. This attribute
+ *	is used with %NL80211_CMD_SET_TX_BITRATE_MASK and with starting AP,
+ *	and joining mesh networks (not IBSS yet). In the later case, it must
+ *	specify just a single bitrate, which is to be used for the beacon.
+ *	The driver must also specify support for this with the extended
+ *	features NL80211_EXT_FEATURE_BEACON_RATE_LEGACY,
+ *	NL80211_EXT_FEATURE_BEACON_RATE_HT and
+ *	NL80211_EXT_FEATURE_BEACON_RATE_VHT.
+ *
+ * @NL80211_ATTR_FRAME_MATCH: A binary attribute which typically must contain
+ *	at least one byte, currently used with @NL80211_CMD_REGISTER_FRAME.
+ * @NL80211_ATTR_FRAME_TYPE: A u16 indicating the frame type/subtype for the
+ *	@NL80211_CMD_REGISTER_FRAME command.
+ * @NL80211_ATTR_TX_FRAME_TYPES: wiphy capability attribute, which is a
+ *	nested attribute of %NL80211_ATTR_FRAME_TYPE attributes, containing
+ *	information about which frame types can be transmitted with
+ *	%NL80211_CMD_FRAME.
+ * @NL80211_ATTR_RX_FRAME_TYPES: wiphy capability attribute, which is a
+ *	nested attribute of %NL80211_ATTR_FRAME_TYPE attributes, containing
+ *	information about which frame types can be registered for RX.
+ *
+ * @NL80211_ATTR_ACK: Flag attribute indicating that the frame was
+ *	acknowledged by the recipient.
+ *
+ * @NL80211_ATTR_PS_STATE: powersave state, using &enum nl80211_ps_state values.
+ *
+ * @NL80211_ATTR_CQM: connection quality monitor configuration in a
+ *	nested attribute with %NL80211_ATTR_CQM_* sub-attributes.
+ *
+ * @NL80211_ATTR_LOCAL_STATE_CHANGE: Flag attribute to indicate that a command
+ *	is requesting a local authentication/association state change without
+ *	invoking actual management frame exchange. This can be used with
+ *	NL80211_CMD_AUTHENTICATE, NL80211_CMD_DEAUTHENTICATE,
+ *	NL80211_CMD_DISASSOCIATE.
+ *
+ * @NL80211_ATTR_AP_ISOLATE: (AP mode) Do not forward traffic between stations
+ *	connected to this BSS.
+ *
+ * @NL80211_ATTR_WIPHY_TX_POWER_SETTING: Transmit power setting type. See
+ *      &enum nl80211_tx_power_setting for possible values.
+ * @NL80211_ATTR_WIPHY_TX_POWER_LEVEL: Transmit power level in signed mBm units.
+ *      This is used in association with @NL80211_ATTR_WIPHY_TX_POWER_SETTING
+ *      for non-automatic settings.
+ *
+ * @NL80211_ATTR_SUPPORT_IBSS_RSN: The device supports IBSS RSN, which mostly
+ *	means support for per-station GTKs.
+ *
+ * @NL80211_ATTR_WIPHY_ANTENNA_TX: Bitmap of allowed antennas for transmitting.
+ *	This can be used to mask out antennas which are not attached or should
+ *	not be used for transmitting. If an antenna is not selected in this
+ *	bitmap the hardware is not allowed to transmit on this antenna.
+ *
+ *	Each bit represents one antenna, starting with antenna 1 at the first
+ *	bit. Depending on which antennas are selected in the bitmap, 802.11n
+ *	drivers can derive which chainmasks to use (if all antennas belonging to
+ *	a particular chain are disabled this chain should be disabled) and if
+ *	a chain has diversity antennas wether diversity should be used or not.
+ *	HT capabilities (STBC, TX Beamforming, Antenna selection) can be
+ *	derived from the available chains after applying the antenna mask.
+ *	Non-802.11n drivers can derive wether to use diversity or not.
+ *	Drivers may reject configurations or RX/TX mask combinations they cannot
+ *	support by returning -EINVAL.
+ *
+ * @NL80211_ATTR_WIPHY_ANTENNA_RX: Bitmap of allowed antennas for receiving.
+ *	This can be used to mask out antennas which are not attached or should
+ *	not be used for receiving. If an antenna is not selected in this bitmap
+ *	the hardware should not be configured to receive on this antenna.
+ *	For a more detailed description see @NL80211_ATTR_WIPHY_ANTENNA_TX.
+ *
+ * @NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX: Bitmap of antennas which are available
+ *	for configuration as TX antennas via the above parameters.
+ *
+ * @NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX: Bitmap of antennas which are available
+ *	for configuration as RX antennas via the above parameters.
+ *
+ * @NL80211_ATTR_MCAST_RATE: Multicast tx rate (in 100 kbps) for IBSS
+ *
+ * @NL80211_ATTR_OFFCHANNEL_TX_OK: For management frame TX, the frame may be
+ *	transmitted on another channel when the channel given doesn't match
+ *	the current channel. If the current channel doesn't match and this
+ *	flag isn't set, the frame will be rejected. This is also used as an
+ *	nl80211 capability flag.
+ *
+ * @NL80211_ATTR_BSS_HT_OPMODE: HT operation mode (u16)
+ *
+ * @NL80211_ATTR_KEY_DEFAULT_TYPES: A nested attribute containing flags
+ *	attributes, specifying what a key should be set as default as.
+ *	See &enum nl80211_key_default_types.
+ *
+ * @NL80211_ATTR_MESH_SETUP: Optional mesh setup parameters.  These cannot be
+ *	changed once the mesh is active.
+ * @NL80211_ATTR_MESH_CONFIG: Mesh configuration parameters, a nested attribute
+ *	containing attributes from &enum nl80211_meshconf_params.
+ * @NL80211_ATTR_SUPPORT_MESH_AUTH: Currently, this means the underlying driver
+ *	allows auth frames in a mesh to be passed to userspace for processing via
+ *	the @NL80211_MESH_SETUP_USERSPACE_AUTH flag.
+ * @NL80211_ATTR_STA_PLINK_STATE: The state of a mesh peer link as defined in
+ *	&enum nl80211_plink_state. Used when userspace is driving the peer link
+ *	management state machine.  @NL80211_MESH_SETUP_USERSPACE_AMPE or
+ *	@NL80211_MESH_SETUP_USERSPACE_MPM must be enabled.
+ *
+ * @NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED: indicates, as part of the wiphy
+ *	capabilities, the supported WoWLAN triggers
+ * @NL80211_ATTR_WOWLAN_TRIGGERS: used by %NL80211_CMD_SET_WOWLAN to
+ *	indicate which WoW triggers should be enabled. This is also
+ *	used by %NL80211_CMD_GET_WOWLAN to get the currently enabled WoWLAN
+ *	triggers.
+ *
+ * @NL80211_ATTR_SCHED_SCAN_INTERVAL: Interval between scheduled scan
+ *	cycles, in msecs.
+ *
+ * @NL80211_ATTR_SCHED_SCAN_MATCH: Nested attribute with one or more
+ *	sets of attributes to match during scheduled scans.  Only BSSs
+ *	that match any of the sets will be reported.  These are
+ *	pass-thru filter rules.
+ *	For a match to succeed, the BSS must match all attributes of a
+ *	set.  Since not every hardware supports matching all types of
+ *	attributes, there is no guarantee that the reported BSSs are
+ *	fully complying with the match sets and userspace needs to be
+ *	able to ignore them by itself.
+ *	Thus, the implementation is somewhat hardware-dependent, but
+ *	this is only an optimization and the userspace application
+ *	needs to handle all the non-filtered results anyway.
+ *	If the match attributes don't make sense when combined with
+ *	the values passed in @NL80211_ATTR_SCAN_SSIDS (eg. if an SSID
+ *	is included in the probe request, but the match attributes
+ *	will never let it go through), -EINVAL may be returned.
+ *	If ommited, no filtering is done.
+ *
+ * @NL80211_ATTR_INTERFACE_COMBINATIONS: Nested attribute listing the supported
+ *	interface combinations. In each nested item, it contains attributes
+ *	defined in &enum nl80211_if_combination_attrs.
+ * @NL80211_ATTR_SOFTWARE_IFTYPES: Nested attribute (just like
+ *	%NL80211_ATTR_SUPPORTED_IFTYPES) containing the interface types that
+ *	are managed in software: interfaces of these types aren't subject to
+ *	any restrictions in their number or combinations.
+ *
+ * @NL80211_ATTR_REKEY_DATA: nested attribute containing the information
+ *	necessary for GTK rekeying in the device, see &enum nl80211_rekey_data.
+ *
+ * @NL80211_ATTR_SCAN_SUPP_RATES: rates per to be advertised as supported in scan,
+ *	nested array attribute containing an entry for each band, with the entry
+ *	being a list of supported rates as defined by IEEE 802.11 7.3.2.2 but
+ *	without the length restriction (at most %NL80211_MAX_SUPP_RATES).
+ *
+ * @NL80211_ATTR_HIDDEN_SSID: indicates whether SSID is to be hidden from Beacon
+ *	and Probe Response (when response to wildcard Probe Request); see
+ *	&enum nl80211_hidden_ssid, represented as a u32
+ *
+ * @NL80211_ATTR_IE_PROBE_RESP: Information element(s) for Probe Response frame.
+ *	This is used with %NL80211_CMD_NEW_BEACON and %NL80211_CMD_SET_BEACON to
+ *	provide extra IEs (e.g., WPS/P2P IE) into Probe Response frames when the
+ *	driver (or firmware) replies to Probe Request frames.
+ * @NL80211_ATTR_IE_ASSOC_RESP: Information element(s) for (Re)Association
+ *	Response frames. This is used with %NL80211_CMD_NEW_BEACON and
+ *	%NL80211_CMD_SET_BEACON to provide extra IEs (e.g., WPS/P2P IE) into
+ *	(Re)Association Response frames when the driver (or firmware) replies to
+ *	(Re)Association Request frames.
+ *
+ * @NL80211_ATTR_STA_WME: Nested attribute containing the wme configuration
+ *	of the station, see &enum nl80211_sta_wme_attr.
+ * @NL80211_ATTR_SUPPORT_AP_UAPSD: the device supports uapsd when working
+ *	as AP.
+ *
+ * @NL80211_ATTR_ROAM_SUPPORT: Indicates whether the firmware is capable of
+ *	roaming to another AP in the same ESS if the signal lever is low.
+ *
+ * @NL80211_ATTR_PMKSA_CANDIDATE: Nested attribute containing the PMKSA caching
+ *	candidate information, see &enum nl80211_pmksa_candidate_attr.
+ *
+ * @NL80211_ATTR_TX_NO_CCK_RATE: Indicates whether to use CCK rate or not
+ *	for management frames transmission. In order to avoid p2p probe/action
+ *	frames are being transmitted at CCK rate in 2GHz band, the user space
+ *	applications use this attribute.
+ *	This attribute is used with %NL80211_CMD_TRIGGER_SCAN and
+ *	%NL80211_CMD_FRAME commands.
+ *
+ * @NL80211_ATTR_TDLS_ACTION: Low level TDLS action code (e.g. link setup
+ *	request, link setup confirm, link teardown, etc.). Values are
+ *	described in the TDLS (802.11z) specification.
+ * @NL80211_ATTR_TDLS_DIALOG_TOKEN: Non-zero token for uniquely identifying a
+ *	TDLS conversation between two devices.
+ * @NL80211_ATTR_TDLS_OPERATION: High level TDLS operation; see
+ *	&enum nl80211_tdls_operation, represented as a u8.
+ * @NL80211_ATTR_TDLS_SUPPORT: A flag indicating the device can operate
+ *	as a TDLS peer sta.
+ * @NL80211_ATTR_TDLS_EXTERNAL_SETUP: The TDLS discovery/setup and teardown
+ *	procedures should be performed by sending TDLS packets via
+ *	%NL80211_CMD_TDLS_MGMT. Otherwise %NL80211_CMD_TDLS_OPER should be
+ *	used for asking the driver to perform a TDLS operation.
+ *
+ * @NL80211_ATTR_DEVICE_AP_SME: This u32 attribute may be listed for devices
+ *	that have AP support to indicate that they have the AP SME integrated
+ *	with support for the features listed in this attribute, see
+ *	&enum nl80211_ap_sme_features.
+ *
+ * @NL80211_ATTR_DONT_WAIT_FOR_ACK: Used with %NL80211_CMD_FRAME, this tells
+ *	the driver to not wait for an acknowledgement. Note that due to this,
+ *	it will also not give a status callback nor return a cookie. This is
+ *	mostly useful for probe responses to save airtime.
+ *
+ * @NL80211_ATTR_FEATURE_FLAGS: This u32 attribute contains flags from
+ *	&enum nl80211_feature_flags and is advertised in wiphy information.
+ * @NL80211_ATTR_PROBE_RESP_OFFLOAD: Indicates that the HW responds to probe
+ *	requests while operating in AP-mode.
+ *	This attribute holds a bitmap of the supported protocols for
+ *	offloading (see &enum nl80211_probe_resp_offload_support_attr).
+ *
+ * @NL80211_ATTR_PROBE_RESP: Probe Response template data. Contains the entire
+ *	probe-response frame. The DA field in the 802.11 header is zero-ed out,
+ *	to be filled by the FW.
+ * @NL80211_ATTR_DISABLE_HT:  Force HT capable interfaces to disable
+ *      this feature.  Currently, only supported in mac80211 drivers.
+ * @NL80211_ATTR_HT_CAPABILITY_MASK: Specify which bits of the
+ *      ATTR_HT_CAPABILITY to which attention should be paid.
+ *      Currently, only mac80211 NICs support this feature.
+ *      The values that may be configured are:
+ *       MCS rates, MAX-AMSDU, HT-20-40 and HT_CAP_SGI_40
+ *       AMPDU density and AMPDU factor.
+ *      All values are treated as suggestions and may be ignored
+ *      by the driver as required.  The actual values may be seen in
+ *      the station debugfs ht_caps file.
+ *
+ * @NL80211_ATTR_DFS_REGION: region for regulatory rules which this country
+ *    abides to when initiating radiation on DFS channels. A country maps
+ *    to one DFS region.
+ *
+ * @NL80211_ATTR_NOACK_MAP: This u16 bitmap contains the No Ack Policy of
+ *      up to 16 TIDs.
+ *
+ * @NL80211_ATTR_INACTIVITY_TIMEOUT: timeout value in seconds, this can be
+ *	used by the drivers which has MLME in firmware and does not have support
+ *	to report per station tx/rx activity to free up the staion entry from
+ *	the list. This needs to be used when the driver advertises the
+ *	capability to timeout the stations.
+ *
+ * @NL80211_ATTR_RX_SIGNAL_DBM: signal strength in dBm (as a 32-bit int);
+ *	this attribute is (depending on the driver capabilities) added to
+ *	received frames indicated with %NL80211_CMD_FRAME.
+ *
+ * @NL80211_ATTR_BG_SCAN_PERIOD: Background scan period in seconds
+ *      or 0 to disable background scan.
+ *
+ * @NL80211_ATTR_USER_REG_HINT_TYPE: type of regulatory hint passed from
+ *	userspace. If unset it is assumed the hint comes directly from
+ *	a user. If set code could specify exactly what type of source
+ *	was used to provide the hint. For the different types of
+ *	allowed user regulatory hints see nl80211_user_reg_hint_type.
+ *
+ * @NL80211_ATTR_CONN_FAILED_REASON: The reason for which AP has rejected
+ *	the connection request from a station. nl80211_connect_failed_reason
+ *	enum has different reasons of connection failure.
+ *
+ * @NL80211_ATTR_AUTH_DATA: Fields and elements in Authentication frames.
+ *	This contains the authentication frame body (non-IE and IE data),
+ *	excluding the Authentication algorithm number, i.e., starting at the
+ *	Authentication transaction sequence number field. It is used with
+ *	authentication algorithms that need special fields to be added into
+ *	the frames (SAE and FILS). Currently, only the SAE cases use the
+ *	initial two fields (Authentication transaction sequence number and
+ *	Status code). However, those fields are included in the attribute data
+ *	for all authentication algorithms to keep the attribute definition
+ *	consistent.
+ *
+ * @NL80211_ATTR_VHT_CAPABILITY: VHT Capability information element (from
+ *	association request when used with NL80211_CMD_NEW_STATION)
+ *
+ * @NL80211_ATTR_SCAN_FLAGS: scan request control flags (u32)
+ *
+ * @NL80211_ATTR_P2P_CTWINDOW: P2P GO Client Traffic Window (u8), used with
+ *	the START_AP and SET_BSS commands
+ * @NL80211_ATTR_P2P_OPPPS: P2P GO opportunistic PS (u8), used with the
+ *	START_AP and SET_BSS commands. This can have the values 0 or 1;
+ *	if not given in START_AP 0 is assumed, if not given in SET_BSS
+ *	no change is made.
+ *
+ * @NL80211_ATTR_LOCAL_MESH_POWER_MODE: local mesh STA link-specific power mode
+ *	defined in &enum nl80211_mesh_power_mode.
+ *
+ * @NL80211_ATTR_ACL_POLICY: ACL policy, see &enum nl80211_acl_policy,
+ *	carried in a u32 attribute
+ *
+ * @NL80211_ATTR_MAC_ADDRS: Array of nested MAC addresses, used for
+ *	MAC ACL.
+ *
+ * @NL80211_ATTR_MAC_ACL_MAX: u32 attribute to advertise the maximum
+ *	number of MAC addresses that a device can support for MAC
+ *	ACL.
+ *
+ * @NL80211_ATTR_RADAR_EVENT: Type of radar event for notification to userspace,
+ *	contains a value of enum nl80211_radar_event (u32).
+ *
+ * @NL80211_ATTR_EXT_CAPA: 802.11 extended capabilities that the kernel driver
+ *	has and handles. The format is the same as the IE contents. See
+ *	802.11-2012 8.4.2.29 for more information.
+ * @NL80211_ATTR_EXT_CAPA_MASK: Extended capabilities that the kernel driver
+ *	has set in the %NL80211_ATTR_EXT_CAPA value, for multibit fields.
+ *
+ * @NL80211_ATTR_STA_CAPABILITY: Station capabilities (u16) are advertised to
+ *	the driver, e.g., to enable TDLS power save (PU-APSD).
+ *
+ * @NL80211_ATTR_STA_EXT_CAPABILITY: Station extended capabilities are
+ *	advertised to the driver, e.g., to enable TDLS off channel operations
+ *	and PU-APSD.
+ *
+ * @NL80211_ATTR_PROTOCOL_FEATURES: global nl80211 feature flags, see
+ *	&enum nl80211_protocol_features, the attribute is a u32.
+ *
+ * @NL80211_ATTR_SPLIT_WIPHY_DUMP: flag attribute, userspace supports
+ *	receiving the data for a single wiphy split across multiple
+ *	messages, given with wiphy dump message
+ *
+ * @NL80211_ATTR_MDID: Mobility Domain Identifier
+ *
+ * @NL80211_ATTR_IE_RIC: Resource Information Container Information
+ *	Element
+ *
+ * @NL80211_ATTR_CRIT_PROT_ID: critical protocol identifier requiring increased
+ *	reliability, see &enum nl80211_crit_proto_id (u16).
+ * @NL80211_ATTR_MAX_CRIT_PROT_DURATION: duration in milliseconds in which
+ *      the connection should have increased reliability (u16).
+ *
+ * @NL80211_ATTR_PEER_AID: Association ID for the peer TDLS station (u16).
+ *	This is similar to @NL80211_ATTR_STA_AID but with a difference of being
+ *	allowed to be used with the first @NL80211_CMD_SET_STATION command to
+ *	update a TDLS peer STA entry.
+ *
+ * @NL80211_ATTR_COALESCE_RULE: Coalesce rule information.
+ *
+ * @NL80211_ATTR_CH_SWITCH_COUNT: u32 attribute specifying the number of TBTT's
+ *	until the channel switch event.
+ * @NL80211_ATTR_CH_SWITCH_BLOCK_TX: flag attribute specifying that transmission
+ *	must be blocked on the current channel (before the channel switch
+ *	operation).
+ * @NL80211_ATTR_CSA_IES: Nested set of attributes containing the IE information
+ *	for the time while performing a channel switch.
+ * @NL80211_ATTR_CSA_C_OFF_BEACON: An array of offsets (u16) to the channel
+ *	switch counters in the beacons tail (%NL80211_ATTR_BEACON_TAIL).
+ * @NL80211_ATTR_CSA_C_OFF_PRESP: An array of offsets (u16) to the channel
+ *	switch counters in the probe response (%NL80211_ATTR_PROBE_RESP).
+ *
+ * @NL80211_ATTR_RXMGMT_FLAGS: flags for nl80211_send_mgmt(), u32.
+ *	As specified in the &enum nl80211_rxmgmt_flags.
+ *
+ * @NL80211_ATTR_STA_SUPPORTED_CHANNELS: array of supported channels.
+ *
+ * @NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES: array of supported
+ *      supported operating classes.
+ *
+ * @NL80211_ATTR_HANDLE_DFS: A flag indicating whether user space
+ *	controls DFS operation in IBSS mode. If the flag is included in
+ *	%NL80211_CMD_JOIN_IBSS request, the driver will allow use of DFS
+ *	channels and reports radar events to userspace. Userspace is required
+ *	to react to radar events, e.g. initiate a channel switch or leave the
+ *	IBSS network.
+ *
+ * @NL80211_ATTR_SUPPORT_5_MHZ: A flag indicating that the device supports
+ *	5 MHz channel bandwidth.
+ * @NL80211_ATTR_SUPPORT_10_MHZ: A flag indicating that the device supports
+ *	10 MHz channel bandwidth.
+ *
+ * @NL80211_ATTR_OPMODE_NOTIF: Operating mode field from Operating Mode
+ *	Notification Element based on association request when used with
+ *	%NL80211_CMD_NEW_STATION or %NL80211_CMD_SET_STATION (only when
+ *	%NL80211_FEATURE_FULL_AP_CLIENT_STATE is supported, or with TDLS);
+ *	u8 attribute.
+ *
+ * @NL80211_ATTR_VENDOR_ID: The vendor ID, either a 24-bit OUI or, if
+ *	%NL80211_VENDOR_ID_IS_LINUX is set, a special Linux ID (not used yet)
+ * @NL80211_ATTR_VENDOR_SUBCMD: vendor sub-command
+ * @NL80211_ATTR_VENDOR_DATA: data for the vendor command, if any; this
+ *	attribute is also used for vendor command feature advertisement
+ * @NL80211_ATTR_VENDOR_EVENTS: used for event list advertising in the wiphy
+ *	info, containing a nested array of possible events
+ *
+ * @NL80211_ATTR_QOS_MAP: IP DSCP mapping for Interworking QoS mapping. This
+ *	data is in the format defined for the payload of the QoS Map Set element
+ *	in IEEE Std 802.11-2012, 8.4.2.97.
+ *
+ * @NL80211_ATTR_MAC_HINT: MAC address recommendation as initial BSS
+ * @NL80211_ATTR_WIPHY_FREQ_HINT: frequency of the recommended initial BSS
+ *
+ * @NL80211_ATTR_MAX_AP_ASSOC_STA: Device attribute that indicates how many
+ *	associated stations are supported in AP mode (including P2P GO); u32.
+ *	Since drivers may not have a fixed limit on the maximum number (e.g.,
+ *	other concurrent operations may affect this), drivers are allowed to
+ *	advertise values that cannot always be met. In such cases, an attempt
+ *	to add a new station entry with @NL80211_CMD_NEW_STATION may fail.
+ *
+ * @NL80211_ATTR_CSA_C_OFFSETS_TX: An array of csa counter offsets (u16) which
+ *	should be updated when the frame is transmitted.
+ * @NL80211_ATTR_MAX_CSA_COUNTERS: U8 attribute used to advertise the maximum
+ *	supported number of csa counters.
+ *
+ * @NL80211_ATTR_TDLS_PEER_CAPABILITY: flags for TDLS peer capabilities, u32.
+ *	As specified in the &enum nl80211_tdls_peer_capability.
+ *
+ * @NL80211_ATTR_SOCKET_OWNER: Flag attribute, if set during interface
+ *	creation then the new interface will be owned by the netlink socket
+ *	that created it and will be destroyed when the socket is closed.
+ *	If set during scheduled scan start then the new scan req will be
+ *	owned by the netlink socket that created it and the scheduled scan will
+ *	be stopped when the socket is closed.
+ *	If set during configuration of regulatory indoor operation then the
+ *	regulatory indoor configuration would be owned by the netlink socket
+ *	that configured the indoor setting, and the indoor operation would be
+ *	cleared when the socket is closed.
+ *	If set during NAN interface creation, the interface will be destroyed
+ *	if the socket is closed just like any other interface. Moreover, NAN
+ *	notifications will be sent in unicast to that socket. Without this
+ *	attribute, the notifications will be sent to the %NL80211_MCGRP_NAN
+ *	multicast group.
+ *	If set during %NL80211_CMD_ASSOCIATE or %NL80211_CMD_CONNECT the
+ *	station will deauthenticate when the socket is closed.
+ *	If set during %NL80211_CMD_JOIN_IBSS the IBSS will be automatically
+ *	torn down when the socket is closed.
+ *	If set during %NL80211_CMD_JOIN_MESH the mesh setup will be
+ *	automatically torn down when the socket is closed.
+ *	If set during %NL80211_CMD_START_AP the AP will be automatically
+ *	disabled when the socket is closed.
+ *
+ * @NL80211_ATTR_TDLS_INITIATOR: flag attribute indicating the current end is
+ *	the TDLS link initiator.
+ *
+ * @NL80211_ATTR_USE_RRM: flag for indicating whether the current connection
+ *	shall support Radio Resource Measurements (11k). This attribute can be
+ *	used with %NL80211_CMD_ASSOCIATE and %NL80211_CMD_CONNECT requests.
+ *	User space applications are expected to use this flag only if the
+ *	underlying device supports these minimal RRM features:
+ *		%NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES,
+ *		%NL80211_FEATURE_QUIET,
+ *	Or, if global RRM is supported, see:
+ *		%NL80211_EXT_FEATURE_RRM
+ *	If this flag is used, driver must add the Power Capabilities IE to the
+ *	association request. In addition, it must also set the RRM capability
+ *	flag in the association request's Capability Info field.
+ *
+ * @NL80211_ATTR_WIPHY_DYN_ACK: flag attribute used to enable ACK timeout
+ *	estimation algorithm (dynack). In order to activate dynack
+ *	%NL80211_FEATURE_ACKTO_ESTIMATION feature flag must be set by lower
+ *	drivers to indicate dynack capability. Dynack is automatically disabled
+ *	setting valid value for coverage class.
+ *
+ * @NL80211_ATTR_TSID: a TSID value (u8 attribute)
+ * @NL80211_ATTR_USER_PRIO: user priority value (u8 attribute)
+ * @NL80211_ATTR_ADMITTED_TIME: admitted time in units of 32 microseconds
+ *	(per second) (u16 attribute)
+ *
+ * @NL80211_ATTR_SMPS_MODE: SMPS mode to use (ap mode). see
+ *	&enum nl80211_smps_mode.
+ *
+ * @NL80211_ATTR_OPER_CLASS: operating class
+ *
+ * @NL80211_ATTR_MAC_MASK: MAC address mask
+ *
+ * @NL80211_ATTR_WIPHY_SELF_MANAGED_REG: flag attribute indicating this device
+ *	is self-managing its regulatory information and any regulatory domain
+ *	obtained from it is coming from the device's wiphy and not the global
+ *	cfg80211 regdomain.
+ *
+ * @NL80211_ATTR_EXT_FEATURES: extended feature flags contained in a byte
+ *	array. The feature flags are identified by their bit index (see &enum
+ *	nl80211_ext_feature_index). The bit index is ordered starting at the
+ *	least-significant bit of the first byte in the array, ie. bit index 0
+ *	is located at bit 0 of byte 0. bit index 25 would be located at bit 1
+ *	of byte 3 (u8 array).
+ *
+ * @NL80211_ATTR_SURVEY_RADIO_STATS: Request overall radio statistics to be
+ *	returned along with other survey data. If set, @NL80211_CMD_GET_SURVEY
+ *	may return a survey entry without a channel indicating global radio
+ *	statistics (only some values are valid and make sense.)
+ *	For devices that don't return such an entry even then, the information
+ *	should be contained in the result as the sum of the respective counters
+ *	over all channels.
+ *
+ * @NL80211_ATTR_SCHED_SCAN_DELAY: delay before the first cycle of a
+ *	scheduled scan is started.  Or the delay before a WoWLAN
+ *	net-detect scan is started, counting from the moment the
+ *	system is suspended.  This value is a u32, in seconds.
+
+ * @NL80211_ATTR_REG_INDOOR: flag attribute, if set indicates that the device
+ *      is operating in an indoor environment.
+ *
+ * @NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS: maximum number of scan plans for
+ *	scheduled scan supported by the device (u32), a wiphy attribute.
+ * @NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL: maximum interval (in seconds) for
+ *	a scan plan (u32), a wiphy attribute.
+ * @NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS: maximum number of iterations in
+ *	a scan plan (u32), a wiphy attribute.
+ * @NL80211_ATTR_SCHED_SCAN_PLANS: a list of scan plans for scheduled scan.
+ *	Each scan plan defines the number of scan iterations and the interval
+ *	between scans. The last scan plan will always run infinitely,
+ *	thus it must not specify the number of iterations, only the interval
+ *	between scans. The scan plans are executed sequentially.
+ *	Each scan plan is a nested attribute of &enum nl80211_sched_scan_plan.
+ * @NL80211_ATTR_PBSS: flag attribute. If set it means operate
+ *	in a PBSS. Specified in %NL80211_CMD_CONNECT to request
+ *	connecting to a PCP, and in %NL80211_CMD_START_AP to start
+ *	a PCP instead of AP. Relevant for DMG networks only.
+ * @NL80211_ATTR_BSS_SELECT: nested attribute for driver supporting the
+ *	BSS selection feature. When used with %NL80211_CMD_GET_WIPHY it contains
+ *	attributes according &enum nl80211_bss_select_attr to indicate what
+ *	BSS selection behaviours are supported. When used with %NL80211_CMD_CONNECT
+ *	it contains the behaviour-specific attribute containing the parameters for
+ *	BSS selection to be done by driver and/or firmware.
+ *
+ * @NL80211_ATTR_STA_SUPPORT_P2P_PS: whether P2P PS mechanism supported
+ *	or not. u8, one of the values of &enum nl80211_sta_p2p_ps_status
+ *
+ * @NL80211_ATTR_PAD: attribute used for padding for 64-bit alignment
+ *
+ * @NL80211_ATTR_IFTYPE_EXT_CAPA: Nested attribute of the following attributes:
+ *	%NL80211_ATTR_IFTYPE, %NL80211_ATTR_EXT_CAPA,
+ *	%NL80211_ATTR_EXT_CAPA_MASK, to specify the extended capabilities per
+ *	interface type.
+ *
+ * @NL80211_ATTR_MU_MIMO_GROUP_DATA: array of 24 bytes that defines a MU-MIMO
+ *	groupID for monitor mode.
+ *	The first 8 bytes are a mask that defines the membership in each
+ *	group (there are 64 groups, group 0 and 63 are reserved),
+ *	each bit represents a group and set to 1 for being a member in
+ *	that group and 0 for not being a member.
+ *	The remaining 16 bytes define the position in each group: 2 bits for
+ *	each group.
+ *	(smaller group numbers represented on most significant bits and bigger
+ *	group numbers on least significant bits.)
+ *	This attribute is used only if all interfaces are in monitor mode.
+ *	Set this attribute in order to monitor packets using the given MU-MIMO
+ *	groupID data.
+ *	to turn off that feature set all the bits of the groupID to zero.
+ * @NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR: mac address for the sniffer to follow
+ *	when using MU-MIMO air sniffer.
+ *	to turn that feature off set an invalid mac address
+ *	(e.g. FF:FF:FF:FF:FF:FF)
+ *
+ * @NL80211_ATTR_SCAN_START_TIME_TSF: The time at which the scan was actually
+ *	started (u64). The time is the TSF of the BSS the interface that
+ *	requested the scan is connected to (if available, otherwise this
+ *	attribute must not be included).
+ * @NL80211_ATTR_SCAN_START_TIME_TSF_BSSID: The BSS according to which
+ *	%NL80211_ATTR_SCAN_START_TIME_TSF is set.
+ * @NL80211_ATTR_MEASUREMENT_DURATION: measurement duration in TUs (u16). If
+ *	%NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY is not set, this is the
+ *	maximum measurement duration allowed. This attribute is used with
+ *	measurement requests. It can also be used with %NL80211_CMD_TRIGGER_SCAN
+ *	if the scan is used for beacon report radio measurement.
+ * @NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY: flag attribute that indicates
+ *	that the duration specified with %NL80211_ATTR_MEASUREMENT_DURATION is
+ *	mandatory. If this flag is not set, the duration is the maximum duration
+ *	and the actual measurement duration may be shorter.
+ *
+ * @NL80211_ATTR_MESH_PEER_AID: Association ID for the mesh peer (u16). This is
+ *	used to pull the stored data for mesh peer in power save state.
+ *
+ * @NL80211_ATTR_NAN_MASTER_PREF: the master preference to be used by
+ *	%NL80211_CMD_START_NAN and optionally with
+ *	%NL80211_CMD_CHANGE_NAN_CONFIG. Its type is u8 and it can't be 0.
+ *	Also, values 1 and 255 are reserved for certification purposes and
+ *	should not be used during a normal device operation.
+ * @NL80211_ATTR_BANDS: operating bands configuration.  This is a u32
+ *	bitmask of BIT(NL80211_BAND_*) as described in %enum
+ *	nl80211_band.  For instance, for NL80211_BAND_2GHZ, bit 0
+ *	would be set.  This attribute is used with
+ *	%NL80211_CMD_START_NAN and %NL80211_CMD_CHANGE_NAN_CONFIG, and
+ *	it is optional.  If no bands are set, it means don't-care and
+ *	the device will decide what to use.
+ * @NL80211_ATTR_NAN_FUNC: a function that can be added to NAN. See
+ *	&enum nl80211_nan_func_attributes for description of this nested
+ *	attribute.
+ * @NL80211_ATTR_NAN_MATCH: used to report a match. This is a nested attribute.
+ *	See &enum nl80211_nan_match_attributes.
+ * @NL80211_ATTR_FILS_KEK: KEK for FILS (Re)Association Request/Response frame
+ *	protection.
+ * @NL80211_ATTR_FILS_NONCES: Nonces (part of AAD) for FILS (Re)Association
+ *	Request/Response frame protection. This attribute contains the 16 octet
+ *	STA Nonce followed by 16 octets of AP Nonce.
+ *
+ * @NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED: Indicates whether or not multicast
+ *	packets should be send out as unicast to all stations (flag attribute).
+ *
+ * @NL80211_ATTR_BSSID: The BSSID of the AP. Note that %NL80211_ATTR_MAC is also
+ *	used in various commands/events for specifying the BSSID.
+ *
+ * @NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI: Relative RSSI threshold by which
+ *	other BSSs has to be better or slightly worse than the current
+ *	connected BSS so that they get reported to user space.
+ *	This will give an opportunity to userspace to consider connecting to
+ *	other matching BSSs which have better or slightly worse RSSI than
+ *	the current connected BSS by using an offloaded operation to avoid
+ *	unnecessary wakeups.
+ *
+ * @NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST: When present the RSSI level for BSSs in
+ *	the specified band is to be adjusted before doing
+ *	%NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI based comparision to figure out
+ *	better BSSs. The attribute value is a packed structure
+ *	value as specified by &struct nl80211_bss_select_rssi_adjust.
+ *
+ * @NL80211_ATTR_TIMEOUT_REASON: The reason for which an operation timed out.
+ *	u32 attribute with an &enum nl80211_timeout_reason value. This is used,
+ *	e.g., with %NL80211_CMD_CONNECT event.
+ *
+ * @NL80211_ATTR_FILS_ERP_USERNAME: EAP Re-authentication Protocol (ERP)
+ *	username part of NAI used to refer keys rRK and rIK. This is used with
+ *	%NL80211_CMD_CONNECT.
+ *
+ * @NL80211_ATTR_FILS_ERP_REALM: EAP Re-authentication Protocol (ERP) realm part
+ *	of NAI specifying the domain name of the ER server. This is used with
+ *	%NL80211_CMD_CONNECT.
+ *
+ * @NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM: Unsigned 16-bit ERP next sequence number
+ *	to use in ERP messages. This is used in generating the FILS wrapped data
+ *	for FILS authentication and is used with %NL80211_CMD_CONNECT.
+ *
+ * @NL80211_ATTR_FILS_ERP_RRK: ERP re-authentication Root Key (rRK) for the
+ *	NAI specified by %NL80211_ATTR_FILS_ERP_USERNAME and
+ *	%NL80211_ATTR_FILS_ERP_REALM. This is used for generating rIK and rMSK
+ *	from successful FILS authentication and is used with
+ *	%NL80211_CMD_CONNECT.
+ *
+ * @NL80211_ATTR_FILS_CACHE_ID: A 2-octet identifier advertized by a FILS AP
+ *	identifying the scope of PMKSAs. This is used with
+ *	@NL80211_CMD_SET_PMKSA and @NL80211_CMD_DEL_PMKSA.
+ *
+ * @NL80211_ATTR_PMK: attribute for passing PMK key material. Used with
+ *	%NL80211_CMD_SET_PMKSA for the PMKSA identified by %NL80211_ATTR_PMKID.
+ *	For %NL80211_CMD_CONNECT it is used to provide PSK for offloading 4-way
+ *	handshake for WPA/WPA2-PSK networks. For 802.1X authentication it is
+ *	used with %NL80211_CMD_SET_PMK. For offloaded FT support this attribute
+ *	specifies the PMK-R0 if NL80211_ATTR_PMKR0_NAME is included as well.
+ *
+ * @NL80211_ATTR_SCHED_SCAN_MULTI: flag attribute which user-space shall use to
+ *	indicate that it supports multiple active scheduled scan requests.
+ * @NL80211_ATTR_SCHED_SCAN_MAX_REQS: indicates maximum number of scheduled
+ *	scan request that may be active for the device (u32).
+ *
+ * @NL80211_ATTR_WANT_1X_4WAY_HS: flag attribute which user-space can include
+ *	in %NL80211_CMD_CONNECT to indicate that for 802.1X authentication it
+ *	wants to use the supported offload of the 4-way handshake.
+ * @NL80211_ATTR_PMKR0_NAME: PMK-R0 Name for offloaded FT.
+ * @NL80211_ATTR_PORT_AUTHORIZED: (reserved)
+ *
+ * @NL80211_ATTR_EXTERNAL_AUTH_ACTION: Identify the requested external
+ *     authentication operation (u32 attribute with an
+ *     &enum nl80211_external_auth_action value). This is used with the
+ *     %NL80211_CMD_EXTERNAL_AUTH request event.
+ * @NL80211_ATTR_EXTERNAL_AUTH_SUPPORT: Flag attribute indicating that the user
+ *     space supports external authentication. This attribute shall be used
+ *     only with %NL80211_CMD_CONNECT request. The driver may offload
+ *     authentication processing to user space if this capability is indicated
+ *     in NL80211_CMD_CONNECT requests from the user space.
+ *
+ * @NL80211_ATTR_NSS: Station's New/updated  RX_NSS value notified using this
+ *	u8 attribute. This is used with %NL80211_CMD_STA_OPMODE_CHANGED.
+ *
+ * @NL80211_ATTR_TXQ_STATS: TXQ statistics (nested attribute, see &enum
+ *      nl80211_txq_stats)
+ * @NL80211_ATTR_TXQ_LIMIT: Total packet limit for the TXQ queues for this phy.
+ *      The smaller of this and the memory limit is enforced.
+ * @NL80211_ATTR_TXQ_MEMORY_LIMIT: Total memory memory limit (in bytes) for the
+ *      TXQ queues for this phy. The smaller of this and the packet limit is
+ *      enforced.
+ * @NL80211_ATTR_TXQ_QUANTUM: TXQ scheduler quantum (bytes). Number of bytes
+ *      a flow is assigned on each round of the DRR scheduler.
+ * @NL80211_ATTR_HE_CAPABILITY: HE Capability information element (from
+ *	association request when used with NL80211_CMD_NEW_STATION). Can be set
+ *	only if %NL80211_STA_FLAG_WME is set.
+ *
+ * @NL80211_ATTR_FTM_RESPONDER: nested attribute which user-space can include
+ *	in %NL80211_CMD_START_AP or %NL80211_CMD_SET_BEACON for fine timing
+ *	measurement (FTM) responder functionality and containing parameters as
+ *	possible, see &enum nl80211_ftm_responder_attr
+ *
+ * @NL80211_ATTR_FTM_RESPONDER_STATS: Nested attribute with FTM responder
+ *	statistics, see &enum nl80211_ftm_responder_stats.
+ *
+ * @NL80211_ATTR_TIMEOUT: Timeout for the given operation in milliseconds (u32),
+ *	if the attribute is not given no timeout is requested. Note that 0 is an
+ *	invalid value.
+ *
+ * @NL80211_ATTR_PEER_MEASUREMENTS: peer measurements request (and result)
+ *	data, uses nested attributes specified in
+ *	&enum nl80211_peer_measurement_attrs.
+ *	This is also used for capability advertisement in the wiphy information,
+ *	with the appropriate sub-attributes.
+ *
+ * @NL80211_ATTR_AIRTIME_WEIGHT: Station's weight when scheduled by the airtime
+ *	scheduler.
+ *
+ * @NL80211_ATTR_STA_TX_POWER_SETTING: Transmit power setting type (u8) for
+ *	station associated with the AP. See &enum nl80211_tx_power_setting for
+ *	possible values.
+ * @NL80211_ATTR_STA_TX_POWER: Transmit power level (s16) in dBm units. This
+ *	allows to set Tx power for a station. If this attribute is not included,
+ *	the default per-interface tx power setting will be overriding. Driver
+ *	should be picking up the lowest tx power, either tx power per-interface
+ *	or per-station.
+ *
+ * @NL80211_ATTR_SAE_PASSWORD: attribute for passing SAE password material. It
+ *	is used with %NL80211_CMD_CONNECT to provide password for offloading
+ *	SAE authentication for WPA3-Personal networks.
+ *
+ * @NL80211_ATTR_TWT_RESPONDER: Enable target wait time responder support.
+ *
+ * @NL80211_ATTR_HE_OBSS_PD: nested attribute for OBSS Packet Detection
+ *	functionality.
+ *
+ * @NL80211_ATTR_WIPHY_EDMG_CHANNELS: bitmap that indicates the 2.16 GHz
+ *	channel(s) that are allowed to be used for EDMG transmissions.
+ *	Defined by IEEE P802.11ay/D4.0 section 9.4.2.251. (u8 attribute)
+ * @NL80211_ATTR_WIPHY_EDMG_BW_CONFIG: Channel BW Configuration subfield encodes
+ *	the allowed channel bandwidth configurations. (u8 attribute)
+ *	Defined by IEEE P802.11ay/D4.0 section 9.4.2.251, Table 13.
+ *
+ * @NL80211_ATTR_VLAN_ID: VLAN ID (1..4094) for the station and VLAN group key
+ *	(u16).
+ *
+ * @NL80211_ATTR_HE_BSS_COLOR: nested attribute for BSS Color Settings.
+ *
+ * @NL80211_ATTR_IFTYPE_AKM_SUITES: nested array attribute, with each entry
+ *	using attributes from &enum nl80211_iftype_akm_attributes. This
+ *	attribute is sent in a response to %NL80211_CMD_GET_WIPHY indicating
+ *	supported AKM suites capability per interface. AKMs advertised in
+ *	%NL80211_ATTR_AKM_SUITES are default capabilities if AKM suites not
+ *	advertised for a specific interface type.
+ *
+ * @NL80211_ATTR_TID_CONFIG: TID specific configuration in a
+ *	nested attribute with &enum nl80211_tid_config_attr sub-attributes;
+ *	on output (in wiphy attributes) it contains only the feature sub-
+ *	attributes.
+ *
+ * @NL80211_ATTR_CONTROL_PORT_NO_PREAUTH: disable preauth frame rx on control
+ *	port in order to forward/receive them as ordinary data frames.
+ *
+ * @NL80211_ATTR_PMK_LIFETIME: Maximum lifetime for PMKSA in seconds (u32,
+ *	dot11RSNAConfigPMKReauthThreshold; 0 is not a valid value).
+ *	An optional parameter configured through %NL80211_CMD_SET_PMKSA.
+ *	Drivers that trigger roaming need to know the lifetime of the
+ *	configured PMKSA for triggering the full vs. PMKSA caching based
+ *	authentication. This timeout helps authentication methods like SAE,
+ *	where PMK gets updated only by going through a full (new SAE)
+ *	authentication instead of getting updated during an association for EAP
+ *	authentication. No new full authentication within the PMK expiry shall
+ *	result in a disassociation at the end of the lifetime.
+ *
+ * @NL80211_ATTR_PMK_REAUTH_THRESHOLD: Reauthentication threshold time, in
+ *	terms of percentage of %NL80211_ATTR_PMK_LIFETIME
+ *	(u8, dot11RSNAConfigPMKReauthThreshold, 1..100). This is an optional
+ *	parameter configured through %NL80211_CMD_SET_PMKSA. Requests the
+ *	driver to trigger a full authentication roam (without PMKSA caching)
+ *	after the reauthentication threshold time, but before the PMK lifetime
+ *	has expired.
+ *
+ *	Authentication methods like SAE need to be able to generate a new PMKSA
+ *	entry without having to force a disconnection after the PMK timeout. If
+ *	no roaming occurs between the reauth threshold and PMK expiration,
+ *	disassociation is still forced.
+ * @NL80211_ATTR_RECEIVE_MULTICAST: multicast flag for the
+ *	%NL80211_CMD_REGISTER_FRAME command, see the description there.
+ * @NL80211_ATTR_WIPHY_FREQ_OFFSET: offset of the associated
+ *	%NL80211_ATTR_WIPHY_FREQ in positive KHz. Only valid when supplied with
+ *	an %NL80211_ATTR_WIPHY_FREQ_OFFSET.
+ * @NL80211_ATTR_CENTER_FREQ1_OFFSET: Center frequency offset in KHz for the
+ *	first channel segment specified in %NL80211_ATTR_CENTER_FREQ1.
+ * @NL80211_ATTR_SCAN_FREQ_KHZ: nested attribute with KHz frequencies
+ *
+ * @NL80211_ATTR_HE_6GHZ_CAPABILITY: HE 6 GHz Band Capability element (from
+ *	association request when used with NL80211_CMD_NEW_STATION).
+ *
+ * @NL80211_ATTR_FILS_DISCOVERY: Optional parameter to configure FILS
+ *	discovery. It is a nested attribute, see
+ *	&enum nl80211_fils_discovery_attributes.
+ *
+ * @NL80211_ATTR_UNSOL_BCAST_PROBE_RESP: Optional parameter to configure
+ *	unsolicited broadcast probe response. It is a nested attribute, see
+ *	&enum nl80211_unsol_bcast_probe_resp_attributes.
+ *
+ * @NL80211_ATTR_S1G_CAPABILITY: S1G Capability information element (from
+ *	association request when used with NL80211_CMD_NEW_STATION)
+ * @NL80211_ATTR_S1G_CAPABILITY_MASK: S1G Capability Information element
+ *	override mask. Used with NL80211_ATTR_S1G_CAPABILITY in
+ *	NL80211_CMD_ASSOCIATE or NL80211_CMD_CONNECT.
+ *
+ * @NL80211_ATTR_SAE_PWE: Indicates the mechanism(s) allowed for SAE PWE
+ *	derivation in WPA3-Personal networks which are using SAE authentication.
+ *	This is a u8 attribute that encapsulates one of the values from
+ *	&enum nl80211_sae_pwe_mechanism.
+ *
+ * @NL80211_ATTR_SAR_SPEC: SAR power limitation specification when
+ *	used with %NL80211_CMD_SET_SAR_SPECS. The message contains fields
+ *	of %nl80211_sar_attrs which specifies the sar type and related
+ *	sar specs. Sar specs contains array of %nl80211_sar_specs_attrs.
+ *
+ * @NL80211_ATTR_RECONNECT_REQUESTED: flag attribute, used with deauth and
+ *	disassoc events to indicate that an immediate reconnect to the AP
+ *	is desired.
+ *
+ * @NUM_NL80211_ATTR: total number of nl80211_attrs available
+ * @NL80211_ATTR_MAX: highest attribute number currently defined
+ * @__NL80211_ATTR_AFTER_LAST: internal use
+ */
+enum nl80211_attrs {
+/* don't change the order or add anything between, this is ABI! */
+	NL80211_ATTR_UNSPEC,
+
+	NL80211_ATTR_WIPHY,
+	NL80211_ATTR_WIPHY_NAME,
+
+	NL80211_ATTR_IFINDEX,
+	NL80211_ATTR_IFNAME,
+	NL80211_ATTR_IFTYPE,
+
+	NL80211_ATTR_MAC,
+
+	NL80211_ATTR_KEY_DATA,
+	NL80211_ATTR_KEY_IDX,
+	NL80211_ATTR_KEY_CIPHER,
+	NL80211_ATTR_KEY_SEQ,
+	NL80211_ATTR_KEY_DEFAULT,
+
+	NL80211_ATTR_BEACON_INTERVAL,
+	NL80211_ATTR_DTIM_PERIOD,
+	NL80211_ATTR_BEACON_HEAD,
+	NL80211_ATTR_BEACON_TAIL,
+
+	NL80211_ATTR_STA_AID,
+	NL80211_ATTR_STA_FLAGS,
+	NL80211_ATTR_STA_LISTEN_INTERVAL,
+	NL80211_ATTR_STA_SUPPORTED_RATES,
+	NL80211_ATTR_STA_VLAN,
+	NL80211_ATTR_STA_INFO,
+
+	NL80211_ATTR_WIPHY_BANDS,
+
+	NL80211_ATTR_MNTR_FLAGS,
+
+	NL80211_ATTR_MESH_ID,
+	NL80211_ATTR_STA_PLINK_ACTION,
+	NL80211_ATTR_MPATH_NEXT_HOP,
+	NL80211_ATTR_MPATH_INFO,
+
+	NL80211_ATTR_BSS_CTS_PROT,
+	NL80211_ATTR_BSS_SHORT_PREAMBLE,
+	NL80211_ATTR_BSS_SHORT_SLOT_TIME,
+
+	NL80211_ATTR_HT_CAPABILITY,
+
+	NL80211_ATTR_SUPPORTED_IFTYPES,
+
+	NL80211_ATTR_REG_ALPHA2,
+	NL80211_ATTR_REG_RULES,
+
+	NL80211_ATTR_MESH_CONFIG,
+
+	NL80211_ATTR_BSS_BASIC_RATES,
+
+	NL80211_ATTR_WIPHY_TXQ_PARAMS,
+	NL80211_ATTR_WIPHY_FREQ,
+	NL80211_ATTR_WIPHY_CHANNEL_TYPE,
+
+	NL80211_ATTR_KEY_DEFAULT_MGMT,
+
+	NL80211_ATTR_MGMT_SUBTYPE,
+	NL80211_ATTR_IE,
+
+	NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
+
+	NL80211_ATTR_SCAN_FREQUENCIES,
+	NL80211_ATTR_SCAN_SSIDS,
+	NL80211_ATTR_GENERATION, /* replaces old SCAN_GENERATION */
+	NL80211_ATTR_BSS,
+
+	NL80211_ATTR_REG_INITIATOR,
+	NL80211_ATTR_REG_TYPE,
+
+	NL80211_ATTR_SUPPORTED_COMMANDS,
+
+	NL80211_ATTR_FRAME,
+	NL80211_ATTR_SSID,
+	NL80211_ATTR_AUTH_TYPE,
+	NL80211_ATTR_REASON_CODE,
+
+	NL80211_ATTR_KEY_TYPE,
+
+	NL80211_ATTR_MAX_SCAN_IE_LEN,
+	NL80211_ATTR_CIPHER_SUITES,
+
+	NL80211_ATTR_FREQ_BEFORE,
+	NL80211_ATTR_FREQ_AFTER,
+
+	NL80211_ATTR_FREQ_FIXED,
+
+
+	NL80211_ATTR_WIPHY_RETRY_SHORT,
+	NL80211_ATTR_WIPHY_RETRY_LONG,
+	NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
+	NL80211_ATTR_WIPHY_RTS_THRESHOLD,
+
+	NL80211_ATTR_TIMED_OUT,
+
+	NL80211_ATTR_USE_MFP,
+
+	NL80211_ATTR_STA_FLAGS2,
+
+	NL80211_ATTR_CONTROL_PORT,
+
+	NL80211_ATTR_TESTDATA,
+
+	NL80211_ATTR_PRIVACY,
+
+	NL80211_ATTR_DISCONNECTED_BY_AP,
+	NL80211_ATTR_STATUS_CODE,
+
+	NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
+	NL80211_ATTR_CIPHER_SUITE_GROUP,
+	NL80211_ATTR_WPA_VERSIONS,
+	NL80211_ATTR_AKM_SUITES,
+
+	NL80211_ATTR_REQ_IE,
+	NL80211_ATTR_RESP_IE,
+
+	NL80211_ATTR_PREV_BSSID,
+
+	NL80211_ATTR_KEY,
+	NL80211_ATTR_KEYS,
+
+	NL80211_ATTR_PID,
+
+	NL80211_ATTR_4ADDR,
+
+	NL80211_ATTR_SURVEY_INFO,
+
+	NL80211_ATTR_PMKID,
+	NL80211_ATTR_MAX_NUM_PMKIDS,
+
+	NL80211_ATTR_DURATION,
+
+	NL80211_ATTR_COOKIE,
+
+	NL80211_ATTR_WIPHY_COVERAGE_CLASS,
+
+	NL80211_ATTR_TX_RATES,
+
+	NL80211_ATTR_FRAME_MATCH,
+
+	NL80211_ATTR_ACK,
+
+	NL80211_ATTR_PS_STATE,
+
+	NL80211_ATTR_CQM,
+
+	NL80211_ATTR_LOCAL_STATE_CHANGE,
+
+	NL80211_ATTR_AP_ISOLATE,
+
+	NL80211_ATTR_WIPHY_TX_POWER_SETTING,
+	NL80211_ATTR_WIPHY_TX_POWER_LEVEL,
+
+	NL80211_ATTR_TX_FRAME_TYPES,
+	NL80211_ATTR_RX_FRAME_TYPES,
+	NL80211_ATTR_FRAME_TYPE,
+
+	NL80211_ATTR_CONTROL_PORT_ETHERTYPE,
+	NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT,
+
+	NL80211_ATTR_SUPPORT_IBSS_RSN,
+
+	NL80211_ATTR_WIPHY_ANTENNA_TX,
+	NL80211_ATTR_WIPHY_ANTENNA_RX,
+
+	NL80211_ATTR_MCAST_RATE,
+
+	NL80211_ATTR_OFFCHANNEL_TX_OK,
+
+	NL80211_ATTR_BSS_HT_OPMODE,
+
+	NL80211_ATTR_KEY_DEFAULT_TYPES,
+
+	NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
+
+	NL80211_ATTR_MESH_SETUP,
+
+	NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
+	NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
+
+	NL80211_ATTR_SUPPORT_MESH_AUTH,
+	NL80211_ATTR_STA_PLINK_STATE,
+
+	NL80211_ATTR_WOWLAN_TRIGGERS,
+	NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED,
+
+	NL80211_ATTR_SCHED_SCAN_INTERVAL,
+
+	NL80211_ATTR_INTERFACE_COMBINATIONS,
+	NL80211_ATTR_SOFTWARE_IFTYPES,
+
+	NL80211_ATTR_REKEY_DATA,
+
+	NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
+	NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
+
+	NL80211_ATTR_SCAN_SUPP_RATES,
+
+	NL80211_ATTR_HIDDEN_SSID,
+
+	NL80211_ATTR_IE_PROBE_RESP,
+	NL80211_ATTR_IE_ASSOC_RESP,
+
+	NL80211_ATTR_STA_WME,
+	NL80211_ATTR_SUPPORT_AP_UAPSD,
+
+	NL80211_ATTR_ROAM_SUPPORT,
+
+	NL80211_ATTR_SCHED_SCAN_MATCH,
+	NL80211_ATTR_MAX_MATCH_SETS,
+
+	NL80211_ATTR_PMKSA_CANDIDATE,
+
+	NL80211_ATTR_TX_NO_CCK_RATE,
+
+	NL80211_ATTR_TDLS_ACTION,
+	NL80211_ATTR_TDLS_DIALOG_TOKEN,
+	NL80211_ATTR_TDLS_OPERATION,
+	NL80211_ATTR_TDLS_SUPPORT,
+	NL80211_ATTR_TDLS_EXTERNAL_SETUP,
+
+	NL80211_ATTR_DEVICE_AP_SME,
+
+	NL80211_ATTR_DONT_WAIT_FOR_ACK,
+
+	NL80211_ATTR_FEATURE_FLAGS,
+
+	NL80211_ATTR_PROBE_RESP_OFFLOAD,
+
+	NL80211_ATTR_PROBE_RESP,
+
+	NL80211_ATTR_DFS_REGION,
+
+	NL80211_ATTR_DISABLE_HT,
+	NL80211_ATTR_HT_CAPABILITY_MASK,
+
+	NL80211_ATTR_NOACK_MAP,
+
+	NL80211_ATTR_INACTIVITY_TIMEOUT,
+
+	NL80211_ATTR_RX_SIGNAL_DBM,
+
+	NL80211_ATTR_BG_SCAN_PERIOD,
+
+	NL80211_ATTR_WDEV,
+
+	NL80211_ATTR_USER_REG_HINT_TYPE,
+
+	NL80211_ATTR_CONN_FAILED_REASON,
+
+	NL80211_ATTR_AUTH_DATA,
+
+	NL80211_ATTR_VHT_CAPABILITY,
+
+	NL80211_ATTR_SCAN_FLAGS,
+
+	NL80211_ATTR_CHANNEL_WIDTH,
+	NL80211_ATTR_CENTER_FREQ1,
+	NL80211_ATTR_CENTER_FREQ2,
+
+	NL80211_ATTR_P2P_CTWINDOW,
+	NL80211_ATTR_P2P_OPPPS,
+
+	NL80211_ATTR_LOCAL_MESH_POWER_MODE,
+
+	NL80211_ATTR_ACL_POLICY,
+
+	NL80211_ATTR_MAC_ADDRS,
+
+	NL80211_ATTR_MAC_ACL_MAX,
+
+	NL80211_ATTR_RADAR_EVENT,
+
+	NL80211_ATTR_EXT_CAPA,
+	NL80211_ATTR_EXT_CAPA_MASK,
+
+	NL80211_ATTR_STA_CAPABILITY,
+	NL80211_ATTR_STA_EXT_CAPABILITY,
+
+	NL80211_ATTR_PROTOCOL_FEATURES,
+	NL80211_ATTR_SPLIT_WIPHY_DUMP,
+
+	NL80211_ATTR_DISABLE_VHT,
+	NL80211_ATTR_VHT_CAPABILITY_MASK,
+
+	NL80211_ATTR_MDID,
+	NL80211_ATTR_IE_RIC,
+
+	NL80211_ATTR_CRIT_PROT_ID,
+	NL80211_ATTR_MAX_CRIT_PROT_DURATION,
+
+	NL80211_ATTR_PEER_AID,
+
+	NL80211_ATTR_COALESCE_RULE,
+
+	NL80211_ATTR_CH_SWITCH_COUNT,
+	NL80211_ATTR_CH_SWITCH_BLOCK_TX,
+	NL80211_ATTR_CSA_IES,
+	NL80211_ATTR_CSA_C_OFF_BEACON,
+	NL80211_ATTR_CSA_C_OFF_PRESP,
+
+	NL80211_ATTR_RXMGMT_FLAGS,
+
+	NL80211_ATTR_STA_SUPPORTED_CHANNELS,
+
+	NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES,
+
+	NL80211_ATTR_HANDLE_DFS,
+
+	NL80211_ATTR_SUPPORT_5_MHZ,
+	NL80211_ATTR_SUPPORT_10_MHZ,
+
+	NL80211_ATTR_OPMODE_NOTIF,
+
+	NL80211_ATTR_VENDOR_ID,
+	NL80211_ATTR_VENDOR_SUBCMD,
+	NL80211_ATTR_VENDOR_DATA,
+	NL80211_ATTR_VENDOR_EVENTS,
+
+	NL80211_ATTR_QOS_MAP,
+
+	NL80211_ATTR_MAC_HINT,
+	NL80211_ATTR_WIPHY_FREQ_HINT,
+
+	NL80211_ATTR_MAX_AP_ASSOC_STA,
+
+	NL80211_ATTR_TDLS_PEER_CAPABILITY,
+
+	NL80211_ATTR_SOCKET_OWNER,
+
+	NL80211_ATTR_CSA_C_OFFSETS_TX,
+	NL80211_ATTR_MAX_CSA_COUNTERS,
+
+	NL80211_ATTR_TDLS_INITIATOR,
+
+	NL80211_ATTR_USE_RRM,
+
+	NL80211_ATTR_WIPHY_DYN_ACK,
+
+	NL80211_ATTR_TSID,
+	NL80211_ATTR_USER_PRIO,
+	NL80211_ATTR_ADMITTED_TIME,
+
+	NL80211_ATTR_SMPS_MODE,
+
+	NL80211_ATTR_OPER_CLASS,
+
+	NL80211_ATTR_MAC_MASK,
+
+	NL80211_ATTR_WIPHY_SELF_MANAGED_REG,
+
+	NL80211_ATTR_EXT_FEATURES,
+
+	NL80211_ATTR_SURVEY_RADIO_STATS,
+
+	NL80211_ATTR_NETNS_FD,
+
+	NL80211_ATTR_SCHED_SCAN_DELAY,
+
+	NL80211_ATTR_REG_INDOOR,
+
+	NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS,
+	NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL,
+	NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS,
+	NL80211_ATTR_SCHED_SCAN_PLANS,
+
+	NL80211_ATTR_PBSS,
+
+	NL80211_ATTR_BSS_SELECT,
+
+	NL80211_ATTR_STA_SUPPORT_P2P_PS,
+
+	NL80211_ATTR_PAD,
+
+	NL80211_ATTR_IFTYPE_EXT_CAPA,
+
+	NL80211_ATTR_MU_MIMO_GROUP_DATA,
+	NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR,
+
+	NL80211_ATTR_SCAN_START_TIME_TSF,
+	NL80211_ATTR_SCAN_START_TIME_TSF_BSSID,
+	NL80211_ATTR_MEASUREMENT_DURATION,
+	NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY,
+
+	NL80211_ATTR_MESH_PEER_AID,
+
+	NL80211_ATTR_NAN_MASTER_PREF,
+	NL80211_ATTR_BANDS,
+	NL80211_ATTR_NAN_FUNC,
+	NL80211_ATTR_NAN_MATCH,
+
+	NL80211_ATTR_FILS_KEK,
+	NL80211_ATTR_FILS_NONCES,
+
+	NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED,
+
+	NL80211_ATTR_BSSID,
+
+	NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI,
+	NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST,
+
+	NL80211_ATTR_TIMEOUT_REASON,
+
+	NL80211_ATTR_FILS_ERP_USERNAME,
+	NL80211_ATTR_FILS_ERP_REALM,
+	NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM,
+	NL80211_ATTR_FILS_ERP_RRK,
+	NL80211_ATTR_FILS_CACHE_ID,
+
+	NL80211_ATTR_PMK,
+
+	NL80211_ATTR_SCHED_SCAN_MULTI,
+	NL80211_ATTR_SCHED_SCAN_MAX_REQS,
+
+	NL80211_ATTR_WANT_1X_4WAY_HS,
+	NL80211_ATTR_PMKR0_NAME,
+	NL80211_ATTR_PORT_AUTHORIZED,
+
+	NL80211_ATTR_EXTERNAL_AUTH_ACTION,
+	NL80211_ATTR_EXTERNAL_AUTH_SUPPORT,
+
+	NL80211_ATTR_NSS,
+	NL80211_ATTR_ACK_SIGNAL,
+
+	NL80211_ATTR_CONTROL_PORT_OVER_NL80211,
+
+	NL80211_ATTR_TXQ_STATS,
+	NL80211_ATTR_TXQ_LIMIT,
+	NL80211_ATTR_TXQ_MEMORY_LIMIT,
+	NL80211_ATTR_TXQ_QUANTUM,
+
+	NL80211_ATTR_HE_CAPABILITY,
+
+	NL80211_ATTR_FTM_RESPONDER,
+
+	NL80211_ATTR_FTM_RESPONDER_STATS,
+
+	NL80211_ATTR_TIMEOUT,
+
+	NL80211_ATTR_PEER_MEASUREMENTS,
+
+	NL80211_ATTR_AIRTIME_WEIGHT,
+	NL80211_ATTR_STA_TX_POWER_SETTING,
+	NL80211_ATTR_STA_TX_POWER,
+
+
+//tianyan@2021.7.27 modify for add wifi6 module start
+	NL80211_ATTR_SAE_PASSWORD,
+//tianyan@2021.7.27 modify for add wifi6 module end
+
+	NL80211_ATTR_TWT_RESPONDER,
+
+	NL80211_ATTR_HE_OBSS_PD,
+
+	NL80211_ATTR_WIPHY_EDMG_CHANNELS,
+	NL80211_ATTR_WIPHY_EDMG_BW_CONFIG,
+
+	NL80211_ATTR_VLAN_ID,
+
+	NL80211_ATTR_HE_BSS_COLOR,
+
+	NL80211_ATTR_IFTYPE_AKM_SUITES,
+
+	NL80211_ATTR_TID_CONFIG,
+
+	NL80211_ATTR_CONTROL_PORT_NO_PREAUTH,
+
+	NL80211_ATTR_PMK_LIFETIME,
+	NL80211_ATTR_PMK_REAUTH_THRESHOLD,
+
+	NL80211_ATTR_RECEIVE_MULTICAST,
+	NL80211_ATTR_WIPHY_FREQ_OFFSET,
+	NL80211_ATTR_CENTER_FREQ1_OFFSET,
+	NL80211_ATTR_SCAN_FREQ_KHZ,
+
+	NL80211_ATTR_HE_6GHZ_CAPABILITY,
+
+	NL80211_ATTR_FILS_DISCOVERY,
+
+	NL80211_ATTR_UNSOL_BCAST_PROBE_RESP,
+
+	NL80211_ATTR_S1G_CAPABILITY,
+	NL80211_ATTR_S1G_CAPABILITY_MASK,
+
+	NL80211_ATTR_SAE_PWE,
+
+	NL80211_ATTR_RECONNECT_REQUESTED,
+
+	NL80211_ATTR_SAR_SPEC,
+
+	NL80211_ATTR_DISABLE_HE,
+
+	/* add attributes here, update the policy in nl80211.c */
+
+	__NL80211_ATTR_AFTER_LAST,
+	NUM_NL80211_ATTR = __NL80211_ATTR_AFTER_LAST,
+	NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
+};
+
+/* source-level API compatibility */
+#define NL80211_ATTR_SCAN_GENERATION NL80211_ATTR_GENERATION
+#define	NL80211_ATTR_MESH_PARAMS NL80211_ATTR_MESH_CONFIG
+#define NL80211_ATTR_IFACE_SOCKET_OWNER NL80211_ATTR_SOCKET_OWNER
+#define NL80211_ATTR_SAE_DATA NL80211_ATTR_AUTH_DATA
+
+/*
+ * Allow user space programs to use #ifdef on new attributes by defining them
+ * here
+ */
+#define NL80211_CMD_CONNECT NL80211_CMD_CONNECT
+#define NL80211_ATTR_HT_CAPABILITY NL80211_ATTR_HT_CAPABILITY
+#define NL80211_ATTR_BSS_BASIC_RATES NL80211_ATTR_BSS_BASIC_RATES
+#define NL80211_ATTR_WIPHY_TXQ_PARAMS NL80211_ATTR_WIPHY_TXQ_PARAMS
+#define NL80211_ATTR_WIPHY_FREQ NL80211_ATTR_WIPHY_FREQ
+#define NL80211_ATTR_WIPHY_CHANNEL_TYPE NL80211_ATTR_WIPHY_CHANNEL_TYPE
+#define NL80211_ATTR_MGMT_SUBTYPE NL80211_ATTR_MGMT_SUBTYPE
+#define NL80211_ATTR_IE NL80211_ATTR_IE
+#define NL80211_ATTR_REG_INITIATOR NL80211_ATTR_REG_INITIATOR
+#define NL80211_ATTR_REG_TYPE NL80211_ATTR_REG_TYPE
+#define NL80211_ATTR_FRAME NL80211_ATTR_FRAME
+#define NL80211_ATTR_SSID NL80211_ATTR_SSID
+#define NL80211_ATTR_AUTH_TYPE NL80211_ATTR_AUTH_TYPE
+#define NL80211_ATTR_REASON_CODE NL80211_ATTR_REASON_CODE
+#define NL80211_ATTR_CIPHER_SUITES_PAIRWISE NL80211_ATTR_CIPHER_SUITES_PAIRWISE
+#define NL80211_ATTR_CIPHER_SUITE_GROUP NL80211_ATTR_CIPHER_SUITE_GROUP
+#define NL80211_ATTR_WPA_VERSIONS NL80211_ATTR_WPA_VERSIONS
+#define NL80211_ATTR_AKM_SUITES NL80211_ATTR_AKM_SUITES
+#define NL80211_ATTR_KEY NL80211_ATTR_KEY
+#define NL80211_ATTR_KEYS NL80211_ATTR_KEYS
+#define NL80211_ATTR_FEATURE_FLAGS NL80211_ATTR_FEATURE_FLAGS
+
+#define NL80211_WIPHY_NAME_MAXLEN		64
+
+#define NL80211_MAX_SUPP_RATES			32
+#define NL80211_MAX_SUPP_HT_RATES		77
+#define NL80211_MAX_SUPP_REG_RULES		64
+#define NL80211_TKIP_DATA_OFFSET_ENCR_KEY	0
+#define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY	16
+#define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY	24
+#define NL80211_HT_CAPABILITY_LEN		26
+#define NL80211_VHT_CAPABILITY_LEN		12
+#define NL80211_HE_MIN_CAPABILITY_LEN           16
+#define NL80211_HE_MAX_CAPABILITY_LEN           54
+#define NL80211_MAX_NR_CIPHER_SUITES		5
+#define NL80211_MAX_NR_AKM_SUITES		2
+
+#define NL80211_MIN_REMAIN_ON_CHANNEL_TIME	10
+
+/* default RSSI threshold for scan results if none specified. */
+#define NL80211_SCAN_RSSI_THOLD_OFF		-300
+
+#define NL80211_CQM_TXE_MAX_INTVL		1800
+
+/**
+ * enum nl80211_iftype - (virtual) interface types
+ *
+ * @NL80211_IFTYPE_UNSPECIFIED: unspecified type, driver decides
+ * @NL80211_IFTYPE_ADHOC: independent BSS member
+ * @NL80211_IFTYPE_STATION: managed BSS member
+ * @NL80211_IFTYPE_AP: access point
+ * @NL80211_IFTYPE_AP_VLAN: VLAN interface for access points; VLAN interfaces
+ *	are a bit special in that they must always be tied to a pre-existing
+ *	AP type interface.
+ * @NL80211_IFTYPE_WDS: wireless distribution interface
+ * @NL80211_IFTYPE_MONITOR: monitor interface receiving all frames
+ * @NL80211_IFTYPE_MESH_POINT: mesh point
+ * @NL80211_IFTYPE_P2P_CLIENT: P2P client
+ * @NL80211_IFTYPE_P2P_GO: P2P group owner
+ * @NL80211_IFTYPE_P2P_DEVICE: P2P device interface type, this is not a netdev
+ *	and therefore can't be created in the normal ways, use the
+ *	%NL80211_CMD_START_P2P_DEVICE and %NL80211_CMD_STOP_P2P_DEVICE
+ *	commands to create and destroy one
+ * @NL80211_IF_TYPE_OCB: Outside Context of a BSS
+ *	This mode corresponds to the MIB variable dot11OCBActivated=true
+ * @NL80211_IFTYPE_NAN: NAN device interface type (not a netdev)
+ * @NL80211_IFTYPE_MAX: highest interface type number currently defined
+ * @NUM_NL80211_IFTYPES: number of defined interface types
+ *
+ * These values are used with the %NL80211_ATTR_IFTYPE
+ * to set the type of an interface.
+ *
+ */
+enum nl80211_iftype {
+	NL80211_IFTYPE_UNSPECIFIED,
+	NL80211_IFTYPE_ADHOC,
+	NL80211_IFTYPE_STATION,
+	NL80211_IFTYPE_AP,
+	NL80211_IFTYPE_AP_VLAN,
+	NL80211_IFTYPE_WDS,
+	NL80211_IFTYPE_MONITOR,
+	NL80211_IFTYPE_MESH_POINT,
+	NL80211_IFTYPE_P2P_CLIENT,
+	NL80211_IFTYPE_P2P_GO,
+	NL80211_IFTYPE_P2P_DEVICE,
+	NL80211_IFTYPE_OCB,
+	NL80211_IFTYPE_NAN,
+
+	/* keep last */
+	NUM_NL80211_IFTYPES,
+	NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1
+};
+
+/**
+ * enum nl80211_sta_flags - station flags
+ *
+ * Station flags. When a station is added to an AP interface, it is
+ * assumed to be already associated (and hence authenticated.)
+ *
+ * @__NL80211_STA_FLAG_INVALID: attribute number 0 is reserved
+ * @NL80211_STA_FLAG_AUTHORIZED: station is authorized (802.1X)
+ * @NL80211_STA_FLAG_SHORT_PREAMBLE: station is capable of receiving frames
+ *	with short barker preamble
+ * @NL80211_STA_FLAG_WME: station is WME/QoS capable
+ * @NL80211_STA_FLAG_MFP: station uses management frame protection
+ * @NL80211_STA_FLAG_AUTHENTICATED: station is authenticated
+ * @NL80211_STA_FLAG_TDLS_PEER: station is a TDLS peer -- this flag should
+ *	only be used in managed mode (even in the flags mask). Note that the
+ *	flag can't be changed, it is only valid while adding a station, and
+ *	attempts to change it will silently be ignored (rather than rejected
+ *	as errors.)
+ * @NL80211_STA_FLAG_ASSOCIATED: station is associated; used with drivers
+ *	that support %NL80211_FEATURE_FULL_AP_CLIENT_STATE to transition a
+ *	previously added station into associated state
+ * @NL80211_STA_FLAG_MAX: highest station flag number currently defined
+ * @__NL80211_STA_FLAG_AFTER_LAST: internal use
+ */
+enum nl80211_sta_flags {
+	__NL80211_STA_FLAG_INVALID,
+	NL80211_STA_FLAG_AUTHORIZED,
+	NL80211_STA_FLAG_SHORT_PREAMBLE,
+	NL80211_STA_FLAG_WME,
+	NL80211_STA_FLAG_MFP,
+	NL80211_STA_FLAG_AUTHENTICATED,
+	NL80211_STA_FLAG_TDLS_PEER,
+	NL80211_STA_FLAG_ASSOCIATED,
+
+	/* keep last */
+	__NL80211_STA_FLAG_AFTER_LAST,
+	NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_sta_p2p_ps_status - station support of P2P PS
+ *
+ * @NL80211_P2P_PS_UNSUPPORTED: station doesn't support P2P PS mechanism
+ * @@NL80211_P2P_PS_SUPPORTED: station supports P2P PS mechanism
+ * @NUM_NL80211_P2P_PS_STATUS: number of values
+ */
+enum nl80211_sta_p2p_ps_status {
+	NL80211_P2P_PS_UNSUPPORTED = 0,
+	NL80211_P2P_PS_SUPPORTED,
+
+	NUM_NL80211_P2P_PS_STATUS,
+};
+
+#define NL80211_STA_FLAG_MAX_OLD_API	NL80211_STA_FLAG_TDLS_PEER
+
+/**
+ * struct nl80211_sta_flag_update - station flags mask/set
+ * @mask: mask of station flags to set
+ * @set: which values to set them to
+ *
+ * Both mask and set contain bits as per &enum nl80211_sta_flags.
+ */
+struct nl80211_sta_flag_update {
+	__u32 mask;
+	__u32 set;
+} __attribute__((packed));
+
+/**
+ * enum nl80211_he_gi - HE guard interval
+ * @NL80211_RATE_INFO_HE_GI_0_8: 0.8 usec
+ * @NL80211_RATE_INFO_HE_GI_1_6: 1.6 usec
+ * @NL80211_RATE_INFO_HE_GI_3_2: 3.2 usec
+ */
+enum nl80211_he_gi {
+	NL80211_RATE_INFO_HE_GI_0_8,
+	NL80211_RATE_INFO_HE_GI_1_6,
+	NL80211_RATE_INFO_HE_GI_3_2,
+};
+
+/**
+ * enum nl80211_he_ru_alloc - HE RU allocation values
+ * @NL80211_RATE_INFO_HE_RU_ALLOC_26: 26-tone RU allocation
+ * @NL80211_RATE_INFO_HE_RU_ALLOC_52: 52-tone RU allocation
+ * @NL80211_RATE_INFO_HE_RU_ALLOC_106: 106-tone RU allocation
+ * @NL80211_RATE_INFO_HE_RU_ALLOC_242: 242-tone RU allocation
+ * @NL80211_RATE_INFO_HE_RU_ALLOC_484: 484-tone RU allocation
+ * @NL80211_RATE_INFO_HE_RU_ALLOC_996: 996-tone RU allocation
+ * @NL80211_RATE_INFO_HE_RU_ALLOC_2x996: 2x996-tone RU allocation
+ */
+enum nl80211_he_ru_alloc {
+	NL80211_RATE_INFO_HE_RU_ALLOC_26,
+	NL80211_RATE_INFO_HE_RU_ALLOC_52,
+	NL80211_RATE_INFO_HE_RU_ALLOC_106,
+	NL80211_RATE_INFO_HE_RU_ALLOC_242,
+	NL80211_RATE_INFO_HE_RU_ALLOC_484,
+	NL80211_RATE_INFO_HE_RU_ALLOC_996,
+	NL80211_RATE_INFO_HE_RU_ALLOC_2x996,
+};
+
+/**
+ * enum nl80211_rate_info - bitrate information
+ *
+ * These attribute types are used with %NL80211_STA_INFO_TXRATE
+ * when getting information about the bitrate of a station.
+ * There are 2 attributes for bitrate, a legacy one that represents
+ * a 16-bit value, and new one that represents a 32-bit value.
+ * If the rate value fits into 16 bit, both attributes are reported
+ * with the same value. If the rate is too high to fit into 16 bits
+ * (>6.5535Gbps) only 32-bit attribute is included.
+ * User space tools encouraged to use the 32-bit attribute and fall
+ * back to the 16-bit one for compatibility with older kernels.
+ *
+ * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved
+ * @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s)
+ * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8)
+ * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 MHz dualchannel bitrate
+ * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval
+ * @NL80211_RATE_INFO_BITRATE32: total bitrate (u32, 100kbit/s)
+ * @NL80211_RATE_INFO_MAX: highest rate_info number currently defined
+ * @NL80211_RATE_INFO_VHT_MCS: MCS index for VHT (u8)
+ * @NL80211_RATE_INFO_VHT_NSS: number of streams in VHT (u8)
+ * @NL80211_RATE_INFO_80_MHZ_WIDTH: 80 MHz VHT rate
+ * @NL80211_RATE_INFO_80P80_MHZ_WIDTH: unused - 80+80 is treated the
+ *	same as 160 for purposes of the bitrates
+ * @NL80211_RATE_INFO_160_MHZ_WIDTH: 160 MHz VHT rate
+ * @NL80211_RATE_INFO_10_MHZ_WIDTH: 10 MHz width - note that this is
+ *	a legacy rate and will be reported as the actual bitrate, i.e.
+ *	half the base (20 MHz) rate
+ * @NL80211_RATE_INFO_5_MHZ_WIDTH: 5 MHz width - note that this is
+ *	a legacy rate and will be reported as the actual bitrate, i.e.
+ *	a quarter of the base (20 MHz) rate
+ * @NL80211_RATE_INFO_HE_MCS: HE MCS index (u8, 0-11)
+ * @NL80211_RATE_INFO_HE_NSS: HE NSS value (u8, 1-8)
+ * @NL80211_RATE_INFO_HE_GI: HE guard interval identifier
+ *	(u8, see &enum nl80211_he_gi)
+ * @NL80211_RATE_INFO_HE_DCM: HE DCM value (u8, 0/1)
+ * @NL80211_RATE_INFO_RU_ALLOC: HE RU allocation, if not present then
+ *	non-OFDMA was used (u8, see &enum nl80211_he_ru_alloc)
+ * @__NL80211_RATE_INFO_AFTER_LAST: internal use
+ */
+enum nl80211_rate_info {
+	__NL80211_RATE_INFO_INVALID,
+	NL80211_RATE_INFO_BITRATE,
+	NL80211_RATE_INFO_MCS,
+	NL80211_RATE_INFO_40_MHZ_WIDTH,
+	NL80211_RATE_INFO_SHORT_GI,
+	NL80211_RATE_INFO_BITRATE32,
+	NL80211_RATE_INFO_VHT_MCS,
+	NL80211_RATE_INFO_VHT_NSS,
+	NL80211_RATE_INFO_80_MHZ_WIDTH,
+	NL80211_RATE_INFO_80P80_MHZ_WIDTH,
+	NL80211_RATE_INFO_160_MHZ_WIDTH,
+	NL80211_RATE_INFO_10_MHZ_WIDTH,
+	NL80211_RATE_INFO_5_MHZ_WIDTH,
+	NL80211_RATE_INFO_HE_MCS,
+	NL80211_RATE_INFO_HE_NSS,
+	NL80211_RATE_INFO_HE_GI,
+	NL80211_RATE_INFO_HE_DCM,
+	NL80211_RATE_INFO_HE_RU_ALLOC,
+
+	/* keep last */
+	__NL80211_RATE_INFO_AFTER_LAST,
+	NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_sta_bss_param - BSS information collected by STA
+ *
+ * These attribute types are used with %NL80211_STA_INFO_BSS_PARAM
+ * when getting information about the bitrate of a station.
+ *
+ * @__NL80211_STA_BSS_PARAM_INVALID: attribute number 0 is reserved
+ * @NL80211_STA_BSS_PARAM_CTS_PROT: whether CTS protection is enabled (flag)
+ * @NL80211_STA_BSS_PARAM_SHORT_PREAMBLE:  whether short preamble is enabled
+ *	(flag)
+ * @NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME:  whether short slot time is enabled
+ *	(flag)
+ * @NL80211_STA_BSS_PARAM_DTIM_PERIOD: DTIM period for beaconing (u8)
+ * @NL80211_STA_BSS_PARAM_BEACON_INTERVAL: Beacon interval (u16)
+ * @NL80211_STA_BSS_PARAM_MAX: highest sta_bss_param number currently defined
+ * @__NL80211_STA_BSS_PARAM_AFTER_LAST: internal use
+ */
+enum nl80211_sta_bss_param {
+	__NL80211_STA_BSS_PARAM_INVALID,
+	NL80211_STA_BSS_PARAM_CTS_PROT,
+	NL80211_STA_BSS_PARAM_SHORT_PREAMBLE,
+	NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME,
+	NL80211_STA_BSS_PARAM_DTIM_PERIOD,
+	NL80211_STA_BSS_PARAM_BEACON_INTERVAL,
+
+	/* keep last */
+	__NL80211_STA_BSS_PARAM_AFTER_LAST,
+	NL80211_STA_BSS_PARAM_MAX = __NL80211_STA_BSS_PARAM_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_sta_info - station information
+ *
+ * These attribute types are used with %NL80211_ATTR_STA_INFO
+ * when getting information about a station.
+ *
+ * @__NL80211_STA_INFO_INVALID: attribute number 0 is reserved
+ * @NL80211_STA_INFO_INACTIVE_TIME: time since last activity (u32, msecs)
+ * @NL80211_STA_INFO_RX_BYTES: total received bytes (MPDU length)
+ *	(u32, from this station)
+ * @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (MPDU length)
+ *	(u32, to this station)
+ * @NL80211_STA_INFO_RX_BYTES64: total received bytes (MPDU length)
+ *	(u64, from this station)
+ * @NL80211_STA_INFO_TX_BYTES64: total transmitted bytes (MPDU length)
+ *	(u64, to this station)
+ * @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm)
+ * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute
+ * 	containing info as possible, see &enum nl80211_rate_info
+ * @NL80211_STA_INFO_RX_PACKETS: total received packet (MSDUs and MMPDUs)
+ *	(u32, from this station)
+ * @NL80211_STA_INFO_TX_PACKETS: total transmitted packets (MSDUs and MMPDUs)
+ *	(u32, to this station)
+ * @NL80211_STA_INFO_TX_RETRIES: total retries (MPDUs) (u32, to this station)
+ * @NL80211_STA_INFO_TX_FAILED: total failed packets (MPDUs)
+ *	(u32, to this station)
+ * @NL80211_STA_INFO_SIGNAL_AVG: signal strength average (u8, dBm)
+ * @NL80211_STA_INFO_LLID: the station's mesh LLID
+ * @NL80211_STA_INFO_PLID: the station's mesh PLID
+ * @NL80211_STA_INFO_PLINK_STATE: peer link state for the station
+ *	(see %enum nl80211_plink_state)
+ * @NL80211_STA_INFO_RX_BITRATE: last unicast data frame rx rate, nested
+ *	attribute, like NL80211_STA_INFO_TX_BITRATE.
+ * @NL80211_STA_INFO_BSS_PARAM: current station's view of BSS, nested attribute
+ *     containing info as possible, see &enum nl80211_sta_bss_param
+ * @NL80211_STA_INFO_CONNECTED_TIME: time since the station is last connected
+ * @NL80211_STA_INFO_STA_FLAGS: Contains a struct nl80211_sta_flag_update.
+ * @NL80211_STA_INFO_BEACON_LOSS: count of times beacon loss was detected (u32)
+ * @NL80211_STA_INFO_T_OFFSET: timing offset with respect to this STA (s64)
+ * @NL80211_STA_INFO_LOCAL_PM: local mesh STA link-specific power mode
+ * @NL80211_STA_INFO_PEER_PM: peer mesh STA link-specific power mode
+ * @NL80211_STA_INFO_NONPEER_PM: neighbor mesh STA power save mode towards
+ *	non-peer STA
+ * @NL80211_STA_INFO_CHAIN_SIGNAL: per-chain signal strength of last PPDU
+ *	Contains a nested array of signal strength attributes (u8, dBm)
+ * @NL80211_STA_INFO_CHAIN_SIGNAL_AVG: per-chain signal strength average
+ *	Same format as NL80211_STA_INFO_CHAIN_SIGNAL.
+ * @NL80211_STA_EXPECTED_THROUGHPUT: expected throughput considering also the
+ *	802.11 header (u32, kbps)
+ * @NL80211_STA_INFO_RX_DROP_MISC: RX packets dropped for unspecified reasons
+ *	(u64)
+ * @NL80211_STA_INFO_BEACON_RX: number of beacons received from this peer (u64)
+ * @NL80211_STA_INFO_BEACON_SIGNAL_AVG: signal strength average
+ *	for beacons only (u8, dBm)
+ * @NL80211_STA_INFO_TID_STATS: per-TID statistics (see &enum nl80211_tid_stats)
+ *	This is a nested attribute where each the inner attribute number is the
+ *	TID+1 and the special TID 16 (i.e. value 17) is used for non-QoS frames;
+ *	each one of those is again nested with &enum nl80211_tid_stats
+ *	attributes carrying the actual values.
+ * @NL80211_STA_INFO_RX_DURATION: aggregate PPDU duration for all frames
+ *	received from the station (u64, usec)
+ * @NL80211_STA_INFO_PAD: attribute used for padding for 64-bit alignment
+ * @NL80211_STA_INFO_ACK_SIGNAL: signal strength of the last ACK frame(u8, dBm)
+ * @NL80211_STA_INFO_DATA_ACK_SIGNAL_AVG: avg signal strength of (data)
+ *	ACK frame (s8, dBm)
+ * @__NL80211_STA_INFO_AFTER_LAST: internal
+ * @NL80211_STA_INFO_MAX: highest possible station info attribute
+ */
+enum nl80211_sta_info {
+	__NL80211_STA_INFO_INVALID,
+	NL80211_STA_INFO_INACTIVE_TIME,
+	NL80211_STA_INFO_RX_BYTES,
+	NL80211_STA_INFO_TX_BYTES,
+	NL80211_STA_INFO_LLID,
+	NL80211_STA_INFO_PLID,
+	NL80211_STA_INFO_PLINK_STATE,
+	NL80211_STA_INFO_SIGNAL,
+	NL80211_STA_INFO_TX_BITRATE,
+	NL80211_STA_INFO_RX_PACKETS,
+	NL80211_STA_INFO_TX_PACKETS,
+	NL80211_STA_INFO_TX_RETRIES,
+	NL80211_STA_INFO_TX_FAILED,
+	NL80211_STA_INFO_SIGNAL_AVG,
+	NL80211_STA_INFO_RX_BITRATE,
+	NL80211_STA_INFO_BSS_PARAM,
+	NL80211_STA_INFO_CONNECTED_TIME,
+	NL80211_STA_INFO_STA_FLAGS,
+	NL80211_STA_INFO_BEACON_LOSS,
+	NL80211_STA_INFO_T_OFFSET,
+	NL80211_STA_INFO_LOCAL_PM,
+	NL80211_STA_INFO_PEER_PM,
+	NL80211_STA_INFO_NONPEER_PM,
+	NL80211_STA_INFO_RX_BYTES64,
+	NL80211_STA_INFO_TX_BYTES64,
+	NL80211_STA_INFO_CHAIN_SIGNAL,
+	NL80211_STA_INFO_CHAIN_SIGNAL_AVG,
+	NL80211_STA_INFO_EXPECTED_THROUGHPUT,
+	NL80211_STA_INFO_RX_DROP_MISC,
+	NL80211_STA_INFO_BEACON_RX,
+	NL80211_STA_INFO_BEACON_SIGNAL_AVG,
+	NL80211_STA_INFO_TID_STATS,
+	NL80211_STA_INFO_RX_DURATION,
+	NL80211_STA_INFO_PAD,
+	NL80211_STA_INFO_ACK_SIGNAL,
+	NL80211_STA_INFO_DATA_ACK_SIGNAL_AVG,
+
+	/* keep last */
+	__NL80211_STA_INFO_AFTER_LAST,
+	NL80211_STA_INFO_MAX = __NL80211_STA_INFO_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_tid_stats - per TID statistics attributes
+ * @__NL80211_TID_STATS_INVALID: attribute number 0 is reserved
+ * @NL80211_TID_STATS_RX_MSDU: number of MSDUs received (u64)
+ * @NL80211_TID_STATS_TX_MSDU: number of MSDUs transmitted (or
+ *	attempted to transmit; u64)
+ * @NL80211_TID_STATS_TX_MSDU_RETRIES: number of retries for
+ *	transmitted MSDUs (not counting the first attempt; u64)
+ * @NL80211_TID_STATS_TX_MSDU_FAILED: number of failed transmitted
+ *	MSDUs (u64)
+ * @NL80211_TID_STATS_PAD: attribute used for padding for 64-bit alignment
+ * @NL80211_TID_STATS_TXQ_STATS: TXQ stats (nested attribute)
+ * @NUM_NL80211_TID_STATS: number of attributes here
+ * @NL80211_TID_STATS_MAX: highest numbered attribute here
+ */
+enum nl80211_tid_stats {
+	__NL80211_TID_STATS_INVALID,
+	NL80211_TID_STATS_RX_MSDU,
+	NL80211_TID_STATS_TX_MSDU,
+	NL80211_TID_STATS_TX_MSDU_RETRIES,
+	NL80211_TID_STATS_TX_MSDU_FAILED,
+	NL80211_TID_STATS_PAD,
+	NL80211_TID_STATS_TXQ_STATS,
+
+	/* keep last */
+	NUM_NL80211_TID_STATS,
+	NL80211_TID_STATS_MAX = NUM_NL80211_TID_STATS - 1
+};
+
+/**
+ * enum nl80211_txq_stats - per TXQ statistics attributes
+ * @__NL80211_TXQ_STATS_INVALID: attribute number 0 is reserved
+ * @NUM_NL80211_TXQ_STATS: number of attributes here
+ * @NL80211_TXQ_STATS_BACKLOG_BYTES: number of bytes currently backlogged
+ * @NL80211_TXQ_STATS_BACKLOG_PACKETS: number of packets currently
+ *      backlogged
+ * @NL80211_TXQ_STATS_FLOWS: total number of new flows seen
+ * @NL80211_TXQ_STATS_DROPS: total number of packet drops
+ * @NL80211_TXQ_STATS_ECN_MARKS: total number of packet ECN marks
+ * @NL80211_TXQ_STATS_OVERLIMIT: number of drops due to queue space overflow
+ * @NL80211_TXQ_STATS_OVERMEMORY: number of drops due to memory limit overflow
+ *      (only for per-phy stats)
+ * @NL80211_TXQ_STATS_COLLISIONS: number of hash collisions
+ * @NL80211_TXQ_STATS_TX_BYTES: total number of bytes dequeued from TXQ
+ * @NL80211_TXQ_STATS_TX_PACKETS: total number of packets dequeued from TXQ
+ * @NL80211_TXQ_STATS_MAX_FLOWS: number of flow buckets for PHY
+ * @NL80211_TXQ_STATS_MAX: highest numbered attribute here
+ */
+enum nl80211_txq_stats {
+	__NL80211_TXQ_STATS_INVALID,
+	NL80211_TXQ_STATS_BACKLOG_BYTES,
+	NL80211_TXQ_STATS_BACKLOG_PACKETS,
+	NL80211_TXQ_STATS_FLOWS,
+	NL80211_TXQ_STATS_DROPS,
+	NL80211_TXQ_STATS_ECN_MARKS,
+	NL80211_TXQ_STATS_OVERLIMIT,
+	NL80211_TXQ_STATS_OVERMEMORY,
+	NL80211_TXQ_STATS_COLLISIONS,
+	NL80211_TXQ_STATS_TX_BYTES,
+	NL80211_TXQ_STATS_TX_PACKETS,
+	NL80211_TXQ_STATS_MAX_FLOWS,
+
+	/* keep last */
+	NUM_NL80211_TXQ_STATS,
+	NL80211_TXQ_STATS_MAX = NUM_NL80211_TXQ_STATS - 1
+};
+
+/**
+ * enum nl80211_mpath_flags - nl80211 mesh path flags
+ *
+ * @NL80211_MPATH_FLAG_ACTIVE: the mesh path is active
+ * @NL80211_MPATH_FLAG_RESOLVING: the mesh path discovery process is running
+ * @NL80211_MPATH_FLAG_SN_VALID: the mesh path contains a valid SN
+ * @NL80211_MPATH_FLAG_FIXED: the mesh path has been manually set
+ * @NL80211_MPATH_FLAG_RESOLVED: the mesh path discovery process succeeded
+ */
+enum nl80211_mpath_flags {
+	NL80211_MPATH_FLAG_ACTIVE =	1<<0,
+	NL80211_MPATH_FLAG_RESOLVING =	1<<1,
+	NL80211_MPATH_FLAG_SN_VALID =	1<<2,
+	NL80211_MPATH_FLAG_FIXED =	1<<3,
+	NL80211_MPATH_FLAG_RESOLVED =	1<<4,
+};
+
+/**
+ * enum nl80211_mpath_info - mesh path information
+ *
+ * These attribute types are used with %NL80211_ATTR_MPATH_INFO when getting
+ * information about a mesh path.
+ *
+ * @__NL80211_MPATH_INFO_INVALID: attribute number 0 is reserved
+ * @NL80211_MPATH_INFO_FRAME_QLEN: number of queued frames for this destination
+ * @NL80211_MPATH_INFO_SN: destination sequence number
+ * @NL80211_MPATH_INFO_METRIC: metric (cost) of this mesh path
+ * @NL80211_MPATH_INFO_EXPTIME: expiration time for the path, in msec from now
+ * @NL80211_MPATH_INFO_FLAGS: mesh path flags, enumerated in
+ * 	&enum nl80211_mpath_flags;
+ * @NL80211_MPATH_INFO_DISCOVERY_TIMEOUT: total path discovery timeout, in msec
+ * @NL80211_MPATH_INFO_DISCOVERY_RETRIES: mesh path discovery retries
+ * @NL80211_MPATH_INFO_MAX: highest mesh path information attribute number
+ *	currently defind
+ * @__NL80211_MPATH_INFO_AFTER_LAST: internal use
+ */
+enum nl80211_mpath_info {
+	__NL80211_MPATH_INFO_INVALID,
+	NL80211_MPATH_INFO_FRAME_QLEN,
+	NL80211_MPATH_INFO_SN,
+	NL80211_MPATH_INFO_METRIC,
+	NL80211_MPATH_INFO_EXPTIME,
+	NL80211_MPATH_INFO_FLAGS,
+	NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
+	NL80211_MPATH_INFO_DISCOVERY_RETRIES,
+
+	/* keep last */
+	__NL80211_MPATH_INFO_AFTER_LAST,
+	NL80211_MPATH_INFO_MAX = __NL80211_MPATH_INFO_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_band_iftype_attr - Interface type data attributes
+ *
+ * @__NL80211_BAND_IFTYPE_ATTR_INVALID: attribute number 0 is reserved
+ * @NL80211_BAND_IFTYPE_ATTR_IFTYPES: nested attribute containing a flag attribute
+ *     for each interface type that supports the band data
+ * @NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC: HE MAC capabilities as in HE
+ *     capabilities IE
+ * @NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY: HE PHY capabilities as in HE
+ *     capabilities IE
+ * @NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET: HE supported NSS/MCS as in HE
+ *     capabilities IE
+ * @NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE: HE PPE thresholds information as
+ *     defined in HE capabilities IE
+ * @NL80211_BAND_IFTYPE_ATTR_MAX: highest band HE capability attribute currently
+ *     defined
+ * @__NL80211_BAND_IFTYPE_ATTR_AFTER_LAST: internal use
+ */
+enum nl80211_band_iftype_attr {
+	__NL80211_BAND_IFTYPE_ATTR_INVALID,
+
+	NL80211_BAND_IFTYPE_ATTR_IFTYPES,
+	NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC,
+	NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY,
+	NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET,
+	NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE,
+
+	/* keep last */
+	__NL80211_BAND_IFTYPE_ATTR_AFTER_LAST,
+	NL80211_BAND_IFTYPE_ATTR_MAX = __NL80211_BAND_IFTYPE_ATTR_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_band_attr - band attributes
+ * @__NL80211_BAND_ATTR_INVALID: attribute number 0 is reserved
+ * @NL80211_BAND_ATTR_FREQS: supported frequencies in this band,
+ *	an array of nested frequency attributes
+ * @NL80211_BAND_ATTR_RATES: supported bitrates in this band,
+ *	an array of nested bitrate attributes
+ * @NL80211_BAND_ATTR_HT_MCS_SET: 16-byte attribute containing the MCS set as
+ *	defined in 802.11n
+ * @NL80211_BAND_ATTR_HT_CAPA: HT capabilities, as in the HT information IE
+ * @NL80211_BAND_ATTR_HT_AMPDU_FACTOR: A-MPDU factor, as in 11n
+ * @NL80211_BAND_ATTR_HT_AMPDU_DENSITY: A-MPDU density, as in 11n
+ * @NL80211_BAND_ATTR_VHT_MCS_SET: 32-byte attribute containing the MCS set as
+ *	defined in 802.11ac
+ * @NL80211_BAND_ATTR_VHT_CAPA: VHT capabilities, as in the HT information IE
+ * @NL80211_BAND_ATTR_IFTYPE_DATA: nested array attribute, with each entry using
+ *	attributes from &enum nl80211_band_iftype_attr
+ * @NL80211_BAND_ATTR_MAX: highest band attribute currently defined
+ * @__NL80211_BAND_ATTR_AFTER_LAST: internal use
+ */
+enum nl80211_band_attr {
+	__NL80211_BAND_ATTR_INVALID,
+	NL80211_BAND_ATTR_FREQS,
+	NL80211_BAND_ATTR_RATES,
+
+	NL80211_BAND_ATTR_HT_MCS_SET,
+	NL80211_BAND_ATTR_HT_CAPA,
+	NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
+	NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
+
+	NL80211_BAND_ATTR_VHT_MCS_SET,
+	NL80211_BAND_ATTR_VHT_CAPA,
+	NL80211_BAND_ATTR_IFTYPE_DATA,
+
+	/* keep last */
+	__NL80211_BAND_ATTR_AFTER_LAST,
+	NL80211_BAND_ATTR_MAX = __NL80211_BAND_ATTR_AFTER_LAST - 1
+};
+
+#define NL80211_BAND_ATTR_HT_CAPA NL80211_BAND_ATTR_HT_CAPA
+
+/**
+ * enum nl80211_wmm_rule - regulatory wmm rule
+ *
+ * @__NL80211_WMMR_INVALID: attribute number 0 is reserved
+ * @NL80211_WMMR_CW_MIN: Minimum contention window slot.
+ * @NL80211_WMMR_CW_MAX: Maximum contention window slot.
+ * @NL80211_WMMR_AIFSN: Arbitration Inter Frame Space.
+ * @NL80211_WMMR_TXOP: Maximum allowed tx operation time.
+ * @nl80211_WMMR_MAX: highest possible wmm rule.
+ * @__NL80211_WMMR_LAST: Internal use.
+ */
+enum nl80211_wmm_rule {
+	__NL80211_WMMR_INVALID,
+	NL80211_WMMR_CW_MIN,
+	NL80211_WMMR_CW_MAX,
+	NL80211_WMMR_AIFSN,
+	NL80211_WMMR_TXOP,
+
+	/* keep last */
+	__NL80211_WMMR_LAST,
+	NL80211_WMMR_MAX = __NL80211_WMMR_LAST - 1
+};
+
+/**
+ * enum nl80211_frequency_attr - frequency attributes
+ * @__NL80211_FREQUENCY_ATTR_INVALID: attribute number 0 is reserved
+ * @NL80211_FREQUENCY_ATTR_FREQ: Frequency in MHz
+ * @NL80211_FREQUENCY_ATTR_DISABLED: Channel is disabled in current
+ *	regulatory domain.
+ * @NL80211_FREQUENCY_ATTR_NO_IR: no mechanisms that initiate radiation
+ * 	are permitted on this channel, this includes sending probe
+ * 	requests, or modes of operation that require beaconing.
+ * @NL80211_FREQUENCY_ATTR_RADAR: Radar detection is mandatory
+ *	on this channel in current regulatory domain.
+ * @NL80211_FREQUENCY_ATTR_MAX_TX_POWER: Maximum transmission power in mBm
+ *	(100 * dBm).
+ * @NL80211_FREQUENCY_ATTR_DFS_STATE: current state for DFS
+ *	(enum nl80211_dfs_state)
+ * @NL80211_FREQUENCY_ATTR_DFS_TIME: time in miliseconds for how long
+ *	this channel is in this DFS state.
+ * @NL80211_FREQUENCY_ATTR_NO_HT40_MINUS: HT40- isn't possible with this
+ *	channel as the control channel
+ * @NL80211_FREQUENCY_ATTR_NO_HT40_PLUS: HT40+ isn't possible with this
+ *	channel as the control channel
+ * @NL80211_FREQUENCY_ATTR_NO_80MHZ: any 80 MHz channel using this channel
+ *	as the primary or any of the secondary channels isn't possible,
+ *	this includes 80+80 channels
+ * @NL80211_FREQUENCY_ATTR_NO_160MHZ: any 160 MHz (but not 80+80) channel
+ *	using this channel as the primary or any of the secondary channels
+ *	isn't possible
+ * @NL80211_FREQUENCY_ATTR_DFS_CAC_TIME: DFS CAC time in milliseconds.
+ * @NL80211_FREQUENCY_ATTR_INDOOR_ONLY: Only indoor use is permitted on this
+ *	channel. A channel that has the INDOOR_ONLY attribute can only be
+ *	used when there is a clear assessment that the device is operating in
+ *	an indoor surroundings, i.e., it is connected to AC power (and not
+ *	through portable DC inverters) or is under the control of a master
+ *	that is acting as an AP and is connected to AC power.
+ * @NL80211_FREQUENCY_ATTR_IR_CONCURRENT: IR operation is allowed on this
+ *	channel if it's connected concurrently to a BSS on the same channel on
+ *	the 2 GHz band or to a channel in the same UNII band (on the 5 GHz
+ *	band), and IEEE80211_CHAN_RADAR is not set. Instantiating a GO or TDLS
+ *	off-channel on a channel that has the IR_CONCURRENT attribute set can be
+ *	done when there is a clear assessment that the device is operating under
+ *	the guidance of an authorized master, i.e., setting up a GO or TDLS
+ *	off-channel while the device is also connected to an AP with DFS and
+ *	radar detection on the UNII band (it is up to user-space, i.e.,
+ *	wpa_supplicant to perform the required verifications). Using this
+ *	attribute for IR is disallowed for master interfaces (IBSS, AP).
+ * @NL80211_FREQUENCY_ATTR_NO_20MHZ: 20 MHz operation is not allowed
+ *	on this channel in current regulatory domain.
+ * @NL80211_FREQUENCY_ATTR_NO_10MHZ: 10 MHz operation is not allowed
+ *	on this channel in current regulatory domain.
+ * @NL80211_FREQUENCY_ATTR_WMM: this channel has wmm limitations.
+ *	This is a nested attribute that contains the wmm limitation per AC.
+ *	(see &enum nl80211_wmm_rule)
+ * @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number
+ *	currently defined
+ * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use
+ *
+ * See https://apps.fcc.gov/eas/comments/GetPublishedDocument.html?id=327&tn=528122
+ * for more information on the FCC description of the relaxations allowed
+ * by NL80211_FREQUENCY_ATTR_INDOOR_ONLY and
+ * NL80211_FREQUENCY_ATTR_IR_CONCURRENT.
+ */
+enum nl80211_frequency_attr {
+	__NL80211_FREQUENCY_ATTR_INVALID,
+	NL80211_FREQUENCY_ATTR_FREQ,
+	NL80211_FREQUENCY_ATTR_DISABLED,
+	NL80211_FREQUENCY_ATTR_NO_IR,
+	__NL80211_FREQUENCY_ATTR_NO_IBSS,
+	NL80211_FREQUENCY_ATTR_RADAR,
+	NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
+	NL80211_FREQUENCY_ATTR_DFS_STATE,
+	NL80211_FREQUENCY_ATTR_DFS_TIME,
+	NL80211_FREQUENCY_ATTR_NO_HT40_MINUS,
+	NL80211_FREQUENCY_ATTR_NO_HT40_PLUS,
+	NL80211_FREQUENCY_ATTR_NO_80MHZ,
+	NL80211_FREQUENCY_ATTR_NO_160MHZ,
+	NL80211_FREQUENCY_ATTR_DFS_CAC_TIME,
+	NL80211_FREQUENCY_ATTR_INDOOR_ONLY,
+	NL80211_FREQUENCY_ATTR_IR_CONCURRENT,
+	NL80211_FREQUENCY_ATTR_NO_20MHZ,
+	NL80211_FREQUENCY_ATTR_NO_10MHZ,
+	NL80211_FREQUENCY_ATTR_WMM,
+
+	/* keep last */
+	__NL80211_FREQUENCY_ATTR_AFTER_LAST,
+	NL80211_FREQUENCY_ATTR_MAX = __NL80211_FREQUENCY_ATTR_AFTER_LAST - 1
+};
+
+#define NL80211_FREQUENCY_ATTR_MAX_TX_POWER NL80211_FREQUENCY_ATTR_MAX_TX_POWER
+#define NL80211_FREQUENCY_ATTR_PASSIVE_SCAN	NL80211_FREQUENCY_ATTR_NO_IR
+#define NL80211_FREQUENCY_ATTR_NO_IBSS		NL80211_FREQUENCY_ATTR_NO_IR
+#define NL80211_FREQUENCY_ATTR_NO_IR		NL80211_FREQUENCY_ATTR_NO_IR
+#define NL80211_FREQUENCY_ATTR_GO_CONCURRENT \
+					NL80211_FREQUENCY_ATTR_IR_CONCURRENT
+
+/**
+ * enum nl80211_bitrate_attr - bitrate attributes
+ * @__NL80211_BITRATE_ATTR_INVALID: attribute number 0 is reserved
+ * @NL80211_BITRATE_ATTR_RATE: Bitrate in units of 100 kbps
+ * @NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE: Short preamble supported
+ *	in 2.4 GHz band.
+ * @NL80211_BITRATE_ATTR_MAX: highest bitrate attribute number
+ *	currently defined
+ * @__NL80211_BITRATE_ATTR_AFTER_LAST: internal use
+ */
+enum nl80211_bitrate_attr {
+	__NL80211_BITRATE_ATTR_INVALID,
+	NL80211_BITRATE_ATTR_RATE,
+	NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE,
+
+	/* keep last */
+	__NL80211_BITRATE_ATTR_AFTER_LAST,
+	NL80211_BITRATE_ATTR_MAX = __NL80211_BITRATE_ATTR_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_initiator - Indicates the initiator of a reg domain request
+ * @NL80211_REGDOM_SET_BY_CORE: Core queried CRDA for a dynamic world
+ * 	regulatory domain.
+ * @NL80211_REGDOM_SET_BY_USER: User asked the wireless core to set the
+ * 	regulatory domain.
+ * @NL80211_REGDOM_SET_BY_DRIVER: a wireless drivers has hinted to the
+ * 	wireless core it thinks its knows the regulatory domain we should be in.
+ * @NL80211_REGDOM_SET_BY_COUNTRY_IE: the wireless core has received an
+ * 	802.11 country information element with regulatory information it
+ * 	thinks we should consider. cfg80211 only processes the country
+ *	code from the IE, and relies on the regulatory domain information
+ *	structure passed by userspace (CRDA) from our wireless-regdb.
+ *	If a channel is enabled but the country code indicates it should
+ *	be disabled we disable the channel and re-enable it upon disassociation.
+ */
+enum nl80211_reg_initiator {
+	NL80211_REGDOM_SET_BY_CORE,
+	NL80211_REGDOM_SET_BY_USER,
+	NL80211_REGDOM_SET_BY_DRIVER,
+	NL80211_REGDOM_SET_BY_COUNTRY_IE,
+};
+
+/**
+ * enum nl80211_reg_type - specifies the type of regulatory domain
+ * @NL80211_REGDOM_TYPE_COUNTRY: the regulatory domain set is one that pertains
+ *	to a specific country. When this is set you can count on the
+ *	ISO / IEC 3166 alpha2 country code being valid.
+ * @NL80211_REGDOM_TYPE_WORLD: the regulatory set domain is the world regulatory
+ * 	domain.
+ * @NL80211_REGDOM_TYPE_CUSTOM_WORLD: the regulatory domain set is a custom
+ * 	driver specific world regulatory domain. These do not apply system-wide
+ * 	and are only applicable to the individual devices which have requested
+ * 	them to be applied.
+ * @NL80211_REGDOM_TYPE_INTERSECTION: the regulatory domain set is the product
+ *	of an intersection between two regulatory domains -- the previously
+ *	set regulatory domain on the system and the last accepted regulatory
+ *	domain request to be processed.
+ */
+enum nl80211_reg_type {
+	NL80211_REGDOM_TYPE_COUNTRY,
+	NL80211_REGDOM_TYPE_WORLD,
+	NL80211_REGDOM_TYPE_CUSTOM_WORLD,
+	NL80211_REGDOM_TYPE_INTERSECTION,
+};
+
+/**
+ * enum nl80211_reg_rule_attr - regulatory rule attributes
+ * @__NL80211_REG_RULE_ATTR_INVALID: attribute number 0 is reserved
+ * @NL80211_ATTR_REG_RULE_FLAGS: a set of flags which specify additional
+ * 	considerations for a given frequency range. These are the
+ * 	&enum nl80211_reg_rule_flags.
+ * @NL80211_ATTR_FREQ_RANGE_START: starting frequencry for the regulatory
+ * 	rule in KHz. This is not a center of frequency but an actual regulatory
+ * 	band edge.
+ * @NL80211_ATTR_FREQ_RANGE_END: ending frequency for the regulatory rule
+ * 	in KHz. This is not a center a frequency but an actual regulatory
+ * 	band edge.
+ * @NL80211_ATTR_FREQ_RANGE_MAX_BW: maximum allowed bandwidth for this
+ *	frequency range, in KHz.
+ * @NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN: the maximum allowed antenna gain
+ * 	for a given frequency range. The value is in mBi (100 * dBi).
+ * 	If you don't have one then don't send this.
+ * @NL80211_ATTR_POWER_RULE_MAX_EIRP: the maximum allowed EIRP for
+ * 	a given frequency range. The value is in mBm (100 * dBm).
+ * @NL80211_ATTR_DFS_CAC_TIME: DFS CAC time in milliseconds.
+ *	If not present or 0 default CAC time will be used.
+ * @NL80211_REG_RULE_ATTR_MAX: highest regulatory rule attribute number
+ *	currently defined
+ * @__NL80211_REG_RULE_ATTR_AFTER_LAST: internal use
+ */
+enum nl80211_reg_rule_attr {
+	__NL80211_REG_RULE_ATTR_INVALID,
+	NL80211_ATTR_REG_RULE_FLAGS,
+
+	NL80211_ATTR_FREQ_RANGE_START,
+	NL80211_ATTR_FREQ_RANGE_END,
+	NL80211_ATTR_FREQ_RANGE_MAX_BW,
+
+	NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
+	NL80211_ATTR_POWER_RULE_MAX_EIRP,
+
+	NL80211_ATTR_DFS_CAC_TIME,
+
+	/* keep last */
+	__NL80211_REG_RULE_ATTR_AFTER_LAST,
+	NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_sched_scan_match_attr - scheduled scan match attributes
+ * @__NL80211_SCHED_SCAN_MATCH_ATTR_INVALID: attribute number 0 is reserved
+ * @NL80211_SCHED_SCAN_MATCH_ATTR_SSID: SSID to be used for matching,
+ *	only report BSS with matching SSID.
+ *	(This cannot be used together with BSSID.)
+ * @NL80211_SCHED_SCAN_MATCH_ATTR_RSSI: RSSI threshold (in dBm) for reporting a
+ *	BSS in scan results. Filtering is turned off if not specified. Note that
+ *	if this attribute is in a match set of its own, then it is treated as
+ *	the default value for all matchsets with an SSID, rather than being a
+ *	matchset of its own without an RSSI filter. This is due to problems with
+ *	how this API was implemented in the past. Also, due to the same problem,
+ *	the only way to create a matchset with only an RSSI filter (with this
+ *	attribute) is if there's only a single matchset with the RSSI attribute.
+ * @NL80211_SCHED_SCAN_MATCH_ATTR_RELATIVE_RSSI: Flag indicating whether
+ *	%NL80211_SCHED_SCAN_MATCH_ATTR_RSSI to be used as absolute RSSI or
+ *	relative to current bss's RSSI.
+ * @NL80211_SCHED_SCAN_MATCH_ATTR_RSSI_ADJUST: When present the RSSI level for
+ *	BSS-es in the specified band is to be adjusted before doing
+ *	RSSI-based BSS selection. The attribute value is a packed structure
+ *	value as specified by &struct nl80211_bss_select_rssi_adjust.
+ * @NL80211_SCHED_SCAN_MATCH_ATTR_BSSID: BSSID to be used for matching
+ *	(this cannot be used together with SSID).
+ * @NL80211_SCHED_SCAN_MATCH_ATTR_MAX: highest scheduled scan filter
+ *	attribute number currently defined
+ * @__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST: internal use
+ */
+enum nl80211_sched_scan_match_attr {
+	__NL80211_SCHED_SCAN_MATCH_ATTR_INVALID,
+
+	NL80211_SCHED_SCAN_MATCH_ATTR_SSID,
+	NL80211_SCHED_SCAN_MATCH_ATTR_RSSI,
+	NL80211_SCHED_SCAN_MATCH_ATTR_RELATIVE_RSSI,
+	NL80211_SCHED_SCAN_MATCH_ATTR_RSSI_ADJUST,
+	NL80211_SCHED_SCAN_MATCH_ATTR_BSSID,
+
+	/* keep last */
+	__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST,
+	NL80211_SCHED_SCAN_MATCH_ATTR_MAX =
+		__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST - 1
+};
+
+/* only for backward compatibility */
+#define NL80211_ATTR_SCHED_SCAN_MATCH_SSID NL80211_SCHED_SCAN_MATCH_ATTR_SSID
+
+/**
+ * enum nl80211_reg_rule_flags - regulatory rule flags
+ *
+ * @NL80211_RRF_NO_OFDM: OFDM modulation not allowed
+ * @NL80211_RRF_NO_CCK: CCK modulation not allowed
+ * @NL80211_RRF_NO_INDOOR: indoor operation not allowed
+ * @NL80211_RRF_NO_OUTDOOR: outdoor operation not allowed
+ * @NL80211_RRF_DFS: DFS support is required to be used
+ * @NL80211_RRF_PTP_ONLY: this is only for Point To Point links
+ * @NL80211_RRF_PTMP_ONLY: this is only for Point To Multi Point links
+ * @NL80211_RRF_NO_IR: no mechanisms that initiate radiation are allowed,
+ * 	this includes probe requests or modes of operation that require
+ * 	beaconing.
+ * @NL80211_RRF_AUTO_BW: maximum available bandwidth should be calculated
+ *	base on contiguous rules and wider channels will be allowed to cross
+ *	multiple contiguous/overlapping frequency ranges.
+ * @NL80211_RRF_IR_CONCURRENT: See %NL80211_FREQUENCY_ATTR_IR_CONCURRENT
+ * @NL80211_RRF_NO_HT40MINUS: channels can't be used in HT40- operation
+ * @NL80211_RRF_NO_HT40PLUS: channels can't be used in HT40+ operation
+ * @NL80211_RRF_NO_80MHZ: 80MHz operation not allowed
+ * @NL80211_RRF_NO_160MHZ: 160MHz operation not allowed
+ */
+enum nl80211_reg_rule_flags {
+	NL80211_RRF_NO_OFDM		= 1<<0,
+	NL80211_RRF_NO_CCK		= 1<<1,
+	NL80211_RRF_NO_INDOOR		= 1<<2,
+	NL80211_RRF_NO_OUTDOOR		= 1<<3,
+	NL80211_RRF_DFS			= 1<<4,
+	NL80211_RRF_PTP_ONLY		= 1<<5,
+	NL80211_RRF_PTMP_ONLY		= 1<<6,
+	NL80211_RRF_NO_IR		= 1<<7,
+	__NL80211_RRF_NO_IBSS		= 1<<8,
+	NL80211_RRF_AUTO_BW		= 1<<11,
+	NL80211_RRF_IR_CONCURRENT	= 1<<12,
+	NL80211_RRF_NO_HT40MINUS	= 1<<13,
+	NL80211_RRF_NO_HT40PLUS		= 1<<14,
+	NL80211_RRF_NO_80MHZ		= 1<<15,
+	NL80211_RRF_NO_160MHZ		= 1<<16,
+};
+
+#define NL80211_RRF_PASSIVE_SCAN	NL80211_RRF_NO_IR
+#define NL80211_RRF_NO_IBSS		NL80211_RRF_NO_IR
+#define NL80211_RRF_NO_IR		NL80211_RRF_NO_IR
+#define NL80211_RRF_NO_HT40		(NL80211_RRF_NO_HT40MINUS |\
+					 NL80211_RRF_NO_HT40PLUS)
+#define NL80211_RRF_GO_CONCURRENT	NL80211_RRF_IR_CONCURRENT
+
+/* For backport compatibility with older userspace */
+#define NL80211_RRF_NO_IR_ALL		(NL80211_RRF_NO_IR | __NL80211_RRF_NO_IBSS)
+
+/**
+ * enum nl80211_dfs_regions - regulatory DFS regions
+ *
+ * @NL80211_DFS_UNSET: Country has no DFS master region specified
+ * @NL80211_DFS_FCC: Country follows DFS master rules from FCC
+ * @NL80211_DFS_ETSI: Country follows DFS master rules from ETSI
+ * @NL80211_DFS_JP: Country follows DFS master rules from JP/MKK/Telec
+ */
+enum nl80211_dfs_regions {
+	NL80211_DFS_UNSET	= 0,
+	NL80211_DFS_FCC		= 1,
+	NL80211_DFS_ETSI	= 2,
+	NL80211_DFS_JP		= 3,
+};
+
+/**
+ * enum nl80211_user_reg_hint_type - type of user regulatory hint
+ *
+ * @NL80211_USER_REG_HINT_USER: a user sent the hint. This is always
+ *	assumed if the attribute is not set.
+ * @NL80211_USER_REG_HINT_CELL_BASE: the hint comes from a cellular
+ *	base station. Device drivers that have been tested to work
+ *	properly to support this type of hint can enable these hints
+ *	by setting the NL80211_FEATURE_CELL_BASE_REG_HINTS feature
+ *	capability on the struct wiphy. The wireless core will
+ *	ignore all cell base station hints until at least one device
+ *	present has been registered with the wireless core that
+ *	has listed NL80211_FEATURE_CELL_BASE_REG_HINTS as a
+ *	supported feature.
+ * @NL80211_USER_REG_HINT_INDOOR: a user sent an hint indicating that the
+ *	platform is operating in an indoor environment.
+ */
+enum nl80211_user_reg_hint_type {
+	NL80211_USER_REG_HINT_USER	= 0,
+	NL80211_USER_REG_HINT_CELL_BASE = 1,
+	NL80211_USER_REG_HINT_INDOOR    = 2,
+};
+
+/**
+ * enum nl80211_survey_info - survey information
+ *
+ * These attribute types are used with %NL80211_ATTR_SURVEY_INFO
+ * when getting information about a survey.
+ *
+ * @__NL80211_SURVEY_INFO_INVALID: attribute number 0 is reserved
+ * @NL80211_SURVEY_INFO_FREQUENCY: center frequency of channel
+ * @NL80211_SURVEY_INFO_NOISE: noise level of channel (u8, dBm)
+ * @NL80211_SURVEY_INFO_IN_USE: channel is currently being used
+ * @NL80211_SURVEY_INFO_TIME: amount of time (in ms) that the radio
+ *	was turned on (on channel or globally)
+ * @NL80211_SURVEY_INFO_TIME_BUSY: amount of the time the primary
+ *	channel was sensed busy (either due to activity or energy detect)
+ * @NL80211_SURVEY_INFO_TIME_EXT_BUSY: amount of time the extension
+ *	channel was sensed busy
+ * @NL80211_SURVEY_INFO_TIME_RX: amount of time the radio spent
+ *	receiving data (on channel or globally)
+ * @NL80211_SURVEY_INFO_TIME_TX: amount of time the radio spent
+ *	transmitting data (on channel or globally)
+ * @NL80211_SURVEY_INFO_TIME_SCAN: time the radio spent for scan
+ *	(on this channel or globally)
+ * @NL80211_SURVEY_INFO_PAD: attribute used for padding for 64-bit alignment
+ * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number
+ *	currently defined
+ * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use
+ */
+enum nl80211_survey_info {
+	__NL80211_SURVEY_INFO_INVALID,
+	NL80211_SURVEY_INFO_FREQUENCY,
+	NL80211_SURVEY_INFO_NOISE,
+	NL80211_SURVEY_INFO_IN_USE,
+	NL80211_SURVEY_INFO_TIME,
+	NL80211_SURVEY_INFO_TIME_BUSY,
+	NL80211_SURVEY_INFO_TIME_EXT_BUSY,
+	NL80211_SURVEY_INFO_TIME_RX,
+	NL80211_SURVEY_INFO_TIME_TX,
+	NL80211_SURVEY_INFO_TIME_SCAN,
+	NL80211_SURVEY_INFO_PAD,
+
+	/* keep last */
+	__NL80211_SURVEY_INFO_AFTER_LAST,
+	NL80211_SURVEY_INFO_MAX = __NL80211_SURVEY_INFO_AFTER_LAST - 1
+};
+
+/* keep old names for compatibility */
+#define NL80211_SURVEY_INFO_CHANNEL_TIME		NL80211_SURVEY_INFO_TIME
+#define NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY		NL80211_SURVEY_INFO_TIME_BUSY
+#define NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY	NL80211_SURVEY_INFO_TIME_EXT_BUSY
+#define NL80211_SURVEY_INFO_CHANNEL_TIME_RX		NL80211_SURVEY_INFO_TIME_RX
+#define NL80211_SURVEY_INFO_CHANNEL_TIME_TX		NL80211_SURVEY_INFO_TIME_TX
+
+/**
+ * enum nl80211_mntr_flags - monitor configuration flags
+ *
+ * Monitor configuration flags.
+ *
+ * @__NL80211_MNTR_FLAG_INVALID: reserved
+ *
+ * @NL80211_MNTR_FLAG_FCSFAIL: pass frames with bad FCS
+ * @NL80211_MNTR_FLAG_PLCPFAIL: pass frames with bad PLCP
+ * @NL80211_MNTR_FLAG_CONTROL: pass control frames
+ * @NL80211_MNTR_FLAG_OTHER_BSS: disable BSSID filtering
+ * @NL80211_MNTR_FLAG_COOK_FRAMES: report frames after processing.
+ *	overrides all other flags.
+ * @NL80211_MNTR_FLAG_ACTIVE: use the configured MAC address
+ *	and ACK incoming unicast packets.
+ *
+ * @__NL80211_MNTR_FLAG_AFTER_LAST: internal use
+ * @NL80211_MNTR_FLAG_MAX: highest possible monitor flag
+ */
+enum nl80211_mntr_flags {
+	__NL80211_MNTR_FLAG_INVALID,
+	NL80211_MNTR_FLAG_FCSFAIL,
+	NL80211_MNTR_FLAG_PLCPFAIL,
+	NL80211_MNTR_FLAG_CONTROL,
+	NL80211_MNTR_FLAG_OTHER_BSS,
+	NL80211_MNTR_FLAG_COOK_FRAMES,
+	NL80211_MNTR_FLAG_ACTIVE,
+
+	/* keep last */
+	__NL80211_MNTR_FLAG_AFTER_LAST,
+	NL80211_MNTR_FLAG_MAX = __NL80211_MNTR_FLAG_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_mesh_power_mode - mesh power save modes
+ *
+ * @NL80211_MESH_POWER_UNKNOWN: The mesh power mode of the mesh STA is
+ *	not known or has not been set yet.
+ * @NL80211_MESH_POWER_ACTIVE: Active mesh power mode. The mesh STA is
+ *	in Awake state all the time.
+ * @NL80211_MESH_POWER_LIGHT_SLEEP: Light sleep mode. The mesh STA will
+ *	alternate between Active and Doze states, but will wake up for
+ *	neighbor's beacons.
+ * @NL80211_MESH_POWER_DEEP_SLEEP: Deep sleep mode. The mesh STA will
+ *	alternate between Active and Doze states, but may not wake up
+ *	for neighbor's beacons.
+ *
+ * @__NL80211_MESH_POWER_AFTER_LAST - internal use
+ * @NL80211_MESH_POWER_MAX - highest possible power save level
+ */
+
+enum nl80211_mesh_power_mode {
+	NL80211_MESH_POWER_UNKNOWN,
+	NL80211_MESH_POWER_ACTIVE,
+	NL80211_MESH_POWER_LIGHT_SLEEP,
+	NL80211_MESH_POWER_DEEP_SLEEP,
+
+	__NL80211_MESH_POWER_AFTER_LAST,
+	NL80211_MESH_POWER_MAX = __NL80211_MESH_POWER_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_meshconf_params - mesh configuration parameters
+ *
+ * Mesh configuration parameters. These can be changed while the mesh is
+ * active.
+ *
+ * @__NL80211_MESHCONF_INVALID: internal use
+ *
+ * @NL80211_MESHCONF_RETRY_TIMEOUT: specifies the initial retry timeout in
+ *	millisecond units, used by the Peer Link Open message
+ *
+ * @NL80211_MESHCONF_CONFIRM_TIMEOUT: specifies the initial confirm timeout, in
+ *	millisecond units, used by the peer link management to close a peer link
+ *
+ * @NL80211_MESHCONF_HOLDING_TIMEOUT: specifies the holding timeout, in
+ *	millisecond units
+ *
+ * @NL80211_MESHCONF_MAX_PEER_LINKS: maximum number of peer links allowed
+ *	on this mesh interface
+ *
+ * @NL80211_MESHCONF_MAX_RETRIES: specifies the maximum number of peer link
+ *	open retries that can be sent to establish a new peer link instance in a
+ *	mesh
+ *
+ * @NL80211_MESHCONF_TTL: specifies the value of TTL field set at a source mesh
+ *	point.
+ *
+ * @NL80211_MESHCONF_AUTO_OPEN_PLINKS: whether we should automatically open
+ *	peer links when we detect compatible mesh peers. Disabled if
+ *	@NL80211_MESH_SETUP_USERSPACE_MPM or @NL80211_MESH_SETUP_USERSPACE_AMPE are
+ *	set.
+ *
+ * @NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES: the number of action frames
+ *	containing a PREQ that an MP can send to a particular destination (path
+ *	target)
+ *
+ * @NL80211_MESHCONF_PATH_REFRESH_TIME: how frequently to refresh mesh paths
+ *	(in milliseconds)
+ *
+ * @NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT: minimum length of time to wait
+ *	until giving up on a path discovery (in milliseconds)
+ *
+ * @NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT: The time (in TUs) for which mesh
+ *	points receiving a PREQ shall consider the forwarding information from
+ *	the root to be valid. (TU = time unit)
+ *
+ * @NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL: The minimum interval of time (in
+ *	TUs) during which an MP can send only one action frame containing a PREQ
+ *	reference element
+ *
+ * @NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME: The interval of time (in TUs)
+ *	that it takes for an HWMP information element to propagate across the
+ *	mesh
+ *
+ * @NL80211_MESHCONF_HWMP_ROOTMODE: whether root mode is enabled or not
+ *
+ * @NL80211_MESHCONF_ELEMENT_TTL: specifies the value of TTL field set at a
+ *	source mesh point for path selection elements.
+ *
+ * @NL80211_MESHCONF_HWMP_RANN_INTERVAL:  The interval of time (in TUs) between
+ *	root announcements are transmitted.
+ *
+ * @NL80211_MESHCONF_GATE_ANNOUNCEMENTS: Advertise that this mesh station has
+ *	access to a broader network beyond the MBSS.  This is done via Root
+ *	Announcement frames.
+ *
+ * @NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL: The minimum interval of time (in
+ *	TUs) during which a mesh STA can send only one Action frame containing a
+ *	PERR element.
+ *
+ * @NL80211_MESHCONF_FORWARDING: set Mesh STA as forwarding or non-forwarding
+ *	or forwarding entity (default is TRUE - forwarding entity)
+ *
+ * @NL80211_MESHCONF_RSSI_THRESHOLD: RSSI threshold in dBm. This specifies the
+ *	threshold for average signal strength of candidate station to establish
+ *	a peer link.
+ *
+ * @NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR: maximum number of neighbors
+ *	to synchronize to for 11s default synchronization method
+ *	(see 11C.12.2.2)
+ *
+ * @NL80211_MESHCONF_HT_OPMODE: set mesh HT protection mode.
+ *
+ * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute
+ *
+ * @NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT: The time (in TUs) for
+ *	which mesh STAs receiving a proactive PREQ shall consider the forwarding
+ *	information to the root mesh STA to be valid.
+ *
+ * @NL80211_MESHCONF_HWMP_ROOT_INTERVAL: The interval of time (in TUs) between
+ *	proactive PREQs are transmitted.
+ *
+ * @NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL: The minimum interval of time
+ *	(in TUs) during which a mesh STA can send only one Action frame
+ *	containing a PREQ element for root path confirmation.
+ *
+ * @NL80211_MESHCONF_POWER_MODE: Default mesh power mode for new peer links.
+ *	type &enum nl80211_mesh_power_mode (u32)
+ *
+ * @NL80211_MESHCONF_AWAKE_WINDOW: awake window duration (in TUs)
+ *
+ * @NL80211_MESHCONF_PLINK_TIMEOUT: If no tx activity is seen from a STA we've
+ *	established peering with for longer than this time (in seconds), then
+ *	remove it from the STA's list of peers. You may set this to 0 to disable
+ *	the removal of the STA. Default is 30 minutes.
+ *
+ * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
+ */
+enum nl80211_meshconf_params {
+	__NL80211_MESHCONF_INVALID,
+	NL80211_MESHCONF_RETRY_TIMEOUT,
+	NL80211_MESHCONF_CONFIRM_TIMEOUT,
+	NL80211_MESHCONF_HOLDING_TIMEOUT,
+	NL80211_MESHCONF_MAX_PEER_LINKS,
+	NL80211_MESHCONF_MAX_RETRIES,
+	NL80211_MESHCONF_TTL,
+	NL80211_MESHCONF_AUTO_OPEN_PLINKS,
+	NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
+	NL80211_MESHCONF_PATH_REFRESH_TIME,
+	NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
+	NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
+	NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
+	NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
+	NL80211_MESHCONF_HWMP_ROOTMODE,
+	NL80211_MESHCONF_ELEMENT_TTL,
+	NL80211_MESHCONF_HWMP_RANN_INTERVAL,
+	NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
+	NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
+	NL80211_MESHCONF_FORWARDING,
+	NL80211_MESHCONF_RSSI_THRESHOLD,
+	NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
+	NL80211_MESHCONF_HT_OPMODE,
+	NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
+	NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
+	NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
+	NL80211_MESHCONF_POWER_MODE,
+	NL80211_MESHCONF_AWAKE_WINDOW,
+	NL80211_MESHCONF_PLINK_TIMEOUT,
+
+	/* keep last */
+	__NL80211_MESHCONF_ATTR_AFTER_LAST,
+	NL80211_MESHCONF_ATTR_MAX = __NL80211_MESHCONF_ATTR_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_mesh_setup_params - mesh setup parameters
+ *
+ * Mesh setup parameters.  These are used to start/join a mesh and cannot be
+ * changed while the mesh is active.
+ *
+ * @__NL80211_MESH_SETUP_INVALID: Internal use
+ *
+ * @NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL: Enable this option to use a
+ *	vendor specific path selection algorithm or disable it to use the
+ *	default HWMP.
+ *
+ * @NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC: Enable this option to use a
+ *	vendor specific path metric or disable it to use the default Airtime
+ *	metric.
+ *
+ * @NL80211_MESH_SETUP_IE: Information elements for this mesh, for instance, a
+ *	robust security network ie, or a vendor specific information element
+ *	that vendors will use to identify the path selection methods and
+ *	metrics in use.
+ *
+ * @NL80211_MESH_SETUP_USERSPACE_AUTH: Enable this option if an authentication
+ *	daemon will be authenticating mesh candidates.
+ *
+ * @NL80211_MESH_SETUP_USERSPACE_AMPE: Enable this option if an authentication
+ *	daemon will be securing peer link frames.  AMPE is a secured version of
+ *	Mesh Peering Management (MPM) and is implemented with the assistance of
+ *	a userspace daemon.  When this flag is set, the kernel will send peer
+ *	management frames to a userspace daemon that will implement AMPE
+ *	functionality (security capabilities selection, key confirmation, and
+ *	key management).  When the flag is unset (default), the kernel can
+ *	autonomously complete (unsecured) mesh peering without the need of a
+ *	userspace daemon.
+ *
+ * @NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC: Enable this option to use a
+ *	vendor specific synchronization method or disable it to use the default
+ *	neighbor offset synchronization
+ *
+ * @NL80211_MESH_SETUP_USERSPACE_MPM: Enable this option if userspace will
+ *	implement an MPM which handles peer allocation and state.
+ *
+ * @NL80211_MESH_SETUP_AUTH_PROTOCOL: Inform the kernel of the authentication
+ *	method (u8, as defined in IEEE 8.4.2.100.6, e.g. 0x1 for SAE).
+ *	Default is no authentication method required.
+ *
+ * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number
+ *
+ * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use
+ */
+enum nl80211_mesh_setup_params {
+	__NL80211_MESH_SETUP_INVALID,
+	NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL,
+	NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC,
+	NL80211_MESH_SETUP_IE,
+	NL80211_MESH_SETUP_USERSPACE_AUTH,
+	NL80211_MESH_SETUP_USERSPACE_AMPE,
+	NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC,
+	NL80211_MESH_SETUP_USERSPACE_MPM,
+	NL80211_MESH_SETUP_AUTH_PROTOCOL,
+
+	/* keep last */
+	__NL80211_MESH_SETUP_ATTR_AFTER_LAST,
+	NL80211_MESH_SETUP_ATTR_MAX = __NL80211_MESH_SETUP_ATTR_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_txq_attr - TX queue parameter attributes
+ * @__NL80211_TXQ_ATTR_INVALID: Attribute number 0 is reserved
+ * @NL80211_TXQ_ATTR_AC: AC identifier (NL80211_AC_*)
+ * @NL80211_TXQ_ATTR_TXOP: Maximum burst time in units of 32 usecs, 0 meaning
+ *	disabled
+ * @NL80211_TXQ_ATTR_CWMIN: Minimum contention window [a value of the form
+ *	2^n-1 in the range 1..32767]
+ * @NL80211_TXQ_ATTR_CWMAX: Maximum contention window [a value of the form
+ *	2^n-1 in the range 1..32767]
+ * @NL80211_TXQ_ATTR_AIFS: Arbitration interframe space [0..255]
+ * @__NL80211_TXQ_ATTR_AFTER_LAST: Internal
+ * @NL80211_TXQ_ATTR_MAX: Maximum TXQ attribute number
+ */
+enum nl80211_txq_attr {
+	__NL80211_TXQ_ATTR_INVALID,
+	NL80211_TXQ_ATTR_AC,
+	NL80211_TXQ_ATTR_TXOP,
+	NL80211_TXQ_ATTR_CWMIN,
+	NL80211_TXQ_ATTR_CWMAX,
+	NL80211_TXQ_ATTR_AIFS,
+
+	/* keep last */
+	__NL80211_TXQ_ATTR_AFTER_LAST,
+	NL80211_TXQ_ATTR_MAX = __NL80211_TXQ_ATTR_AFTER_LAST - 1
+};
+
+enum nl80211_ac {
+	NL80211_AC_VO,
+	NL80211_AC_VI,
+	NL80211_AC_BE,
+	NL80211_AC_BK,
+	NL80211_NUM_ACS
+};
+
+/* backward compat */
+#define NL80211_TXQ_ATTR_QUEUE	NL80211_TXQ_ATTR_AC
+#define NL80211_TXQ_Q_VO	NL80211_AC_VO
+#define NL80211_TXQ_Q_VI	NL80211_AC_VI
+#define NL80211_TXQ_Q_BE	NL80211_AC_BE
+#define NL80211_TXQ_Q_BK	NL80211_AC_BK
+
+/**
+ * enum nl80211_channel_type - channel type
+ * @NL80211_CHAN_NO_HT: 20 MHz, non-HT channel
+ * @NL80211_CHAN_HT20: 20 MHz HT channel
+ * @NL80211_CHAN_HT40MINUS: HT40 channel, secondary channel
+ *	below the control channel
+ * @NL80211_CHAN_HT40PLUS: HT40 channel, secondary channel
+ *	above the control channel
+ */
+enum nl80211_channel_type {
+	NL80211_CHAN_NO_HT,
+	NL80211_CHAN_HT20,
+	NL80211_CHAN_HT40MINUS,
+	NL80211_CHAN_HT40PLUS
+};
+
+/**
+ * enum nl80211_chan_width - channel width definitions
+ *
+ * These values are used with the %NL80211_ATTR_CHANNEL_WIDTH
+ * attribute.
+ *
+ * @NL80211_CHAN_WIDTH_20_NOHT: 20 MHz, non-HT channel
+ * @NL80211_CHAN_WIDTH_20: 20 MHz HT channel
+ * @NL80211_CHAN_WIDTH_40: 40 MHz channel, the %NL80211_ATTR_CENTER_FREQ1
+ *	attribute must be provided as well
+ * @NL80211_CHAN_WIDTH_80: 80 MHz channel, the %NL80211_ATTR_CENTER_FREQ1
+ *	attribute must be provided as well
+ * @NL80211_CHAN_WIDTH_80P80: 80+80 MHz channel, the %NL80211_ATTR_CENTER_FREQ1
+ *	and %NL80211_ATTR_CENTER_FREQ2 attributes must be provided as well
+ * @NL80211_CHAN_WIDTH_160: 160 MHz channel, the %NL80211_ATTR_CENTER_FREQ1
+ *	attribute must be provided as well
+ * @NL80211_CHAN_WIDTH_5: 5 MHz OFDM channel
+ * @NL80211_CHAN_WIDTH_10: 10 MHz OFDM channel
+ */
+enum nl80211_chan_width {
+	NL80211_CHAN_WIDTH_20_NOHT,
+	NL80211_CHAN_WIDTH_20,
+	NL80211_CHAN_WIDTH_40,
+	NL80211_CHAN_WIDTH_80,
+	NL80211_CHAN_WIDTH_80P80,
+	NL80211_CHAN_WIDTH_160,
+	NL80211_CHAN_WIDTH_5,
+	NL80211_CHAN_WIDTH_10,
+};
+
+/**
+ * enum nl80211_bss_scan_width - control channel width for a BSS
+ *
+ * These values are used with the %NL80211_BSS_CHAN_WIDTH attribute.
+ *
+ * @NL80211_BSS_CHAN_WIDTH_20: control channel is 20 MHz wide or compatible
+ * @NL80211_BSS_CHAN_WIDTH_10: control channel is 10 MHz wide
+ * @NL80211_BSS_CHAN_WIDTH_5: control channel is 5 MHz wide
+ */
+enum nl80211_bss_scan_width {
+	NL80211_BSS_CHAN_WIDTH_20,
+	NL80211_BSS_CHAN_WIDTH_10,
+	NL80211_BSS_CHAN_WIDTH_5,
+};
+
+/**
+ * enum nl80211_bss - netlink attributes for a BSS
+ *
+ * @__NL80211_BSS_INVALID: invalid
+ * @NL80211_BSS_BSSID: BSSID of the BSS (6 octets)
+ * @NL80211_BSS_FREQUENCY: frequency in MHz (u32)
+ * @NL80211_BSS_TSF: TSF of the received probe response/beacon (u64)
+ *	(if @NL80211_BSS_PRESP_DATA is present then this is known to be
+ *	from a probe response, otherwise it may be from the same beacon
+ *	that the NL80211_BSS_BEACON_TSF will be from)
+ * @NL80211_BSS_BEACON_INTERVAL: beacon interval of the (I)BSS (u16)
+ * @NL80211_BSS_CAPABILITY: capability field (CPU order, u16)
+ * @NL80211_BSS_INFORMATION_ELEMENTS: binary attribute containing the
+ *	raw information elements from the probe response/beacon (bin);
+ *	if the %NL80211_BSS_BEACON_IES attribute is present and the data is
+ *	different then the IEs here are from a Probe Response frame; otherwise
+ *	they are from a Beacon frame.
+ *	However, if the driver does not indicate the source of the IEs, these
+ *	IEs may be from either frame subtype.
+ *	If present, the @NL80211_BSS_PRESP_DATA attribute indicates that the
+ *	data here is known to be from a probe response, without any heuristics.
+ * @NL80211_BSS_SIGNAL_MBM: signal strength of probe response/beacon
+ *	in mBm (100 * dBm) (s32)
+ * @NL80211_BSS_SIGNAL_UNSPEC: signal strength of the probe response/beacon
+ *	in unspecified units, scaled to 0..100 (u8)
+ * @NL80211_BSS_STATUS: status, if this BSS is "used"
+ * @NL80211_BSS_SEEN_MS_AGO: age of this BSS entry in ms
+ * @NL80211_BSS_BEACON_IES: binary attribute containing the raw information
+ *	elements from a Beacon frame (bin); not present if no Beacon frame has
+ *	yet been received
+ * @NL80211_BSS_CHAN_WIDTH: channel width of the control channel
+ *	(u32, enum nl80211_bss_scan_width)
+ * @NL80211_BSS_BEACON_TSF: TSF of the last received beacon (u64)
+ *	(not present if no beacon frame has been received yet)
+ * @NL80211_BSS_PRESP_DATA: the data in @NL80211_BSS_INFORMATION_ELEMENTS and
+ *	@NL80211_BSS_TSF is known to be from a probe response (flag attribute)
+ * @NL80211_BSS_LAST_SEEN_BOOTTIME: CLOCK_BOOTTIME timestamp when this entry
+ *	was last updated by a received frame. The value is expected to be
+ *	accurate to about 10ms. (u64, nanoseconds)
+ * @NL80211_BSS_PAD: attribute used for padding for 64-bit alignment
+ * @NL80211_BSS_PARENT_TSF: the time at the start of reception of the first
+ *	octet of the timestamp field of the last beacon/probe received for
+ *	this BSS. The time is the TSF of the BSS specified by
+ *	@NL80211_BSS_PARENT_BSSID. (u64).
+ * @NL80211_BSS_PARENT_BSSID: the BSS according to which @NL80211_BSS_PARENT_TSF
+ *	is set.
+ * @NL80211_BSS_CHAIN_SIGNAL: per-chain signal strength of last BSS update.
+ *	Contains a nested array of signal strength attributes (u8, dBm),
+ *	using the nesting index as the antenna number.
+ * @__NL80211_BSS_AFTER_LAST: internal
+ * @NL80211_BSS_MAX: highest BSS attribute
+ */
+enum nl80211_bss {
+	__NL80211_BSS_INVALID,
+	NL80211_BSS_BSSID,
+	NL80211_BSS_FREQUENCY,
+	NL80211_BSS_TSF,
+	NL80211_BSS_BEACON_INTERVAL,
+	NL80211_BSS_CAPABILITY,
+	NL80211_BSS_INFORMATION_ELEMENTS,
+	NL80211_BSS_SIGNAL_MBM,
+	NL80211_BSS_SIGNAL_UNSPEC,
+	NL80211_BSS_STATUS,
+	NL80211_BSS_SEEN_MS_AGO,
+	NL80211_BSS_BEACON_IES,
+	NL80211_BSS_CHAN_WIDTH,
+	NL80211_BSS_BEACON_TSF,
+	NL80211_BSS_PRESP_DATA,
+	NL80211_BSS_LAST_SEEN_BOOTTIME,
+	NL80211_BSS_PAD,
+	NL80211_BSS_PARENT_TSF,
+	NL80211_BSS_PARENT_BSSID,
+	NL80211_BSS_CHAIN_SIGNAL,
+
+	/* keep last */
+	__NL80211_BSS_AFTER_LAST,
+	NL80211_BSS_MAX = __NL80211_BSS_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_bss_status - BSS "status"
+ * @NL80211_BSS_STATUS_AUTHENTICATED: Authenticated with this BSS.
+ *	Note that this is no longer used since cfg80211 no longer
+ *	keeps track of whether or not authentication was done with
+ *	a given BSS.
+ * @NL80211_BSS_STATUS_ASSOCIATED: Associated with this BSS.
+ * @NL80211_BSS_STATUS_IBSS_JOINED: Joined to this IBSS.
+ *
+ * The BSS status is a BSS attribute in scan dumps, which
+ * indicates the status the interface has wrt. this BSS.
+ */
+enum nl80211_bss_status {
+	NL80211_BSS_STATUS_AUTHENTICATED,
+	NL80211_BSS_STATUS_ASSOCIATED,
+	NL80211_BSS_STATUS_IBSS_JOINED,
+};
+
+/**
+ * enum nl80211_auth_type - AuthenticationType
+ *
+ * @NL80211_AUTHTYPE_OPEN_SYSTEM: Open System authentication
+ * @NL80211_AUTHTYPE_SHARED_KEY: Shared Key authentication (WEP only)
+ * @NL80211_AUTHTYPE_FT: Fast BSS Transition (IEEE 802.11r)
+ * @NL80211_AUTHTYPE_NETWORK_EAP: Network EAP (some Cisco APs and mainly LEAP)
+ * @NL80211_AUTHTYPE_SAE: Simultaneous authentication of equals
+ * @NL80211_AUTHTYPE_FILS_SK: Fast Initial Link Setup shared key
+ * @NL80211_AUTHTYPE_FILS_SK_PFS: Fast Initial Link Setup shared key with PFS
+ * @NL80211_AUTHTYPE_FILS_PK: Fast Initial Link Setup public key
+ * @__NL80211_AUTHTYPE_NUM: internal
+ * @NL80211_AUTHTYPE_MAX: maximum valid auth algorithm
+ * @NL80211_AUTHTYPE_AUTOMATIC: determine automatically (if necessary by
+ *	trying multiple times); this is invalid in netlink -- leave out
+ *	the attribute for this on CONNECT commands.
+ */
+enum nl80211_auth_type {
+	NL80211_AUTHTYPE_OPEN_SYSTEM,
+	NL80211_AUTHTYPE_SHARED_KEY,
+	NL80211_AUTHTYPE_FT,
+	NL80211_AUTHTYPE_NETWORK_EAP,
+	NL80211_AUTHTYPE_SAE,
+	NL80211_AUTHTYPE_FILS_SK,
+	NL80211_AUTHTYPE_FILS_SK_PFS,
+	NL80211_AUTHTYPE_FILS_PK,
+
+	/* keep last */
+	__NL80211_AUTHTYPE_NUM,
+	NL80211_AUTHTYPE_MAX = __NL80211_AUTHTYPE_NUM - 1,
+	NL80211_AUTHTYPE_AUTOMATIC
+};
+
+/**
+ * enum nl80211_key_type - Key Type
+ * @NL80211_KEYTYPE_GROUP: Group (broadcast/multicast) key
+ * @NL80211_KEYTYPE_PAIRWISE: Pairwise (unicast/individual) key
+ * @NL80211_KEYTYPE_PEERKEY: PeerKey (DLS)
+ * @NUM_NL80211_KEYTYPES: number of defined key types
+ */
+enum nl80211_key_type {
+	NL80211_KEYTYPE_GROUP,
+	NL80211_KEYTYPE_PAIRWISE,
+	NL80211_KEYTYPE_PEERKEY,
+
+	NUM_NL80211_KEYTYPES
+};
+
+/**
+ * enum nl80211_mfp - Management frame protection state
+ * @NL80211_MFP_NO: Management frame protection not used
+ * @NL80211_MFP_REQUIRED: Management frame protection required
+ * @NL80211_MFP_OPTIONAL: Management frame protection is optional
+ */
+enum nl80211_mfp {
+	NL80211_MFP_NO,
+	NL80211_MFP_REQUIRED,
+	NL80211_MFP_OPTIONAL,
+};
+
+enum nl80211_wpa_versions {
+	NL80211_WPA_VERSION_1 = 1 << 0,
+	NL80211_WPA_VERSION_2 = 1 << 1,
+//tianyan@2021.7.27 modify for add wifi6 module start
+	NL80211_WPA_VERSION_3 = 1 << 2,
+//tianyan@2021.7.27 modify for add wifi6 module end
+};
+
+/**
+ * enum nl80211_key_default_types - key default types
+ * @__NL80211_KEY_DEFAULT_TYPE_INVALID: invalid
+ * @NL80211_KEY_DEFAULT_TYPE_UNICAST: key should be used as default
+ *	unicast key
+ * @NL80211_KEY_DEFAULT_TYPE_MULTICAST: key should be used as default
+ *	multicast key
+ * @NUM_NL80211_KEY_DEFAULT_TYPES: number of default types
+ */
+enum nl80211_key_default_types {
+	__NL80211_KEY_DEFAULT_TYPE_INVALID,
+	NL80211_KEY_DEFAULT_TYPE_UNICAST,
+	NL80211_KEY_DEFAULT_TYPE_MULTICAST,
+
+	NUM_NL80211_KEY_DEFAULT_TYPES
+};
+
+/**
+ * enum nl80211_key_attributes - key attributes
+ * @__NL80211_KEY_INVALID: invalid
+ * @NL80211_KEY_DATA: (temporal) key data; for TKIP this consists of
+ *	16 bytes encryption key followed by 8 bytes each for TX and RX MIC
+ *	keys
+ * @NL80211_KEY_IDX: key ID (u8, 0-3)
+ * @NL80211_KEY_CIPHER: key cipher suite (u32, as defined by IEEE 802.11
+ *	section 7.3.2.25.1, e.g. 0x000FAC04)
+ * @NL80211_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and
+ *	CCMP keys, each six bytes in little endian
+ * @NL80211_KEY_DEFAULT: flag indicating default key
+ * @NL80211_KEY_DEFAULT_MGMT: flag indicating default management key
+ * @NL80211_KEY_TYPE: the key type from enum nl80211_key_type, if not
+ *	specified the default depends on whether a MAC address was
+ *	given with the command using the key or not (u32)
+ * @NL80211_KEY_DEFAULT_TYPES: A nested attribute containing flags
+ *	attributes, specifying what a key should be set as default as.
+ *	See &enum nl80211_key_default_types.
+ * @__NL80211_KEY_AFTER_LAST: internal
+ * @NL80211_KEY_MAX: highest key attribute
+ */
+enum nl80211_key_attributes {
+	__NL80211_KEY_INVALID,
+	NL80211_KEY_DATA,
+	NL80211_KEY_IDX,
+	NL80211_KEY_CIPHER,
+	NL80211_KEY_SEQ,
+	NL80211_KEY_DEFAULT,
+	NL80211_KEY_DEFAULT_MGMT,
+	NL80211_KEY_TYPE,
+	NL80211_KEY_DEFAULT_TYPES,
+
+	/* keep last */
+	__NL80211_KEY_AFTER_LAST,
+	NL80211_KEY_MAX = __NL80211_KEY_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_tx_rate_attributes - TX rate set attributes
+ * @__NL80211_TXRATE_INVALID: invalid
+ * @NL80211_TXRATE_LEGACY: Legacy (non-MCS) rates allowed for TX rate selection
+ *	in an array of rates as defined in IEEE 802.11 7.3.2.2 (u8 values with
+ *	1 = 500 kbps) but without the IE length restriction (at most
+ *	%NL80211_MAX_SUPP_RATES in a single array).
+ * @NL80211_TXRATE_HT: HT (MCS) rates allowed for TX rate selection
+ *	in an array of MCS numbers.
+ * @NL80211_TXRATE_VHT: VHT rates allowed for TX rate selection,
+ *	see &struct nl80211_txrate_vht
+ * @NL80211_TXRATE_GI: configure GI, see &enum nl80211_txrate_gi
+ * @__NL80211_TXRATE_AFTER_LAST: internal
+ * @NL80211_TXRATE_MAX: highest TX rate attribute
+ */
+enum nl80211_tx_rate_attributes {
+	__NL80211_TXRATE_INVALID,
+	NL80211_TXRATE_LEGACY,
+	NL80211_TXRATE_HT,
+	NL80211_TXRATE_VHT,
+	NL80211_TXRATE_GI,
+
+	/* keep last */
+	__NL80211_TXRATE_AFTER_LAST,
+	NL80211_TXRATE_MAX = __NL80211_TXRATE_AFTER_LAST - 1
+};
+
+#define NL80211_TXRATE_MCS NL80211_TXRATE_HT
+#define NL80211_VHT_NSS_MAX		8
+
+/**
+ * struct nl80211_txrate_vht - VHT MCS/NSS txrate bitmap
+ * @mcs: MCS bitmap table for each NSS (array index 0 for 1 stream, etc.)
+ */
+struct nl80211_txrate_vht {
+	__u16 mcs[NL80211_VHT_NSS_MAX];
+};
+
+enum nl80211_txrate_gi {
+	NL80211_TXRATE_DEFAULT_GI,
+	NL80211_TXRATE_FORCE_SGI,
+	NL80211_TXRATE_FORCE_LGI,
+};
+
+/**
+ * enum nl80211_band - Frequency band
+ * @NL80211_BAND_2GHZ: 2.4 GHz ISM band
+ * @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz)
+ * @NL80211_BAND_60GHZ: around 60 GHz band (58.32 - 64.80 GHz)
+ * @NUM_NL80211_BANDS: number of bands, avoid using this in userspace
+ *	since newer kernel versions may support more bands
+ */
+enum nl80211_band {
+	NL80211_BAND_2GHZ,
+	NL80211_BAND_5GHZ,
+	NL80211_BAND_60GHZ,
+
+	NUM_NL80211_BANDS,
+};
+
+/**
+ * enum nl80211_ps_state - powersave state
+ * @NL80211_PS_DISABLED: powersave is disabled
+ * @NL80211_PS_ENABLED: powersave is enabled
+ */
+enum nl80211_ps_state {
+	NL80211_PS_DISABLED,
+	NL80211_PS_ENABLED,
+};
+
+/**
+ * enum nl80211_attr_cqm - connection quality monitor attributes
+ * @__NL80211_ATTR_CQM_INVALID: invalid
+ * @NL80211_ATTR_CQM_RSSI_THOLD: RSSI threshold in dBm. This value specifies
+ *	the threshold for the RSSI level at which an event will be sent. Zero
+ *	to disable.  Alternatively, if %NL80211_EXT_FEATURE_CQM_RSSI_LIST is
+ *	set, multiple values can be supplied as a low-to-high sorted array of
+ *	threshold values in dBm.  Events will be sent when the RSSI value
+ *	crosses any of the thresholds.
+ * @NL80211_ATTR_CQM_RSSI_HYST: RSSI hysteresis in dBm. This value specifies
+ *	the minimum amount the RSSI level must change after an event before a
+ *	new event may be issued (to reduce effects of RSSI oscillation).
+ * @NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT: RSSI threshold event
+ * @NL80211_ATTR_CQM_PKT_LOSS_EVENT: a u32 value indicating that this many
+ *	consecutive packets were not acknowledged by the peer
+ * @NL80211_ATTR_CQM_TXE_RATE: TX error rate in %. Minimum % of TX failures
+ *	during the given %NL80211_ATTR_CQM_TXE_INTVL before an
+ *	%NL80211_CMD_NOTIFY_CQM with reported %NL80211_ATTR_CQM_TXE_RATE and
+ *	%NL80211_ATTR_CQM_TXE_PKTS is generated.
+ * @NL80211_ATTR_CQM_TXE_PKTS: number of attempted packets in a given
+ *	%NL80211_ATTR_CQM_TXE_INTVL before %NL80211_ATTR_CQM_TXE_RATE is
+ *	checked.
+ * @NL80211_ATTR_CQM_TXE_INTVL: interval in seconds. Specifies the periodic
+ *	interval in which %NL80211_ATTR_CQM_TXE_PKTS and
+ *	%NL80211_ATTR_CQM_TXE_RATE must be satisfied before generating an
+ *	%NL80211_CMD_NOTIFY_CQM. Set to 0 to turn off TX error reporting.
+ * @NL80211_ATTR_CQM_BEACON_LOSS_EVENT: flag attribute that's set in a beacon
+ *	loss event
+ * @NL80211_ATTR_CQM_RSSI_LEVEL: the RSSI value in dBm that triggered the
+ *	RSSI threshold event.
+ * @__NL80211_ATTR_CQM_AFTER_LAST: internal
+ * @NL80211_ATTR_CQM_MAX: highest key attribute
+ */
+enum nl80211_attr_cqm {
+	__NL80211_ATTR_CQM_INVALID,
+	NL80211_ATTR_CQM_RSSI_THOLD,
+	NL80211_ATTR_CQM_RSSI_HYST,
+	NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
+	NL80211_ATTR_CQM_PKT_LOSS_EVENT,
+	NL80211_ATTR_CQM_TXE_RATE,
+	NL80211_ATTR_CQM_TXE_PKTS,
+	NL80211_ATTR_CQM_TXE_INTVL,
+	NL80211_ATTR_CQM_BEACON_LOSS_EVENT,
+	NL80211_ATTR_CQM_RSSI_LEVEL,
+
+	/* keep last */
+	__NL80211_ATTR_CQM_AFTER_LAST,
+	NL80211_ATTR_CQM_MAX = __NL80211_ATTR_CQM_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_cqm_rssi_threshold_event - RSSI threshold event
+ * @NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW: The RSSI level is lower than the
+ *      configured threshold
+ * @NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH: The RSSI is higher than the
+ *      configured threshold
+ * @NL80211_CQM_RSSI_BEACON_LOSS_EVENT: (reserved, never sent)
+ */
+enum nl80211_cqm_rssi_threshold_event {
+	NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
+	NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
+	NL80211_CQM_RSSI_BEACON_LOSS_EVENT,
+};
+
+
+/**
+ * enum nl80211_tx_power_setting - TX power adjustment
+ * @NL80211_TX_POWER_AUTOMATIC: automatically determine transmit power
+ * @NL80211_TX_POWER_LIMITED: limit TX power by the mBm parameter
+ * @NL80211_TX_POWER_FIXED: fix TX power to the mBm parameter
+ */
+enum nl80211_tx_power_setting {
+	NL80211_TX_POWER_AUTOMATIC,
+	NL80211_TX_POWER_LIMITED,
+	NL80211_TX_POWER_FIXED,
+};
+
+/**
+ * enum nl80211_packet_pattern_attr - packet pattern attribute
+ * @__NL80211_PKTPAT_INVALID: invalid number for nested attribute
+ * @NL80211_PKTPAT_PATTERN: the pattern, values where the mask has
+ *	a zero bit are ignored
+ * @NL80211_PKTPAT_MASK: pattern mask, must be long enough to have
+ *	a bit for each byte in the pattern. The lowest-order bit corresponds
+ *	to the first byte of the pattern, but the bytes of the pattern are
+ *	in a little-endian-like format, i.e. the 9th byte of the pattern
+ *	corresponds to the lowest-order bit in the second byte of the mask.
+ *	For example: The match 00:xx:00:00:xx:00:00:00:00:xx:xx:xx (where
+ *	xx indicates "don't care") would be represented by a pattern of
+ *	twelve zero bytes, and a mask of "0xed,0x01".
+ *	Note that the pattern matching is done as though frames were not
+ *	802.11 frames but 802.3 frames, i.e. the frame is fully unpacked
+ *	first (including SNAP header unpacking) and then matched.
+ * @NL80211_PKTPAT_OFFSET: packet offset, pattern is matched after
+ *	these fixed number of bytes of received packet
+ * @NUM_NL80211_PKTPAT: number of attributes
+ * @MAX_NL80211_PKTPAT: max attribute number
+ */
+enum nl80211_packet_pattern_attr {
+	__NL80211_PKTPAT_INVALID,
+	NL80211_PKTPAT_MASK,
+	NL80211_PKTPAT_PATTERN,
+	NL80211_PKTPAT_OFFSET,
+
+	NUM_NL80211_PKTPAT,
+	MAX_NL80211_PKTPAT = NUM_NL80211_PKTPAT - 1,
+};
+
+/**
+ * struct nl80211_pattern_support - packet pattern support information
+ * @max_patterns: maximum number of patterns supported
+ * @min_pattern_len: minimum length of each pattern
+ * @max_pattern_len: maximum length of each pattern
+ * @max_pkt_offset: maximum Rx packet offset
+ *
+ * This struct is carried in %NL80211_WOWLAN_TRIG_PKT_PATTERN when
+ * that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED or in
+ * %NL80211_ATTR_COALESCE_RULE_PKT_PATTERN when that is part of
+ * %NL80211_ATTR_COALESCE_RULE in the capability information given
+ * by the kernel to userspace.
+ */
+struct nl80211_pattern_support {
+	__u32 max_patterns;
+	__u32 min_pattern_len;
+	__u32 max_pattern_len;
+	__u32 max_pkt_offset;
+} __attribute__((packed));
+
+/* only for backward compatibility */
+#define __NL80211_WOWLAN_PKTPAT_INVALID __NL80211_PKTPAT_INVALID
+#define NL80211_WOWLAN_PKTPAT_MASK NL80211_PKTPAT_MASK
+#define NL80211_WOWLAN_PKTPAT_PATTERN NL80211_PKTPAT_PATTERN
+#define NL80211_WOWLAN_PKTPAT_OFFSET NL80211_PKTPAT_OFFSET
+#define NUM_NL80211_WOWLAN_PKTPAT NUM_NL80211_PKTPAT
+#define MAX_NL80211_WOWLAN_PKTPAT MAX_NL80211_PKTPAT
+#define nl80211_wowlan_pattern_support nl80211_pattern_support
+
+/**
+ * enum nl80211_wowlan_triggers - WoWLAN trigger definitions
+ * @__NL80211_WOWLAN_TRIG_INVALID: invalid number for nested attributes
+ * @NL80211_WOWLAN_TRIG_ANY: wake up on any activity, do not really put
+ *	the chip into a special state -- works best with chips that have
+ *	support for low-power operation already (flag)
+ *	Note that this mode is incompatible with all of the others, if
+ *	any others are even supported by the device.
+ * @NL80211_WOWLAN_TRIG_DISCONNECT: wake up on disconnect, the way disconnect
+ *	is detected is implementation-specific (flag)
+ * @NL80211_WOWLAN_TRIG_MAGIC_PKT: wake up on magic packet (6x 0xff, followed
+ *	by 16 repetitions of MAC addr, anywhere in payload) (flag)
+ * @NL80211_WOWLAN_TRIG_PKT_PATTERN: wake up on the specified packet patterns
+ *	which are passed in an array of nested attributes, each nested attribute
+ *	defining a with attributes from &struct nl80211_wowlan_trig_pkt_pattern.
+ *	Each pattern defines a wakeup packet. Packet offset is associated with
+ *	each pattern which is used while matching the pattern. The matching is
+ *	done on the MSDU, i.e. as though the packet was an 802.3 packet, so the
+ *	pattern matching is done after the packet is converted to the MSDU.
+ *
+ *	In %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, it is a binary attribute
+ *	carrying a &struct nl80211_pattern_support.
+ *
+ *	When reporting wakeup. it is a u32 attribute containing the 0-based
+ *	index of the pattern that caused the wakeup, in the patterns passed
+ *	to the kernel when configuring.
+ * @NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED: Not a real trigger, and cannot be
+ *	used when setting, used only to indicate that GTK rekeying is supported
+ *	by the device (flag)
+ * @NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE: wake up on GTK rekey failure (if
+ *	done by the device) (flag)
+ * @NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST: wake up on EAP Identity Request
+ *	packet (flag)
+ * @NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE: wake up on 4-way handshake (flag)
+ * @NL80211_WOWLAN_TRIG_RFKILL_RELEASE: wake up when rfkill is released
+ *	(on devices that have rfkill in the device) (flag)
+ * @NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211: For wakeup reporting only, contains
+ *	the 802.11 packet that caused the wakeup, e.g. a deauth frame. The frame
+ *	may be truncated, the @NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN
+ *	attribute contains the original length.
+ * @NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN: Original length of the 802.11
+ *	packet, may be bigger than the @NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211
+ *	attribute if the packet was truncated somewhere.
+ * @NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023: For wakeup reporting only, contains the
+ *	802.11 packet that caused the wakeup, e.g. a magic packet. The frame may
+ *	be truncated, the @NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN attribute
+ *	contains the original length.
+ * @NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN: Original length of the 802.3
+ *	packet, may be bigger than the @NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023
+ *	attribute if the packet was truncated somewhere.
+ * @NL80211_WOWLAN_TRIG_TCP_CONNECTION: TCP connection wake, see DOC section
+ *	"TCP connection wakeup" for more details. This is a nested attribute
+ *	containing the exact information for establishing and keeping alive
+ *	the TCP connection.
+ * @NL80211_WOWLAN_TRIG_TCP_WAKEUP_MATCH: For wakeup reporting only, the
+ *	wakeup packet was received on the TCP connection
+ * @NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST: For wakeup reporting only, the
+ *	TCP connection was lost or failed to be established
+ * @NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS: For wakeup reporting only,
+ *	the TCP connection ran out of tokens to use for data to send to the
+ *	service
+ * @NL80211_WOWLAN_TRIG_NET_DETECT: wake up when a configured network
+ *	is detected.  This is a nested attribute that contains the
+ *	same attributes used with @NL80211_CMD_START_SCHED_SCAN.  It
+ *	specifies how the scan is performed (e.g. the interval, the
+ *	channels to scan and the initial delay) as well as the scan
+ *	results that will trigger a wake (i.e. the matchsets).  This
+ *	attribute is also sent in a response to
+ *	@NL80211_CMD_GET_WIPHY, indicating the number of match sets
+ *	supported by the driver (u32).
+ * @NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS: nested attribute
+ *	containing an array with information about what triggered the
+ *	wake up.  If no elements are present in the array, it means
+ *	that the information is not available.  If more than one
+ *	element is present, it means that more than one match
+ *	occurred.
+ *	Each element in the array is a nested attribute that contains
+ *	one optional %NL80211_ATTR_SSID attribute and one optional
+ *	%NL80211_ATTR_SCAN_FREQUENCIES attribute.  At least one of
+ *	these attributes must be present.  If
+ *	%NL80211_ATTR_SCAN_FREQUENCIES contains more than one
+ *	frequency, it means that the match occurred in more than one
+ *	channel.
+ * @NUM_NL80211_WOWLAN_TRIG: number of wake on wireless triggers
+ * @MAX_NL80211_WOWLAN_TRIG: highest wowlan trigger attribute number
+ *
+ * These nested attributes are used to configure the wakeup triggers and
+ * to report the wakeup reason(s).
+ */
+enum nl80211_wowlan_triggers {
+	__NL80211_WOWLAN_TRIG_INVALID,
+	NL80211_WOWLAN_TRIG_ANY,
+	NL80211_WOWLAN_TRIG_DISCONNECT,
+	NL80211_WOWLAN_TRIG_MAGIC_PKT,
+	NL80211_WOWLAN_TRIG_PKT_PATTERN,
+	NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED,
+	NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE,
+	NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST,
+	NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE,
+	NL80211_WOWLAN_TRIG_RFKILL_RELEASE,
+	NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211,
+	NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN,
+	NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023,
+	NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN,
+	NL80211_WOWLAN_TRIG_TCP_CONNECTION,
+	NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH,
+	NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST,
+	NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS,
+	NL80211_WOWLAN_TRIG_NET_DETECT,
+	NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS,
+
+	/* keep last */
+	NUM_NL80211_WOWLAN_TRIG,
+	MAX_NL80211_WOWLAN_TRIG = NUM_NL80211_WOWLAN_TRIG - 1
+};
+
+/**
+ * DOC: TCP connection wakeup
+ *
+ * Some devices can establish a TCP connection in order to be woken up by a
+ * packet coming in from outside their network segment, or behind NAT. If
+ * configured, the device will establish a TCP connection to the given
+ * service, and periodically send data to that service. The first data
+ * packet is usually transmitted after SYN/ACK, also ACKing the SYN/ACK.
+ * The data packets can optionally include a (little endian) sequence
+ * number (in the TCP payload!) that is generated by the device, and, also
+ * optionally, a token from a list of tokens. This serves as a keep-alive
+ * with the service, and for NATed connections, etc.
+ *
+ * During this keep-alive period, the server doesn't send any data to the
+ * client. When receiving data, it is compared against the wakeup pattern
+ * (and mask) and if it matches, the host is woken up. Similarly, if the
+ * connection breaks or cannot be established to start with, the host is
+ * also woken up.
+ *
+ * Developer's note: ARP offload is required for this, otherwise TCP
+ * response packets might not go through correctly.
+ */
+
+/**
+ * struct nl80211_wowlan_tcp_data_seq - WoWLAN TCP data sequence
+ * @start: starting value
+ * @offset: offset of sequence number in packet
+ * @len: length of the sequence value to write, 1 through 4
+ *
+ * Note: don't confuse with the TCP sequence number(s), this is for the
+ * keepalive packet payload. The actual value is written into the packet
+ * in little endian.
+ */
+struct nl80211_wowlan_tcp_data_seq {
+	__u32 start, offset, len;
+};
+
+/**
+ * struct nl80211_wowlan_tcp_data_token - WoWLAN TCP data token config
+ * @offset: offset of token in packet
+ * @len: length of each token
+ * @token_stream: stream of data to be used for the tokens, the length must
+ *	be a multiple of @len for this to make sense
+ */
+struct nl80211_wowlan_tcp_data_token {
+	__u32 offset, len;
+	__u8 token_stream[];
+};
+
+/**
+ * struct nl80211_wowlan_tcp_data_token_feature - data token features
+ * @min_len: minimum token length
+ * @max_len: maximum token length
+ * @bufsize: total available token buffer size (max size of @token_stream)
+ */
+struct nl80211_wowlan_tcp_data_token_feature {
+	__u32 min_len, max_len, bufsize;
+};
+
+/**
+ * enum nl80211_wowlan_tcp_attrs - WoWLAN TCP connection parameters
+ * @__NL80211_WOWLAN_TCP_INVALID: invalid number for nested attributes
+ * @NL80211_WOWLAN_TCP_SRC_IPV4: source IPv4 address (in network byte order)
+ * @NL80211_WOWLAN_TCP_DST_IPV4: destination IPv4 address
+ *	(in network byte order)
+ * @NL80211_WOWLAN_TCP_DST_MAC: destination MAC address, this is given because
+ *	route lookup when configured might be invalid by the time we suspend,
+ *	and doing a route lookup when suspending is no longer possible as it
+ *	might require ARP querying.
+ * @NL80211_WOWLAN_TCP_SRC_PORT: source port (u16); optional, if not given a
+ *	socket and port will be allocated
+ * @NL80211_WOWLAN_TCP_DST_PORT: destination port (u16)
+ * @NL80211_WOWLAN_TCP_DATA_PAYLOAD: data packet payload, at least one byte.
+ *	For feature advertising, a u32 attribute holding the maximum length
+ *	of the data payload.
+ * @NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ: data packet sequence configuration
+ *	(if desired), a &struct nl80211_wowlan_tcp_data_seq. For feature
+ *	advertising it is just a flag
+ * @NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN: data packet token configuration,
+ *	see &struct nl80211_wowlan_tcp_data_token and for advertising see
+ *	&struct nl80211_wowlan_tcp_data_token_feature.
+ * @NL80211_WOWLAN_TCP_DATA_INTERVAL: data interval in seconds, maximum
+ *	interval in feature advertising (u32)
+ * @NL80211_WOWLAN_TCP_WAKE_PAYLOAD: wake packet payload, for advertising a
+ *	u32 attribute holding the maximum length
+ * @NL80211_WOWLAN_TCP_WAKE_MASK: Wake packet payload mask, not used for
+ *	feature advertising. The mask works like @NL80211_PKTPAT_MASK
+ *	but on the TCP payload only.
+ * @NUM_NL80211_WOWLAN_TCP: number of TCP attributes
+ * @MAX_NL80211_WOWLAN_TCP: highest attribute number
+ */
+enum nl80211_wowlan_tcp_attrs {
+	__NL80211_WOWLAN_TCP_INVALID,
+	NL80211_WOWLAN_TCP_SRC_IPV4,
+	NL80211_WOWLAN_TCP_DST_IPV4,
+	NL80211_WOWLAN_TCP_DST_MAC,
+	NL80211_WOWLAN_TCP_SRC_PORT,
+	NL80211_WOWLAN_TCP_DST_PORT,
+	NL80211_WOWLAN_TCP_DATA_PAYLOAD,
+	NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ,
+	NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
+	NL80211_WOWLAN_TCP_DATA_INTERVAL,
+	NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
+	NL80211_WOWLAN_TCP_WAKE_MASK,
+
+	/* keep last */
+	NUM_NL80211_WOWLAN_TCP,
+	MAX_NL80211_WOWLAN_TCP = NUM_NL80211_WOWLAN_TCP - 1
+};
+
+/**
+ * struct nl80211_coalesce_rule_support - coalesce rule support information
+ * @max_rules: maximum number of rules supported
+ * @pat: packet pattern support information
+ * @max_delay: maximum supported coalescing delay in msecs
+ *
+ * This struct is carried in %NL80211_ATTR_COALESCE_RULE in the
+ * capability information given by the kernel to userspace.
+ */
+struct nl80211_coalesce_rule_support {
+	__u32 max_rules;
+	struct nl80211_pattern_support pat;
+	__u32 max_delay;
+} __attribute__((packed));
+
+/**
+ * enum nl80211_attr_coalesce_rule - coalesce rule attribute
+ * @__NL80211_COALESCE_RULE_INVALID: invalid number for nested attribute
+ * @NL80211_ATTR_COALESCE_RULE_DELAY: delay in msecs used for packet coalescing
+ * @NL80211_ATTR_COALESCE_RULE_CONDITION: condition for packet coalescence,
+ *	see &enum nl80211_coalesce_condition.
+ * @NL80211_ATTR_COALESCE_RULE_PKT_PATTERN: packet offset, pattern is matched
+ *	after these fixed number of bytes of received packet
+ * @NUM_NL80211_ATTR_COALESCE_RULE: number of attributes
+ * @NL80211_ATTR_COALESCE_RULE_MAX: max attribute number
+ */
+enum nl80211_attr_coalesce_rule {
+	__NL80211_COALESCE_RULE_INVALID,
+	NL80211_ATTR_COALESCE_RULE_DELAY,
+	NL80211_ATTR_COALESCE_RULE_CONDITION,
+	NL80211_ATTR_COALESCE_RULE_PKT_PATTERN,
+
+	/* keep last */
+	NUM_NL80211_ATTR_COALESCE_RULE,
+	NL80211_ATTR_COALESCE_RULE_MAX = NUM_NL80211_ATTR_COALESCE_RULE - 1
+};
+
+/**
+ * enum nl80211_coalesce_condition - coalesce rule conditions
+ * @NL80211_COALESCE_CONDITION_MATCH: coalaesce Rx packets when patterns
+ *	in a rule are matched.
+ * @NL80211_COALESCE_CONDITION_NO_MATCH: coalesce Rx packets when patterns
+ *	in a rule are not matched.
+ */
+enum nl80211_coalesce_condition {
+	NL80211_COALESCE_CONDITION_MATCH,
+	NL80211_COALESCE_CONDITION_NO_MATCH
+};
+
+/**
+ * enum nl80211_iface_limit_attrs - limit attributes
+ * @NL80211_IFACE_LIMIT_UNSPEC: (reserved)
+ * @NL80211_IFACE_LIMIT_MAX: maximum number of interfaces that
+ *	can be chosen from this set of interface types (u32)
+ * @NL80211_IFACE_LIMIT_TYPES: nested attribute containing a
+ *	flag attribute for each interface type in this set
+ * @NUM_NL80211_IFACE_LIMIT: number of attributes
+ * @MAX_NL80211_IFACE_LIMIT: highest attribute number
+ */
+enum nl80211_iface_limit_attrs {
+	NL80211_IFACE_LIMIT_UNSPEC,
+	NL80211_IFACE_LIMIT_MAX,
+	NL80211_IFACE_LIMIT_TYPES,
+
+	/* keep last */
+	NUM_NL80211_IFACE_LIMIT,
+	MAX_NL80211_IFACE_LIMIT = NUM_NL80211_IFACE_LIMIT - 1
+};
+
+/**
+ * enum nl80211_if_combination_attrs -- interface combination attributes
+ *
+ * @NL80211_IFACE_COMB_UNSPEC: (reserved)
+ * @NL80211_IFACE_COMB_LIMITS: Nested attributes containing the limits
+ *	for given interface types, see &enum nl80211_iface_limit_attrs.
+ * @NL80211_IFACE_COMB_MAXNUM: u32 attribute giving the total number of
+ *	interfaces that can be created in this group. This number doesn't
+ *	apply to interfaces purely managed in software, which are listed
+ *	in a separate attribute %NL80211_ATTR_INTERFACES_SOFTWARE.
+ * @NL80211_IFACE_COMB_STA_AP_BI_MATCH: flag attribute specifying that
+ *	beacon intervals within this group must be all the same even for
+ *	infrastructure and AP/GO combinations, i.e. the GO(s) must adopt
+ *	the infrastructure network's beacon interval.
+ * @NL80211_IFACE_COMB_NUM_CHANNELS: u32 attribute specifying how many
+ *	different channels may be used within this group.
+ * @NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS: u32 attribute containing the bitmap
+ *	of supported channel widths for radar detection.
+ * @NL80211_IFACE_COMB_RADAR_DETECT_REGIONS: u32 attribute containing the bitmap
+ *	of supported regulatory regions for radar detection.
+ * @NL80211_IFACE_COMB_BI_MIN_GCD: u32 attribute specifying the minimum GCD of
+ *	different beacon intervals supported by all the interface combinations
+ *	in this group (if not present, all beacon intervals be identical).
+ * @NUM_NL80211_IFACE_COMB: number of attributes
+ * @MAX_NL80211_IFACE_COMB: highest attribute number
+ *
+ * Examples:
+ *	limits = [ #{STA} <= 1, #{AP} <= 1 ], matching BI, channels = 1, max = 2
+ *	=> allows an AP and a STA that must match BIs
+ *
+ *	numbers = [ #{AP, P2P-GO} <= 8 ], BI min gcd, channels = 1, max = 8,
+ *	=> allows 8 of AP/GO that can have BI gcd >= min gcd
+ *
+ *	numbers = [ #{STA} <= 2 ], channels = 2, max = 2
+ *	=> allows two STAs on different channels
+ *
+ *	numbers = [ #{STA} <= 1, #{P2P-client,P2P-GO} <= 3 ], max = 4
+ *	=> allows a STA plus three P2P interfaces
+ *
+ * The list of these four possiblities could completely be contained
+ * within the %NL80211_ATTR_INTERFACE_COMBINATIONS attribute to indicate
+ * that any of these groups must match.
+ *
+ * "Combinations" of just a single interface will not be listed here,
+ * a single interface of any valid interface type is assumed to always
+ * be possible by itself. This means that implicitly, for each valid
+ * interface type, the following group always exists:
+ *	numbers = [ #{<type>} <= 1 ], channels = 1, max = 1
+ */
+enum nl80211_if_combination_attrs {
+	NL80211_IFACE_COMB_UNSPEC,
+	NL80211_IFACE_COMB_LIMITS,
+	NL80211_IFACE_COMB_MAXNUM,
+	NL80211_IFACE_COMB_STA_AP_BI_MATCH,
+	NL80211_IFACE_COMB_NUM_CHANNELS,
+	NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
+	NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
+	NL80211_IFACE_COMB_BI_MIN_GCD,
+
+	/* keep last */
+	NUM_NL80211_IFACE_COMB,
+	MAX_NL80211_IFACE_COMB = NUM_NL80211_IFACE_COMB - 1
+};
+
+
+/**
+ * enum nl80211_plink_state - state of a mesh peer link finite state machine
+ *
+ * @NL80211_PLINK_LISTEN: initial state, considered the implicit
+ *	state of non existant mesh peer links
+ * @NL80211_PLINK_OPN_SNT: mesh plink open frame has been sent to
+ *	this mesh peer
+ * @NL80211_PLINK_OPN_RCVD: mesh plink open frame has been received
+ *	from this mesh peer
+ * @NL80211_PLINK_CNF_RCVD: mesh plink confirm frame has been
+ *	received from this mesh peer
+ * @NL80211_PLINK_ESTAB: mesh peer link is established
+ * @NL80211_PLINK_HOLDING: mesh peer link is being closed or cancelled
+ * @NL80211_PLINK_BLOCKED: all frames transmitted from this mesh
+ *	plink are discarded
+ * @NUM_NL80211_PLINK_STATES: number of peer link states
+ * @MAX_NL80211_PLINK_STATES: highest numerical value of plink states
+ */
+enum nl80211_plink_state {
+	NL80211_PLINK_LISTEN,
+	NL80211_PLINK_OPN_SNT,
+	NL80211_PLINK_OPN_RCVD,
+	NL80211_PLINK_CNF_RCVD,
+	NL80211_PLINK_ESTAB,
+	NL80211_PLINK_HOLDING,
+	NL80211_PLINK_BLOCKED,
+
+	/* keep last */
+	NUM_NL80211_PLINK_STATES,
+	MAX_NL80211_PLINK_STATES = NUM_NL80211_PLINK_STATES - 1
+};
+
+/**
+ * enum nl80211_plink_action - actions to perform in mesh peers
+ *
+ * @NL80211_PLINK_ACTION_NO_ACTION: perform no action
+ * @NL80211_PLINK_ACTION_OPEN: start mesh peer link establishment
+ * @NL80211_PLINK_ACTION_BLOCK: block traffic from this mesh peer
+ * @NUM_NL80211_PLINK_ACTIONS: number of possible actions
+ */
+enum plink_actions {
+	NL80211_PLINK_ACTION_NO_ACTION,
+	NL80211_PLINK_ACTION_OPEN,
+	NL80211_PLINK_ACTION_BLOCK,
+
+	NUM_NL80211_PLINK_ACTIONS,
+};
+
+
+#define NL80211_KCK_LEN			16
+#define NL80211_KEK_LEN			16
+#define NL80211_REPLAY_CTR_LEN		8
+
+/**
+ * enum nl80211_rekey_data - attributes for GTK rekey offload
+ * @__NL80211_REKEY_DATA_INVALID: invalid number for nested attributes
+ * @NL80211_REKEY_DATA_KEK: key encryption key (binary)
+ * @NL80211_REKEY_DATA_KCK: key confirmation key (binary)
+ * @NL80211_REKEY_DATA_REPLAY_CTR: replay counter (binary)
+ * @NUM_NL80211_REKEY_DATA: number of rekey attributes (internal)
+ * @MAX_NL80211_REKEY_DATA: highest rekey attribute (internal)
+ */
+enum nl80211_rekey_data {
+	__NL80211_REKEY_DATA_INVALID,
+	NL80211_REKEY_DATA_KEK,
+	NL80211_REKEY_DATA_KCK,
+	NL80211_REKEY_DATA_REPLAY_CTR,
+
+	/* keep last */
+	NUM_NL80211_REKEY_DATA,
+	MAX_NL80211_REKEY_DATA = NUM_NL80211_REKEY_DATA - 1
+};
+
+/**
+ * enum nl80211_hidden_ssid - values for %NL80211_ATTR_HIDDEN_SSID
+ * @NL80211_HIDDEN_SSID_NOT_IN_USE: do not hide SSID (i.e., broadcast it in
+ *	Beacon frames)
+ * @NL80211_HIDDEN_SSID_ZERO_LEN: hide SSID by using zero-length SSID element
+ *	in Beacon frames
+ * @NL80211_HIDDEN_SSID_ZERO_CONTENTS: hide SSID by using correct length of SSID
+ *	element in Beacon frames but zero out each byte in the SSID
+ */
+enum nl80211_hidden_ssid {
+	NL80211_HIDDEN_SSID_NOT_IN_USE,
+	NL80211_HIDDEN_SSID_ZERO_LEN,
+	NL80211_HIDDEN_SSID_ZERO_CONTENTS
+};
+
+/**
+ * enum nl80211_sta_wme_attr - station WME attributes
+ * @__NL80211_STA_WME_INVALID: invalid number for nested attribute
+ * @NL80211_STA_WME_UAPSD_QUEUES: bitmap of uapsd queues. the format
+ *	is the same as the AC bitmap in the QoS info field.
+ * @NL80211_STA_WME_MAX_SP: max service period. the format is the same
+ *	as the MAX_SP field in the QoS info field (but already shifted down).
+ * @__NL80211_STA_WME_AFTER_LAST: internal
+ * @NL80211_STA_WME_MAX: highest station WME attribute
+ */
+enum nl80211_sta_wme_attr {
+	__NL80211_STA_WME_INVALID,
+	NL80211_STA_WME_UAPSD_QUEUES,
+	NL80211_STA_WME_MAX_SP,
+
+	/* keep last */
+	__NL80211_STA_WME_AFTER_LAST,
+	NL80211_STA_WME_MAX = __NL80211_STA_WME_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_pmksa_candidate_attr - attributes for PMKSA caching candidates
+ * @__NL80211_PMKSA_CANDIDATE_INVALID: invalid number for nested attributes
+ * @NL80211_PMKSA_CANDIDATE_INDEX: candidate index (u32; the smaller, the higher
+ *	priority)
+ * @NL80211_PMKSA_CANDIDATE_BSSID: candidate BSSID (6 octets)
+ * @NL80211_PMKSA_CANDIDATE_PREAUTH: RSN pre-authentication supported (flag)
+ * @NUM_NL80211_PMKSA_CANDIDATE: number of PMKSA caching candidate attributes
+ *	(internal)
+ * @MAX_NL80211_PMKSA_CANDIDATE: highest PMKSA caching candidate attribute
+ *	(internal)
+ */
+enum nl80211_pmksa_candidate_attr {
+	__NL80211_PMKSA_CANDIDATE_INVALID,
+	NL80211_PMKSA_CANDIDATE_INDEX,
+	NL80211_PMKSA_CANDIDATE_BSSID,
+	NL80211_PMKSA_CANDIDATE_PREAUTH,
+
+	/* keep last */
+	NUM_NL80211_PMKSA_CANDIDATE,
+	MAX_NL80211_PMKSA_CANDIDATE = NUM_NL80211_PMKSA_CANDIDATE - 1
+};
+
+/**
+ * enum nl80211_tdls_operation - values for %NL80211_ATTR_TDLS_OPERATION
+ * @NL80211_TDLS_DISCOVERY_REQ: Send a TDLS discovery request
+ * @NL80211_TDLS_SETUP: Setup TDLS link
+ * @NL80211_TDLS_TEARDOWN: Teardown a TDLS link which is already established
+ * @NL80211_TDLS_ENABLE_LINK: Enable TDLS link
+ * @NL80211_TDLS_DISABLE_LINK: Disable TDLS link
+ */
+enum nl80211_tdls_operation {
+	NL80211_TDLS_DISCOVERY_REQ,
+	NL80211_TDLS_SETUP,
+	NL80211_TDLS_TEARDOWN,
+	NL80211_TDLS_ENABLE_LINK,
+	NL80211_TDLS_DISABLE_LINK,
+};
+
+/*
+ * enum nl80211_ap_sme_features - device-integrated AP features
+ * Reserved for future use, no bits are defined in
+ * NL80211_ATTR_DEVICE_AP_SME yet.
+enum nl80211_ap_sme_features {
+};
+ */
+
+/**
+ * enum nl80211_feature_flags - device/driver features
+ * @NL80211_FEATURE_SK_TX_STATUS: This driver supports reflecting back
+ *	TX status to the socket error queue when requested with the
+ *	socket option.
+ * @NL80211_FEATURE_HT_IBSS: This driver supports IBSS with HT datarates.
+ * @NL80211_FEATURE_INACTIVITY_TIMER: This driver takes care of freeing up
+ *	the connected inactive stations in AP mode.
+ * @NL80211_FEATURE_CELL_BASE_REG_HINTS: This driver has been tested
+ *	to work properly to suppport receiving regulatory hints from
+ *	cellular base stations.
+ * @NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL: (no longer available, only
+ *	here to reserve the value for API/ABI compatibility)
+ * @NL80211_FEATURE_SAE: This driver supports simultaneous authentication of
+ *	equals (SAE) with user space SME (NL80211_CMD_AUTHENTICATE) in station
+ *	mode
+ * @NL80211_FEATURE_LOW_PRIORITY_SCAN: This driver supports low priority scan
+ * @NL80211_FEATURE_SCAN_FLUSH: Scan flush is supported
+ * @NL80211_FEATURE_AP_SCAN: Support scanning using an AP vif
+ * @NL80211_FEATURE_VIF_TXPOWER: The driver supports per-vif TX power setting
+ * @NL80211_FEATURE_NEED_OBSS_SCAN: The driver expects userspace to perform
+ *	OBSS scans and generate 20/40 BSS coex reports. This flag is used only
+ *	for drivers implementing the CONNECT API, for AUTH/ASSOC it is implied.
+ * @NL80211_FEATURE_P2P_GO_CTWIN: P2P GO implementation supports CT Window
+ *	setting
+ * @NL80211_FEATURE_P2P_GO_OPPPS: P2P GO implementation supports opportunistic
+ *	powersave
+ * @NL80211_FEATURE_FULL_AP_CLIENT_STATE: The driver supports full state
+ *	transitions for AP clients. Without this flag (and if the driver
+ *	doesn't have the AP SME in the device) the driver supports adding
+ *	stations only when they're associated and adds them in associated
+ *	state (to later be transitioned into authorized), with this flag
+ *	they should be added before even sending the authentication reply
+ *	and then transitioned into authenticated, associated and authorized
+ *	states using station flags.
+ *	Note that even for drivers that support this, the default is to add
+ *	stations in authenticated/associated state, so to add unauthenticated
+ *	stations the authenticated/associated bits have to be set in the mask.
+ * @NL80211_FEATURE_ADVERTISE_CHAN_LIMITS: cfg80211 advertises channel limits
+ *	(HT40, VHT 80/160 MHz) if this flag is set
+ * @NL80211_FEATURE_USERSPACE_MPM: This driver supports a userspace Mesh
+ *	Peering Management entity which may be implemented by registering for
+ *	beacons or NL80211_CMD_NEW_PEER_CANDIDATE events. The mesh beacon is
+ *	still generated by the driver.
+ * @NL80211_FEATURE_ACTIVE_MONITOR: This driver supports an active monitor
+ *	interface. An active monitor interface behaves like a normal monitor
+ *	interface, but gets added to the driver. It ensures that incoming
+ *	unicast packets directed at the configured interface address get ACKed.
+ * @NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE: This driver supports dynamic
+ *	channel bandwidth change (e.g., HT 20 <-> 40 MHz channel) during the
+ *	lifetime of a BSS.
+ * @NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES: This device adds a DS Parameter
+ *	Set IE to probe requests.
+ * @NL80211_FEATURE_WFA_TPC_IE_IN_PROBES: This device adds a WFA TPC Report IE
+ *	to probe requests.
+ * @NL80211_FEATURE_QUIET: This device, in client mode, supports Quiet Period
+ *	requests sent to it by an AP.
+ * @NL80211_FEATURE_TX_POWER_INSERTION: This device is capable of inserting the
+ *	current tx power value into the TPC Report IE in the spectrum
+ *	management TPC Report action frame, and in the Radio Measurement Link
+ *	Measurement Report action frame.
+ * @NL80211_FEATURE_ACKTO_ESTIMATION: This driver supports dynamic ACK timeout
+ *	estimation (dynack). %NL80211_ATTR_WIPHY_DYN_ACK flag attribute is used
+ *	to enable dynack.
+ * @NL80211_FEATURE_STATIC_SMPS: Device supports static spatial
+ *	multiplexing powersave, ie. can turn off all but one chain
+ *	even on HT connections that should be using more chains.
+ * @NL80211_FEATURE_DYNAMIC_SMPS: Device supports dynamic spatial
+ *	multiplexing powersave, ie. can turn off all but one chain
+ *	and then wake the rest up as required after, for example,
+ *	rts/cts handshake.
+ * @NL80211_FEATURE_SUPPORTS_WMM_ADMISSION: the device supports setting up WMM
+ *	TSPEC sessions (TID aka TSID 0-7) with the %NL80211_CMD_ADD_TX_TS
+ *	command. Standard IEEE 802.11 TSPEC setup is not yet supported, it
+ *	needs to be able to handle Block-Ack agreements and other things.
+ * @NL80211_FEATURE_MAC_ON_CREATE: Device supports configuring
+ *	the vif's MAC address upon creation.
+ *	See 'macaddr' field in the vif_params (cfg80211.h).
+ * @NL80211_FEATURE_TDLS_CHANNEL_SWITCH: Driver supports channel switching when
+ *	operating as a TDLS peer.
+ * @NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR: This device/driver supports using a
+ *	random MAC address during scan (if the device is unassociated); the
+ *	%NL80211_SCAN_FLAG_RANDOM_ADDR flag may be set for scans and the MAC
+ *	address mask/value will be used.
+ * @NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR: This device/driver supports
+ *	using a random MAC address for every scan iteration during scheduled
+ *	scan (while not associated), the %NL80211_SCAN_FLAG_RANDOM_ADDR may
+ *	be set for scheduled scan and the MAC address mask/value will be used.
+ * @NL80211_FEATURE_ND_RANDOM_MAC_ADDR: This device/driver supports using a
+ *	random MAC address for every scan iteration during "net detect", i.e.
+ *	scan in unassociated WoWLAN, the %NL80211_SCAN_FLAG_RANDOM_ADDR may
+ *	be set for scheduled scan and the MAC address mask/value will be used.
+ */
+enum nl80211_feature_flags {
+	NL80211_FEATURE_SK_TX_STATUS			= 1 << 0,
+	NL80211_FEATURE_HT_IBSS				= 1 << 1,
+	NL80211_FEATURE_INACTIVITY_TIMER		= 1 << 2,
+	NL80211_FEATURE_CELL_BASE_REG_HINTS		= 1 << 3,
+	NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL	= 1 << 4,
+	NL80211_FEATURE_SAE				= 1 << 5,
+	NL80211_FEATURE_LOW_PRIORITY_SCAN		= 1 << 6,
+	NL80211_FEATURE_SCAN_FLUSH			= 1 << 7,
+	NL80211_FEATURE_AP_SCAN				= 1 << 8,
+	NL80211_FEATURE_VIF_TXPOWER			= 1 << 9,
+	NL80211_FEATURE_NEED_OBSS_SCAN			= 1 << 10,
+	NL80211_FEATURE_P2P_GO_CTWIN			= 1 << 11,
+	NL80211_FEATURE_P2P_GO_OPPPS			= 1 << 12,
+	/* bit 13 is reserved */
+	NL80211_FEATURE_ADVERTISE_CHAN_LIMITS		= 1 << 14,
+	NL80211_FEATURE_FULL_AP_CLIENT_STATE		= 1 << 15,
+	NL80211_FEATURE_USERSPACE_MPM			= 1 << 16,
+	NL80211_FEATURE_ACTIVE_MONITOR			= 1 << 17,
+	NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE	= 1 << 18,
+	NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES	= 1 << 19,
+	NL80211_FEATURE_WFA_TPC_IE_IN_PROBES		= 1 << 20,
+	NL80211_FEATURE_QUIET				= 1 << 21,
+	NL80211_FEATURE_TX_POWER_INSERTION		= 1 << 22,
+	NL80211_FEATURE_ACKTO_ESTIMATION		= 1 << 23,
+	NL80211_FEATURE_STATIC_SMPS			= 1 << 24,
+	NL80211_FEATURE_DYNAMIC_SMPS			= 1 << 25,
+	NL80211_FEATURE_SUPPORTS_WMM_ADMISSION		= 1 << 26,
+	NL80211_FEATURE_MAC_ON_CREATE			= 1 << 27,
+	NL80211_FEATURE_TDLS_CHANNEL_SWITCH		= 1 << 28,
+	NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR		= 1 << 29,
+	NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR	= 1 << 30,
+	NL80211_FEATURE_ND_RANDOM_MAC_ADDR		= 1 << 31,
+};
+
+/**
+ * enum nl80211_ext_feature_index - bit index of extended features.
+ * @NL80211_EXT_FEATURE_VHT_IBSS: This driver supports IBSS with VHT datarates.
+ * @NL80211_EXT_FEATURE_RRM: This driver supports RRM. When featured, user can
+ *	can request to use RRM (see %NL80211_ATTR_USE_RRM) with
+ *	%NL80211_CMD_ASSOCIATE and %NL80211_CMD_CONNECT requests, which will set
+ *	the ASSOC_REQ_USE_RRM flag in the association request even if
+ *	NL80211_FEATURE_QUIET is not advertized.
+ * @NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER: This device supports MU-MIMO air
+ *	sniffer which means that it can be configured to hear packets from
+ *	certain groups which can be configured by the
+ *	%NL80211_ATTR_MU_MIMO_GROUP_DATA attribute,
+ *	or can be configured to follow a station by configuring the
+ *	%NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR attribute.
+ * @NL80211_EXT_FEATURE_SCAN_START_TIME: This driver includes the actual
+ *	time the scan started in scan results event. The time is the TSF of
+ *	the BSS that the interface that requested the scan is connected to
+ *	(if available).
+ * @NL80211_EXT_FEATURE_BSS_PARENT_TSF: Per BSS, this driver reports the
+ *	time the last beacon/probe was received. The time is the TSF of the
+ *	BSS that the interface that requested the scan is connected to
+ *	(if available).
+ * @NL80211_EXT_FEATURE_SET_SCAN_DWELL: This driver supports configuration of
+ *	channel dwell time.
+ * @NL80211_EXT_FEATURE_BEACON_RATE_LEGACY: Driver supports beacon rate
+ *	configuration (AP/mesh), supporting a legacy (non HT/VHT) rate.
+ * @NL80211_EXT_FEATURE_BEACON_RATE_HT: Driver supports beacon rate
+ *	configuration (AP/mesh) with HT rates.
+ * @NL80211_EXT_FEATURE_BEACON_RATE_VHT: Driver supports beacon rate
+ *	configuration (AP/mesh) with VHT rates.
+ * @NL80211_EXT_FEATURE_FILS_STA: This driver supports Fast Initial Link Setup
+ *	with user space SME (NL80211_CMD_AUTHENTICATE) in station mode.
+ * @NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA: This driver supports randomized TA
+ *	in @NL80211_CMD_FRAME while not associated.
+ * @NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED: This driver supports
+ *	randomized TA in @NL80211_CMD_FRAME while associated.
+ * @NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI: The driver supports sched_scan
+ *	for reporting BSSs with better RSSI than the current connected BSS
+ *	(%NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI).
+ * @NL80211_EXT_FEATURE_CQM_RSSI_LIST: With this driver the
+ *	%NL80211_ATTR_CQM_RSSI_THOLD attribute accepts a list of zero or more
+ *	RSSI threshold values to monitor rather than exactly one threshold.
+ * @NL80211_EXT_FEATURE_FILS_SK_OFFLOAD: Driver SME supports FILS shared key
+ *	authentication with %NL80211_CMD_CONNECT.
+ * @NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK: Device wants to do 4-way
+ *	handshake with PSK in station mode (PSK is passed as part of the connect
+ *	and associate commands), doing it in the host might not be supported.
+ * @NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X: Device wants to do doing 4-way
+ *	handshake with 802.1X in station mode (will pass EAP frames to the host
+ *	and accept the set_pmk/del_pmk commands), doing it in the host might not
+ *	be supported.
+ * @NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME: Driver is capable of overriding
+ *	the max channel attribute in the FILS request params IE with the
+ *	actual dwell time.
+ * @NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP: Driver accepts broadcast probe
+ *	response
+ * @NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE: Driver supports sending
+ *	the first probe request in each channel at rate of at least 5.5Mbps.
+ * @NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION: Driver supports
+ *	probe request tx deferral and suppression
+ * @NL80211_EXT_FEATURE_MFP_OPTIONAL: Driver supports the %NL80211_MFP_OPTIONAL
+ *	value in %NL80211_ATTR_USE_MFP.
+ * @NL80211_EXT_FEATURE_LOW_SPAN_SCAN: Driver supports low span scan.
+ * @NL80211_EXT_FEATURE_LOW_POWER_SCAN: Driver supports low power scan.
+ * @NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN: Driver supports high accuracy scan.
+ * @NL80211_EXT_FEATURE_DFS_OFFLOAD: HW/driver will offload DFS actions.
+ *	Device or driver will do all DFS-related actions by itself,
+ *	informing user-space about CAC progress, radar detection event,
+ *	channel change triggered by radar detection event.
+ *	No need to start CAC from user-space, no need to react to
+ *	"radar detected" event.
+ * @NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211: Driver supports sending and
+ *	receiving control port frames over nl80211 instead of the netdevice.
+ * @NL80211_EXT_FEATURE_DATA_ACK_SIGNAL_SUPPORT: This Driver support data ack
+ *	rssi if firmware support, this flag is to intimate about ack rssi
+ *	support to nl80211.
+ * @NL80211_EXT_FEATURE_TXQS: Driver supports FQ-CoDel-enabled intermediate
+ *      TXQs.
+ * @NL80211_EXT_FEATURE_SCAN_RANDOM_SN: Driver/device supports randomizing the
+ *	SN in probe request frames if requested by %NL80211_SCAN_FLAG_RANDOM_SN.
+ * @NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT: Driver/device can omit all data
+ *	except for supported rates from the probe request content if requested
+ *	by the %NL80211_SCAN_FLAG_MIN_PREQ_CONTENT flag.
+ * @NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER: Driver supports enabling fine
+ *	timing measurement responder role.
+ *
+ * @NL80211_EXT_FEATURE_CAN_REPLACE_PTK0: Driver/device confirm that they are
+ *      able to rekey an in-use key correctly. Userspace must not rekey PTK keys
+ *      if this flag is not set. Ignoring this can leak clear text packets and/or
+ *      freeze the connection.
+ * @NL80211_EXT_FEATURE_EXT_KEY_ID: Driver supports "Extended Key ID for
+ *      Individually Addressed Frames" from IEEE802.11-2016.
+ *
+ * @NL80211_EXT_FEATURE_AIRTIME_FAIRNESS: Driver supports getting airtime
+ *	fairness for transmitted packets and has enabled airtime fairness
+ *	scheduling.
+ *
+ * @NL80211_EXT_FEATURE_AP_PMKSA_CACHING: Driver/device supports PMKSA caching
+ *	(set/del PMKSA operations) in AP mode.
+ *
+ * @NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD: Driver supports
+ *	filtering of sched scan results using band specific RSSI thresholds.
+ *
+ * @NL80211_EXT_FEATURE_STA_TX_PWR: This driver supports controlling tx power
+ *	to a station.
+ *
+ * @NL80211_EXT_FEATURE_SAE_OFFLOAD: Device wants to do SAE authentication in
+ *	station mode (SAE password is passed as part of the connect command).
+ *
+ * @NL80211_EXT_FEATURE_VLAN_OFFLOAD: The driver supports a single netdev
+ *	with VLAN tagged frames and separate VLAN-specific netdevs added using
+ *	vconfig similarly to the Ethernet case.
+ *
+ * @NL80211_EXT_FEATURE_AQL: The driver supports the Airtime Queue Limit (AQL)
+ *	feature, which prevents bufferbloat by using the expected transmission
+ *	time to limit the amount of data buffered in the hardware.
+ *
+ * @NL80211_EXT_FEATURE_BEACON_PROTECTION: The driver supports Beacon protection
+ *	and can receive key configuration for BIGTK using key indexes 6 and 7.
+ * @NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT: The driver supports Beacon
+ *	protection as a client only and cannot transmit protected beacons.
+ *
+ * @NL80211_EXT_FEATURE_CONTROL_PORT_NO_PREAUTH: The driver can disable the
+ *	forwarding of preauth frames over the control port. They are then
+ *	handled as ordinary data frames.
+ *
+ * @NL80211_EXT_FEATURE_PROTECTED_TWT: Driver supports protected TWT frames
+ *
+ * @NL80211_EXT_FEATURE_DEL_IBSS_STA: The driver supports removing stations
+ *      in IBSS mode, essentially by dropping their state.
+ *
+ * @NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS: management frame registrations
+ *	are possible for multicast frames and those will be reported properly.
+ *
+ * @NL80211_EXT_FEATURE_SCAN_FREQ_KHZ: This driver supports receiving and
+ *	reporting scan request with %NL80211_ATTR_SCAN_FREQ_KHZ. In order to
+ *	report %NL80211_ATTR_SCAN_FREQ_KHZ, %NL80211_SCAN_FLAG_FREQ_KHZ must be
+ *	included in the scan request.
+ *
+ * @NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS: The driver
+ *	can report tx status for control port over nl80211 tx operations.
+ *
+ * @NL80211_EXT_FEATURE_OPERATING_CHANNEL_VALIDATION: Driver supports Operating
+ *	Channel Validation (OCV) when using driver's SME for RSNA handshakes.
+ *
+ * @NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK: Device wants to do 4-way
+ *	handshake with PSK in AP mode (PSK is passed as part of the start AP
+ *	command).
+ *
+ * @NL80211_EXT_FEATURE_SAE_OFFLOAD_AP: Device wants to do SAE authentication
+ *	in AP mode (SAE password is passed as part of the start AP command).
+ *
+ * @NL80211_EXT_FEATURE_FILS_DISCOVERY: Driver/device supports FILS discovery
+ *	frames transmission
+ *
+ * @NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP: Driver/device supports
+ *	unsolicited broadcast probe response transmission
+ *
+ * @NL80211_EXT_FEATURE_BEACON_RATE_HE: Driver supports beacon rate
+ *	configuration (AP/mesh) with HE rates.
+ *
+ * @NL80211_EXT_FEATURE_SECURE_LTF: Device supports secure LTF measurement
+ *      exchange protocol.
+ *
+ * @NL80211_EXT_FEATURE_SECURE_RTT: Device supports secure RTT measurement
+ *      exchange protocol.
+ *
+ * @NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE: Device supports management
+ *      frame protection for all management frames exchanged during the
+ *      negotiation and range measurement procedure.
+ *
+ * @NUM_NL80211_EXT_FEATURES: number of extended features.
+ * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
+ */
+enum nl80211_ext_feature_index {
+	NL80211_EXT_FEATURE_VHT_IBSS,
+	NL80211_EXT_FEATURE_RRM,
+	NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER,
+	NL80211_EXT_FEATURE_SCAN_START_TIME,
+	NL80211_EXT_FEATURE_BSS_PARENT_TSF,
+	NL80211_EXT_FEATURE_SET_SCAN_DWELL,
+	NL80211_EXT_FEATURE_BEACON_RATE_LEGACY,
+	NL80211_EXT_FEATURE_BEACON_RATE_HT,
+	NL80211_EXT_FEATURE_BEACON_RATE_VHT,
+	NL80211_EXT_FEATURE_FILS_STA,
+	NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA,
+	NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED,
+	NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI,
+	NL80211_EXT_FEATURE_CQM_RSSI_LIST,
+	NL80211_EXT_FEATURE_FILS_SK_OFFLOAD,
+	NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK,
+	NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X,
+	NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME,
+	NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP,
+	NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE,
+	NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION,
+	NL80211_EXT_FEATURE_MFP_OPTIONAL,
+	NL80211_EXT_FEATURE_LOW_SPAN_SCAN,
+	NL80211_EXT_FEATURE_LOW_POWER_SCAN,
+	NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN,
+	NL80211_EXT_FEATURE_DFS_OFFLOAD,
+	NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211,
+	NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT,
+	/* we renamed this - stay compatible */
+	NL80211_EXT_FEATURE_DATA_ACK_SIGNAL_SUPPORT = NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT,
+	NL80211_EXT_FEATURE_TXQS,
+	NL80211_EXT_FEATURE_SCAN_RANDOM_SN,
+	NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT,
+	NL80211_EXT_FEATURE_CAN_REPLACE_PTK0,
+	NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER,
+	NL80211_EXT_FEATURE_AIRTIME_FAIRNESS,
+	NL80211_EXT_FEATURE_AP_PMKSA_CACHING,
+	NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD,
+	NL80211_EXT_FEATURE_EXT_KEY_ID,
+	NL80211_EXT_FEATURE_STA_TX_PWR,
+
+//tianyan@2021.7.27 modify for add wifi6 module start
+	NL80211_EXT_FEATURE_SAE_OFFLOAD,
+//tianyan@2021.7.27 modify for add wifi6 module end
+	NL80211_EXT_FEATURE_VLAN_OFFLOAD,
+	NL80211_EXT_FEATURE_AQL,
+	NL80211_EXT_FEATURE_BEACON_PROTECTION,
+	NL80211_EXT_FEATURE_CONTROL_PORT_NO_PREAUTH,
+	NL80211_EXT_FEATURE_PROTECTED_TWT,
+	NL80211_EXT_FEATURE_DEL_IBSS_STA,
+	NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS,
+	NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT,
+	NL80211_EXT_FEATURE_SCAN_FREQ_KHZ,
+	NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS,
+	NL80211_EXT_FEATURE_OPERATING_CHANNEL_VALIDATION,
+	NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK,
+	NL80211_EXT_FEATURE_SAE_OFFLOAD_AP,
+	NL80211_EXT_FEATURE_FILS_DISCOVERY,
+	NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP,
+	NL80211_EXT_FEATURE_BEACON_RATE_HE,
+	NL80211_EXT_FEATURE_SECURE_LTF,
+	NL80211_EXT_FEATURE_SECURE_RTT,
+	NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE,
+
+	/* add new features before the definition below */
+	NUM_NL80211_EXT_FEATURES,
+	MAX_NL80211_EXT_FEATURES = NUM_NL80211_EXT_FEATURES - 1
+};
+
+/**
+ * enum nl80211_probe_resp_offload_support_attr - optional supported
+ *	protocols for probe-response offloading by the driver/FW.
+ *	To be used with the %NL80211_ATTR_PROBE_RESP_OFFLOAD attribute.
+ *	Each enum value represents a bit in the bitmap of supported
+ *	protocols. Typically a subset of probe-requests belonging to a
+ *	supported protocol will be excluded from offload and uploaded
+ *	to the host.
+ *
+ * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS: Support for WPS ver. 1
+ * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2: Support for WPS ver. 2
+ * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P: Support for P2P
+ * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U: Support for 802.11u
+ */
+enum nl80211_probe_resp_offload_support_attr {
+	NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS =	1<<0,
+	NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 =	1<<1,
+	NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P =	1<<2,
+	NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U =	1<<3,
+};
+
+/**
+ * enum nl80211_connect_failed_reason - connection request failed reasons
+ * @NL80211_CONN_FAIL_MAX_CLIENTS: Maximum number of clients that can be
+ *	handled by the AP is reached.
+ * @NL80211_CONN_FAIL_BLOCKED_CLIENT: Connection request is rejected due to ACL.
+ */
+enum nl80211_connect_failed_reason {
+	NL80211_CONN_FAIL_MAX_CLIENTS,
+	NL80211_CONN_FAIL_BLOCKED_CLIENT,
+};
+
+/**
+ * enum nl80211_timeout_reason - timeout reasons
+ *
+ * @NL80211_TIMEOUT_UNSPECIFIED: Timeout reason unspecified.
+ * @NL80211_TIMEOUT_SCAN: Scan (AP discovery) timed out.
+ * @NL80211_TIMEOUT_AUTH: Authentication timed out.
+ * @NL80211_TIMEOUT_ASSOC: Association timed out.
+ */
+enum nl80211_timeout_reason {
+	NL80211_TIMEOUT_UNSPECIFIED,
+	NL80211_TIMEOUT_SCAN,
+	NL80211_TIMEOUT_AUTH,
+	NL80211_TIMEOUT_ASSOC,
+};
+
+/**
+ * enum nl80211_scan_flags -  scan request control flags
+ *
+ * Scan request control flags are used to control the handling
+ * of NL80211_CMD_TRIGGER_SCAN and NL80211_CMD_START_SCHED_SCAN
+ * requests.
+ *
+ * NL80211_SCAN_FLAG_LOW_SPAN, NL80211_SCAN_FLAG_LOW_POWER, and
+ * NL80211_SCAN_FLAG_HIGH_ACCURACY flags are exclusive of each other, i.e., only
+ * one of them can be used in the request.
+ *
+ * @NL80211_SCAN_FLAG_LOW_PRIORITY: scan request has low priority
+ * @NL80211_SCAN_FLAG_FLUSH: flush cache before scanning
+ * @NL80211_SCAN_FLAG_AP: force a scan even if the interface is configured
+ *	as AP and the beaconing has already been configured. This attribute is
+ *	dangerous because will destroy stations performance as a lot of frames
+ *	will be lost while scanning off-channel, therefore it must be used only
+ *	when really needed
+ * @NL80211_SCAN_FLAG_RANDOM_ADDR: use a random MAC address for this scan (or
+ *	for scheduled scan: a different one for every scan iteration). When the
+ *	flag is set, depending on device capabilities the @NL80211_ATTR_MAC and
+ *	@NL80211_ATTR_MAC_MASK attributes may also be given in which case only
+ *	the masked bits will be preserved from the MAC address and the remainder
+ *	randomised. If the attributes are not given full randomisation (46 bits,
+ *	locally administered 1, multicast 0) is assumed.
+ *	This flag must not be requested when the feature isn't supported, check
+ *	the nl80211 feature flags for the device.
+ * @NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME: fill the dwell time in the FILS
+ *	request parameters IE in the probe request
+ * @NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP: accept broadcast probe responses
+ * @NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE: send probe request frames at
+ *	rate of at least 5.5M. In case non OCE AP is dicovered in the channel,
+ *	only the first probe req in the channel will be sent in high rate.
+ * @NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION: allow probe request
+ *	tx deferral (dot11FILSProbeDelay shall be set to 15ms)
+ *	and suppression (if it has received a broadcast Probe Response frame,
+ *	Beacon frame or FILS Discovery frame from an AP that the STA considers
+ *	a suitable candidate for (re-)association - suitable in terms of
+ *	SSID and/or RSSI.
+ * @NL80211_SCAN_FLAG_LOW_SPAN: Span corresponds to the total time taken to
+ *	accomplish the scan. Thus, this flag intends the driver to perform the
+ *	scan request with lesser span/duration. It is specific to the driver
+ *	implementations on how this is accomplished. Scan accuracy may get
+ *	impacted with this flag.
+ * @NL80211_SCAN_FLAG_LOW_POWER: This flag intends the scan attempts to consume
+ *	optimal possible power. Drivers can resort to their specific means to
+ *	optimize the power. Scan accuracy may get impacted with this flag.
+ * @NL80211_SCAN_FLAG_HIGH_ACCURACY: Accuracy here intends to the extent of scan
+ *	results obtained. Thus HIGH_ACCURACY scan flag aims to get maximum
+ *	possible scan results. This flag hints the driver to use the best
+ *	possible scan configuration to improve the accuracy in scanning.
+ *	Latency and power use may get impacted with this flag.
+ * @NL80211_SCAN_FLAG_RANDOM_SN: randomize the sequence number in probe
+ *	request frames from this scan to avoid correlation/tracking being
+ *	possible.
+ * @NL80211_SCAN_FLAG_MIN_PREQ_CONTENT: minimize probe request content to
+ *	only have supported rates and no additional capabilities (unless
+ *	added by userspace explicitly.)
+ */
+enum nl80211_scan_flags {
+	NL80211_SCAN_FLAG_LOW_PRIORITY				= 1<<0,
+	NL80211_SCAN_FLAG_FLUSH					= 1<<1,
+	NL80211_SCAN_FLAG_AP					= 1<<2,
+	NL80211_SCAN_FLAG_RANDOM_ADDR				= 1<<3,
+	NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME			= 1<<4,
+	NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP		= 1<<5,
+	NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE		= 1<<6,
+	NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION	= 1<<7,
+	NL80211_SCAN_FLAG_LOW_SPAN				= 1<<8,
+	NL80211_SCAN_FLAG_LOW_POWER				= 1<<9,
+	NL80211_SCAN_FLAG_HIGH_ACCURACY				= 1<<10,
+	NL80211_SCAN_FLAG_RANDOM_SN				= 1<<11,
+	NL80211_SCAN_FLAG_MIN_PREQ_CONTENT			= 1<<12,
+};
+
+/**
+ * enum nl80211_acl_policy - access control policy
+ *
+ * Access control policy is applied on a MAC list set by
+ * %NL80211_CMD_START_AP and %NL80211_CMD_SET_MAC_ACL, to
+ * be used with %NL80211_ATTR_ACL_POLICY.
+ *
+ * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
+ *	listed in ACL, i.e. allow all the stations which are not listed
+ *	in ACL to authenticate.
+ * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow the stations which are listed
+ *	in ACL, i.e. deny all the stations which are not listed in ACL.
+ */
+enum nl80211_acl_policy {
+	NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED,
+	NL80211_ACL_POLICY_DENY_UNLESS_LISTED,
+};
+
+/**
+ * enum nl80211_smps_mode - SMPS mode
+ *
+ * Requested SMPS mode (for AP mode)
+ *
+ * @NL80211_SMPS_OFF: SMPS off (use all antennas).
+ * @NL80211_SMPS_STATIC: static SMPS (use a single antenna)
+ * @NL80211_SMPS_DYNAMIC: dynamic smps (start with a single antenna and
+ *	turn on other antennas after CTS/RTS).
+ */
+enum nl80211_smps_mode {
+	NL80211_SMPS_OFF,
+	NL80211_SMPS_STATIC,
+	NL80211_SMPS_DYNAMIC,
+
+	__NL80211_SMPS_AFTER_LAST,
+	NL80211_SMPS_MAX = __NL80211_SMPS_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_radar_event - type of radar event for DFS operation
+ *
+ * Type of event to be used with NL80211_ATTR_RADAR_EVENT to inform userspace
+ * about detected radars or success of the channel available check (CAC)
+ *
+ * @NL80211_RADAR_DETECTED: A radar pattern has been detected. The channel is
+ *	now unusable.
+ * @NL80211_RADAR_CAC_FINISHED: Channel Availability Check has been finished,
+ *	the channel is now available.
+ * @NL80211_RADAR_CAC_ABORTED: Channel Availability Check has been aborted, no
+ *	change to the channel status.
+ * @NL80211_RADAR_NOP_FINISHED: The Non-Occupancy Period for this channel is
+ *	over, channel becomes usable.
+ * @NL80211_RADAR_PRE_CAC_EXPIRED: Channel Availability Check done on this
+ *	non-operating channel is expired and no longer valid. New CAC must
+ *	be done on this channel before starting the operation. This is not
+ *	applicable for ETSI dfs domain where pre-CAC is valid for ever.
+ * @NL80211_RADAR_CAC_STARTED: Channel Availability Check has been started,
+ *	should be generated by HW if NL80211_EXT_FEATURE_DFS_OFFLOAD is enabled.
+ */
+enum nl80211_radar_event {
+	NL80211_RADAR_DETECTED,
+	NL80211_RADAR_CAC_FINISHED,
+	NL80211_RADAR_CAC_ABORTED,
+	NL80211_RADAR_NOP_FINISHED,
+	NL80211_RADAR_PRE_CAC_EXPIRED,
+	NL80211_RADAR_CAC_STARTED,
+};
+
+/**
+ * enum nl80211_dfs_state - DFS states for channels
+ *
+ * Channel states used by the DFS code.
+ *
+ * @NL80211_DFS_USABLE: The channel can be used, but channel availability
+ *	check (CAC) must be performed before using it for AP or IBSS.
+ * @NL80211_DFS_UNAVAILABLE: A radar has been detected on this channel, it
+ *	is therefore marked as not available.
+ * @NL80211_DFS_AVAILABLE: The channel has been CAC checked and is available.
+ */
+enum nl80211_dfs_state {
+	NL80211_DFS_USABLE,
+	NL80211_DFS_UNAVAILABLE,
+	NL80211_DFS_AVAILABLE,
+};
+
+/**
+ * enum enum nl80211_protocol_features - nl80211 protocol features
+ * @NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP: nl80211 supports splitting
+ *	wiphy dumps (if requested by the application with the attribute
+ *	%NL80211_ATTR_SPLIT_WIPHY_DUMP. Also supported is filtering the
+ *	wiphy dump by %NL80211_ATTR_WIPHY, %NL80211_ATTR_IFINDEX or
+ *	%NL80211_ATTR_WDEV.
+ */
+enum nl80211_protocol_features {
+	NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP =	1 << 0,
+};
+
+/**
+ * enum nl80211_crit_proto_id - nl80211 critical protocol identifiers
+ *
+ * @NL80211_CRIT_PROTO_UNSPEC: protocol unspecified.
+ * @NL80211_CRIT_PROTO_DHCP: BOOTP or DHCPv6 protocol.
+ * @NL80211_CRIT_PROTO_EAPOL: EAPOL protocol.
+ * @NL80211_CRIT_PROTO_APIPA: APIPA protocol.
+ * @NUM_NL80211_CRIT_PROTO: must be kept last.
+ */
+enum nl80211_crit_proto_id {
+	NL80211_CRIT_PROTO_UNSPEC,
+	NL80211_CRIT_PROTO_DHCP,
+	NL80211_CRIT_PROTO_EAPOL,
+	NL80211_CRIT_PROTO_APIPA,
+	/* add other protocols before this one */
+	NUM_NL80211_CRIT_PROTO
+};
+
+/* maximum duration for critical protocol measures */
+#define NL80211_CRIT_PROTO_MAX_DURATION		5000 /* msec */
+
+/**
+ * enum nl80211_rxmgmt_flags - flags for received management frame.
+ *
+ * Used by cfg80211_rx_mgmt()
+ *
+ * @NL80211_RXMGMT_FLAG_ANSWERED: frame was answered by device/driver.
+ * @NL80211_RXMGMT_FLAG_EXTERNAL_AUTH: Host driver intends to offload
+ *	the authentication. Exclusively defined for host drivers that
+ *	advertises the SME functionality but would like the userspace
+ *	to handle certain authentication algorithms (e.g. SAE).
+ */
+enum nl80211_rxmgmt_flags {
+	NL80211_RXMGMT_FLAG_ANSWERED = 1 << 0,
+//tianyan@2021.7.27 modify for add wifi6 module start
+	NL80211_RXMGMT_FLAG_EXTERNAL_AUTH = 1 << 1,
+//tianyan@2021.7.27 modify for add wifi6 module end
+};
+
+/*
+ * If this flag is unset, the lower 24 bits are an OUI, if set
+ * a Linux nl80211 vendor ID is used (no such IDs are allocated
+ * yet, so that's not valid so far)
+ */
+#define NL80211_VENDOR_ID_IS_LINUX	0x80000000
+
+/**
+ * struct nl80211_vendor_cmd_info - vendor command data
+ * @vendor_id: If the %NL80211_VENDOR_ID_IS_LINUX flag is clear, then the
+ *	value is a 24-bit OUI; if it is set then a separately allocated ID
+ *	may be used, but no such IDs are allocated yet. New IDs should be
+ *	added to this file when needed.
+ * @subcmd: sub-command ID for the command
+ */
+struct nl80211_vendor_cmd_info {
+	__u32 vendor_id;
+	__u32 subcmd;
+};
+
+/**
+ * enum nl80211_tdls_peer_capability - TDLS peer flags.
+ *
+ * Used by tdls_mgmt() to determine which conditional elements need
+ * to be added to TDLS Setup frames.
+ *
+ * @NL80211_TDLS_PEER_HT: TDLS peer is HT capable.
+ * @NL80211_TDLS_PEER_VHT: TDLS peer is VHT capable.
+ * @NL80211_TDLS_PEER_WMM: TDLS peer is WMM capable.
+ */
+enum nl80211_tdls_peer_capability {
+	NL80211_TDLS_PEER_HT = 1<<0,
+	NL80211_TDLS_PEER_VHT = 1<<1,
+	NL80211_TDLS_PEER_WMM = 1<<2,
+};
+
+/**
+ * enum nl80211_sched_scan_plan - scanning plan for scheduled scan
+ * @__NL80211_SCHED_SCAN_PLAN_INVALID: attribute number 0 is reserved
+ * @NL80211_SCHED_SCAN_PLAN_INTERVAL: interval between scan iterations. In
+ *	seconds (u32).
+ * @NL80211_SCHED_SCAN_PLAN_ITERATIONS: number of scan iterations in this
+ *	scan plan (u32). The last scan plan must not specify this attribute
+ *	because it will run infinitely. A value of zero is invalid as it will
+ *	make the scan plan meaningless.
+ * @NL80211_SCHED_SCAN_PLAN_MAX: highest scheduled scan plan attribute number
+ *	currently defined
+ * @__NL80211_SCHED_SCAN_PLAN_AFTER_LAST: internal use
+ */
+enum nl80211_sched_scan_plan {
+	__NL80211_SCHED_SCAN_PLAN_INVALID,
+	NL80211_SCHED_SCAN_PLAN_INTERVAL,
+	NL80211_SCHED_SCAN_PLAN_ITERATIONS,
+
+	/* keep last */
+	__NL80211_SCHED_SCAN_PLAN_AFTER_LAST,
+	NL80211_SCHED_SCAN_PLAN_MAX =
+		__NL80211_SCHED_SCAN_PLAN_AFTER_LAST - 1
+};
+
+/**
+ * struct nl80211_bss_select_rssi_adjust - RSSI adjustment parameters.
+ *
+ * @band: band of BSS that must match for RSSI value adjustment. The value
+ *	of this field is according to &enum nl80211_band.
+ * @delta: value used to adjust the RSSI value of matching BSS in dB.
+ */
+struct nl80211_bss_select_rssi_adjust {
+	__u8 band;
+	__s8 delta;
+} __attribute__((packed));
+
+/**
+ * enum nl80211_bss_select_attr - attributes for bss selection.
+ *
+ * @__NL80211_BSS_SELECT_ATTR_INVALID: reserved.
+ * @NL80211_BSS_SELECT_ATTR_RSSI: Flag indicating only RSSI-based BSS selection
+ *	is requested.
+ * @NL80211_BSS_SELECT_ATTR_BAND_PREF: attribute indicating BSS
+ *	selection should be done such that the specified band is preferred.
+ *	When there are multiple BSS-es in the preferred band, the driver
+ *	shall use RSSI-based BSS selection as a second step. The value of
+ *	this attribute is according to &enum nl80211_band (u32).
+ * @NL80211_BSS_SELECT_ATTR_RSSI_ADJUST: When present the RSSI level for
+ *	BSS-es in the specified band is to be adjusted before doing
+ *	RSSI-based BSS selection. The attribute value is a packed structure
+ *	value as specified by &struct nl80211_bss_select_rssi_adjust.
+ * @NL80211_BSS_SELECT_ATTR_MAX: highest bss select attribute number.
+ * @__NL80211_BSS_SELECT_ATTR_AFTER_LAST: internal use.
+ *
+ * One and only one of these attributes are found within %NL80211_ATTR_BSS_SELECT
+ * for %NL80211_CMD_CONNECT. It specifies the required BSS selection behaviour
+ * which the driver shall use.
+ */
+enum nl80211_bss_select_attr {
+	__NL80211_BSS_SELECT_ATTR_INVALID,
+	NL80211_BSS_SELECT_ATTR_RSSI,
+	NL80211_BSS_SELECT_ATTR_BAND_PREF,
+	NL80211_BSS_SELECT_ATTR_RSSI_ADJUST,
+
+	/* keep last */
+	__NL80211_BSS_SELECT_ATTR_AFTER_LAST,
+	NL80211_BSS_SELECT_ATTR_MAX = __NL80211_BSS_SELECT_ATTR_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_nan_function_type - NAN function type
+ *
+ * Defines the function type of a NAN function
+ *
+ * @NL80211_NAN_FUNC_PUBLISH: function is publish
+ * @NL80211_NAN_FUNC_SUBSCRIBE: function is subscribe
+ * @NL80211_NAN_FUNC_FOLLOW_UP: function is follow-up
+ */
+enum nl80211_nan_function_type {
+	NL80211_NAN_FUNC_PUBLISH,
+	NL80211_NAN_FUNC_SUBSCRIBE,
+	NL80211_NAN_FUNC_FOLLOW_UP,
+
+	/* keep last */
+	__NL80211_NAN_FUNC_TYPE_AFTER_LAST,
+	NL80211_NAN_FUNC_MAX_TYPE = __NL80211_NAN_FUNC_TYPE_AFTER_LAST - 1,
+};
+
+/**
+ * enum nl80211_nan_publish_type - NAN publish tx type
+ *
+ * Defines how to send publish Service Discovery Frames
+ *
+ * @NL80211_NAN_SOLICITED_PUBLISH: publish function is solicited
+ * @NL80211_NAN_UNSOLICITED_PUBLISH: publish function is unsolicited
+ */
+enum nl80211_nan_publish_type {
+	NL80211_NAN_SOLICITED_PUBLISH = 1 << 0,
+	NL80211_NAN_UNSOLICITED_PUBLISH = 1 << 1,
+};
+
+/**
+ * enum nl80211_nan_func_term_reason - NAN functions termination reason
+ *
+ * Defines termination reasons of a NAN function
+ *
+ * @NL80211_NAN_FUNC_TERM_REASON_USER_REQUEST: requested by user
+ * @NL80211_NAN_FUNC_TERM_REASON_TTL_EXPIRED: timeout
+ * @NL80211_NAN_FUNC_TERM_REASON_ERROR: errored
+ */
+enum nl80211_nan_func_term_reason {
+	NL80211_NAN_FUNC_TERM_REASON_USER_REQUEST,
+	NL80211_NAN_FUNC_TERM_REASON_TTL_EXPIRED,
+	NL80211_NAN_FUNC_TERM_REASON_ERROR,
+};
+
+#define NL80211_NAN_FUNC_SERVICE_ID_LEN 6
+#define NL80211_NAN_FUNC_SERVICE_SPEC_INFO_MAX_LEN 0xff
+#define NL80211_NAN_FUNC_SRF_MAX_LEN 0xff
+
+/**
+ * enum nl80211_nan_func_attributes - NAN function attributes
+ * @__NL80211_NAN_FUNC_INVALID: invalid
+ * @NL80211_NAN_FUNC_TYPE: &enum nl80211_nan_function_type (u8).
+ * @NL80211_NAN_FUNC_SERVICE_ID: 6 bytes of the service ID hash as
+ *	specified in NAN spec. This is a binary attribute.
+ * @NL80211_NAN_FUNC_PUBLISH_TYPE: relevant if the function's type is
+ *	publish. Defines the transmission type for the publish Service Discovery
+ *	Frame, see &enum nl80211_nan_publish_type. Its type is u8.
+ * @NL80211_NAN_FUNC_PUBLISH_BCAST: relevant if the function is a solicited
+ *	publish. Should the solicited publish Service Discovery Frame be sent to
+ *	the NAN Broadcast address. This is a flag.
+ * @NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE: relevant if the function's type is
+ *	subscribe. Is the subscribe active. This is a flag.
+ * @NL80211_NAN_FUNC_FOLLOW_UP_ID: relevant if the function's type is follow up.
+ *	The instance ID for the follow up Service Discovery Frame. This is u8.
+ * @NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID: relevant if the function's type
+ *	is follow up. This is a u8.
+ *	The requestor instance ID for the follow up Service Discovery Frame.
+ * @NL80211_NAN_FUNC_FOLLOW_UP_DEST: the MAC address of the recipient of the
+ *	follow up Service Discovery Frame. This is a binary attribute.
+ * @NL80211_NAN_FUNC_CLOSE_RANGE: is this function limited for devices in a
+ *	close range. The range itself (RSSI) is defined by the device.
+ *	This is a flag.
+ * @NL80211_NAN_FUNC_TTL: strictly positive number of DWs this function should
+ *	stay active. If not present infinite TTL is assumed. This is a u32.
+ * @NL80211_NAN_FUNC_SERVICE_INFO: array of bytes describing the service
+ *	specific info. This is a binary attribute.
+ * @NL80211_NAN_FUNC_SRF: Service Receive Filter. This is a nested attribute.
+ *	See &enum nl80211_nan_srf_attributes.
+ * @NL80211_NAN_FUNC_RX_MATCH_FILTER: Receive Matching filter. This is a nested
+ *	attribute. It is a list of binary values.
+ * @NL80211_NAN_FUNC_TX_MATCH_FILTER: Transmit Matching filter. This is a
+ *	nested attribute. It is a list of binary values.
+ * @NL80211_NAN_FUNC_INSTANCE_ID: The instance ID of the function.
+ *	Its type is u8 and it cannot be 0.
+ * @NL80211_NAN_FUNC_TERM_REASON: NAN function termination reason.
+ *	See &enum nl80211_nan_func_term_reason.
+ *
+ * @NUM_NL80211_NAN_FUNC_ATTR: internal
+ * @NL80211_NAN_FUNC_ATTR_MAX: highest NAN function attribute
+ */
+enum nl80211_nan_func_attributes {
+	__NL80211_NAN_FUNC_INVALID,
+	NL80211_NAN_FUNC_TYPE,
+	NL80211_NAN_FUNC_SERVICE_ID,
+	NL80211_NAN_FUNC_PUBLISH_TYPE,
+	NL80211_NAN_FUNC_PUBLISH_BCAST,
+	NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE,
+	NL80211_NAN_FUNC_FOLLOW_UP_ID,
+	NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID,
+	NL80211_NAN_FUNC_FOLLOW_UP_DEST,
+	NL80211_NAN_FUNC_CLOSE_RANGE,
+	NL80211_NAN_FUNC_TTL,
+	NL80211_NAN_FUNC_SERVICE_INFO,
+	NL80211_NAN_FUNC_SRF,
+	NL80211_NAN_FUNC_RX_MATCH_FILTER,
+	NL80211_NAN_FUNC_TX_MATCH_FILTER,
+	NL80211_NAN_FUNC_INSTANCE_ID,
+	NL80211_NAN_FUNC_TERM_REASON,
+
+	/* keep last */
+	NUM_NL80211_NAN_FUNC_ATTR,
+	NL80211_NAN_FUNC_ATTR_MAX = NUM_NL80211_NAN_FUNC_ATTR - 1
+};
+
+/**
+ * enum nl80211_nan_srf_attributes - NAN Service Response filter attributes
+ * @__NL80211_NAN_SRF_INVALID: invalid
+ * @NL80211_NAN_SRF_INCLUDE: present if the include bit of the SRF set.
+ *	This is a flag.
+ * @NL80211_NAN_SRF_BF: Bloom Filter. Present if and only if
+ *	%NL80211_NAN_SRF_MAC_ADDRS isn't present. This attribute is binary.
+ * @NL80211_NAN_SRF_BF_IDX: index of the Bloom Filter. Mandatory if
+ *	%NL80211_NAN_SRF_BF is present. This is a u8.
+ * @NL80211_NAN_SRF_MAC_ADDRS: list of MAC addresses for the SRF. Present if
+ *	and only if %NL80211_NAN_SRF_BF isn't present. This is a nested
+ *	attribute. Each nested attribute is a MAC address.
+ * @NUM_NL80211_NAN_SRF_ATTR: internal
+ * @NL80211_NAN_SRF_ATTR_MAX: highest NAN SRF attribute
+ */
+enum nl80211_nan_srf_attributes {
+	__NL80211_NAN_SRF_INVALID,
+	NL80211_NAN_SRF_INCLUDE,
+	NL80211_NAN_SRF_BF,
+	NL80211_NAN_SRF_BF_IDX,
+	NL80211_NAN_SRF_MAC_ADDRS,
+
+	/* keep last */
+	NUM_NL80211_NAN_SRF_ATTR,
+	NL80211_NAN_SRF_ATTR_MAX = NUM_NL80211_NAN_SRF_ATTR - 1,
+};
+
+/**
+ * enum nl80211_nan_match_attributes - NAN match attributes
+ * @__NL80211_NAN_MATCH_INVALID: invalid
+ * @NL80211_NAN_MATCH_FUNC_LOCAL: the local function that had the
+ *	match. This is a nested attribute.
+ *	See &enum nl80211_nan_func_attributes.
+ * @NL80211_NAN_MATCH_FUNC_PEER: the peer function
+ *	that caused the match. This is a nested attribute.
+ *	See &enum nl80211_nan_func_attributes.
+ *
+ * @NUM_NL80211_NAN_MATCH_ATTR: internal
+ * @NL80211_NAN_MATCH_ATTR_MAX: highest NAN match attribute
+ */
+enum nl80211_nan_match_attributes {
+	__NL80211_NAN_MATCH_INVALID,
+	NL80211_NAN_MATCH_FUNC_LOCAL,
+	NL80211_NAN_MATCH_FUNC_PEER,
+
+	/* keep last */
+	NUM_NL80211_NAN_MATCH_ATTR,
+	NL80211_NAN_MATCH_ATTR_MAX = NUM_NL80211_NAN_MATCH_ATTR - 1
+};
+
+/**
+ * nl80211_external_auth_action - Action to perform with external
+ *     authentication request. Used by NL80211_ATTR_EXTERNAL_AUTH_ACTION.
+ * @NL80211_EXTERNAL_AUTH_START: Start the authentication.
+ * @NL80211_EXTERNAL_AUTH_ABORT: Abort the ongoing authentication.
+ */
+enum nl80211_external_auth_action {
+	NL80211_EXTERNAL_AUTH_START,
+	NL80211_EXTERNAL_AUTH_ABORT,
+};
+
+#endif /* __LINUX_NL80211_H */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11.h
index 6cbdb45..8c1a745 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11.h
@@ -1,9 +1,9 @@
 /*
  * Fundamental types and constants relating to 802.11
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -5305,6 +5305,9 @@
 	DOT11_5GHZ_40MHZ_CLASS_30	= 127,	/* Ch 153-161, upper */
 	DOT11_2GHZ_40MHZ_CLASS_32	= 83,	/* Ch 1-7,     lower */
 	DOT11_2GHZ_40MHZ_CLASS_33	= 84,	/* Ch 5-11,    upper */
+	DOT11_6GHZ_20MHZ_CLASS_131	= 131,	/* Ch 1-233  */
+	DOT11_6GHZ_40MHZ_CLASS_132	= 132,	/* Ch 3-227 */
+	DOT11_6GHZ_80MHZ_CLASS_133	= 133,	/* Ch 7-215 */
 } dot11_op_class_t;
 
 /* QoS map */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11ah.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11ah.h
new file mode 100755
index 0000000..35455bd
--- /dev/null
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11ah.h
@@ -0,0 +1,283 @@
+/*
+ * Basic types and constants relating to 802.11ah standard.
+ * This is a portion of 802.11ah definition. The rest are in 802.11.h.
+ *
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
+ *
+ * Copyright (C) 1999-2016, Broadcom Corporation
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *      Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#ifndef _802_11ah_h_
+#define _802_11ah_h_
+
+#include <typedefs.h>
+
+/* This marks the start of a packed structure section. */
+#include <packed_section_start.h>
+
+/**
+ * TWT IE (sec 8.4.2.196)
+ */
+
+/* TWT element - top */
+BWL_PRE_PACKED_STRUCT struct twt_ie_top {
+	uint8 id;
+	uint8 len;
+	uint8 ctrl;		/* Control */
+} BWL_POST_PACKED_STRUCT;
+
+typedef struct twt_ie_top twt_ie_top_t;
+
+/* S1G Action IDs */
+#define S1G_ACTION_TWT_SETUP	6u
+#define S1G_ACTION_TWT_TEARDOWN	7u
+#define S1G_ACTION_TWT_INFO	11u
+
+/* S1G Action frame offsets */
+#define S1G_AF_CAT_OFF	0u
+#define S1G_AF_ACT_OFF	1u
+
+/* TWT Setup */
+#define S1G_AF_TWT_SETUP_TOKEN_OFF	2u
+#define S1G_AF_TWT_SETUP_TWT_IE_OFF	3u
+
+/* TWT Teardown */
+#define S1G_AF_TWT_TEARDOWN_FLOW_OFF	2u
+
+/* TWT Information */
+#define S1G_AF_TWT_INFO_OFF	2u
+
+#define TWT_BCAST_WAKE_TIME_OFFSET	10u
+#define TWT_BCAST_WAKE_TIME_SHIFT	10u
+#define TWT_BCAST_WAKE_TIME_MASK	0x03FFFC00u
+#define TWT_BCAST_WAKE_TIME_ZERO_BIT_SZ	10u
+
+/* Control field (Figure 9-589aw) */
+#define TWT_CTRL_NDP_PAGING_IND		0x01u	/* NDP Paging Indication */
+#define TWT_CTRL_RESP_PM_MODE		0x02u	/* Respondor PM Mode */
+#define TWT_CTRL_NEGO_TYPE_IDX		2u
+#define TWT_CTRL_NEGO_TYPE_MASK		0x0Cu	/* TWT Negotiation Type */
+#define TWT_CTRL_NEGO_TYPE_SHIFT	2u
+
+/* TWT Negotiation Type (Table 9-262j1) */
+typedef enum twt_ctrl_nego_type {
+	TWT_CTRL_NEGO_TYPE_0	= 0,	/* Individual TWT Setup */
+	TWT_CTRL_NEGO_TYPE_1	= 1,	/* Wake TBTT Negotiation */
+	TWT_CTRL_NEGO_TYPE_2	= 2,	/* Broadcast TWT IE in Beacon */
+	TWT_CTRL_NEGO_TYPE_3	= 3,	/* Broadcast TWT memberships */
+} twt_ctrl_nego_type_t;
+
+/* Request Type field (Figure 9-589ay) */
+#define TWT_REQ_TYPE_REQUEST		0x0001u	/* Request */
+#define TWT_REQ_TYPE_SETUP_CMD_MASK	0x000eu	/* Setup Command */
+#define TWT_REQ_TYPE_SETUP_CMD_SHIFT	1u
+#define TWT_REQ_TYPE_TRIGGER		0x0010u	/* Trigger */
+#define TWT_REQ_TYPE_IMPLICIT		0x0020u	/* Implicit */
+#define TWT_REQ_TYPE_LAST_BCAST_PARAM	0x0020u	/* Last Broadcast Parameter Set */
+#define TWT_REQ_TYPE_FLOW_TYPE		0x0040u	/* Flow Type */
+#define TWT_REQ_TYPE_FLOW_ID_MASK	0x0380u	/* Flow Identifier */
+#define TWT_REQ_TYPE_FLOW_ID_SHIFT	7u
+#define TWT_REQ_TYPE_BTWT_RECOMM_MASK	0x0380u	/* Broadcast TWT Recommendation */
+#define TWT_REQ_TYPE_BTWT_RECOMM_SHIFT	7u
+#define TWT_REQ_TYPE_WAKE_EXP_MASK	0x7c00u	/* Wake Interval Exponent */
+#define TWT_REQ_TYPE_WAKE_EXP_SHIFT	10u
+#define TWT_REQ_TYPE_PROTECTION		0x8000u	/* Protection */
+
+/* Setup Command field (Table 9-262k) */
+#define TWT_SETUP_CMD_REQUEST_TWT	0u	/* Request TWT */
+#define TWT_SETUP_CMD_SUGGEST_TWT	1u	/* Suggest TWT */
+#define TWT_SETUP_CMD_DEMAND_TWT	2u	/* Demand TWT */
+#define TWT_SETUP_CMD_GROUPING_TWT	3u	/* Grouping TWT */
+#define TWT_SETUP_CMD_ACCEPT_TWT	4u	/* Accept TWT */
+#define TWT_SETUP_CMD_ALTERNATE_TWT		5u	/* Alternate TWT */
+#define TWT_SETUP_CMD_DICTATE_TWT	6u	/* Dictate TWT */
+#define TWT_SETUP_CMD_REJECT_TWT	7u	/* Reject TWT */
+
+/* Broadcast TWT Recommendation field (Table 9-262k1) */
+#define TWT_BCAST_FRAME_RECOMM_0	0u	/* No constrains on frames in Broadcast TWT SP */
+#define TWT_BCAST_FRAME_RECOMM_1	1u	/* Do not contain RUs for random access */
+#define TWT_BCAST_FRAME_RECOMM_2	2u	/* Can contain RUs for random access */
+#define TWT_BCAST_FRAME_RECOMM_3	3u
+
+/* Request Type subfield - 2 octets */
+typedef uint16 twt_request_type_t;	/* 16 bit request type */
+
+/* Target Wake Time - 8 octets or 0 octet */
+typedef uint64 twt_target_wake_time_t;	/* 64 bit TSF time of TWT Responding STA */
+typedef uint16 twt_bcast_wake_time_t;	/* 16 bit Wake Time of Bcast scheduling STA */
+typedef uint16 twt_bcast_twt_info_t;	/* 16 bit Broadcast TWT Info subfield */
+
+/* TWT Group Assignment Info - 9 octets (long format) or 3 octets (short format) or 0 octet */
+/* Group Assignment Info field - short format - Zero Offset Preset field is 0 */
+BWL_PRE_PACKED_STRUCT struct twt_grp_short {
+	uint8 grpid_n_0off;	/* Group ID and Zero Offset Present */
+	uint16 unit_n_off;	/* TWT Unit and TWT Offset */
+} BWL_POST_PACKED_STRUCT;
+
+typedef struct twt_grp_short twt_grp_short_t;
+
+/* Group Assignment Info field - long format - Zero Offset Preset field is 1 */
+#define TWT_ZERO_OFF_GRP_LEN 6u
+BWL_PRE_PACKED_STRUCT struct twt_grp_long {
+	uint8 grpid_n_0off;	/* Group ID and Zero Offset Present */
+	uint8 grp_0off[TWT_ZERO_OFF_GRP_LEN];	/* Zero Offset of Group */
+	uint16 unit_n_off;	/* Unit and Offset */
+} BWL_POST_PACKED_STRUCT;
+
+typedef struct twt_grp_long twt_grp_long_t;
+
+/* TWT Unit and TWT Offset field */
+#define TWT_UNIT_MASK		0x000fu		/* TWT Unit */
+#define TWT_OFFSET_MASK		0xfff0u		/* TWT Offset */
+#define TWT_OFFSET_SHIFT	4u
+
+/* TWT Unit field (table 8-248m) */
+#define TWT_UNIT_32us		0u
+#define TWT_UNIT_256us		1u
+#define TWT_UNIT_1024us		2u
+#define TWT_UNIT_8ms192us	3u
+#define TWT_UNIT_32ms768us	4u
+#define TWT_UNIT_262ms144us	5u
+#define TWT_UNIT_1s048576us	6u
+#define TWT_UNIT_8s388608us	7u
+#define TWT_UNIT_33s554432us	8u
+#define TWT_UNIT_268s435456us	9u
+#define TWT_UNIT_1073s741824us	10u
+#define TWT_UNIT_8589s934592us	11u
+
+/* TWT element - bottom */
+BWL_PRE_PACKED_STRUCT struct twt_ie_itwt_bottom {
+	uint8 nom_wake_dur;		/* Nominal Minimum Wake Duration */
+	uint16 wake_int_mant;		/* TWT Wake Interval Mantissa */
+	uint8 channel;			/* TWT Channel */
+	/* NDP Paging field */
+} BWL_POST_PACKED_STRUCT;
+
+typedef struct twt_ie_itwt_bottom twt_ie_itwt_bottom_t;
+
+/* TWT element - bottom */
+BWL_PRE_PACKED_STRUCT struct twt_ie_btwt_bottom {
+	uint8 nom_wake_dur;		/* Nominal Minimum Wake Duration */
+	uint16 wake_int_mant;		/* TWT Wake Interval Mantissa */
+	twt_bcast_twt_info_t btwt_info;	/* Broadcast TWT Info */
+	/* NDP Paging field */
+} BWL_POST_PACKED_STRUCT;
+
+typedef struct twt_ie_btwt_bottom twt_ie_btwt_bottom_t;
+
+/* TWT IE structure for broadcast TWT */
+typedef struct twt_last_bcast_ie {
+	twt_ie_top_t top;		/* Element id, len, control fields */
+	twt_request_type_t req_type;	/* request type field */
+	twt_bcast_wake_time_t twt;	/* twt field */
+	twt_ie_btwt_bottom_t btwt_bottom;	/* wake dur, int, BID Info */
+} twt_last_bcast_ie_t;
+
+/* Nominal Minimum Wake Duration */
+#define TWT_NOM_WAKE_DUR_UNIT	256u	/* Nominal Minimum Wake Duration is in 256us units */
+
+/* TWT IE field lengths */
+#define TWT_IE_NOM_MIN_TWT_WK_DUR_SZ		1u	/* 1 byte */
+#define TWT_IE_TWT_WAKE_INT_MANT_SZ		2u	/* 2 bytes */
+#define TWT_IE_BCAST_TWT_INFO_SZ		2u	/* 2 byte */
+#define TWT_IE_TWT_CHANNEL_SZ			1u	/* 1 byte */
+
+/* Broadcast TWT info subfield format (figure 9-589ay1) */
+#define TWT_BTWT_PERSIST_EXPO_MASK		0x0007u	/* Broadcast TWT Persistence Exponent */
+#define TWT_BCAST_TWT_ID_MASK			0x00F8u	/* Broadcast TWT ID */
+#define TWT_BCAST_TWT_ID_SHIFT			3u
+#define TWT_BTWT_PERSIST_MANT_MASK		0xFF00u	/* Broadcast TWT Persistence Mantissa */
+#define TWT_BTWT_PERSIST_MANT_SHIFT		8u
+
+#define TWT_BTWT_PERSIST_INDEFINITE		0xFFu
+
+/* NDP Paging field - 4 octets or 0 octet */
+typedef uint32 twt_ndp_paging_t;
+
+#define TWT_NDP_PAGING_PID		0x000001ffu	/* P-ID */
+#define TWT_NDP_PAGING_MAX_PERIOD	0x0001fe00u	/* Max NDP Paging Period */
+#define TWT_NDP_PAGING_PART_TSF_OFF	0x001e0000u	/* Partial TSF Offset */
+#define TWT_NDP_PAGING_ACTION		0x00e00000u	/* Action */
+#define TWT_NDP_PAGING_MIN_SLEEP	0x3f000000u	/* Min Sleep Duration */
+
+/* Action field (table 8-248n) */
+#define TWT_ACTION_SEND_PSP_TRIG	0u	/* Send a PS-Poll or uplink trigger frame */
+#define TWT_ACTION_WAKE_MIN_SLEEP	1u	/* Wake up at the time indicated by
+						 * Min Sleep Duration
+						 */
+#define TWT_ACTION_WAKE_RCV_BCN		2u	/* Wake up to receive the Beacon */
+#define TWT_ACTION_WAKE_RCV_DTIM	3u	/* Wake up to receive the DTIM Beacon */
+#define TWT_ACTION_WAKE_IND_TIME	4u	/* Wakeup at the time indicated by the sum of
+						 * the Min Sleep Duration field and the ASD subfield
+						 * in the APDI field of the NDP Paging frame
+						 */
+
+/* TWT Teardown for Negotiation type 0 or 1 */
+#define TWT_TEARDOWN_FLOW_ID_MASK		0x07u
+/* TWT Teardown for Negotiation type 3 */
+#define TWT_TEARDOWN_BTWT_ID_MASK		0x1Fu
+
+#define TWT_TEARDOWN_NEGO_TYPE_MASK		0x60u
+#define TWT_TEARDOWN_NEGO_TYPE_SHIFT		5u
+/* Teardown All TWT indication */
+#define TWT_TEARDOWN_ALL_TWT			0x80u
+
+/* TWT Information field byte 0 */
+#define TWT_INFO_FLOW_ID_MASK		0x07u
+#define TWT_INFO_RESP_REQ		0x08u
+#define TWT_INFO_NEXT_TWT_REQ		0x10u
+#define TWT_INFO_NEXT_TWT_SIZE_MASK	0x60u
+#define TWT_INFO_NEXT_TWT_SIZE_SHIFT	0x5u
+#define TWT_INFO_ALL_TWT		0x80u
+
+/* Next TWT Subfield Size field encoding */
+#define TWT_INFO_NEXT_TWT_SIZE_0_IDX	0u	/* 0 byte */
+#define TWT_INFO_NEXT_TWT_SIZE_32_IDX	1u	/* 4 bytes */
+#define TWT_INFO_NEXT_TWT_SIZE_48_IDX	2u	/* 6 bytes */
+#define TWT_INFO_NEXT_TWT_SIZE_64_IDX	3u	/* 8 bytes */
+
+/* Next TWT Subfield Size field */
+#define TWT_INFO_NEXT_TWT_SIZE_0	0u	/* 0 byte */
+#define TWT_INFO_NEXT_TWT_SIZE_32	4u	/* 4 bytes */
+#define TWT_INFO_NEXT_TWT_SIZE_48	6u	/* 6 bytes */
+#define TWT_INFO_NEXT_TWT_SIZE_64	8u	/* 8 bytes */
+
+/* Old macro definitions - To be removed - Start here */
+#define TWT_BCAST_MAX_VALID_FLOW_ID	3u
+#define TWT_CTRL_BCAST			0x04u	/* Broadcast */
+#define TWT_CTRL_WAKE_TBTT_NEGO		0x08u	/* Wake TBTT Negotiation */
+#define TWT_SETUP_CMD_GRPING_TWT	3u	/* Grouping TWT */
+#define TWT_SETUP_CMD_ALTER_TWT		5u	/* Alternate TWT */
+#define TWT_IE_BCAST_TWT_ID_SZ		1u	/* 1 byte */
+#define TWT_INFO_BROADCAST_RESCHED	0x80u
+
+typedef struct twt_ie_itwt_bottom twt_ie_bottom_t;
+/* Old macro definitions - To be removed - End here */
+
+/* This marks the end of a packed structure section. */
+#include <packed_section_end.h>
+
+#endif /* _802_11ah_h_ */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11ax.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11ax.h
old mode 100644
new mode 100755
index 24fe183..1566a1b
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11ax.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11ax.h
@@ -2,9 +2,9 @@
  * Basic types and constants relating to 802.11ax/HE STA
  * This is a portion of 802.11ax definition. The rest are in 802.11.h.
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11e.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11e.h
index fc6bc80..65fb149 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11e.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11e.h
@@ -1,9 +1,9 @@
 /*
  * 802.11e protocol header file
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11s.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11s.h
index 384fbe6..fb55aa0 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11s.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.11s.h
@@ -1,9 +1,9 @@
 /*
  * Fundamental types and constants relating to 802.11s Mesh
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.1d.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.1d.h
index 7fdaae9..5ef8935 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.1d.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.1d.h
@@ -1,9 +1,9 @@
 /*
  * Fundamental types and constants relating to 802.1D
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.3.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.3.h
index b3b5edc..769e33a 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.3.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/802.3.h
@@ -1,9 +1,9 @@
 /*
  * Fundamental constants relating to 802.3
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/aidmp.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/aidmp.h
index e915c5c..59436e7 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/aidmp.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/aidmp.h
@@ -1,9 +1,9 @@
 /*
  * Broadcom AMBA Interconnect definitions.
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcm_cfg.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcm_cfg.h
index 110accc..f070d89 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcm_cfg.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcm_cfg.h
@@ -1,9 +1,9 @@
 /*
  * BCM common config options
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcm_mpool_pub.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcm_mpool_pub.h
index 81a370c..78219d7 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcm_mpool_pub.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcm_mpool_pub.h
@@ -35,9 +35,9 @@
  *              and instrumentation on top of the heap, without modifying the heap
  *              allocation implementation.
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcm_ring.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcm_ring.h
index 63e41f4..644d588 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcm_ring.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcm_ring.h
@@ -6,9 +6,9 @@
  *
  * NOTE: A ring of size N, may only hold N-1 elements.
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -103,9 +103,9 @@
  * private L1 data cache.
  * +----------------------------------------------------------------------------
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmarp.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmarp.h
index df28421..0ba1099 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmarp.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmarp.h
@@ -1,9 +1,9 @@
 /*
  * Fundamental constants relating to ARP Protocol
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmbloom.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmbloom.h
index 263657f..ccf9b9c 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmbloom.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmbloom.h
@@ -1,9 +1,9 @@
 /*
  * Bloom filter support
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmcdc.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmcdc.h
index c4c0bd8..e53a236 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmcdc.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmcdc.h
@@ -4,9 +4,9 @@
  *
  * Definitions subject to change without notice.
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmdefs.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmdefs.h
index 014c7ce..99e3f83 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmdefs.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmdefs.h
@@ -1,9 +1,9 @@
 /*
  * Misc system wide definitions
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmdevs.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmdevs.h
index b7acf2b..7358b4b 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmdevs.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmdevs.h
@@ -1,9 +1,9 @@
 /*
  * Broadcom device-specific manifest constants.
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -73,6 +73,7 @@
 #define BCM_DNGL_BL_PID_4354	0xbd26
 #define BCM_DNGL_BL_PID_43569   0xbd27
 #define BCM_DNGL_BL_PID_4373	0xbd29
+#define BCM_DNGL_BL_PID_43439   0xbd3d
 
 #define BCM_DNGL_BDC_PID	0x0bdc
 #define BCM_DNGL_JTAG_PID	0x4a44
@@ -536,6 +537,7 @@
 				case BCM43458_CHIP_ID
 
 #define BCM43430_CHIP_ID	43430		/* 43430 chipcommon chipid */
+#define BCM43439_CHIP_ID	43439		/* 43439 chipcommon chipid */
 #define BCM43018_CHIP_ID	43018		/* 43018 chipcommon chipid */
 #define BCM4349_CHIP_ID		0x4349		/* 4349 chipcommon chipid */
 #define BCM4355_CHIP_ID		0x4355		/* 4355 chipcommon chipid */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmdhcp.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmdhcp.h
index e4f1d20..04f0abb 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmdhcp.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmdhcp.h
@@ -1,9 +1,9 @@
 /*
  * Fundamental constants relating to DHCP Protocol
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmendian.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmendian.h
index 091ba18..5d145f9 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmendian.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmendian.h
@@ -1,9 +1,9 @@
 /*
  * Byte order utilities
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmeth.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmeth.h
index bf833e9..5a8c70d 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmeth.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmeth.h
@@ -1,9 +1,9 @@
 /*
  * Broadcom Ethernettype  protocol definitions
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmevent.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmevent.h
old mode 100644
new mode 100755
index c40af1d..51f0157
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmevent.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmevent.h
@@ -3,9 +3,9 @@
  *
  * Dependencies: bcmeth.h
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -312,9 +312,11 @@
 #define WLC_E_LDF_HOGGER		192 	/* Detection Hogger Squasher -Cambium */
 #define WLC_E_DLTRO         193     /*   DHCP lease time renew offload */
 #define WLC_E_OVERTEMP			194	/* Overtemp notification */
-#define WLC_E_LAST			195	/* highest val + 1 for range checking */
-#if (WLC_E_LAST > 195)
-#error "WLC_E_LAST: Invalid value for last event; must be <= 195."
+#define WLC_E_TWT_TEARDOWN		195	/* TWT Teardown Complete Event */
+#define WLC_E_EXT_ASSOC_FRAME_RX 	196     /* association requeste received */
+#define WLC_E_LAST			197	/* highest val + 1 for range checking */
+#if (WLC_E_LAST > 197)
+#error "WLC_E_LAST: Invalid value for last event; must be <= 197."
 #endif /* WLC_E_LAST */
 
 /* define an API for getting the string name of an event */
@@ -994,6 +996,16 @@
 	/* wl_twt_sdesc_t desc; - defined in wlioctl.h */
 } wl_twt_setup_cplt_t;
 
+#define WL_TWT_TEARDOWN_CPLT_VER	0
+
+/* TWT Teardown Completion event data */
+typedef struct wl_twt_teardown_cplt {
+	uint16 version;
+	uint16 length;	/* the byte count of fields from 'status' onwards */
+	int32 status;
+	/* wl_twt_teardesc_t desc; - defined in wlioctl.h */
+} wl_twt_teardown_cplt_t;
+
 #define WL_INVALID_IE_EVENT_VERSION	0
 
 /* Invalid IE Event data */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmicmp.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmicmp.h
index 807bf37..007ba14 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmicmp.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmicmp.h
@@ -1,9 +1,9 @@
 /*
  * Fundamental constants relating to ICMP Protocol
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmiov.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmiov.h
index 5bd754e..e0290f2 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmiov.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmiov.h
@@ -4,9 +4,9 @@
  * To be used in firmware and host apps or dhd - reducing code size,
  * duplication, and maintenance overhead.
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmip.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmip.h
index ee0abe6..6ed708a 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmip.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmip.h
@@ -1,9 +1,9 @@
 /*
  * Fundamental constants relating to IP Protocol
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmipv6.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmipv6.h
index db87441..245cf5f 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmipv6.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmipv6.h
@@ -1,9 +1,9 @@
 /*
  * Fundamental constants relating to Neighbor Discovery Protocol
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmmsgbuf.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmmsgbuf.h
index 6ebe60c..cf6707e 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmmsgbuf.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmmsgbuf.h
@@ -4,9 +4,9 @@
  *
  * Definitions subject to change without notice.
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmnvram.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmnvram.h
index dd410b6..9f37464 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmnvram.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmnvram.h
@@ -1,9 +1,9 @@
 /*
  * NVRAM variable manipulation
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmpcie.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmpcie.h
index 5d16fed..bd7eb5a 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmpcie.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmpcie.h
@@ -3,9 +3,9 @@
  * Software-specific definitions shared between device and host side
  * Explains the shared area between host and dongle
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmpcispi.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmpcispi.h
index 2b5a2bb..1662bf1 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmpcispi.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmpcispi.h
@@ -1,9 +1,9 @@
 /*
  * Broadcom PCI-SPI Host Controller Register Definitions
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmperf.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmperf.h
index 55cfd34..f7f4d94 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmperf.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmperf.h
@@ -1,9 +1,9 @@
 /*
  * Performance counters software interface.
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdbus.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdbus.h
index bded9f7..f1f46d4 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdbus.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdbus.h
@@ -2,9 +2,9 @@
  * Definitions for API from sdio common code (bcmsdh) to individual
  * host controller drivers.
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdh.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdh.h
index efc8258..1e0609f 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdh.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdh.h
@@ -3,9 +3,9 @@
  *     export functions to client drivers
  *     abstract OS and BUS specific details of SDIO
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -238,6 +238,7 @@
 extern void bcmsdh_oob_intr_unregister(bcmsdh_info_t *sdh);
 extern void bcmsdh_oob_intr_set(bcmsdh_info_t *sdh, bool enable);
 #endif /* defined(OOB_INTR_ONLY) || defined(BCMSPI_ANDROID) */
+extern void *bcmsdh_get_dev(bcmsdh_info_t *sdh);
 extern void bcmsdh_dev_pm_stay_awake(bcmsdh_info_t *sdh);
 extern void bcmsdh_dev_relax(bcmsdh_info_t *sdh);
 extern bool bcmsdh_dev_pm_enabled(bcmsdh_info_t *sdh);
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h
index 26c5bd2..17c119f 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdh_sdmmc.h
@@ -1,9 +1,9 @@
 /*
  * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdpcm.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdpcm.h
old mode 100644
new mode 100755
index 37d968b..6d18f53
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdpcm.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdpcm.h
@@ -2,9 +2,9 @@
  * Broadcom SDIO/PCMCIA
  * Software-specific definitions shared between device and host side
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdspi.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdspi.h
old mode 100644
new mode 100755
index 52883dd..8860bc6
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdspi.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdspi.h
@@ -1,9 +1,9 @@
 /*
  * SD-SPI Protocol Conversion - BCMSDH->SPI Translation Layer
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdstd.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdstd.h
old mode 100644
new mode 100755
index 7485343..2f07291
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdstd.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsdstd.h
@@ -1,9 +1,9 @@
 /*
  *  'Standard' SDIO HOST CONTROLLER driver
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmspi.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmspi.h
old mode 100644
new mode 100755
index 5146a7f..22f78b2
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmspi.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmspi.h
@@ -1,9 +1,9 @@
 /*
  * Broadcom SPI Low-Level Hardware Driver API
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmspibrcm.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmspibrcm.h
old mode 100644
new mode 100755
index 74b9abc..afb157b
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmspibrcm.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmspibrcm.h
@@ -1,9 +1,9 @@
 /*
  * SD-SPI Protocol Conversion - BCMSDH->gSPI Translation Layer
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsrom_fmt.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsrom_fmt.h
old mode 100644
new mode 100755
index e6d90cd..a8bc9d2
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsrom_fmt.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsrom_fmt.h
@@ -1,9 +1,9 @@
 /*
  * SROM format definition.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsrom_tbl.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsrom_tbl.h
old mode 100644
new mode 100755
index e42663b..59a9d52
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsrom_tbl.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmsrom_tbl.h
@@ -1,9 +1,9 @@
 /*
  * Table that encodes the srom formats for PCI/PCIe NICs.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmstdlib_s.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmstdlib_s.h
old mode 100644
new mode 100755
index 582612e..a235bd5
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmstdlib_s.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmstdlib_s.h
@@ -1,9 +1,9 @@
 /*
  * Broadcom Secure Standard Library.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmtcp.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmtcp.h
old mode 100644
new mode 100755
index 610f878..2890dfc
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmtcp.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmtcp.h
@@ -1,9 +1,9 @@
 /*
  * Fundamental constants relating to TCP Protocol
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmtlv.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmtlv.h
old mode 100644
new mode 100755
index 83d4c91..979324b
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmtlv.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmtlv.h
@@ -1,9 +1,9 @@
 /*
  * TLV and XTLV support
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmudp.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmudp.h
old mode 100644
new mode 100755
index 5c4a10c..0f61b81
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmudp.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmudp.h
@@ -1,9 +1,9 @@
 /*
  * Fundamental constants relating to UDP Protocol
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmutils.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmutils.h
old mode 100644
new mode 100755
index cacf4fd..69110f3
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmutils.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/bcmutils.h
@@ -1,9 +1,9 @@
 /*
  * Misc useful os-independent macros and functions.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/brcm_nl80211.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/brcm_nl80211.h
old mode 100644
new mode 100755
index 84eacf9..1e28a2f
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/brcm_nl80211.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/brcm_nl80211.h
@@ -1,9 +1,9 @@
 /*
  * Definitions for nl80211 vendor command/event access to host driver
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -47,6 +47,7 @@
 	BRCM_VENDOR_SCMD_MPC            = 7,
 	BRCM_VENDOR_SCMD_BAND           = 8,
 	BRCM_VENDOR_SCMD_ACS            = 9,
+	BRCM_VENDOR_SCMD_SET_MAC        = 10,
 	BRCM_VENDOR_SCMD_MAX
 };
 
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/dbus.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/dbus.h
old mode 100644
new mode 100755
index 3b6a7c2..ff8be44
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/dbus.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/dbus.h
@@ -2,9 +2,9 @@
  * Dongle BUS interface Abstraction layer
  *   target serial buses like USB, SDIO, SPI, etc.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/dhd_daemon.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/dhd_daemon.h
old mode 100644
new mode 100755
index 90ad408..06f062e
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/dhd_daemon.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/dhd_daemon.h
@@ -1,9 +1,9 @@
 /*
  * Header file for DHD daemon to handle timeouts
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/dhdioctl.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/dhdioctl.h
old mode 100644
new mode 100755
index 6b0582a..cdcbdb1
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/dhdioctl.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/dhdioctl.h
@@ -5,9 +5,9 @@
  *
  * Definitions subject to change without notice.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/dnglevent.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/dnglevent.h
old mode 100644
new mode 100755
index 46defe2..a554dea
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/dnglevent.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/dnglevent.h
@@ -1,9 +1,9 @@
 /*
  * Broadcom Event  protocol definitions
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/eapol.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/eapol.h
old mode 100644
new mode 100755
index 440a7fa..74dd9ee
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/eapol.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/eapol.h
@@ -5,9 +5,9 @@
  * IEEE Std 802.1X-2001
  * IEEE 802.1X RADIUS Usage Guidelines
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/epivers.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/epivers.h
index 46c98b9..651b4cb 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/epivers.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/epivers.h
@@ -15,26 +15,26 @@
 
 #define	EPI_MINOR_VERSION	10
 
-#define	EPI_RC_NUMBER		80
+#define	EPI_RC_NUMBER		96
 
 #define	EPI_INCREMENTAL_NUMBER	0
 
 #define	EPI_BUILD_NUMBER	0
 
-#define	EPI_VERSION		100, 10, 80, 0
+#define	EPI_VERSION		100, 10, 96, 0
 
-#define	EPI_VERSION_NUM		0x640a5000
+#define	EPI_VERSION_NUM		0x640a6000
 
-#define EPI_VERSION_DEV		100.10.80
+#define EPI_VERSION_DEV		100.10.96
 
 /* Driver Version String, ASCII, 32 chars max */
 #ifdef BCMINTERNAL
-#define	EPI_VERSION_STR		"100.10.80 (b285849 BCMINT)"
+#define	EPI_VERSION_STR		"100.10.96 (8c0aa58 BCMINT)"
 #else
 #ifdef WLTEST
-#define	EPI_VERSION_STR		"100.10.80 (b285849 WLTEST)"
+#define	EPI_VERSION_STR		"100.10.96 (8c0aa58 WLTEST)"
 #else
-#define	EPI_VERSION_STR		"100.10.80 (b285849)"
+#define	EPI_VERSION_STR		"100.10.96 (8c0aa58)"
 #endif
 #endif /* BCMINTERNAL */
 
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/etd.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/etd.h
old mode 100644
new mode 100755
index daa69bc..c36034f
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/etd.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/etd.h
@@ -1,9 +1,9 @@
 /*
  * Extended Trap data component interface file.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/ethernet.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/ethernet.h
old mode 100644
new mode 100755
index 6408ffb..078047b
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/ethernet.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/ethernet.h
@@ -1,9 +1,9 @@
 /*
  * From FreeBSD 2.2.7: Fundamental constants relating to ethernet.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/event_log.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/event_log.h
old mode 100644
new mode 100755
index b1aee3a..2a0af2d
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/event_log.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/event_log.h
@@ -1,9 +1,9 @@
 /*
  * EVENT_LOG system definitions
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/event_log_payload.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/event_log_payload.h
old mode 100644
new mode 100755
index a33064f..ddcdcc4
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/event_log_payload.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/event_log_payload.h
@@ -4,9 +4,9 @@
  * This file describes the payloads of event log entries that are data buffers
  * rather than formatted string entries. The contents are generally XTLVs.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/event_log_set.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/event_log_set.h
old mode 100644
new mode 100755
index 7541a81..7a23a0e
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/event_log_set.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/event_log_set.h
@@ -1,9 +1,9 @@
 /*
  * EVENT_LOG system definitions
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/event_log_tag.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/event_log_tag.h
old mode 100644
new mode 100755
index 0e33635..6de9b94
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/event_log_tag.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/event_log_tag.h
@@ -1,9 +1,9 @@
 /*
  * EVENT_LOG system definitions
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/event_trace.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/event_trace.h
old mode 100644
new mode 100755
index 3495ecb..0c665da
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/event_trace.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/event_trace.h
@@ -1,9 +1,9 @@
 /*
  * Trace log blocks sent over HBUS
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/fils.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/fils.h
old mode 100644
new mode 100755
index c5cf876..40a7cb6
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/fils.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/fils.h
@@ -1,8 +1,8 @@
 /*
  * Fundamental types and constants relating to FILS AUTHENTICATION
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hnd_armtrap.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hnd_armtrap.h
old mode 100644
new mode 100755
index ac61c90..7d6c5da
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hnd_armtrap.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hnd_armtrap.h
@@ -1,9 +1,9 @@
 /*
  * HND arm trap handling.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hnd_cons.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hnd_cons.h
old mode 100644
new mode 100755
index 94af2fe..f6825e8
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hnd_cons.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hnd_cons.h
@@ -1,9 +1,9 @@
 /*
  * Console support for RTE - for host use only.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hnd_debug.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hnd_debug.h
old mode 100644
new mode 100755
index d21715f..7b723de
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hnd_debug.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hnd_debug.h
@@ -1,9 +1,9 @@
 /*
  * HND Run Time Environment debug info area
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hnd_pktpool.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hnd_pktpool.h
old mode 100644
new mode 100755
index a437230..a79f9bb
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hnd_pktpool.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hnd_pktpool.h
@@ -1,9 +1,9 @@
 /*
  * HND generic packet pool operation primitives
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hnd_pktq.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hnd_pktq.h
old mode 100644
new mode 100755
index 88fab42..47911b6
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hnd_pktq.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hnd_pktq.h
@@ -1,9 +1,9 @@
 /*
  * HND generic pktq operation primitives
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hnd_trap.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hnd_trap.h
old mode 100644
new mode 100755
index 5482654..7ecf449
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hnd_trap.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hnd_trap.h
@@ -1,9 +1,9 @@
 /*
  * HND Trap handling.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hndchipc.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hndchipc.h
old mode 100644
new mode 100755
index e12545a..a0ecc7b
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hndchipc.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hndchipc.h
@@ -1,9 +1,9 @@
 /*
  * HND SiliconBackplane chipcommon support - OS independent.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hndlhl.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hndlhl.h
old mode 100644
new mode 100755
index f7f4611..e0af659
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hndlhl.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hndlhl.h
@@ -1,9 +1,9 @@
 /*
  * HND SiliconBackplane PMU support.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hndmem.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hndmem.h
old mode 100644
new mode 100755
index 8b40e91..fd4a174
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hndmem.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hndmem.h
@@ -1,9 +1,9 @@
 /*
  * Utility routines for configuring different memories in Broadcom chips.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hndoobr.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hndoobr.h
old mode 100644
new mode 100755
index f277e5c..d6de88a
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hndoobr.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hndoobr.h
@@ -1,9 +1,9 @@
 /*
  * HND OOBR interface header
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hndpmu.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hndpmu.h
old mode 100644
new mode 100755
index d2e11b1..9e25aff
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hndpmu.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hndpmu.h
@@ -1,9 +1,9 @@
 /*
  * HND SiliconBackplane PMU support.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hndsoc.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hndsoc.h
old mode 100644
new mode 100755
index c3942a8..bf4a503
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hndsoc.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/hndsoc.h
@@ -1,9 +1,9 @@
 /*
  * Broadcom HND chip & on-chip-interconnect-related definitions.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/ifx_nl80211.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/ifx_nl80211.h
new file mode 100755
index 0000000..272c3e6
--- /dev/null
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/ifx_nl80211.h
@@ -0,0 +1,294 @@
+/*
+ * Infineon Technologies OUI and vendor specific assignments
+ *
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation,
+ * an Infineon company
+ *
+ * This program is the proprietary software of infineon and/or
+ * its licensors, and may only be used, duplicated, modified or distributed
+ * pursuant to the terms and conditions of a separate, written license
+ * agreement executed between you and infineon (an "Authorized License").
+ * Except as set forth in an Authorized License, infineon grants no license
+ * (express or implied), right to use, or waiver of any kind with respect to
+ * the Software, and infineon expressly reserves all rights in and to the
+ * Software and all intellectual property rights therein.  IF YOU HAVE NO
+ * AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY
+ * WAY, AND SHOULD IMMEDIATELY NOTIFY INFINEON AND DISCONTINUE ALL USE OF
+ * THE SOFTWARE.
+ *
+ * Except as expressly set forth in the Authorized License,
+ *
+ * 1. This program, including its structure, sequence and organization,
+ * constitutes the valuable trade secrets of infineon, and you shall use
+ * all reasonable efforts to protect the confidentiality thereof, and to
+ * use this information only in connection with your use of infineon
+ * integrated circuit products.
+ *
+ * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED
+ * "AS IS" AND WITH ALL FAULTS AND INFINEON MAKES NO PROMISES,
+ * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR
+ * OTHERWISE, WITH RESPECT TO THE SOFTWARE.  INFINEON SPECIFICALLY
+ * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+ * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+ * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+ * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING
+ * OUT OF USE OR PERFORMANCE OF THE SOFTWARE.
+ *
+ * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL
+ * INFINEON OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL,
+ * SPECIAL, INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR
+ * IN ANY WAY RELATING TO YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN
+ * IF INFINEON HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR (ii)
+ * ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE ITSELF
+ * OR U.S. $1, WHICHEVER IS GREATER. THESE LIMITATIONS SHALL APPLY
+ * NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.
+ *
+ *
+ * <<Infineon-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#ifndef IFX_VENDOR_H
+#define IFX_VENDOR_H
+
+/*
+ * This file is a registry of identifier assignments from the Infineon
+ * OUI 00:03:19 for purposes other than MAC address assignment. New identifiers
+ * can be assigned through normal review process for changes to the upstream
+ * hostap.git repository.
+ */
+#define OUI_IFX		0x000319
+
+/*
+ * enum ifx_nl80211_vendor_subcmds - IFX nl80211 vendor command identifiers
+ *
+ * @IFX_VENDOR_SCMD_UNSPEC: Reserved value 0
+ *
+ * @IFX_VENDOR_SCMD_FRAMEBURST: Vendor command to enable/disable Frameburst
+ *
+ * @IFX_VENDOR_SCMD_MUEDCA_OPT_ENABLE: Vendor command to enable/disable HE MU-EDCA opt
+ *
+ * @IFX_VENDOR_SCMD_LDPC_CAP: Vendor command enable/disable LDPC Capability
+ *
+ * @IFX_VENDOR_SCMD_AMSDU: Vendor command to enable/disable AMSDU on all the TID queues
+ *
+ * @IFX_VENDOR_SCMD_TWT: Vendor subcommand to configure TWT
+ *	Uses attributes defined in enum ifx_vendor_attr_twt.
+ *
+ * @IFX_VENDOR_SCMD_OCE_ENABLE: Vendor command to enable/disable OCE Capability
+ *
+ * @IFX_VENDOR_SCMD_RANDMAC: Vendor command to enable/disable RANDMAC Capability
+ *
+ * @IFX_VENDOR_SCMD_MAX: This acts as a the tail of cmds list.
+ *      Make sure it located at the end of the list.
+ */
+enum ifx_nl80211_vendor_subcmds {
+	/*
+	 * TODO: IFX Vendor subcmd enum IDs between 1-10 are reserved
+	 * to be be filled later with BRCM Vendor subcmds that are
+	 * already used by IFX.
+	 */
+	IFX_VENDOR_SCMD_UNSPEC		= 0,
+	/* Reserved 1-5 */
+	IFX_VENDOR_SCMD_FRAMEBURST	= 6,
+	/* Reserved 7-9 */
+#ifdef P2P_RAND
+	IFX_VENDOR_SCMD_SET_P2P_RAND_MAC = 10,
+#endif /* P2P_RAND */
+	IFX_VENDOR_SCMD_MUEDCA_OPT_ENABLE = 11,
+	IFX_VENDOR_SCMD_LDPC_CAP	= 12,
+	IFX_VENDOR_SCMD_AMSDU		= 13,
+	IFX_VENDOR_SCMD_TWT		= 14,
+	IFX_VENDOR_SCMD_OCE_ENABLE      = 15,
+	/* Reserved 16 */
+	IFX_VENDOR_SCMD_RANDMAC         = 17,
+	IFX_VENDOR_SCMD_MAX
+};
+
+/*
+ * enum ifx_vendor_attr - IFX nl80211 vendor attributes
+ *
+ * @IFX_VENDOR_ATTR_UNSPEC: Reserved value 0
+ *
+ * @IFX_VENDOR_ATTR_MAX: This acts as a the tail of attrs list.
+ *      Make sure it located at the end of the list.
+ */
+enum ifx_vendor_attr {
+	/*
+	 * TODO: IFX Vendor attr enum IDs between 0-10 are reserved
+	 * to be filled later with BRCM Vendor attrs that are
+	 * already used by IFX.
+	 */
+	IFX_VENDOR_ATTR_UNSPEC		= 0,
+	IFX_VENDOR_ATTR_PAD		= 1,
+	IFX_VENDOR_ATTR_MAC_ADDR        = 2,
+	/* Reserved 1-10 */
+	IFX_VENDOR_ATTR_MAX		= 11
+};
+
+/*
+ * enum ifx_vendor_attr_twt - Attributes for the TWT vendor command
+ *
+ * @IFX_VENDOR_ATTR_TWT_UNSPEC: Reserved value 0
+ *
+ * @IFX_VENDOR_ATTR_TWT_OPER: To specify the type of TWT operation
+ *	to be performed. Uses attributes defined in enum ifx_twt_oper.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAMS: Nester attributes representing the
+ *	parameters configured for TWT. These parameters are defined in
+ *	the enum ifx_vendor_attr_twt_param.
+ *
+ * @IFX_VENDOR_ATTR_TWT_MAX: This acts as a the tail of cmds list.
+ *      Make sure it located at the end of the list.
+ */
+enum ifx_vendor_attr_twt {
+	IFX_VENDOR_ATTR_TWT_UNSPEC,
+	IFX_VENDOR_ATTR_TWT_OPER,
+	IFX_VENDOR_ATTR_TWT_PARAMS,
+	IFX_VENDOR_ATTR_TWT_MAX
+};
+
+/*
+ * enum ifx_twt_oper - TWT operation to be specified using the vendor
+ * attribute IFX_VENDOR_ATTR_TWT_OPER
+ *
+ * @IFX_TWT_OPER_UNSPEC: Reserved value 0
+ *
+ * @IFX_TWT_OPER_SETUP: Setup a TWT session. Required parameters are
+ *	obtained through the nested attrs under IFX_VENDOR_ATTR_TWT_PARAMS.
+ *
+ * @IFX_TWT_OPER_TEARDOWN: Teardown the already negotiated TWT session.
+ *	Required parameters are obtained through the nested attrs under
+ *	IFX_VENDOR_ATTR_TWT_PARAMS.
+ *
+ * @IFX_TWT_OPER_MAX: This acts as a the tail of the list.
+ *      Make sure it located at the end of the list.
+ */
+enum ifx_twt_oper {
+	IFX_TWT_OPER_UNSPEC,
+	IFX_TWT_OPER_SETUP,
+	IFX_TWT_OPER_TEARDOWN,
+	IFX_TWT_OPER_MAX
+};
+
+/*
+ * enum ifx_vendor_attr_twt_param - TWT parameters
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_UNSPEC: Reserved value 0
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_NEGO_TYPE: Specifies the type of Negotiation to be
+ *	done during Setup. The four possible types are
+ *	0 - Individual TWT Negotiation
+ *	1 - Wake TBTT Negotiation
+ *	2 - Broadcast TWT in Beacon
+ *	3 - Broadcast TWT Membership Negotiation
+ *
+ *	The possible values are defined in the enum ifx_twt_param_nego_type
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_SETUP_CMD_TYPE: Specifies the type of TWT Setup frame
+ *	when sent by the TWT Requesting STA
+ *	0 - Request
+ *	1 - Suggest
+ *	2 - Demand
+ *
+ *	when sent by the TWT Responding STA.
+ *	3 - Grouping
+ *	4 - Accept
+ *	5 - Alternate
+ *	6 - Dictate
+ *	7 - Reject
+ *
+ *	The possible values are defined in the enum ifx_twt_oper_setup_cmd_type.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_DIALOG_TOKEN: Dialog Token used by the TWT Requesting STA to
+ *	identify the TWT Setup request/response transaction.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME: Target Wake Time.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME_OFFSET: Target Wake Time Offset.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION: Nominal Minimum TWT Wake Duration.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_EXPONENT: TWT Wake Interval Exponent.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_MANTISSA: TWT Wake Interval Mantissa.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_REQUESTOR: Specify this is a TWT Requesting / Responding STA.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_TRIGGER: Specify Trigger based / Non-Trigger based TWT Session.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_IMPLICIT: Specify Implicit / Explicit TWT session.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_FLOW_TYPE: Specify Un-Announced / Announced TWT session.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_FLOW_ID: Flow ID of an iTWT session.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_BCAST_TWT_ID: Brocast TWT ID of a bTWT session.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_PROTECTION: Specifies whether Tx within SP is protected.
+ *	Set to 1 to indicate that TXOPs within the TWT SPs shall be initiated
+ *	with a NAV protection mechanism, such as (MU) RTS/CTS or CTS-to-self frame;
+ *	otherwise, it shall set it to 0.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_CHANNEL: TWT channel field which is set to 0, unless
+ * 	the HE STA sets up a subchannel selective transmission operation.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_TWT_INFO_FRAME_DISABLED: TWT Information frame RX handing
+ *	disabled / enabled.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION_UNIT: Nominal Minimum TWT Wake Duration
+ *	Unit. 0 represents unit in "256 usecs" and 1 represents unit in "TUs".
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_TEARDOWN_ALL_TWT: Teardown all negotiated TWT sessions.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_MAX: This acts as a the tail of the list.
+ *      Make sure it located at the end of the list.
+ */
+enum ifx_vendor_attr_twt_param {
+	IFX_VENDOR_ATTR_TWT_PARAM_UNSPEC,
+	IFX_VENDOR_ATTR_TWT_PARAM_NEGO_TYPE,
+	IFX_VENDOR_ATTR_TWT_PARAM_SETUP_CMD_TYPE,
+	IFX_VENDOR_ATTR_TWT_PARAM_DIALOG_TOKEN,
+	IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME,
+	IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME_OFFSET,
+	IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION,
+	IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_EXPONENT,
+	IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_MANTISSA,
+	IFX_VENDOR_ATTR_TWT_PARAM_REQUESTOR,
+	IFX_VENDOR_ATTR_TWT_PARAM_TRIGGER,
+	IFX_VENDOR_ATTR_TWT_PARAM_IMPLICIT,
+	IFX_VENDOR_ATTR_TWT_PARAM_FLOW_TYPE,
+	IFX_VENDOR_ATTR_TWT_PARAM_FLOW_ID,
+	IFX_VENDOR_ATTR_TWT_PARAM_BCAST_TWT_ID,
+	IFX_VENDOR_ATTR_TWT_PARAM_PROTECTION,
+	IFX_VENDOR_ATTR_TWT_PARAM_CHANNEL,
+	IFX_VENDOR_ATTR_TWT_PARAM_TWT_INFO_FRAME_DISABLED,
+	IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION_UNIT,
+	IFX_VENDOR_ATTR_TWT_PARAM_TEARDOWN_ALL_TWT,
+	IFX_VENDOR_ATTR_TWT_PARAM_MAX
+};
+
+enum ifx_twt_param_nego_type {
+	IFX_TWT_PARAM_NEGO_TYPE_INVALID			= -1,
+	IFX_TWT_PARAM_NEGO_TYPE_ITWT			= 0,
+	IFX_TWT_PARAM_NEGO_TYPE_WAKE_TBTT		= 1,
+	IFX_TWT_PARAM_NEGO_TYPE_BTWT_IE_BCN		= 2,
+	IFX_TWT_PARAM_NEGO_TYPE_BTWT			= 3,
+	IFX_TWT_PARAM_NEGO_TYPE_MAX			= 4
+};
+
+enum ifx_twt_oper_setup_cmd_type {
+	IFX_TWT_OPER_SETUP_CMD_TYPE_INVALID	= -1,
+	IFX_TWT_OPER_SETUP_CMD_TYPE_REQUEST	= 0,
+	IFX_TWT_OPER_SETUP_CMD_TYPE_SUGGEST	= 1,
+	IFX_TWT_OPER_SETUP_CMD_TYPE_DEMAND	= 2,
+	IFX_TWT_OPER_SETUP_CMD_TYPE_GROUPING	= 3,
+	IFX_TWT_OPER_SETUP_CMD_TYPE_ACCEPT	= 4,
+	IFX_TWT_OPER_SETUP_CMD_TYPE_ALTERNATE	= 5,
+	IFX_TWT_OPER_SETUP_CMD_TYPE_DICTATE	= 6,
+	IFX_TWT_OPER_SETUP_CMD_TYPE_REJECT	= 7,
+	IFX_TWT_OPER_SETUP_CMD_TYPE_MAX		= 8
+};
+
+#endif /* IFX_VENDOR_H */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/linux_osl.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/linux_osl.h
index de6785e..98b6179 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/linux_osl.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/linux_osl.h
@@ -1,9 +1,9 @@
 /*
  * Linux OS Independent Layer
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -446,13 +446,20 @@
 
 /* map/unmap physical to virtual I/O */
 #if !defined(CONFIG_MMC_MSM7X00A)
+/* REG_MAP: Arguments type casted to 'unsigned long' for 32 bit variables.
+ * REG_MAP_XBIT: Arguments not type casted, because variables of type like
+ * phys_addr_t can be 32 or 64 bit depending on platform architecture.
+*/
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0))
 #define	REG_MAP(pa, size)	ioremap_nocache((unsigned long)(pa), (unsigned long)(size))
+#define	REG_MAP_XBIT(pa, size)	ioremap_nocache((pa), (size))
 #else
 #define REG_MAP(pa, size)	ioremap((unsigned long)(pa), (unsigned long)(size))
+#define REG_MAP_XBIT(pa, size)	ioremap((pa), (size))
 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0) */
 #else
 #define REG_MAP(pa, size)       (void *)(0)
+#define REG_MAP_XBIT(pa, size)	(void *)(0)
 #endif /* !defined(CONFIG_MMC_MSM7X00A */
 #define	REG_UNMAP(va)		iounmap((va))
 
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/linux_pkt.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/linux_pkt.h
old mode 100644
new mode 100755
index 1292b1a..ad3f9ac
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/linux_pkt.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/linux_pkt.h
@@ -1,9 +1,9 @@
 /*
  * Linux Packet (skb) interface
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/linuxver.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/linuxver.h
index e6aa882..a523ac0 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/linuxver.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/linuxver.h
@@ -2,9 +2,9 @@
  * Linux-specific abstractions to gain some independence from linux kernel versions.
  * Pave over some 2.2 versus 2.4 versus 2.6 kernel differences.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -880,6 +880,53 @@
 }
 #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)) */
 
+/* Android GKI kernel does not allow direct file access by driver. */
+#ifdef DHD_DENY_DIRECT_FS_ACCESS
+static inline
+ssize_t __kernel_does_not_allow_write(struct file *file,
+                                      const char __user *buf,
+                                      size_t count, loff_t *pos) {
+	return -EPERM;
+}
+static inline
+ssize_t __kernel_does_not_allow_read(struct file *file,
+                                     char __user *buf,
+                                     size_t count, loff_t *pos) {
+	return -EPERM;
+}
+static inline
+int __kernel_does_not_allow_unlink(struct user_namespace *mnt_userns,
+                                   struct inode *dir,
+                                   struct dentry *dentry,
+                                   struct inode **delegated_inode) {
+	return -EPERM;
+}
+static inline
+int __kernel_does_not_allow_kern_path(const char *name,
+                                      unsigned flag, struct path *path) {
+	return -EPERM;
+}
+static inline
+struct file *__kernel_does_not_allow_filp_open(const char *filename,
+                                               int flags, umode_t mode) {
+	return ERR_PTR(-EPERM);
+}
+
+#define vfs_read(fp, buf, len, pos) __kernel_does_not_allow_read(fp, buf, len, pos)
+#define vfs_write(fp, buf, len, pos) __kernel_does_not_allow_write(fp, buf, len, pos)
+#define kernel_read(fp, buf, len, pos) __kernel_does_not_allow_read(fp, buf, len, pos)
+#define kernel_write(fp, buf, len, pos) __kernel_does_not_allow_read(fp, buf, len, pos)
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
+#define vfs_unlink(a, b)  __kernel_does_not_allow_unlink(a, b, 0, NULL)
+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0))
+#define vfs_unlink(a, b, c)  __kernel_does_not_allow_unlink(NULL, a, b, c)
+#else
+#define vfs_unlink(a, b, c, d)  __kernel_does_not_allow_unlink(a, b, c, d)
+#endif // endif
+#define kern_path(a, b, c)  __kernel_does_not_allow_kern_path(a, b, c)
+#define filp_open(a, b, c)  __kernel_does_not_allow_filp_open(a, b, c)
+#else
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
 #define vfs_write(fp, buf, len, pos) kernel_write(fp, buf, len, pos)
 #define vfs_read(fp, buf, len, pos) kernel_read(fp, buf, len, pos)
@@ -887,6 +934,7 @@
 #else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) */
 #define kernel_read_compat(file, offset, addr, count) kernel_read(file, offset, addr, count)
 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) */
+#endif /* DHD_SUPPORT_ANDROID_GKI_KERNEL */
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
 #define timespec64 timespec
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/lpflags.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/lpflags.h
old mode 100644
new mode 100755
index 6f56f97..9ef3362
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/lpflags.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/lpflags.h
@@ -1,9 +1,9 @@
 /*
  * Chip related low power flags
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/mbo.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/mbo.h
old mode 100644
new mode 100755
index a52198b..2b9ddbc
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/mbo.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/mbo.h
@@ -1,9 +1,9 @@
 /*
  * Fundamental types and constants relating to WFA MBO
  * (Multiband Operation)
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/miniopt.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/miniopt.h
old mode 100644
new mode 100755
index 2db807b..0efa45f
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/miniopt.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/miniopt.h
@@ -1,9 +1,9 @@
 /*
  * Command line options parser.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/msf.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/msf.h
old mode 100644
new mode 100755
index 9491806..1ec021b
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/msf.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/msf.h
@@ -1,9 +1,9 @@
 /*
  * Common interface to MSF (multi-segment format) definitions.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/msgtrace.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/msgtrace.h
old mode 100644
new mode 100755
index 1d1cfe0..82b03ca
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/msgtrace.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/msgtrace.h
@@ -1,9 +1,9 @@
 /*
  * Trace messages sent over HBUS
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/nan.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/nan.h
old mode 100644
new mode 100755
index 7c37f6d..01f2b48
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/nan.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/nan.h
@@ -2,9 +2,9 @@
  * Fundamental types and constants relating to WFA NAN
  * (Neighbor Awareness Networking)
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/osl.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/osl.h
old mode 100644
new mode 100755
index 0d8c4a3..a6dc799
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/osl.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/osl.h
@@ -1,9 +1,9 @@
 /*
  * OS Abstraction Layer
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/osl_decl.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/osl_decl.h
old mode 100644
new mode 100755
index a36c7c4..5ca76a7
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/osl_decl.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/osl_decl.h
@@ -1,9 +1,9 @@
 /*
  * osl forward declarations
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/osl_ext.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/osl_ext.h
old mode 100644
new mode 100755
index 97fa174..490356e
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/osl_ext.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/osl_ext.h
@@ -2,9 +2,9 @@
  * OS Abstraction Layer Extension - the APIs defined by the "extension" API
  * are only supported by a subset of all operating systems.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/p2p.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/p2p.h
old mode 100644
new mode 100755
index 9e1d9a8..0365d54
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/p2p.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/p2p.h
@@ -1,9 +1,9 @@
 /*
  * Fundamental types and constants relating to WFA P2P (aka WiFi Direct)
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/packed_section_end.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/packed_section_end.h
old mode 100644
new mode 100755
index c1654c8..70518fd
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/packed_section_end.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/packed_section_end.h
@@ -15,9 +15,9 @@
  * #include <packed_section_end.h>
  *
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/packed_section_start.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/packed_section_start.h
old mode 100644
new mode 100755
index 56b21fd..536e8ed
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/packed_section_start.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/packed_section_start.h
@@ -15,9 +15,9 @@
  * #include <packed_section_end.h>
  *
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/pcicfg.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/pcicfg.h
old mode 100644
new mode 100755
index 03d53f0..168b375
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/pcicfg.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/pcicfg.h
@@ -1,9 +1,9 @@
 /*
  * pcicfg.h: PCI configuration constants and structures.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/pcie_core.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/pcie_core.h
old mode 100644
new mode 100755
index 4a6ff73..de72080
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/pcie_core.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/pcie_core.h
@@ -1,9 +1,9 @@
 /*
  * BCM43XX PCIE core hardware definitions.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/rte_ioctl.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/rte_ioctl.h
old mode 100644
new mode 100755
index 76e24e7..a4874f5
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/rte_ioctl.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/rte_ioctl.h
@@ -1,9 +1,9 @@
 /*
  * HND Run Time Environment ioctl.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbchipc.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbchipc.h
old mode 100644
new mode 100755
index 731ef6c..531f393
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbchipc.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbchipc.h
@@ -7,9 +7,9 @@
  *
  * $Id: sbchipc.h 701163 2017-05-23 22:21:03Z $
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbconfig.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbconfig.h
old mode 100644
new mode 100755
index 285084b..71b8711
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbconfig.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbconfig.h
@@ -1,9 +1,9 @@
 /*
  * Broadcom SiliconBackplane hardware register definitions.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbgci.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbgci.h
old mode 100644
new mode 100755
index cd27717..17ae67e
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbgci.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbgci.h
@@ -1,9 +1,9 @@
 /*
  * SiliconBackplane GCI core hardware definitions
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbhndarm.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbhndarm.h
old mode 100644
new mode 100755
index 7f8787f..6bc8cd7
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbhndarm.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbhndarm.h
@@ -1,9 +1,9 @@
 /*
  * Broadcom SiliconBackplane ARM definitions
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbhnddma.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbhnddma.h
old mode 100644
new mode 100755
index 052430c..d404373
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbhnddma.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbhnddma.h
@@ -2,9 +2,9 @@
  * Generic Broadcom Home Networking Division (HND) DMA engine HW interface
  * This supports the following chips: BCM42xx, 44xx, 47xx .
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -230,6 +230,9 @@
 	uint32	addrhigh;	/**< descriptor ring base address bits 63:32 (8K aligned) */
 	uint32	status0;	/**< current descriptor, xmt state */
 	uint32	status1;	/**< active descriptor, xmt error */
+#if defined(BCMQT) && defined(BCMSPI)
+	uint32 PAD[2];
+#endif /* defined(BCMQT) && defined(BCMSPI) */
 } dma64regs_t;
 
 typedef volatile struct {
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbpcmcia.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbpcmcia.h
old mode 100644
new mode 100755
index c194719..7b39833
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbpcmcia.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbpcmcia.h
@@ -1,9 +1,9 @@
 /*
  * BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbsdio.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbsdio.h
old mode 100644
new mode 100755
index 19f921c..d8870a0
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbsdio.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbsdio.h
@@ -4,9 +4,9 @@
  *
  * SDIO core support 1bit, 4 bit SDIO mode as well as SPI mode.
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h
old mode 100644
new mode 100755
index 2edda4a..80910e8
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbsdpcmdev.h
@@ -2,9 +2,9 @@
  * Broadcom SiliconBackplane SDIO/PCMCIA hardware-specific
  * device core support
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -140,7 +140,7 @@
 		sdiodma64_t sdiod64;
 	} dma;
 
-	uint32 PAD[12];			/* 0x300-0x32c */
+	uint32 PAD[4];			/* 0x320-0x32c */
 	uint32 chipid;			/* SDIO ChipID Register, 0x330, rev31 */
 	uint32 eromptr;			/* SDIO EromPtrOffset Register, 0x334, rev31 */
 	uint32 PAD[50];
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbsocram.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbsocram.h
old mode 100644
new mode 100755
index 75587be..3b6f088
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbsocram.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbsocram.h
@@ -1,9 +1,9 @@
 /*
  * BCM47XX Sonics SiliconBackplane embedded ram core
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbsysmem.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbsysmem.h
old mode 100644
new mode 100755
index d41d87d..d05649d
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbsysmem.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sbsysmem.h
@@ -1,9 +1,9 @@
 /*
  * SiliconBackplane System Memory core
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sdio.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sdio.h
index a0d95d5..e6c5c17 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sdio.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sdio.h
@@ -2,9 +2,9 @@
  * SDIO spec header file
  * Protocol and standard (common) device definitions
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sdioh.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sdioh.h
old mode 100644
new mode 100755
index 6ab58ab..db64440
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sdioh.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sdioh.h
@@ -2,9 +2,9 @@
  * SDIO Host Controller Spec header file
  * Register map and definitions for the Standard Host Controller
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sdiovar.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sdiovar.h
old mode 100644
new mode 100755
index b580264..9894791
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sdiovar.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sdiovar.h
@@ -2,9 +2,9 @@
  * Structure used by apps whose drivers access SDIO drivers.
  * Pulled out separately so dhdu and wlu can both use it.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sdspi.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sdspi.h
old mode 100644
new mode 100755
index 291fd54..2e3a719
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sdspi.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/sdspi.h
@@ -1,9 +1,9 @@
 /*
  * SD-SPI Protocol Standard
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/siutils.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/siutils.h
old mode 100644
new mode 100755
index 03b2ab8..fba4e73
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/siutils.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/siutils.h
@@ -2,9 +2,9 @@
  * Misc utility routines for accessing the SOC Interconnects
  * of Broadcom HNBU chips.
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/spid.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/spid.h
old mode 100644
new mode 100755
index 9426078..4a6ee31
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/spid.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/spid.h
@@ -1,9 +1,9 @@
 /*
  * SPI device spec header file
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/trxhdr.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/trxhdr.h
old mode 100644
new mode 100755
index 41f1166..85b2247
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/trxhdr.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/trxhdr.h
@@ -1,9 +1,9 @@
 /*
  * TRX image file header format.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/typedefs.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/typedefs.h
old mode 100644
new mode 100755
index 2d5120b..1de4dd3
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/typedefs.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/typedefs.h
@@ -1,7 +1,7 @@
 /*
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -325,6 +325,9 @@
 /* Suppress unused parameter warning */
 #define UNUSED_PARAMETER(x) (void)(x)
 
+/* Suppress unused function warning */
+#define UNUSED_FUNCTION(x) (void)(x)
+
 /* Avoid warning for discarded const or volatile qualifier in special cases (-Wcast-qual) */
 #define DISCARD_QUAL(ptr, type) ((type *)(uintptr)(ptr))
 
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/vlan.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/vlan.h
old mode 100644
new mode 100755
index 5c5ebdf..6e0a2d4
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/vlan.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/vlan.h
@@ -1,9 +1,9 @@
 /*
  * 802.1Q VLAN protocol definitions
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wl_iw.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wl_iw.h
old mode 100644
new mode 100755
index bfb9955..511a217
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wl_iw.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wl_iw.h
@@ -1,9 +1,9 @@
 /*
  * Linux Wireless Extensions support
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wlfc_proto.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wlfc_proto.h
old mode 100644
new mode 100755
index 1e91e74..d46faa0
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wlfc_proto.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wlfc_proto.h
@@ -1,7 +1,7 @@
 /*
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wlioctl.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wlioctl.h
old mode 100644
new mode 100755
index b1cfe0e..0e87ace
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wlioctl.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wlioctl.h
@@ -6,9 +6,9 @@
  *
  * Definitions subject to change without notice.
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -15778,6 +15778,8 @@
 /* -------------- dynamic BTCOEX --------------- */
 #define DCTL_TROWS	2			/**< currently practical number of rows  */
 #define DCTL_TROWS_MAX	4			/**<  2 extra rows RFU */
+/* Default Agg mode is Firmware Driven */
+#define DCTL_AGG_MODE_DFLT 0
 /* DYNCTL profile flags */
 #define DCTL_FLAGS_DISABLED	0		/**< default value: all features disabled */
 #define DCTL_FLAGS_DYNCTL	(1 << 0)	/**<  1 - enabled, 0 - legacy only */
@@ -15835,6 +15837,7 @@
 	btc_thr_data_t msw_data[DCTL_TROWS_MAX];
 	/** dynctl desense switching data table */
 	btc_thr_data_t dsns_data[DCTL_TROWS_MAX];
+	uint16	custom_agg_mode;
 } BWL_POST_PACKED_STRUCT dctl_prof_t;
 #include <packed_section_end.h>
 
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wlioctl_defs.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wlioctl_defs.h
index dc862a0..9e2f0b1 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wlioctl_defs.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wlioctl_defs.h
@@ -4,9 +4,9 @@
  *
  * Definitions subject to change without notice.
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -570,7 +570,7 @@
 					 WPA3_AUTH_1X_SUITE_B_SHA384 | WPA3_AUTH_PSK_SHA384 |\
 					 WPA3_AUTH_1X_SHA384 | WPA3_AUTH_SAE)
 #define WPA3_AUTH_ENABLED(wpa_auth)	((wpa_auth) & WPA3_AUTH_MASK)
-
+#define NON_WPA3_AUTH_ENABLED(wpa_auth)	((wpa_auth) & ~WPA3_AUTH_MASK)
 /* pmkid */
 #define	MAXPMKID		16
 
@@ -2367,4 +2367,9 @@
 /* The macro for data field in empty vendor specific action frame */
 #define VS_EMPTY_ACTION 0xac
 
+#define H2_OCL_RSSI_DELTA	10	/* hysteresis rssi delta */
+#define	H2_OCL_RSSI_THRESHOLD	-70	/**< Low value, e.g. for forcing roam */
+#define	H2_OCL_RSSI_INVALID	0	/* invalid RSSI value */
+#define H2_OCL_DISABLED_RSSI	0x02   /* Disabled because of ocl_rssi_threshold */
+
 #endif /* wlioctl_defs_h */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wlioctl_utils.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wlioctl_utils.h
old mode 100644
new mode 100755
index f8d5155..0b3d272
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wlioctl_utils.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wlioctl_utils.h
@@ -1,9 +1,9 @@
 /*
  * Custom OID/ioctl related helper functions.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wpa.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wpa.h
index c6f4619..d823dbf 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wpa.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wpa.h
@@ -1,9 +1,9 @@
 /*
  * Fundamental types and constants relating to WPA
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wps.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wps.h
old mode 100644
new mode 100755
index d5f2e4c..3cfd277
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wps.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/include/wps.h
@@ -1,9 +1,9 @@
 /*
  * WPS IE definitions
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/linux_osl.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/linux_osl.c
index d7d0c79..43cfeaa 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/linux_osl.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/linux_osl.c
@@ -1,9 +1,9 @@
 /*
  * Linux OS Independent Layer
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/linux_osl_priv.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/linux_osl_priv.h
old mode 100644
new mode 100755
index ca71d66..61d3a4e
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/linux_osl_priv.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/linux_osl_priv.h
@@ -1,9 +1,9 @@
 /*
  * Private header file for Linux OS Independent Layer
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/linux_pkt.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/linux_pkt.c
old mode 100644
new mode 100755
index b42dac9..83d8654
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/linux_pkt.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/linux_pkt.c
@@ -1,9 +1,9 @@
 /*
  * Linux Packet (skb) interface
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/otpdefs.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/otpdefs.h
old mode 100644
new mode 100755
index dff03f9..6bd45c6
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/otpdefs.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/otpdefs.h
@@ -1,9 +1,9 @@
 /*
  * otpdefs.h SROM/OTP definitions.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright 2021 Broadcom
+ * Copyright 2016 Broadcom
  *
  * This program is the proprietary software of Broadcom and/or
  * its licensors, and may only be used, duplicated, modified or distributed
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/pcie_core.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/pcie_core.c
old mode 100644
new mode 100755
index 6fb018a..8a03251
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/pcie_core.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/pcie_core.c
@@ -3,9 +3,9 @@
  * Contains PCIe related functions that are shared between different driver models (e.g. firmware
  * builds, DHD builds, BMAC builds), in order to avoid code duplication.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/sbutils.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/sbutils.c
old mode 100644
new mode 100755
index 55c7aad..42853fe
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/sbutils.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/sbutils.c
@@ -2,9 +2,9 @@
  * Misc utility routines for accessing chip-specific features
  * of the SiliconBackplane-based Broadcom chips.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/siutils.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/siutils.c
index f2746a3..d9530f7 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/siutils.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/siutils.c
@@ -2,9 +2,9 @@
  * Misc utility routines for accessing chip-specific features
  * of the SiliconBackplane-based Broadcom chips.
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -699,9 +699,12 @@
 #endif // endif
 	uint32 erombase;
 #ifdef BCMSDIO
-	uint8 cardcap;
 	sdpcmd_regs_t *sdioc;
-#endif // endif
+	uint8 cardcap;
+#ifdef BCMSPI
+	uint32 spidreg;
+#endif /* BCMSPI */
+#endif /* BCMSDIO */
 
 	ASSERT(GOODREGS(regs));
 
@@ -748,20 +751,35 @@
 		erombase = R_REG(osh, &cc->eromptr);
 #ifdef BCMSDIO
 	} else if ((bustype == SDIO_BUS) || (bustype == SPI_BUS)) {
+		if (bustype == SDIO_BUS) {
+			cardcap = bcmsdh_cfg_read(sdh, SDIO_FUNC_0, SDIOD_CCCR_BRCM_CARDCAP, NULL);
+			if (cardcap & SDIOD_CCCR_BRCM_CARDCAP_CHIPID_PRESENT)
+				sih->chipidpresent = TRUE;
+			if (cardcap & SDIOD_CCCR_BRCM_CARDCAP_SECURE_MODE)
+				sih->secureboot = TRUE;
+		}
+#ifdef BCMSPI
+		else {
+			spidreg = bcmsdh_cfg_read_word(sdh, SDIO_FUNC_0, SPID_RESET_BP, NULL);
+			if (spidreg & SPID_SECURE_MODE) {
+				printf("Security related features are present\n");
+				sih->secureboot = TRUE;
+			}
+			if (spidreg & SPID_CHIPID_PRESENT) {
+				printf("Chip ID is present in SPI core\n");
+				sih->chipidpresent = true;
+			}
+		}
+#endif /* BCMSPI */
 		cc = (chipcregs_t *)sii->curmap;
-		cardcap = bcmsdh_cfg_read(sdh, SDIO_FUNC_0, SDIOD_CCCR_BRCM_CARDCAP, NULL);
-		if (cardcap & SDIOD_CCCR_BRCM_CARDCAP_CHIPID_PRESENT) {
-			sih->chipidpresent = TRUE;
+		if (sih->chipidpresent) {
 			sdioc = si_get_sdio_addrbase(sdh);
 			w = R_REG(osh, &sdioc->chipid);
 			erombase = R_REG(osh, &sdioc->eromptr);
 		} else {
 			erombase = R_REG(osh, &cc->eromptr);
 		}
-		if (cardcap & SDIOD_CCCR_BRCM_CARDCAP_SECURE_MODE) {
-			sih->secureboot = TRUE;
-		}
-#endif // endif
+#endif /* BCMSDIO */
 	} else {
 		cc = (chipcregs_t *)REG_MAP(SI_ENUM_BASE(sih), SI_CORE_SIZE);
 		erombase = R_REG(osh, &cc->eromptr);
@@ -2026,6 +2044,7 @@
 	switch (CHIPID(sih->chip)) {
 	case BCM43018_CHIP_ID:
 	case BCM43430_CHIP_ID:
+	case BCM43439_CHIP_ID:
 		hosti = CHIP_HOSTIF_SDIOMODE;
 		break;
 	case BCM43012_CHIP_ID:
@@ -3096,6 +3115,7 @@
 	uint memsize = 0;
 
 	if (CHIPID(sih->chip) == BCM43430_CHIP_ID ||
+		CHIPID(sih->chip) == BCM43439_CHIP_ID ||
 		CHIPID(sih->chip) == BCM43018_CHIP_ID) {
 		return (64 * 1024);
 	}
@@ -3347,6 +3367,7 @@
 	switch (CHIPID(sih->chip)) {
 	case BCM43018_CHIP_ID:
 	case BCM43430_CHIP_ID:
+	case BCM43439_CHIP_ID:
 		return FALSE;
 	case BCM4335_CHIP_ID:
 	CASE_BCM4345_CHIP:
@@ -3650,6 +3671,7 @@
 #ifdef SAVERESTORE
 		case BCM43018_CHIP_ID:
 		case BCM43430_CHIP_ID:
+		case BCM43439_CHIP_ID:
 			if (SR_ENAB() && sr_isenab(sih)) {
 				/* read back the pll openloop state */
 				data = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL8, 0, 0);
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/siutils_priv.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/siutils_priv.h
old mode 100644
new mode 100755
index e42df98..27a30fa
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/siutils_priv.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/siutils_priv.h
@@ -1,9 +1,9 @@
 /*
  * Include file private to the SOC Interconnect support files.
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_android.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_android.c
index 15e0aeb..1c72d15 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_android.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_android.c
@@ -1,9 +1,9 @@
 /*
  * Linux cfg80211 driver - Android related functions
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -147,6 +147,9 @@
 #endif /* AUTOMOTIVE_FEATURE */
 #define CMD_SET_CSA       "SETCSA"
 #define CMD_RSDB_MODE	"RSDB_MODE"
+#ifdef WL11AX
+#define CMD_GETBSSCOLOR "BSSCOLOR"
+#endif /* WL11AX */
 #ifdef WL_SUPPORT_AUTO_CHANNEL
 #define CMD_SET_HAPD_AUTO_CHANNEL	"HAPD_AUTO_CHANNEL"
 #endif /* WL_SUPPORT_AUTO_CHANNEL */
@@ -985,6 +988,9 @@
 #define M_HOGSQS_DUR_THR (M_HOGSQS_CFG + 0x4)
 #define M_HOGSQS_STAT (M_HOGSQS_CFG + 0x6)
 #define M_HOGSQS_TXCFE_DET_CNT (M_HOGSQS_CFG + 0xe)
+
+/* hidden node recovery command */
+#define HOGSQS_CMD_HNRECOVER 0x9001
 static int
 wl_android_hogsqs(struct net_device *dev, char *command, int total_len)
 {
@@ -1013,6 +1019,9 @@
 		} else if (!strncmp(pos, "count", strlen("count"))) {
 			reg = M_HOGSQS_TXCFE_DET_CNT;
 			pos2 = pos + strlen("count");
+		} else if (!strncmp(pos, "hnrecovery", strlen("hnrecovery"))) {
+			reg = HOGSQS_CMD_HNRECOVER;
+			pos2 = pos + strlen("hnrecovery");
 		} else {
 			DHD_ERROR(("%s: Error wrong argument is on %s \n", __FUNCTION__,
 			CMD_AP_HOGSQS));
@@ -1501,6 +1510,35 @@
 	return bytes_written;
 }
 
+/* returns bsscolor using wpa_cli driver command "driver bsscolor" */
+#ifdef WL11AX
+int wl_android_get_bsscolor(struct net_device *dev, char *command, int total_len)
+{
+	bcm_xtlv_t read_he_xtlv_subcmd;
+	int  err = 0;
+        int bytes_written = 0;
+	u8 color = 0;
+	u8 ioctl_buf[WLC_IOCTL_SMLEN]= {0};
+	read_he_xtlv_subcmd.id = WL_HE_CMD_BSSCOLOR;
+        read_he_xtlv_subcmd.len = 0;
+
+	/* To get fw iovars of the form wl he bsscolor call the
+	   parent iovar with the subcmd filled and passed along */
+	err = wldev_iovar_getbuf(dev, "he", &read_he_xtlv_subcmd, sizeof(read_he_xtlv_subcmd),
+                ioctl_buf, sizeof(ioctl_buf), NULL);
+
+	if (unlikely(err)) {
+                WL_ERR(("he bsscolor failed. Error (%d)\n", err));
+                return err;
+        } else {
+	      color = *(u8 *)ioctl_buf;
+        }
+
+	bytes_written = snprintf(command, total_len, "%d", color);
+        return bytes_written;
+}
+#endif /* WL11AX */
+
 /* returns current datarate datarate returned from firmware are in 500kbps */
 #ifdef AUTOMOTIVE_FEATURE
 int wl_android_get_datarate(struct net_device *dev, char *command, int total_len)
@@ -10128,6 +10166,11 @@
 	else if (strnicmp(command, CMD_SCAN_PROTECT_BSS, strlen(CMD_SCAN_PROTECT_BSS)) == 0) {
 		bytes_written = wl_android_scan_protect_bss(net, command, priv_cmd.total_len);
 	}
+#ifdef WL11AX
+	else if (strnicmp(command, CMD_GETBSSCOLOR, strlen(CMD_GETBSSCOLOR)) == 0) {
+		bytes_written = wl_android_get_bsscolor(net, command, priv_cmd.total_len);
+	}
+#endif /* WL11AX */
 	else {
 		DHD_ERROR(("Unknown PRIVATE command %s - ignored\n", command));
 		bytes_written = scnprintf(command, sizeof("FAIL"), "FAIL");
@@ -10553,7 +10596,7 @@
 }
 
 s32
-wl_cfg80211_static_if_open(struct net_device *net)
+wl_cfg80211_static_if_open(struct net_device *net, u8 *mac_addr)
 {
 	struct wireless_dev *wdev = NULL;
 	struct bcm_cfg80211 *cfg = wl_get_cfg(net);
@@ -10568,7 +10611,7 @@
 		return BCME_ERROR;
 	}
 	if (static_if_ndev_get_state(cfg, net) != NDEV_STATE_FW_IF_CREATED) {
-		wdev = wl_cfg80211_add_if(cfg, primary_ndev, wl_iftype, net->name, NULL);
+		wdev = wl_cfg80211_add_if(cfg, primary_ndev, wl_iftype, net->name, mac_addr);
 		if (!wdev) {
 			WL_ERR(("[STATIC_IF] wdev is NULL, can't proceed"));
 			return BCME_ERROR;
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_android.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_android.h
old mode 100644
new mode 100755
index 4b43ad5..0542c5b
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_android.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_android.h
@@ -1,9 +1,9 @@
 /*
  * Linux cfg80211 driver - Android related functions
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfg80211.c
index 9e3f9f4..02e3590 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfg80211.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfg80211.c
@@ -1,9 +1,9 @@
 /*
  * Linux cfg80211 driver
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -36,6 +36,7 @@
 #include <bcmutils.h>
 #include <bcmstdlib_s.h>
 #include <bcmwifi_channels.h>
+#include <bcmwifi_rspec.h>
 #include <bcmendian.h>
 #include <ethernet.h>
 #ifdef WL_WPS_SYNC
@@ -58,6 +59,9 @@
 #include <linux/etherdevice.h>
 #include <linux/wireless.h>
 #include <linux/ieee80211.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0))
+#include <linux/bitfield.h>
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) */
 #include <linux/wait.h>
 #include <net/cfg80211.h>
 #include <net/rtnetlink.h>
@@ -123,6 +127,10 @@
 #include <dhd_bandsteer.h>
 #endif /* DHD_BANDSTEER */
 
+#ifdef WL11AX
+#include "wl_twt.h"
+#endif /* WL11AX */
+
 #ifdef BCMWAPI_WPI
 /* these items should evetually go into wireless.h of the linux system headfile dir */
 #ifndef IW_ENCODE_ALG_SM4
@@ -182,6 +190,7 @@
 #define IBSS_IF_NAME "ibss%d"
 #endif /* WLAIBSS_MCHAN */
 
+#define DHD_IOVAR_BUF_SIZE 128
 #ifdef VSDB
 /* sleep time to keep STA's connecting or connection for continuous af tx or finding a peer */
 #define DEFAULT_SLEEP_TIME_VSDB		120
@@ -506,6 +515,45 @@
 	NULL
 };
 
+#if defined(WL11AX) || defined(WL_DISABLE_HE_SOFTAP) || defined(WL_DISABLE_HE_P2P)
+bool
+wl_he_get_uint_cb(void *ctx, uint16 *id, uint16 *len)
+{
+        he_xtlv_v32 *v32 = ctx;
+
+        *id = v32->id;
+        *len = v32->len;
+
+        return FALSE;
+}
+
+void
+wl_he_pack_uint_cb(void *ctx, uint16 id, uint16 len, uint8 *buf)
+{
+        he_xtlv_v32 *v32 = ctx;
+
+        BCM_REFERENCE(id);
+        BCM_REFERENCE(len);
+
+        v32->val = htod32(v32->val);
+
+        switch (v32->len) {
+                case sizeof(uint8):
+                        *buf = (uint8)v32->val;
+                        break;
+                case sizeof(uint16):
+                        store16_ua(buf, (uint16)v32->val);
+                        break;
+                case sizeof(uint32):
+                        store32_ua(buf, v32->val);
+                        break;
+                default:
+                        /* ASSERT(0); */
+                        break;
+        }
+}
+#endif /* WL11AX || WL_DISABLE_HE_SOFTAP || WL_DISABLE_HE_P2P */
+
 typedef struct wl_vndr_oui_entry {
 	uchar oui[DOT11_OUI_LEN];
 	struct list_head list;
@@ -566,12 +614,25 @@
 	struct net_device *dev, u8 *mac,
 	struct station_info *sinfo);
 #endif // endif
+#if defined(WL_6E) || (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0))
+static int wl_cfg80211_set_bitrate(struct wiphy *wiphy,
+                               struct net_device *dev,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+	defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+                               unsigned int link_id,
+#endif // endif
+                               const u8 *addr,
+                               const struct cfg80211_bitrate_mask *mask);
+#endif /* WL_6E || (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)) */
+
 static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
 	struct cfg80211_connect_params *sme);
+#if defined(WL_FILS) || defined(WL_OWE)
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
 static int wl_cfg80211_update_connect_params(struct wiphy *wiphy, struct net_device *dev,
 	struct cfg80211_connect_params *sme, u32 changed);
 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) */
+#endif /* defined(WL_FILS) || defined(WL_OWE) */
 static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
 	u16 reason_code);
 #if defined(WL_CFG80211_P2P_DEV_IF)
@@ -680,7 +741,11 @@
 s32 wl_cfg80211_add_del_bss(struct bcm_cfg80211 *cfg,
 	struct net_device *ndev, s32 bsscfg_idx,
 	wl_iftype_t brcm_iftype, s32 del, u8 *addr);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) || defined(WL_COMPAT_WIRELESS)
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+	defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+static s32 wl_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev, unsigned int link_id);
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) || \
+	defined(WL_COMPAT_WIRELESS)
 static s32 wl_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev);
 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) */
 #ifdef GTK_OFFLOAD_SUPPORT
@@ -710,6 +775,16 @@
 	struct cfg80211_external_auth_params *params);
 #endif /* WL_SAE */
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+static int wl_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
+	s32 rssi_thold, u32 rssi_hyst);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */
+
+#if defined(WL_OWE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0))
+static int wl_cfg80211_update_owe_info(struct wiphy *wiphy, struct net_device *dev,
+		struct cfg80211_update_owe_info *owe_info);
+#endif /* WL_OWE && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) */
+
 /*
  * event & event Q handlers for cfg80211 interfaces
  */
@@ -750,6 +825,14 @@
 static s32 wl_handle_rssi_monitor_event(struct bcm_cfg80211 *wl, bcm_struct_cfgdev *cfgdev,
 	const wl_event_msg_t *e, void *data);
 #endif /* RSSI_MONITOR_SUPPORT */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+static s32 wl_notify_rssi_change_ind(struct bcm_cfg80211 *cfg, struct wireless_dev *wdev,
+        const wl_event_msg_t *e, void *data);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
+static s32 wl_notify_beacon_loss(struct bcm_cfg80211 *cfg, struct wireless_dev *wdev,
+	const wl_event_msg_t *e, void *data);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) */
 static s32 wl_notifier_change_state(struct bcm_cfg80211 *cfg, struct net_info *_net_info,
 	enum wl_status state, bool set);
 #ifdef CUSTOM_EVENT_PM_WAKE
@@ -1246,6 +1329,10 @@
                                 &he_cap->he_cap_elem;
 	struct ieee80211_he_mcs_nss_supp *he_mcs =
                                 &he_cap->he_mcs_nss_supp;
+#ifdef WL_6E
+	struct ieee80211_he_6ghz_capa *he_6ghz_capa = &data->he_6ghz_capa;
+	u16 sixghz_capa = 0;
+#endif /* WL_6E */
 
 	if(data == NULL) {
                WL_ERR(("failed to allco mem\n"));
@@ -1254,47 +1341,95 @@
 
 	data->types_mask= BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP);
 	he_cap->has_he = true;
-        he_cap_elem->mac_cap_info[0] =
-                     IEEE80211_HE_MAC_CAP0_HTC_HE | IEEE80211_HE_MAC_CAP0_TWT_REQ;
 
-        he_cap_elem->mac_cap_info[2] =
-                     IEEE80211_HE_MAC_CAP2_BSR;
-	if ((band == NL80211_BAND_5GHZ) || (band == NL80211_BAND_6GHZ))
-		he_cap_elem->phy_cap_info[0] =
-			IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
-			IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
-			IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G;
-        he_cap_elem->phy_cap_info[1] =
-                        IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD;
-        he_cap_elem->phy_cap_info[2] =
-			IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US;
-	he_cap_elem->phy_cap_info[3] =
-                        IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER;
-        he_cap_elem->phy_cap_info[4] =
-                        IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE |
-                        IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_MASK |
-                        IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_4;
-	he_cap_elem->phy_cap_info[5] =
-                        IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_2;
-	he_cap_elem->phy_cap_info[6] =
-                        IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU |
-			IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU |
-                        IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB |
-                        IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB |
-                        IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB |
-                        IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT;
-	he_cap_elem->phy_cap_info[7] =
-                        IEEE80211_HE_PHY_CAP7_MAX_NC_1;
-	he_cap_elem->phy_cap_info[8] =
-                        IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU |
-                        IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU;
-	he_cap_elem->phy_cap_info[9] =
-                        IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU |
-                        IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU;
+	/* HE MAC Capabilities Information */
+	he_cap_elem->mac_cap_info[0] = IEEE80211_HE_MAC_CAP0_HTC_HE |
+				       IEEE80211_HE_MAC_CAP0_TWT_REQ |
+				       IEEE80211_HE_MAC_CAP0_TWT_RES;
+
+	he_cap_elem->mac_cap_info[1] = IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_8US |
+				       IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US;
+
+	he_cap_elem->mac_cap_info[2] = IEEE80211_HE_MAC_CAP2_BSR |
+				       IEEE80211_HE_MAC_CAP2_BCAST_TWT;
+
+	he_cap_elem->mac_cap_info[3] = IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0))
+				       IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_1 |
+#else
+				       IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_1 |
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) */
+				       IEEE80211_HE_MAC_CAP3_FLEX_TWT_SCHED;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0))
+	he_cap_elem->mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU;
+#else
+	he_cap_elem->mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU;
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) */
+
+	/* HE PHY Capabilities Information */
+	he_cap_elem->phy_cap_info[0] = IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G |
+				       IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G;
+
+	he_cap_elem->phy_cap_info[1] = IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD;
+
+	he_cap_elem->phy_cap_info[2] = IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US |
+				       IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO |
+				       IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO;
+
+	he_cap_elem->phy_cap_info[3] = IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_QPSK |
+				       IEEE80211_HE_PHY_CAP3_DCM_MAX_TX_NSS_2 |
+				       IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM;
+
+	he_cap_elem->phy_cap_info[4] = IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE |
+				       IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_8;
+
+	he_cap_elem->phy_cap_info[5] = IEEE80211_HE_PHY_CAP5_NG16_SU_FEEDBACK |
+				       IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK;
+
+	he_cap_elem->phy_cap_info[6] = IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU |
+				       IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU |
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0))
+				       IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB |
+				       IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB	|
+#else
+				       IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB |
+				       IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB |
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) */
+				       IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB |
+				       IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE |
+				       IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT;
+
+	he_cap_elem->phy_cap_info[7] = IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI |
+				       IEEE80211_HE_PHY_CAP7_MAX_NC_1;
+
+	he_cap_elem->phy_cap_info[8] = IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI |
+				       IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G;
+
+	he_cap_elem->phy_cap_info[9] = IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU |
+				       IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB |
+				       IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB;
+
+	/* HE Supported MCS and NSS Set */
 	he_mcs->rx_mcs_80 = cpu_to_le16(0xfffa);
 	he_mcs->tx_mcs_80 = cpu_to_le16(0xfffa);
-	he_mcs->rx_mcs_160 = cpu_to_le16((0xfffa));
-	he_mcs->tx_mcs_160 = cpu_to_le16((0xfffa));
+
+#ifdef WL_6E
+	if (band == NL80211_BAND_6GHZ) {
+		sixghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START,
+					  IEEE80211_HT_MPDU_DENSITY_8);
+		sixghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP,
+					  IEEE80211_VHT_MAX_AMPDU_1024K);
+		sixghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN,
+					  IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454);
+		sixghz_capa |= FIELD_PREP(IEEE80211_HE_6GHZ_CAP_SM_PS,
+					  WLAN_HT_CAP_SM_PS_DISABLED);
+		sixghz_capa |= IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS;
+		sixghz_capa |= IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS;
+		he_6ghz_capa->capa = cpu_to_le16(sixghz_capa);
+	}
+#endif /* WL_6E */
+
 	return idx;
 }
 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 21) */
@@ -6610,6 +6745,7 @@
 }
 #endif /* WL_FILS */
 
+#if defined(WL_FILS) || defined(WL_OWE)
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
 #define UPDATE_ASSOC_IES	BIT(0)
 #ifndef UPDATE_FILS_ERP_INFO
@@ -6663,6 +6799,7 @@
 
 }
 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) */
+#endif /* defined(WL_FILS) || defined(WL_OWE) */
 
 #ifdef WL_SAE
 static int
@@ -6789,6 +6926,72 @@
 }
 #endif /* WL_SAE */
 
+#if defined(WL_6E) || (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0))
+static int wl_cfg80211_set_bitrate(struct wiphy *wiphy,
+                                struct net_device *dev,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+	defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+                               unsigned int link_id,
+#endif // endif
+                                const u8 *addr,
+                                const struct cfg80211_bitrate_mask *mask)
+{
+	int he = 0;
+	uint32 rspec = 0;
+	uint8 hegi;
+	char iovbuf[WLC_IOCTL_SMLEN];
+	int ret = BCME_OK, band = 0;
+
+	ret = wldev_iovar_getint(dev, "he", &he);
+	if (unlikely(ret)) {
+               WL_ERR(("error reading he (%d)\n", ret));
+               return -ENOTSUPP;
+	}
+	for (band = 0; band < NUM_NL80211_BANDS; band++) {
+		if (band != NL80211_BAND_2GHZ && band != NL80211_BAND_5GHZ &&
+		    band != NL80211_BAND_6GHZ) {
+			continue;
+		}
+
+		/* Skip setting HE rates if legacy rate set is called from userspace */
+		if (!mask->control[band].he_mcs[0]) {
+			continue;
+		}
+
+		if (he) {
+			rspec = WL_RSPEC_ENCODE_HE;     /* 11ax HE */
+			rspec |= (WL_RSPEC_HE_NSS_UNSPECIFIED << WL_RSPEC_HE_NSS_SHIFT) | mask->control[band].he_mcs[0];
+			/* set the other rspec fields */
+			hegi = mask->control[band].he_gi;
+			rspec |= ((hegi != 0xFF) ? HE_GI_TO_RSPEC(hegi) : 0);
+
+			if (band == NL80211_BAND_2GHZ) {
+				ret = wldev_iovar_setbuf(dev, "2g_rate", (char *)&rspec, 4,
+						iovbuf, WLC_IOCTL_SMLEN, NULL);
+			}
+			if (band == NL80211_BAND_5GHZ) {
+				ret = wldev_iovar_setbuf(dev, "5g_rate", (char *)&rspec, 4,
+						iovbuf, WLC_IOCTL_SMLEN, NULL);
+			}
+			if (band == NL80211_BAND_6GHZ) {
+				ret = wldev_iovar_setbuf(dev, "6g_rate", (char *)&rspec, 4,
+						iovbuf, WLC_IOCTL_SMLEN, NULL);
+			}
+
+			if (unlikely(ret)) {
+				WL_ERR(("%s: set rate failed, retcode = %d\n",
+					__FUNCTION__, ret));
+			}
+		}
+		else  {
+			WL_ERR(("Only HE supported\n"));
+			return -ENOTSUPP;
+		}
+	}
+	return ret;
+}
+#endif /* WL_6E || (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)) */
+
 #define MAX_SCAN_ABORT_WAIT_CNT 20
 #define WAIT_SCAN_ABORT_OSL_SLEEP_TIME 10
 
@@ -7356,7 +7559,12 @@
 
 	wdev = dev->ieee80211_ptr;
 	wait_cnt = WAIT_FOR_DISCONNECT_STATE_SYNC;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+	defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+	while ((wdev->connected) && wait_cnt) {
+#else
 	while ((wdev->current_bss) && wait_cnt) {
+#endif // endif
 		WL_DBG(("Waiting for disconnect sync, wait_cnt: %d\n", wait_cnt));
 		wait_cnt--;
 		OSL_SLEEP(50);
@@ -7364,7 +7572,12 @@
 
 	if (wait_cnt == 0) {
 		/* state didn't get cleared within given timeout */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+	defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+		WL_INFORM_MEM(("cfg80211 state. wdev->connected is true\n"));
+#else
 		WL_INFORM_MEM(("cfg80211 state. wdev->current_bss non null\n"));
+#endif // endif
 	} else {
 		WL_MEM(("cfg80211 disconnect state sync done\n"));
 	}
@@ -10420,7 +10633,7 @@
 			}
 
 			timeout = wait_for_completion_timeout(&netinfo->mgmt_tx_cpl,
-				MGMT_AUTH_FRAME_WAIT_TIME);
+				msecs_to_jiffies(MGMT_AUTH_FRAME_WAIT_TIME));
 			if ((timeout > 0) || test_bit(MGMT_TX_ACK, &netinfo->mgmt_txstatus)) {
 				WL_DBG(("TX auth frame operation is success\n"));
 				ack = true;
@@ -10688,8 +10901,22 @@
 	}
 
 set_channel:
+#ifdef WL_6E
+	if (chan->band == IEEE80211_BAND_6GHZ)
+		chspec = wf_channel2chspec6E(_chan, bw);
+	else
+#endif /* WL_6E */
 	chspec = wf_channel2chspec(_chan, bw);
+
 	if (wf_chspec_valid(chspec)) {
+		if (IS_RADAR_CHAN(chan->flags)) {
+			WL_ERR(("enable radar  center_freq:%d, chan->flags:0x%x, dfs_state:%d \n", chan->center_freq,  chan->flags, chan->dfs_state));
+			err = wldev_iovar_setint(dev, "radar", 1);
+		}
+		else {
+			WL_ERR(("disable radar center_freq:%d, chan->flags:0x%x, dfs_state:%d \n", chan->center_freq,  chan->flags, chan->dfs_state));
+			err = wldev_iovar_setint(dev, "radar", 0);
+		}
 		fw_chspec = wl_chspec_host_to_driver(chspec);
 		if (fw_chspec != INVCHANSPEC) {
 			if ((err = wldev_iovar_setint(dev, "chanspec",
@@ -11040,6 +11267,16 @@
 			wpa_auth |= WPA3_AUTH_1X_SUITE_B_SHA384;
 			break;
 #endif /* WL_SAE */
+#ifdef WL_OWE
+		case RSN_AKM_OWE:
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0))
+			wpa_auth |= WPA3_AUTH_OWE;
+#else
+			WL_ERR(("Kernel version 5.2 or higher supports for OWE AP\n"));
+			return BCME_ERROR;
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) */
+		break;
+#endif /* WL_OWE */
 #endif /* MFP */
 		default:
 			WL_ERR(("No Key Mgmt Info\n"));
@@ -12640,6 +12877,16 @@
 	s32 bssidx = 0;
 	u32 dev_role = 0;
 	dhd_pub_t *dhd = (dhd_pub_t *)(cfg->pub);
+#ifdef WL11AX
+#if (defined IFX_CFG80211_5_4_21 || (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) && \
+	LINUX_VERSION_CODE <= KERNEL_VERSION(5, 18, 19)))
+	uint8 se_he_xtlv[32];
+	int se_he_xtlv_len= sizeof(se_he_xtlv);
+	he_xtlv_v32 v32;
+#endif /* IFX_CFG80211_5_4_21 ||
+	(LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) &&
+	LINUX_VERSION_CODE <= KERNEL_VERSION(5, 18, 19)) */
+#endif /* WL11AX */
 #ifdef WL11U
 	bcm_tlv_t *interworking_ie;
 	u32 iw_ie_len = 0;
@@ -12709,7 +12956,12 @@
 
 #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) && !defined(WL_COMPAT_WIRELESS))
 	if ((err = wl_cfg80211_set_channel(wiphy, dev,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+	defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+		dev->ieee80211_ptr->u.ap.preset_chandef.chan,
+#else
 		dev->ieee80211_ptr->preset_chandef.chan,
+#endif // endif
 		NL80211_CHAN_HT20) < 0)) {
 		WL_ERR(("Set channel failed \n"));
 		goto fail;
@@ -12768,6 +13020,34 @@
 	wl_set_drv_status(cfg, CONNECTED, dev);
 	WL_DBG(("** AP/GO Created **\n"));
 
+#ifdef WL11AX
+#if (defined IFX_CFG80211_5_4_21 || (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) && \
+	LINUX_VERSION_CODE <= KERNEL_VERSION(5, 18, 19)))
+	/* Set he_bss_color in hostapd */
+	if (info->he_bss_color.enabled)
+	{
+		v32.id = WL_HE_CMD_BSSCOLOR;
+		v32.len = sizeof(s32);
+		v32.val = info->he_bss_color.color;
+		/* To set fw iovars of the form wl he bsscolor where
+		   he is parent iovar followed by subcmd */
+		err = bcm_pack_xtlv_buf((void *)&v32, se_he_xtlv, sizeof(se_he_xtlv),
+				BCM_XTLV_OPTION_ALIGN32, wl_he_get_uint_cb, wl_he_pack_uint_cb,
+				&se_he_xtlv_len);
+		if (err != BCME_OK) {
+			WL_ERR(("failed to pack he bsscolor_xtlv=%d\n", err));
+		}
+		else {
+			err = wldev_iovar_setbuf_bsscfg(dev, "he", &se_he_xtlv, sizeof(se_he_xtlv),
+					cfg->ioctl_buf, WLC_IOCTL_SMLEN, bssidx, &cfg->ioctl_buf_sync);
+				if (unlikely(err)) {
+					WL_ERR(("failed to set he bsscolor, error=%d\n", err));
+				}
+		}
+	}
+#endif /* IFX_CFG80211_5_4_21 || (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0) && LINUX_VERSION_CODE <= KERNEL_VERSION(5, 18, 19) */
+#endif /* WL11AX */
+
 #ifdef WL_CFG80211_ACL
 	/* Enfoce Admission Control. */
 	if ((err = wl_cfg80211_set_mac_acl(wiphy, dev, info->acl)) < 0) {
@@ -12815,14 +13095,12 @@
 	/* Configure hidden SSID */
 	if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE) {
 		if ((err = wldev_iovar_setint(dev, "closednet", 1)) < 0)
-			WL_ERR(("failed to set hidden 1: %d\n", err));
+			WL_ERR(("failed to set hidden : %d\n", err));
 		WL_DBG(("hidden_ssid_enum_val: %d \n", info->hidden_ssid));
-//add by qs.xiong 20221102 to fix ap unhidden fail
 	}else{
-		if ((err = wldev_iovar_setint(dev, "closednet",0 )) < 0)
-			WL_ERR(("failed to set hidden 0 : %d\n", err));
-	}
-//add by qs.xiong 20221102 to fix ap unhidden fail
+		if ((err = wldev_iovar_setint(dev, "closednet",1 )) < 0)
+			WL_ERR(("failed to set unhidden : %d\n", err));
+	}	
 
 #ifdef SUPPORT_AP_RADIO_PWRSAVE
 	if (dev_role == NL80211_IFTYPE_AP) {
@@ -12835,7 +13113,12 @@
 #endif /* SUPPORT_AP_RADIO_PWRSAVE */
 
 #ifdef ENABLE_HOGSQS
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+	defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+	chan_h = dev->ieee80211_ptr->u.ap.preset_chandef.chan;
+#else
 	chan_h = dev->ieee80211_ptr->preset_chandef.chan;
+#endif // endif
 	if (chan_h->band == IEEE80211_BAND_5GHZ) {
 		s32 value = 0x0;
 
@@ -12856,7 +13139,12 @@
 	if (err) {
 		WL_ERR(("ADD/SET beacon failed\n"));
 		wl_flush_fw_log_buffer(dev, FW_LOGSET_MASK_ALL);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+	defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+		wl_cfg80211_stop_ap(wiphy, dev, 0);
+#else
 		wl_cfg80211_stop_ap(wiphy, dev);
+#endif // endif
 		if (dev_role == NL80211_IFTYPE_AP) {
 			dhd->op_mode &= ~DHD_FLAG_HOSTAP_MODE;
 #ifdef PKT_FILTER_SUPPORT
@@ -12889,10 +13177,19 @@
 	return err;
 }
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+	defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+static s32
+wl_cfg80211_stop_ap(
+	struct wiphy *wiphy,
+	struct net_device *dev,
+	unsigned int link_id)
+#else
 static s32
 wl_cfg80211_stop_ap(
 	struct wiphy *wiphy,
 	struct net_device *dev)
+#endif // endif
 {
 	int err = 0;
 	u32 dev_role = 0;
@@ -13639,6 +13936,9 @@
 	.sched_scan_start = wl_cfg80211_sched_scan_start,
 	.sched_scan_stop = wl_cfg80211_sched_scan_stop,
 #endif /* WL_SCHED_SCAN */
+#if defined(WL_6E) || (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0))
+       .set_bitrate_mask = wl_cfg80211_set_bitrate,
+#endif /* WL_6E || (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)) */
 #if defined(WL_SUPPORT_BACKPORTED_KPATCHES) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, \
 	2, 0))
 	.del_station = wl_cfg80211_del_station,
@@ -13676,6 +13976,12 @@
 #ifdef WL_SAE
 	.external_auth = wl_cfg80211_external_auth,
 #endif /* WL_SAE */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+	.set_cqm_rssi_config = wl_cfg80211_set_cqm_rssi_config,
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */
+#if defined(WL_OWE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0))
+	.update_owe_info = wl_cfg80211_update_owe_info,
+#endif /* WL_OWE && LINUX_VERSION_CODE > KERNEL_VERSION(5, 2, 0) */
 };
 
 s32 wl_mode_to_nl80211_iftype(s32 mode)
@@ -13701,9 +14007,11 @@
 	bool notify, bool user_enforced, int revinfo)
 {
 	s32 ret = BCME_OK;
-#ifdef WL_NAN
+#if defined(WL_NAN) ||  (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
 	struct wireless_dev *wdev = ndev_to_wdev(net);
 	struct wiphy *wiphy = wdev->wiphy;
+#endif // endif
+#ifdef WL_NAN
 	struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
 	if (cfg->nan_enable) {
 		mutex_lock(&cfg->if_sync);
@@ -13720,6 +14028,13 @@
 	if (ret < 0) {
 		WL_ERR(("set country Failed :%d\n", ret));
 	}
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
+	else {
+		/* Notification new country hints */
+		if (notify && !(wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED))
+			regulatory_hint(wiphy, country_code);
+	}
+#endif // endif
 	return ret;
 }
 
@@ -13749,6 +14064,162 @@
 	return BCME_OK;
 }
 
+#if defined(WL_SELF_MANAGED_REGDOM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
+enum regdom_freq_bands wl_get_regdom_freq_bands(int channel) {
+	enum regdom_freq_bands area = WL_REGRULE_2G;
+	if (channel > 0 && channel <=13)
+		area = WL_REGRULE_2G;
+	else if (channel == 14)
+		area = WL_REGRULE_2G_14;
+	else if (channel >= 36 && channel <= 48)
+		area = WL_REGRULE_5G_UNII1;
+	else if (channel >= 52 && channel <= 64)
+		area = WL_REGRULE_5G_UNII2A;
+	else if (channel >= 100 && channel <=144)
+		area = WL_REGRULE_5G_UNII2C;
+	else if (channel >= 149 && channel <=165)
+		area = WL_REGRULE_5G_UNII3;
+	return area;
+}
+
+int
+wl_construct_regrule(struct wiphy *wiphy, struct ieee80211_reg_rule *rules, int *nrules)
+{
+	int i,j;
+	int index = 0;
+	struct ieee80211_supported_band *band;
+	struct ieee80211_channel *channels;
+	struct ieee80211_reg_rule *rule;
+
+	if (rules == NULL)
+		return BCME_BADARG;
+
+	*nrules = 0;
+	for( i = IEEE80211_BAND_2GHZ; i <= IEEE80211_BAND_5GHZ; ++i){
+		int maxbw = 20;
+		band = wiphy->bands[i];
+		if (!band)
+			continue;
+		channels = &band->channels[0];
+
+		/* get max bw from channel.flags */
+		for( j = 0; j < band->n_channels; ++j) {
+			if (channels[j].flags == IEEE80211_CHAN_NO_HT40)
+				maxbw = MAX(maxbw, 20);
+			else if ( (channels[j].flags == IEEE80211_CHAN_NO_HT40PLUS) ||
+				(channels[j].flags == IEEE80211_CHAN_NO_HT40MINUS))
+				maxbw = MAX(maxbw, 40);
+		}
+		if ( band->vht_cap.vht_supported )
+			maxbw = MAX(maxbw, 80);
+
+		/* filling tables for reg_rule per channels */
+		for( j = 0; j < band->n_channels; ++j) {
+			index = wl_get_regdom_freq_bands(channels[j].hw_value);
+			rule = &rules[index];
+			if (channels[j].flags & IEEE80211_CHAN_DISABLED)
+				continue;
+			if (rule->freq_range.start_freq_khz == 0) {
+				(*nrules)++;
+				/* adding default information */
+				rule->freq_range.start_freq_khz =
+					MHZ_TO_KHZ(channels[j].center_freq - 10);
+				rule->freq_range.end_freq_khz =
+					MHZ_TO_KHZ(channels[j].center_freq + 10);
+				rule->freq_range.max_bandwidth_khz = MHZ_TO_KHZ(maxbw);
+				rule->power_rule.max_antenna_gain = DBI_TO_MBI(6);
+				rule->power_rule.max_eirp = DBM_TO_MBM(20);
+				/* adding regulatory flags */
+				if ( i == IEEE80211_BAND_5GHZ)
+					rule->flags |= NL80211_RRF_AUTO_BW;
+				if (channels[j].flags & IEEE80211_CHAN_RADAR)
+					rule->flags |= NL80211_RRF_DFS | NL80211_RRF_NO_IR;
+				if (channels[j].flags & IEEE80211_CHAN_NO_IR)
+					rule->flags |= NL80211_RRF_NO_IR;
+
+				rule->dfs_cac_ms = 0;
+			}
+			else {
+				rule->freq_range.end_freq_khz =
+					MHZ_TO_KHZ(channels[j].center_freq + 10);
+			}
+		}
+	}
+	for(i=0;i<WL_REGRULE_MAX;++i) {
+		if (rules[i].freq_range.start_freq_khz) {
+			WL_DBG(("new regdom[%d] - (%d - %d @ %d), (%d, %d), %x\n", i,
+				rules[i].freq_range.start_freq_khz,
+				rules[i].freq_range.end_freq_khz,
+				rules[i].freq_range.max_bandwidth_khz,
+				rules[i].power_rule.max_antenna_gain,
+				rules[i].power_rule.max_eirp, rules[i].flags));
+		}
+	}
+	return BCME_OK;
+}
+
+static struct ieee80211_regdomain *wl_get_regdom(struct wiphy *wiphy)
+{
+	int err = BCME_OK;
+	struct ieee80211_regdomain *regd = NULL;
+	struct ieee80211_reg_rule *rules = NULL;
+	int nrules = 0;
+	struct bcm_cfg80211 *cfg;
+	struct net_device *dev;
+	dhd_pub_t *dhdp;
+	wl_country_t cspec;
+	int len, i;
+	gfp_t flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
+
+	cfg = wiphy_priv(wiphy);
+	dhdp = (struct dhd_pub *)(cfg->pub);
+	if (!cfg || !cfg->wdev || !dhdp) {
+		goto done;
+	}
+	dev = bcmcfg_to_prmry_ndev(cfg);
+	if (!dev) {
+		goto done;
+	}
+
+	rules = kzalloc(sizeof(struct ieee80211_reg_rule) * WL_REGRULE_MAX, flags);
+
+	if (wl_construct_regrule(wiphy, rules, &nrules) == BCME_OK) {
+		len = sizeof(struct ieee80211_regdomain) +
+			sizeof(struct ieee80211_reg_rule) * nrules;
+		regd = kzalloc(len, flags);
+		regd->alpha2[0] = '9';
+		regd->alpha2[1] = '9';
+		for( i = 0; i < WL_REGRULE_MAX; ++i) {
+			if (rules[i].freq_range.start_freq_khz) {
+				memcpy(&regd->reg_rules[regd->n_reg_rules++],
+					&rules[i], sizeof(struct ieee80211_reg_rule));
+			}
+		}
+	}
+	else {
+		/* if failed to get reg_rules, use brcm_regdom */
+		len = sizeof(brcm_regdom);
+		regd = kmemdup(&brcm_regdom, len, flags);
+	}
+	kfree(rules);
+
+	/* get current country code, if nothing, get from firmware. */
+	if (dhdp->dhd_cspec.ccode[0] && dhdp->dhd_cspec.ccode[1])
+		memcpy(&cspec, &dhdp->dhd_cspec, sizeof(wl_country_t));
+	else
+		err = wldev_iovar_getbuf(dev, "country", NULL, 0, &cspec, sizeof(cspec), NULL);
+done:
+	if (regd && err == BCME_OK) {
+		/* mapping current country code */
+		regd->alpha2[0] = cspec.ccode[0];
+		regd->alpha2[1] = cspec.ccode[1];
+	}
+
+	return regd;
+}
+
+#endif /* WL_SELF_MANAGED_REGDOM */
+
 #ifdef WL_SAE
 static s32 wl_wiphy_update_sae(struct wiphy *wiphy, dhd_pub_t *dhd)
 {
@@ -13760,6 +14231,11 @@
 		wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_SAE_OFFLOAD);
 		WL_DBG(("%s intsae enabled\n", __FUNCTION__));
 	}
+
+	if (FW_SUPPORTED(dhd, ap_pmksa)) {
+		WL_ERR(("Firmware support AP PMKSA\n"));
+		wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_AP_PMKSA_CACHING);
+	}
 	return BCME_OK;
 }
 #endif /* WL_SAE */
@@ -13892,7 +14368,8 @@
 #endif /* WL_SUPPORT_BACKPORTED_KPATCHES) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) */
 
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 2, 0)) || defined(WL_COMPAT_WIRELESS)
-	wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
+	if (FW_SUPPORTED(dhd, tdls))
+		wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
 #endif // endif
 
 #if defined(CONFIG_PM) && defined(WL_CFG80211_P2P_DEV_IF)
@@ -13909,18 +14386,12 @@
 	* Note: wiphy->wowlan_config is freed by cfg80211 layer.
 	* so use malloc instead of MALLOC(osh) to avoid false alarm.
 	*/
-	brcm_wowlan_config = kmalloc(sizeof(struct cfg80211_wowlan), GFP_KERNEL);
+	brcm_wowlan_config = kzalloc(sizeof(struct cfg80211_wowlan), GFP_KERNEL);
 	if (brcm_wowlan_config) {
 		brcm_wowlan_config->disconnect = true;
 		brcm_wowlan_config->gtk_rekey_failure = true;
 		brcm_wowlan_config->eap_identity_req = true;
 		brcm_wowlan_config->four_way_handshake = true;
-		brcm_wowlan_config->patterns = NULL;
-		brcm_wowlan_config->n_patterns = 0;
-		brcm_wowlan_config->tcp = NULL;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
-		brcm_wowlan_config->nd_config = NULL;
-#endif // endif
 	} else {
 		WL_ERR(("Can not allocate memory for brcm_wowlan_config,"
 			" So wiphy->wowlan_config is set to NULL\n"));
@@ -13938,12 +14409,17 @@
 #endif /* CONFIG_PM && WL_CFG80211_P2P_DEV_IF */
 
 	WL_DBG(("Registering custom regulatory)\n"));
+#if defined(WL_SELF_MANAGED_REGDOM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
+        wdev->wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED;
+        wdev->wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF;
+#else
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
 	wdev->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
 #else
 	wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
 #endif /* LINUX_VERSION_CODE > KERNEL_VERSION(3, 14, 0) */
 	wiphy_apply_custom_regulatory(wdev->wiphy, &brcm_regdom);
+#endif /* WL_SELF_MANAGED_REGDOM */
 
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 14, 0)) || defined(WL_VENDOR_EXT_SUPPORT)
 	WL_INFORM_MEM(("Registering Vendor80211\n"));
@@ -13975,6 +14451,9 @@
 
 #ifdef WL_SAE
 	wdev->wiphy->features |= NL80211_FEATURE_SAE;
+	if (FW_SUPPORTED(dhd, ap_pmksa)) {
+		wiphy_ext_feature_set(wdev->wiphy, NL80211_EXT_FEATURE_AP_PMKSA_CACHING);
+	}
 #endif /* WL_SAE */
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)) && defined(BCMSUP_4WAY_HANDSHAKE)
 	if (FW_SUPPORTED(dhd, idsup)) {
@@ -16026,8 +16505,14 @@
 			ndev = cfgdev_to_wlc_ndev(cfgdev, cfg);
 			if (ndev) {
 				wdev = ndev->ieee80211_ptr;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+	defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+				wdev->u.client.ssid_len = min(ssid->SSID_len, (uint32)DOT11_MAX_SSID_LEN);
+				memcpy(wdev->u.client.ssid, ssid->SSID, wdev->u.client.ssid_len);
+#else
 				wdev->ssid_len = min(ssid->SSID_len, (uint32)DOT11_MAX_SSID_LEN);
 				memcpy(wdev->ssid, ssid->SSID, wdev->ssid_len);
+#endif // endif
 				WL_ERR(("SSID is %s\n", ssid->SSID));
 				wl_update_prof(cfg, ndev, NULL, ssid, WL_PROF_SSID);
 			} else {
@@ -16072,6 +16557,71 @@
 }
 #endif /* RSSI_MONITOR_SUPPORT */
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+static s32
+wl_notify_rssi_change_ind(struct bcm_cfg80211 *cfg, struct wireless_dev *wdev,
+	const wl_event_msg_t *e, void *data)
+{
+	wl_event_data_rssi_t *value = (struct wl_event_data_rssi *)data;
+	u32 event = ntoh32(e->event_type);
+	u32 status = ntoh32(e->status);
+	u32 reason = ntoh32(e->reason);
+	s32 rssi = 0;
+
+	WL_DBG(("Enter: event %d (%d), status=%d\n",
+			event, reason, status));
+
+	if (!cfg->cqm_info.enable)
+		return 0;
+
+	rssi = ntohl(value->rssi);
+	cfg80211_cqm_rssi_notify(wdev->netdev,
+		(rssi > cfg->cqm_info.rssi_threshold ?
+			NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH :
+			NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW),
+		rssi, GFP_KERNEL);
+
+	return 0;
+}
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
+static s32
+wl_notify_beacon_loss(struct bcm_cfg80211 *cfg, struct wireless_dev *wdev,
+	const wl_event_msg_t *e, void *data)
+{
+	struct cfg80211_bss *bss;
+	struct wiphy *wiphy = bcmcfg_to_wiphy(cfg);
+	struct wl_profile *profile = wl_get_profile_by_netdev(cfg, wdev->netdev);
+
+	if (!profile)
+		return WL_INVALID;
+
+	if (!us_ap_select)
+		return 0;
+
+	WL_DBG(("Enter: event %d (%d), status=%d\n",
+		ntoh32(e->event_type), ntoh32(e->status), ntoh32(e->reason)));
+
+	/* On beacon loss event, supplicant will trigger new scan request
+	 * with NL80211_SCAN_FLAG_FLUSH Flag set, but the flushed AP bss entry
+	 * still remains as it is still held by cfg in associated state. Unlinking this
+	 * current BSS from cfg cached bss list on beacon loss event here
+	 * would allow supplicant to receive new scanned entries
+	 * without current bss and select new bss to trigger roam.
+	 */
+	bss = CFG80211_GET_BSS(wiphy, NULL, profile->bssid, 0, 0);
+	if (bss) {
+		cfg80211_unlink_bss(wiphy, bss);
+		cfg80211_put_bss(wiphy, bss);
+	}
+
+	cfg80211_cqm_beacon_loss_notify(wdev->netdev, GFP_KERNEL);
+
+	return 0;
+}
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) */
+
 static s32
 wl_notify_roaming_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
 	const wl_event_msg_t *e, void *data)
@@ -16796,8 +17346,14 @@
 	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)) || defined(WL_FILS_ROAM_OFFLD) || \
 	defined(CFG80211_ROAM_API_GE_4_12)
 	memset(&roam_info, 0, sizeof(struct cfg80211_roam_info));
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+	defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+	roam_info.links[0].channel = notify_channel;
+	roam_info.links[0].bssid = curbssid;
+#else
 	roam_info.channel = notify_channel;
 	roam_info.bssid = curbssid;
+#endif // endif
 	roam_info.req_ie = conn_info->req_ie;
 	roam_info.req_ie_len = conn_info->req_ie_len;
 	roam_info.resp_ie = conn_info->resp_ie;
@@ -17752,6 +18308,47 @@
 		}
 		isfree = true;
 #endif /* WL_SAE */
+#if defined(WL_OWE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0))
+	} else if (event == WLC_E_EXT_ASSOC_FRAME_RX) {
+		struct cfg80211_update_owe_info owe_info;
+		bcm_tlv_t *owe_info_ie = NULL;
+		u8 *ies = NULL;
+		u32 ies_len;
+
+		WL_DBG(("EVENT: WLC_E_EXT_ASSOC_FRAME_RX received\n"));
+
+		if (ndev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) {
+			WL_ERR(("OWE ASSOC REQ: not AP I/F\n"));
+			return -EINVAL;
+		}
+
+		ies = (u8 *)((wl_event_rx_frame_data_t *)rxframe + 1) + DOT11_MGMT_HDR_LEN;
+		ies_len = mgmt_frame_len - DOT11_MGMT_HDR_LEN;
+
+		ies += DOT11_ASSOC_REQ_FIXED_LEN;
+		if (ies_len <= DOT11_ASSOC_REQ_FIXED_LEN) {
+			WL_ERR(("OWE ASSOC REQ: event data too small. Ignoring event\n"));
+			return -EINVAL;
+		}
+		ies_len -= DOT11_ASSOC_REQ_FIXED_LEN;
+
+		memset(&owe_info, 0, sizeof(struct cfg80211_update_owe_info));
+		memcpy(owe_info.peer, e->addr.octet, ETH_ALEN);
+		owe_info.ie = ies;
+		owe_info.ie_len = ies_len;
+
+		owe_info_ie = bcm_parse_tlvs((const u8 *)owe_info.ie, owe_info.ie_len, DOT11_MNG_RSN_ID);
+		if (owe_info_ie)
+			WL_INFORM(("OWE ASSOC REQ: found RSNIE"));
+
+		owe_info_ie = bcm_parse_tlvs((const u8 *)owe_info.ie, owe_info.ie_len, DOT11_MNG_ID_EXT_ID);
+		if (owe_info_ie && DOT11_OWE_DH_PARAM_IE(owe_info_ie))
+			WL_INFORM(("OWE ASSOC REQ: found OWE DH PARAM"));
+
+		cfg80211_update_owe_info_event(ndev, &owe_info, GFP_KERNEL);
+
+		return 0;
+#endif /* WL_OWE && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) */
 	} else {
 		mgmt_frame = (u8 *)((wl_event_rx_frame_data_t *)rxframe + 1);
 
@@ -17945,6 +18542,15 @@
 	cfg->evt_handler[WLC_E_LDF_HOGGER] = wl_cfg80211_hogsqs_notify;
 #endif /* ENABLE_HOGSQS */
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+	cfg->evt_handler[WLC_E_RSSI] = wl_notify_rssi_change_ind;
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
+	cfg->evt_handler[WLC_E_BCNLOST_MSG] = wl_notify_beacon_loss;
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) */
+#if defined(WL_OWE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0))
+	cfg->evt_handler[WLC_E_EXT_ASSOC_FRAME_RX] = wl_notify_rx_mgmt_frame;
+#endif /* WL_OWE && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) */
 }
 
 #if defined(STATIC_WL_PRIV_STRUCT)
@@ -18549,6 +19155,7 @@
 	u32 chan = 0;
 	struct net_device *primary_dev = bcmcfg_to_prmry_ndev(cfg);
 	dhd_pub_t *dhd = cfg->pub;
+	s32 ifidx = DHD_BAD_IF;
 #ifdef RTT_SUPPORT
 	rtt_status_info_t *rtt_status;
 #endif /* RTT_SUPPORT */
@@ -18556,6 +19163,12 @@
 		WL_ERR(("busstate is DHD_BUS_DOWN!\n"));
 		return 0;
 	}
+
+	ifidx = dhd_net2idx(dhd->info, _net_info->ndev);
+	if (ifidx == DHD_BAD_IF) {
+		WL_ERR(("ifidx is invalid\n"));
+		return BCME_ERROR;
+	}
 	WL_DBG(("Enter state %d set %d _net_info->pm_restore %d iface %s\n",
 		state, set, _net_info->pm_restore, _net_info->ndev->name));
 
@@ -18646,6 +19259,9 @@
 			wl_cfg80211_set_frameburst(cfg, FALSE);
 		}
 #endif /* DISABLE_WL_FRAMEBURST_SOFTAP */
+#ifdef WL11AX
+		wl_twt_cleanup_session_records(dhd, (u8)ifidx);
+#endif /* WL11AX */
 	}
 	return err;
 }
@@ -20150,8 +20766,23 @@
 		wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
 	}
 
-	if (notify)
-		wiphy_apply_custom_regulatory(wiphy, &brcm_regdom);
+	if (notify) {
+#if defined(WL_SELF_MANAGED_REGDOM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
+		if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) {
+			struct ieee80211_regdomain *regd = wl_get_regdom(wiphy);
+			regulatory_set_wiphy_regd(wiphy, regd);
+			kfree(regd);
+		}
+		else
+#endif // endif
+		{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+			wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
+#endif // endif
+			wiphy_apply_custom_regulatory(wiphy, &brcm_regdom);
+		}
+
+	}
 #ifdef WL_SAE
 	(void)wl_wiphy_update_sae(wiphy, dhd);
 #endif /* WL_SAE */
@@ -20446,8 +21077,14 @@
 			u8 *latest_bssid = wl_read_prof(cfg, ndev, WL_PROF_LATEST_BSSID);
 			struct wiphy *wiphy = bcmcfg_to_wiphy(cfg);
 			struct wireless_dev *wdev = ndev->ieee80211_ptr;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+	defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+			struct cfg80211_bss *bss = CFG80211_GET_BSS(wiphy, NULL, latest_bssid,
+				wdev->u.client.ssid, wdev->u.client.ssid_len);
+#else
 			struct cfg80211_bss *bss = CFG80211_GET_BSS(wiphy, NULL, latest_bssid,
 				wdev->ssid, wdev->ssid_len);
+#endif // endif
 
 			BCM_REFERENCE(bss);
 
@@ -20642,6 +21279,8 @@
 		cfg->wdev->wiphy->features |= NL80211_FEATURE_FW_4WAY_HANDSHAKE;
 	}
 #endif /* BCMSUP_4WAY_HANDSHAKE */
+       /* Set the flag of DFS offload to the driver */
+	wiphy_ext_feature_set(cfg->wdev->wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD);
 	err = __wl_cfg80211_up(cfg);
 	if (unlikely(err))
 		WL_ERR(("__wl_cfg80211_up failed\n"));
@@ -22344,13 +22983,20 @@
 				}
 
 				/*
-				 * skip parsing the HE capab & oper IE from upper layer
-				 * to avoid sending it to the FW, as these IEs will be
-				 * added by the FW based on the MAC & PHY capab if HE
-				 * is enabled.
+				 * skip parsing the HE capab, oper & 6GHz Band capab IE
+				 * from upper layer to avoid sending it to the FW, as
+				 * these IEs will be added by the FW based on the MAC &
+				 * PHY capab if HE is enabled.
+				 * Skip guarding with WL11AX flag because these IEs being
+				 * supplied from hostapd, using 11ax enabled hostapd and
+				 * 11ax disabled DHD (in case of legacy chips), guarding
+				 * under WL11AX flag would cause this code to be skipped
+				 * causing double IE addition issue (one from fw and one
+				 * dhd).
 				 */
 				if ((ie->data[0] == EXT_MNG_HE_CAP_ID) ||
-				    (ie->data[0] == EXT_MNG_HE_OP_ID)) {
+				    (ie->data[0] == EXT_MNG_HE_OP_ID) ||
+				    (ie->data[0] == EXT_MNG_HE_6GBAND_CAP_ID)) {
 					goto end;
 				}
 			} else {
@@ -22986,6 +23632,13 @@
 
 	}
 
+#ifdef WL_6E
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION (5, 4, 0))
+	if (CHSPEC_IS6G(chanspec))
+		freq = ieee80211_channel_to_frequency(channel, NL80211_BAND_6GHZ);
+	else
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION (5, 4, 0) */
+#endif /* WL_6E */
 	if (CHSPEC_IS5G(chanspec))
 		freq = ieee80211_channel_to_frequency(channel, NL80211_BAND_5GHZ);
 	else
@@ -23059,7 +23712,11 @@
 		WL_ERR(("chspec_chandef failed\n"));
 		return;
 	}
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION (3, 8, 0))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) || \
+	defined(DHD_ANDROID_KERNEL5_15_SUPPORT)
+	freq = chandef.chan ? chandef.chan->center_freq : chandef.center_freq1;
+	cfg80211_ch_switch_notify(dev, &chandef, 0);
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION (3, 8, 0))
 	freq = chandef.chan ? chandef.chan->center_freq : chandef.center_freq1;
 	cfg80211_ch_switch_notify(dev, &chandef);
 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION (3, 5, 0) && (LINUX_VERSION_CODE <= (3, 7, \
@@ -25515,50 +26172,8 @@
 
 	MFREE(cfg->osh, ver_ptr, alloc_len);
 }
+
 #if defined(WL_DISABLE_HE_SOFTAP) || defined(WL_DISABLE_HE_P2P)
-typedef struct {
-	uint16 id;
-	uint16 len;
-	uint32 val;
-} he_xtlv_v32;
-
-	static bool
-wl_he_get_uint_cb(void *ctx, uint16 *id, uint16 *len)
-{
-	he_xtlv_v32 *v32 = ctx;
-
-	*id = v32->id;
-	*len = v32->len;
-
-	return FALSE;
-}
-
-	static void
-wl_he_pack_uint_cb(void *ctx, uint16 id, uint16 len, uint8 *buf)
-{
-	he_xtlv_v32 *v32 = ctx;
-
-	BCM_REFERENCE(id);
-	BCM_REFERENCE(len);
-
-	v32->val = htod32(v32->val);
-
-	switch (v32->len) {
-		case sizeof(uint8):
-			*buf = (uint8)v32->val;
-			break;
-		case sizeof(uint16):
-			store16_ua(buf, (uint16)v32->val);
-			break;
-		case sizeof(uint32):
-			store32_ua(buf, v32->val);
-			break;
-		default:
-			/* ASSERT(0); */
-			break;
-	}
-}
-
 int wl_cfg80211_set_he_mode(struct net_device *dev, struct bcm_cfg80211 *cfg,
 		s32 bssidx, u32 interface_type, bool set)
 {
@@ -25921,6 +26536,41 @@
 }
 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0) */
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+static int wl_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy,
+	struct net_device *dev,	s32 rssi_thold, u32 rssi_hyst)
+{
+	struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+	wl_rssi_event_t rssi = {};
+	int err = 0;
+
+	if (rssi_thold == 0) {
+		cfg->cqm_info.enable = 0;
+		cfg->cqm_info.rssi_threshold = 0;
+	} else {
+		cfg->cqm_info.enable = 1;
+		cfg->cqm_info.rssi_threshold = rssi_thold;
+
+		rssi.rate_limit_msec = 0;
+		rssi.rssi_levels[rssi.num_rssi_levels++] = S8_MIN;
+		rssi.rssi_levels[rssi.num_rssi_levels++] =
+				cfg->cqm_info.rssi_threshold;
+		rssi.rssi_levels[rssi.num_rssi_levels++] = S8_MAX;
+	}
+
+	err = wldev_iovar_setbuf(dev, "rssi_event", &rssi, sizeof(rssi),
+		cfg->ioctl_buf, WLC_IOCTL_SMLEN, &cfg->ioctl_buf_sync);
+
+	if (err < 0)
+		WL_ERR(("set rssi_event iovar failed (%d)\n", err));
+
+	WL_DBG(("enable = %d, rssi_threshold = %d\n",
+		cfg->cqm_info.enable, cfg->cqm_info.rssi_threshold));
+
+	return err;
+}
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */
+
 #ifdef WL_WIPSEVT
 int
 wl_cfg80211_wips_event(uint16 misdeauth, char* bssid)
@@ -26013,3 +26663,41 @@
 	cfg80211_vendor_event(skb, kflags);
 }
 #endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(3, 11, 1) */
+
+#if defined(WL_OWE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0))
+static int wl_cfg80211_update_owe_info(struct wiphy *wiphy, struct net_device *dev,
+	struct cfg80211_update_owe_info *owe_info)
+{
+	struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+	bcm_tlv_t *owe_info_ie = NULL;
+	s32 bssidx = -1;
+	int ret = BCME_OK;
+
+	if (owe_info->status != DOT11_SC_SUCCESS) {
+		/* may need to pass down unsuccessful status to the firmware */
+		WL_DBG(("Update OWE info failure status %d\n", owe_info->status));
+	} else {
+		owe_info_ie = bcm_parse_tlvs((const u8 *)owe_info->ie, owe_info->ie_len, DOT11_MNG_RSN_ID);
+		if (owe_info_ie)
+			WL_INFORM(("Update OWE info found RSNIE"));
+
+		owe_info_ie = bcm_parse_tlvs((const u8 *)owe_info->ie, owe_info->ie_len, DOT11_MNG_ID_EXT_ID);
+		if (owe_info_ie && DOT11_OWE_DH_PARAM_IE(owe_info_ie))
+			WL_INFORM(("Update OWE info found OWE DH PARAM"));
+
+		bssidx = wl_get_bssidx_by_wdev(cfg, dev->ieee80211_ptr);
+		if (bssidx == WL_INVALID) {
+			WL_DBG(("I/F not available. Do nothing.\n"));
+			return -EINVAL;
+		}
+
+		ret = wl_cfg80211_set_mgmt_vndr_ies(cfg, ndev_to_cfgdev(dev), bssidx,
+				VNDR_IE_ASSOCRSP_FLAG, owe_info->ie, owe_info->ie_len);
+		if (ret) {
+			WL_ERR(("error(%d) updating vndr ies\n", ret));
+		}
+	}
+
+	return ret;
+}
+#endif /* WL_OWE && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfg80211.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfg80211.h
index a8557ed..e5d0bf3 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfg80211.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfg80211.h
@@ -1,9 +1,9 @@
 /*
  * Linux cfg80211 driver
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -100,6 +100,12 @@
 #define IS_AKM_OWE(akm) FALSE
 #endif // endif
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
+#define IS_RADAR_CHAN(flags) (flags & (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_PASSIVE_SCAN))
+#else
+#define IS_RADAR_CHAN(flags) (flags & (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR))
+#endif // endif
+
 #define htod32(i) (i)
 #define htod16(i) (i)
 #define dtoh64(i) (i)
@@ -607,6 +613,18 @@
     TDLS_STATE_NMI_CREATE
 };
 
+#if defined(WL_SELF_MANAGED_REGDOM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
+enum regdom_freq_bands {
+	WL_REGRULE_2G = 0,      /* 1 - 13 */
+	WL_REGRULE_2G_14,       /* 14 */
+	WL_REGRULE_5G_UNII1,    /* 36 - 48 */
+	WL_REGRULE_5G_UNII2A,   /* 52 - 64 */
+	WL_REGRULE_5G_UNII2C,   /* 100 - 144 */
+	WL_REGRULE_5G_UNII3,    /* 149 - 165 */
+	WL_REGRULE_MAX
+};
+#endif /* WL_SELF_MANAGED_REGDOM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) */
+
 /* beacon / probe_response */
 struct beacon_proberesp {
 	__le64 timestamp;
@@ -1231,6 +1249,13 @@
 	const void *data_buf[1]; /* array of user space buffer pointers. */
 } buf_data_t;
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+struct cqm_rssi_info {
+	bool enable;
+	s32 rssi_threshold;
+};
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */
+
 /* private data of cfg80211 interface */
 struct bcm_cfg80211 {
 	struct wireless_dev *wdev;	/* representing cfg cfg80211 device */
@@ -1255,6 +1280,9 @@
 	struct wl_scan_results *bss_list;
 	struct wl_scan_results *scan_results;
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+	struct cqm_rssi_info cqm_info; /* trigger cqm event for rssi based bgscan */
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */
 	/* scan request object for internal purpose */
 	struct wl_scan_req *scan_req_int;
 	/* information element object for internal purpose */
@@ -1538,6 +1566,17 @@
 	CONCURRENCY_RSDB_MODE
 } wl_concurrency_mode_t;
 
+#if defined(WL11AX) || defined(WL_DISABLE_HE_SOFTAP) || defined(WL_DISABLE_HE_P2P)
+typedef struct {
+	uint16 id;
+	uint16 len;
+	uint32 val;
+} he_xtlv_v32;
+
+bool wl_he_get_uint_cb(void *ctx, uint16 *id, uint16 *len);
+void wl_he_pack_uint_cb(void *ctx, uint16 id, uint16 len, uint8 *buf);
+#endif /* WL11AX || WL_DISABLE_HE_SOFTAP || WL_DISABLE_HE_P2P */
+
 s32 wl_iftype_to_mode(wl_iftype_t iftype);
 
 #define BCM_LIST_FOR_EACH_ENTRY_SAFE(pos, next, head, member) \
@@ -2606,7 +2645,7 @@
 extern struct net_device *wl_cfg80211_register_static_if(struct bcm_cfg80211 *cfg,
 	u16 iftype, char *ifname, int ifidx);
 extern void wl_cfg80211_unregister_static_if(struct bcm_cfg80211 * cfg);
-extern s32 wl_cfg80211_static_if_open(struct net_device *net);
+extern s32 wl_cfg80211_static_if_open(struct net_device *net, u8 *mac_addr);
 extern s32 wl_cfg80211_static_if_close(struct net_device *net);
 extern struct net_device * wl_cfg80211_post_static_ifcreate(struct bcm_cfg80211 *cfg,
 	wl_if_event_info *event, u8 *addr, s32 iface_type, const char *iface_name);
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfg_btcoex.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfg_btcoex.c
old mode 100644
new mode 100755
index d364b6b..46d7bef
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfg_btcoex.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfg_btcoex.c
@@ -1,9 +1,9 @@
 /*
  * Linux cfg80211 driver - Dongle Host Driver (DHD) related
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgp2p.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
old mode 100644
new mode 100755
index fa567bc..463e748
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
@@ -1,9 +1,9 @@
 /*
  * Linux cfgp2p driver
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -384,7 +384,11 @@
 wl_cfgp2p_set_firm_p2p(struct bcm_cfg80211 *cfg)
 {
 	struct net_device *ndev = bcmcfg_to_prmry_ndev(cfg);
+#ifdef P2P_RAND
+        struct ether_addr *p2p_dev_addr = wl_to_p2p_bss_macaddr(cfg, P2PAPI_BSSCFG_DEVICE);
+#else
 	struct ether_addr null_eth_addr = { { 0, 0, 0, 0, 0, 0 } };
+#endif /* P2P_RAND */
 	s32 ret = BCME_OK;
 	s32 val = 0;
 	/* Do we have to check whether APSTA is enabled or not ? */
@@ -419,8 +423,14 @@
 	 * After Initializing firmware, we have to set current mac address to
 	 * firmware for P2P device address
 	 */
-	ret = wldev_iovar_setbuf_bsscfg(ndev, "p2p_da_override", &null_eth_addr,
-		sizeof(null_eth_addr), cfg->ioctl_buf, WLC_IOCTL_MAXLEN, 0, &cfg->ioctl_buf_sync);
+#ifdef P2P_RAND
+        //Override default firmware mac setting for p2p dev interface
+	ret = wldev_iovar_setbuf_bsscfg(ndev, "p2p_da_override", p2p_dev_addr,
+		sizeof(*p2p_dev_addr), cfg->ioctl_buf, WLC_IOCTL_MAXLEN, 0, &cfg->ioctl_buf_sync);
+#else
+        ret = wldev_iovar_setbuf_bsscfg(ndev, "p2p_da_override", &null_eth_addr,
+                sizeof(null_eth_addr), cfg->ioctl_buf, WLC_IOCTL_MAXLEN, 0, &cfg->ioctl_buf_sync);
+#endif /* P2P_RAND */
 	if (ret && ret != BCME_UNSUPPORTED) {
 		CFGP2P_ERR(("failed to update device address ret %d\n", ret));
 	}
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgp2p.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgp2p.h
old mode 100644
new mode 100755
index 95be464..9b45d0e
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgp2p.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgp2p.h
@@ -1,9 +1,9 @@
 /*
  * Linux cfgp2p driver
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgscan.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgscan.c
index ba5cc7e..e6e03d4 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgscan.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgscan.c
@@ -1,9 +1,9 @@
 /*
  * Linux cfg80211 driver scan related code
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -717,7 +717,7 @@
 			WL_INFORM_MEM(("ESCAN ABORTED\n"));
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
-			if (p2p_scan(cfg) && cfg->scan_request &&
+			if (p2p_is_on(cfg) && p2p_scan(cfg) && cfg->scan_request &&
 				(cfg->scan_request->flags & NL80211_SCAN_FLAG_FLUSH)) {
 				WL_ERR(("scan list is changed"));
 				cfg->bss_list = wl_escan_get_buf(cfg, FALSE);
@@ -937,11 +937,6 @@
 }
 #endif /* WL_SCAN_TYPE */
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
-#define IS_RADAR_CHAN(flags) (flags & (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_PASSIVE_SCAN))
-#else
-#define IS_RADAR_CHAN(flags) (flags & (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR))
-#endif // endif
 static void
 wl_cfgscan_populate_scan_channels(struct bcm_cfg80211 *cfg, u16 *channel_list,
 	struct cfg80211_scan_request *request, u32 *num_channels)
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgscan.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgscan.h
old mode 100644
new mode 100755
index 2e29cf1..8694a6e
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgscan.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgscan.h
@@ -1,9 +1,9 @@
 /*
  * Header for Linux cfg80211 scan
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgvendor.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgvendor.c
index 3dd8083..26f697d 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgvendor.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgvendor.c
@@ -1,9 +1,9 @@
 /*
  * Linux cfg80211 Vendor Extension Code
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -91,7 +91,12 @@
 #ifdef PROP_TXSTATUS
 #include <dhd_wlfc.h>
 #endif // endif
+#ifdef WL11AX
+#include "wl_twt.h"
+#endif /* WL11AX */
+#include <bcmiov.h>
 #include <brcm_nl80211.h>
+#include <ifx_nl80211.h>
 
 char*
 wl_get_kernel_timestamp(void)
@@ -453,7 +458,11 @@
 wl_cfgvendor_gscan_get_capabilities(struct wiphy *wiphy,
 	struct wireless_dev *wdev, const void  *data, int len)
 {
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+	return -EOPNOTSUPP;
+#else
 	return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
 }
 #endif /* GSCAN_SUPPORT */
 
@@ -1321,7 +1330,11 @@
 static int wl_cfgvendor_set_rssi_monitor(struct wiphy *wiphy,
 	struct wireless_dev *wdev, const void  *data, int len)
 {
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+	return -EOPNOTSUPP;
+#else
 	return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
 }
 #endif /* RSSI_MONITOR_SUPPORT */
 
@@ -1466,7 +1479,11 @@
 wl_cfgvendor_get_wake_reason_stats(struct wiphy *wiphy,
         struct wireless_dev *wdev, const void *data, int len)
 {
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+	return -EOPNOTSUPP;
+#else
 	return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
 }
 #endif /* DHD_WAKE_STATUS */
 
@@ -1536,19 +1553,19 @@
 	return err;
 }
 
-#ifndef CONFIG_SOC_S5E5515
 static int
 wl_cfgvendor_set_random_mac(struct wiphy *wiphy,
 	struct wireless_dev *wdev, const void *data, int len)
 {
-	int err = BCME_OK;
 
 	WL_ERR(("ANDR_WIFI_ATTRIBUTE_RANDOM_MAC is not available\n"));
-	err = BCME_UNSUPPORTED;
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+	return -EOPNOTSUPP;
+#else
+	return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
 
-	return err;
 }
-#endif /* CONFIG_SOC_S5E5515 */
 
 static int
 wl_cfgvendor_set_tx_power_scenario(struct wiphy *wiphy,
@@ -1648,14 +1665,22 @@
 wl_cfgvendor_chavoid_set_config(struct wiphy *wiphy,
 		struct wireless_dev *wdev, const void  *data, int len)
 {
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+	return -EOPNOTSUPP;
+#else
 	return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
 }
 
 static int
 wl_cfgvendor_usable_channel(struct wiphy *wiphy,
 		struct wireless_dev *wdev, const void  *data, int len)
 {
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+	return -EOPNOTSUPP;
+#else
 	return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
 }
 #ifdef RTT_SUPPORT
 void
@@ -6403,7 +6428,11 @@
 static int wl_cfgvendor_lstats_get_info(struct wiphy *wiphy,
 	struct wireless_dev *wdev, const void  *data, int len)
 {
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+	return -EOPNOTSUPP;
+#else
 	return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
 }
 #endif /* LINKSTAT_SUPPORT */
 
@@ -6885,38 +6914,62 @@
 wl_cfgvendor_dbg_trigger_mem_dump(struct wiphy *wiphy,
 		struct wireless_dev *wdev, const void  *data, int len)
 {
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+	return -EOPNOTSUPP;
+#else
 	return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
 }
 
 static int
 wl_cfgvendor_dbg_get_mem_dump(struct wiphy *wiphy,
 		struct wireless_dev *wdev, const void *data, int len)
 {
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+	return -EOPNOTSUPP;
+#else
 	return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
 }
 
 static int wl_cfgvendor_dbg_start_logging(struct wiphy *wiphy,
 	struct wireless_dev *wdev, const void  *data, int len)
 {
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+	return -EOPNOTSUPP;
+#else
 	return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
 }
 
 static int wl_cfgvendor_dbg_reset_logging(struct wiphy *wiphy,
 	struct wireless_dev *wdev, const void  *data, int len)
 {
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+	return -EOPNOTSUPP;
+#else
 	return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
 }
 
 static int wl_cfgvendor_dbg_get_ring_status(struct wiphy *wiphy,
 	struct wireless_dev *wdev, const void  *data, int len)
 {
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+	return -EOPNOTSUPP;
+#else
 	return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
 }
 
 static int wl_cfgvendor_dbg_get_ring_data(struct wiphy *wiphy,
 	struct wireless_dev *wdev, const void  *data, int len)
 {
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+	return -EOPNOTSUPP;
+#else
 	return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
 }
 #endif /* DEBUGABILITY */
 
@@ -7417,6 +7470,127 @@
 	return ret;
 }
 
+#ifdef WL11AX
+static int wl_cfgvendor_priv_muedca_opt_enable(struct wiphy *wiphy,
+                struct wireless_dev *wdev, const void *data, int len)
+{
+	int ret = BCME_OK;
+	uint val = *(uint *)data;
+	struct net_device *dev;
+	uint8 se_he_xtlv[32];
+	bcm_xtlv_t read_he_xtlv_subcmd;
+	int se_he_xtlv_len = sizeof(se_he_xtlv);
+	s32 bssidx = 0;
+	int err = 0;
+	int ioctl_buf[WLC_IOCTL_SMLEN/2] = {0};
+	struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+    read_he_xtlv_subcmd.id = WL_HE_CMD_MUEDCA_OPT;
+    read_he_xtlv_subcmd.len = 0;
+    dev = wdev_to_ndev(wdev);
+
+	if (val == 0xa) {
+		/* To get fw iovars of the form "wl he muedca_opt_enable" using iw,call the
+			parent iovar "he" with the subcmd filled and passed along
+			./iw dev wlan0 vendor recv 0x000319 0xb 0xa */
+		ret = wldev_iovar_getbuf(dev, "he", &read_he_xtlv_subcmd, sizeof(read_he_xtlv_subcmd),
+									ioctl_buf, sizeof(ioctl_buf), NULL);
+		if (ret) {
+			WL_ERR(("Failed : %d\n", ret));
+		} else {
+			WL_DBG(("Get muedca_opt_enable : %d\n", *(int *)ioctl_buf));
+			err =  wl_cfgvendor_send_cmd_reply(wiphy,ioctl_buf, sizeof(int));
+			if (unlikely(err)) {
+				WL_ERR(("Vendor Command reply failed ret:%d \n", err));
+			}
+		}
+	} else {
+		read_he_xtlv_subcmd.len = sizeof(s32);
+		read_he_xtlv_subcmd.data[0] = val;
+		WL_DBG(("Enable muedca"));
+		err = bcm_pack_xtlv_buf((void *)&read_he_xtlv_subcmd, se_he_xtlv, sizeof(se_he_xtlv),
+				BCM_XTLV_OPTION_ALIGN32, wl_he_get_uint_cb, wl_he_pack_uint_cb,
+				&se_he_xtlv_len);
+		if (err) {
+			WL_ERR(("failed to pack he muedca_opt=%d\n", err));
+		} else {
+			/* To set fw iovars of the form "wl he muedca_opt_enable" using iw where
+			   "he" is the parent iovar followed by subcmd
+			   ./iw dev wlan0 vendor send 0x000319 0xb 0x1 */
+			err = wldev_iovar_setbuf_bsscfg(dev, "he", &se_he_xtlv, sizeof(se_he_xtlv),
+					cfg->ioctl_buf, WLC_IOCTL_SMLEN, bssidx, &cfg->ioctl_buf_sync);
+			if (unlikely(err)) {
+				WL_ERR(("failed to set he muedca_opt_enable, error=%d\n", err));
+			}
+		}
+	}
+        return ret;
+}
+#endif /* WL11AX */
+
+static int wl_cfgvendor_priv_ldpc_cap(struct wiphy *wiphy,
+		struct wireless_dev *wdev, const void *data, int len)
+{
+	int ret = BCME_OK;
+	int val = *(int *)data;
+	int get_ldpc_cap = 0;
+	int err = 0;
+	struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+
+	if (val == 0xa) {
+		ret = wldev_iovar_getint(bcmcfg_to_prmry_ndev(cfg), "ldpc_cap", &get_ldpc_cap);
+		if (ret) {
+			WL_ERR(("Failed :  %d\n", ret));
+		} else {
+			WL_DBG(("Get ldpc_cap : %d\n", get_ldpc_cap));
+			err =  wl_cfgvendor_send_cmd_reply(wiphy, &get_ldpc_cap, sizeof(int));
+			if (unlikely(err)) {
+				WL_ERR(("Vendor Command reply failed ret:%d \n", err));
+			}
+		}
+	} else {
+		WL_DBG(("Set ldpc_cap %d\n", val));
+		ret = wldev_iovar_setint(bcmcfg_to_prmry_ndev(cfg), "ldpc_cap", val);
+		if (ret < 0) {
+			WL_ERR(("Failed to set ldpc_cap, ret=%d\n", ret));
+		} else {
+			WL_DBG(("ldpc_cap is %s\n", val ? "enabled" : "disabled"));
+		}
+	}
+	return ret;
+}
+
+static int wl_cfgvendor_priv_amsdu(struct wiphy *wiphy,
+                struct wireless_dev *wdev, const void *data, int len)
+{
+        int ret = BCME_OK;
+        int val = *(int *)data;
+        int get_amsdu = 0;
+        int err = 0;
+        struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+
+        if (val == 0xa) {
+                ret = wldev_iovar_getint(bcmcfg_to_prmry_ndev(cfg), "amsdu", &get_amsdu);
+                if (ret) {
+                        WL_ERR(("Failed :  %d\n", ret));
+                } else {
+                        WL_DBG(("Get amsdu : %d\n", get_amsdu));
+                        err =  wl_cfgvendor_send_cmd_reply(wiphy, &get_amsdu, sizeof(int));
+                        if (unlikely(err)) {
+                                WL_ERR(("Vendor Command reply failed ret:%d \n", err));
+                        }
+                }
+        } else {
+                WL_DBG(("Set amsdu %d\n", val));
+                ret = wldev_iovar_setint(bcmcfg_to_prmry_ndev(cfg), "amsdu", val);
+                if (ret < 0) {
+                        WL_ERR(("Failed to set amsdu, ret=%d\n", ret));
+                } else {
+                        WL_DBG(("amsdu is %s\n", val ? "enabled" : "disabled"));
+                }
+        }
+        return ret;
+}
+
 static int wl_cfgvendor_dbg_get_version(struct wiphy *wiphy,
 	struct wireless_dev *wdev, const void *data, int len)
 {
@@ -7578,19 +7752,31 @@
 static int wl_cfgvendor_dbg_start_pkt_fate_monitoring(struct wiphy *wiphy,
 	struct wireless_dev *wdev, const void *data, int len)
 {
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+	return -EOPNOTSUPP;
+#else
 	return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
 }
 
 static int wl_cfgvendor_dbg_get_tx_pkt_fates(struct wiphy *wiphy,
 	struct wireless_dev *wdev, const void  *data, int len)
 {
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+	return -EOPNOTSUPP;
+#else
 	return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
 }
 
 static int wl_cfgvendor_dbg_get_rx_pkt_fates(struct wiphy *wiphy,
 	struct wireless_dev *wdev, const void  *data, int len)
 {
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+	return -EOPNOTSUPP;
+#else
 	return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
 }
 #endif /* DBG_PKT_MON */
 
@@ -7608,6 +7794,7 @@
 	uint8 src_mac[ETHER_ADDR_LEN];
 	uint8 dst_mac[ETHER_ADDR_LEN];
 	uint32 period_msec = 0;
+	uint16 ether_type = ETHERTYPE_IP;
 	const struct nlattr *iter;
 	struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
 	dhd_pub_t *dhd_pub = cfg->pub;
@@ -7653,6 +7840,15 @@
 			case MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC:
 				period_msec = nla_get_u32(iter);
 				break;
+			case MKEEP_ALIVE_ATTRIBUTE_ETHER_TYPE:
+				ether_type = nla_get_u16(iter);
+				if (!((ether_type == ETHERTYPE_IP) ||
+						(ether_type == ETHERTYPE_IPV6))) {
+					WL_ERR(("Invalid ether type, %2x\n", ether_type));
+					ret = BCME_BADARG;
+					goto exit;
+				}
+				break;
 			default:
 				WL_ERR(("Unknown type: %d\n", type));
 				ret = BCME_BADARG;
@@ -7667,7 +7863,7 @@
 	}
 
 	ret = dhd_dev_start_mkeep_alive(dhd_pub, mkeep_alive_id, ip_pkt, ip_pkt_len, src_mac,
-		dst_mac, period_msec);
+		dst_mac, period_msec, ether_type);
 	if (ret < 0) {
 		WL_ERR(("start_mkeep_alive is failed ret: %d\n", ret));
 	}
@@ -7861,7 +8057,11 @@
 	dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub);
 
 	if (dhdp && !FW_SUPPORTED(dhdp, ndoe)) {
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+		ret = -EOPNOTSUPP;
+#else
 		ret = WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
 		goto exit;
 	}
 
@@ -7890,7 +8090,11 @@
 static int wl_cfgvendor_configure_nd_offload(struct wiphy *wiphy,
 	struct wireless_dev *wdev, const void  *data, int len)
 {
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+	return -EOPNOTSUPP;
+#else
 	return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
 }
 #endif /* NDO_CONFIG_SUPPORT */
 
@@ -7983,18 +8187,83 @@
 	return ret;
 }
 
+#ifdef P2P_RAND
+static int
+wl_cfgvendor_set_p2p_rand_mac(struct wiphy *wiphy,
+		struct wireless_dev *wdev, const void  *data, int len)
+{
+	struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+	int type, err = 0;
+
+        if (!data) {
+                WL_ERR(("%s data is not available\n",__FUNCTION__));
+                return -EINVAL;
+        }
+        if (len <= 0) {
+                WL_ERR(("%s invalid len %d\n",__FUNCTION__, len));
+	        return -EINVAL;
+	}
+	if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE) {
+                WL_ERR(("%s wrong interface type , wdev->iftype=%d\n",__FUNCTION__,wdev->iftype));
+	        return -EINVAL;
+	}
+
+	BCM_REFERENCE(cfg);
+	type = nla_type(data);
+	if (type == BRCM_ATTR_DRIVER_MAC_ADDR || type == IFX_VENDOR_ATTR_MAC_ADDR) {
+		if (nla_len(data) != ETHER_ADDR_LEN) {
+			WL_ERR(("%s nla_len is not ethernet address \n",__FUNCTION__));
+			err = -EINVAL;
+			goto exit;
+		}
+                //setting p2p device address
+		(void)memcpy_s(wl_to_p2p_bss_macaddr(cfg, P2PAPI_BSSCFG_DEVICE), ETHER_ADDR_LEN,
+				nla_data(data), ETHER_ADDR_LEN);
+		(void)memcpy_s(wdev->address, ETHER_ADDR_LEN, nla_data(data), ETHER_ADDR_LEN);
+		err = wl_cfgp2p_disable_discovery(cfg);
+		if (unlikely(err < 0)) {
+			WL_ERR(("%s P2P disable discovery failed, ret=%d\n",__FUNCTION__, err));
+			goto exit;
+		}
+		err = wl_cfgp2p_set_firm_p2p(cfg);
+		if (unlikely(err < 0)) {
+			WL_ERR(("%s Set P2P_da_override failed ret=%d\n",__FUNCTION__, err));
+			goto exit;
+		}
+		err = wl_cfgp2p_enable_discovery(cfg, bcmcfg_to_prmry_ndev(cfg), NULL, 0);
+		if (unlikely(err < 0)) {
+			WL_ERR(("%s P2P enable discovery failed, ret=%d\n",__FUNCTION__, err));
+			goto exit;
+		}
+	} else {
+		WL_ERR(("%s unexpected attrib type:%d\n", __FUNCTION__,type));
+		return -EINVAL;
+	}
+exit:
+	return err;
+}
+#endif /* P2P_RAND */
+
 static int
 wl_cfgvendor_set_multista_primary_connection(struct wiphy *wiphy,
         struct wireless_dev *wdev, const void  *data, int len)
 {
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+	return -EOPNOTSUPP;
+#else
 	return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
 }
 
 static int
 wl_cfgvendor_set_multista_use_case(struct wiphy *wiphy,
         struct wireless_dev *wdev, const void  *data, int len)
 {
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+	return -EOPNOTSUPP;
+#else
 	return WIFI_ERROR_NOT_SUPPORTED;
+#endif // endif
 }
 
 #ifdef WL_SUPPORT_ACS_OFFLOAD
@@ -8442,7 +8711,268 @@
 
 	return ret;
 }
-#endif // endif
+#endif /* WL_SUPPORT_ACS_OFFLOAD */
+
+#ifdef WL11AX
+static void
+wl_cfgvendor_twt_parse_params(const struct nlattr *attr_iter, wl_twt_param_t *twt_param)
+{
+	int tmp, twt_param_attr;
+	const struct nlattr *twt_param_iter;
+
+	nla_for_each_nested(twt_param_iter, attr_iter, tmp) {
+		twt_param_attr = nla_type(twt_param_iter);
+		switch (twt_param_attr) {
+			case IFX_VENDOR_ATTR_TWT_PARAM_NEGO_TYPE:
+				twt_param->negotiation_type = nla_get_u8(twt_param_iter);
+				break;
+			case IFX_VENDOR_ATTR_TWT_PARAM_SETUP_CMD_TYPE:
+				twt_param->setup_cmd = nla_get_u8(twt_param_iter);
+				break;
+			case IFX_VENDOR_ATTR_TWT_PARAM_DIALOG_TOKEN:
+				twt_param->dialog_token = nla_get_u8(twt_param_iter);
+				break;
+			case IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME:
+				twt_param->twt = nla_get_u64(twt_param_iter);
+				break;
+			case IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME_OFFSET:
+				twt_param->twt_offset = nla_get_u64(twt_param_iter);
+				break;
+			case IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION:
+				twt_param->min_twt = nla_get_u8(twt_param_iter);
+				break;
+			case IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_EXPONENT:
+				twt_param->exponent = nla_get_u8(twt_param_iter);
+				break;
+			case IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_MANTISSA:
+				twt_param->mantissa = nla_get_u16(twt_param_iter);
+				break;
+			case IFX_VENDOR_ATTR_TWT_PARAM_REQUESTOR:
+				twt_param->requestor = nla_get_u8(twt_param_iter);
+				break;
+			case IFX_VENDOR_ATTR_TWT_PARAM_TRIGGER:
+				twt_param->trigger = nla_get_u8(twt_param_iter);
+				break;
+			case IFX_VENDOR_ATTR_TWT_PARAM_IMPLICIT:
+				twt_param->implicit = nla_get_u8(twt_param_iter);
+				break;
+			case IFX_VENDOR_ATTR_TWT_PARAM_FLOW_TYPE:
+				twt_param->flow_type = nla_get_u8(twt_param_iter);
+				break;
+			case IFX_VENDOR_ATTR_TWT_PARAM_FLOW_ID:
+				twt_param->flow_id = nla_get_u8(twt_param_iter);
+				break;
+			case IFX_VENDOR_ATTR_TWT_PARAM_BCAST_TWT_ID:
+				twt_param->bcast_twt_id = nla_get_u8(twt_param_iter);
+				break;
+			case IFX_VENDOR_ATTR_TWT_PARAM_PROTECTION:
+				twt_param->protection = nla_get_u8(twt_param_iter);
+				break;
+			case IFX_VENDOR_ATTR_TWT_PARAM_CHANNEL:
+				twt_param->twt_channel = nla_get_u8(twt_param_iter);
+				break;
+			case IFX_VENDOR_ATTR_TWT_PARAM_TWT_INFO_FRAME_DISABLED:
+				twt_param->twt_info_frame_disabled =
+					nla_get_u8(twt_param_iter);
+				break;
+			case IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION_UNIT:
+				twt_param->min_twt_unit = nla_get_u8(twt_param_iter);
+				break;
+			case IFX_VENDOR_ATTR_TWT_PARAM_TEARDOWN_ALL_TWT:
+				twt_param->teardown_all_twt =
+					nla_get_u8(twt_param_iter);
+				break;
+			default:
+				WL_INFORM(("Unknown TWT param, skipping"));
+				break;
+		}
+	}
+}
+
+int wl_cfgvendor_twt(struct wiphy *wiphy, struct wireless_dev *wdev,
+		     const void  *data, int len)
+{
+	int tmp, attr_type;
+	const struct nlattr *attr_iter;
+	struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+	struct net_device *pri_ndev = bcmcfg_to_prmry_ndev(cfg);
+
+	wl_twt_param_t twt_param = {
+		.twt_oper = 0,
+		.negotiation_type = IFX_TWT_PARAM_NEGO_TYPE_ITWT,
+		.setup_cmd = IFX_TWT_OPER_SETUP_CMD_TYPE_REQUEST,
+		.dialog_token = 1,
+		.twt = 0,
+		.twt_offset = 0,
+		.requestor = 1,
+		.trigger = 0,
+		.implicit = 1,
+		.flow_type = 0,
+		.flow_id = 0,
+		.bcast_twt_id = 0,
+		.protection = 0,
+		.twt_channel = 0,
+		.twt_info_frame_disabled = 0,
+		.min_twt_unit = 0,
+		.teardown_all_twt = 0
+	};
+
+	nla_for_each_attr(attr_iter, data, len, tmp) {
+		attr_type = nla_type(attr_iter);
+
+		switch (attr_type) {
+			case IFX_VENDOR_ATTR_TWT_OPER:
+				twt_param.twt_oper = nla_get_u8(attr_iter);
+				break;
+			case IFX_VENDOR_ATTR_TWT_PARAMS:
+				wl_cfgvendor_twt_parse_params(attr_iter, &twt_param);
+				break;
+			default:
+				WL_INFORM(("Unknown TWT attribute %d, skipping",
+					   attr_type));
+				break;
+		}
+	}
+
+	return wl_twt_oper(pri_ndev, wdev, twt_param);
+}
+
+#endif /* WL11AX */
+
+static int wl_cfgvendor_oce_enable(struct wiphy *wiphy,
+		struct wireless_dev *wdev, const void *data, int len)
+{
+	int ret = BCME_OK;
+	uint8 val = *(uint8 *)data;
+	struct net_device *dev;
+	s32 bssidx = 0;
+	int err = 0;
+	uint8 oce_xtlv[WLC_IOCTL_SMLEN] = {0};
+	bcm_iov_buf_t iov_buf_data, *iov_buf = NULL;
+	struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+	dev = wdev_to_ndev(wdev);
+
+	if (val == 0xa) {
+		bcm_xtlv_t *pxtlv_recv = NULL;
+		iov_buf_data.version = WL_OCE_IOV_VERSION;
+		iov_buf_data.id = WL_OCE_CMD_ENABLE;
+
+		/* To get fw iovars of the form "wl oce enable" using iw,call the
+		 * parent iovar "oce" with the subcmd filled and passed along
+		 * ./iw dev wlan0 vendor recv 0x000319 0xf 0xa */
+		ret = wldev_iovar_getbuf(dev, "oce", &iov_buf_data, sizeof(iov_buf_data),
+				oce_xtlv, sizeof(oce_xtlv), NULL);
+
+		if (ret) {
+			WL_ERR(("Failed to get oce enable: %d\n", ret));
+		} else {
+			iov_buf = (bcm_iov_buf_t *)oce_xtlv;
+			pxtlv_recv = (bcm_xtlv_t *)((uint8 *)iov_buf->data);
+			WL_DBG(("Get oce_enable : %d\n", pxtlv_recv->data[0]));
+			err = wl_cfgvendor_send_cmd_reply(wiphy, &pxtlv_recv->data[0], sizeof(int));
+			if (unlikely(err)) {
+				WL_ERR(("Vendor Command reply failed ret:%d \n", err));
+				return err;
+			}
+		}
+	} else {
+		uint8 *pxtlv_data = NULL;
+		uint16 buflen = 0, buflen_start = 0, iovlen = 0;
+		iov_buf = (bcm_iov_buf_t *)oce_xtlv;
+		iov_buf->version = WL_OCE_IOV_VERSION;
+		iov_buf->id = WL_OCE_CMD_ENABLE;
+		pxtlv_data = (uint8 *)&iov_buf->data[0];
+		buflen = buflen_start = WLC_IOCTL_SMLEN - sizeof(bcm_iov_buf_t);
+
+		ret = bcm_pack_xtlv_entry(&pxtlv_data, &buflen, WL_OCE_XTLV_ENABLE,
+				sizeof(val), &val, BCM_XTLV_OPTION_ALIGN32);
+		if (ret != BCME_OK) {
+			WL_ERR(("Failed to enable oce: %d\n", ret));
+		} else {
+			iov_buf->len = buflen_start - buflen;
+			iovlen = sizeof(bcm_iov_buf_t) + iov_buf->len;
+
+			/* To set fw iovars of the form "wl oce enable 1" using iw,call the
+			 * parent iovar "oce" with the subcmd filled and passed along
+			 * ./iw dev wlan0 vendor recv 0x000319 0xf 0x1 */
+			err = wldev_iovar_setbuf_bsscfg(dev, "oce", (void *)iov_buf, iovlen,
+					cfg->ioctl_buf, WLC_IOCTL_SMLEN, bssidx, &cfg->ioctl_buf_sync);
+			if (unlikely(err)) {
+                                WL_ERR(("Failed to set oce enable, error=:%d\n", err));
+                                return err;
+                        }
+		}
+	}
+	return ret;
+}
+
+static int wl_cfgvendor_randmac(struct wiphy *wiphy,
+              struct wireless_dev *wdev, const void *data, int len)
+{
+        int ret = BCME_OK;
+	wl_randmac_t *iov_buf = NULL;
+        uint8 val = *(uint8 *)data;
+        struct net_device *dev;
+        s32 bssidx = 0;
+        int err = 0;
+        uint8 randmac_xtlv[WLC_IOCTL_SMLEN] = {0};
+        struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+        dev = wdev_to_ndev(wdev);
+
+	iov_buf = (wl_randmac_t *)randmac_xtlv;
+        iov_buf->version = WL_RANDMAC_API_VERSION;
+        iov_buf->subcmd_id = WL_RANDMAC_SUBCMD_ENABLE;
+        iov_buf->len = WL_RANDMAC_IOV_HDR_SIZE;
+
+        if (val == 0x1) {
+                /* To set fw iovars of the form "wl randmac enable" using iw,call the
+                 * parent iovar "randmac" with the subcmd filled and passed along
+                 * ./iw dev wlan0 vendor send 0x000319 0x11 0x1 */
+		ret = wldev_iovar_setbuf_bsscfg(dev, "randmac", (void *)iov_buf, iov_buf->len,
+                                        cfg->ioctl_buf, WLC_IOCTL_SMLEN, bssidx, &cfg->ioctl_buf_sync);
+                if (ret) {
+                        WL_ERR(("Failed to set randmac enable: %d\n", ret));
+			return ret;
+                }
+        } else if (val == 0x0) {
+		iov_buf->subcmd_id = WL_RANDMAC_SUBCMD_DISABLE;
+
+                /* To set fw iovars of the form "wl randmac disable" using iw,call the
+                 * parent iovar "randmac" with the subcmd filled and passed along
+                 * ./iw dev wlan0 vendor send 0x000319 0x11 0x0 */
+		ret = wldev_iovar_setbuf_bsscfg(dev, "randmac", (void *)iov_buf, iov_buf->len,
+					cfg->ioctl_buf, WLC_IOCTL_SMLEN, bssidx, &cfg->ioctl_buf_sync);
+		if (ret) {
+                        WL_ERR(("Failed to set randmac disable: %d\n", ret));
+			return ret;
+                }
+        } else if (val == 0xa) {
+		int result_data = 0;
+		wl_randmac_t *iov_resp = NULL;
+		uint8 resp_xtlv[WLC_IOCTL_SMLEN] = {0};
+
+                /* To get fw iovars of the form "wl randmac" using iw,call the
+                 * parent iovar "randmac" with the subcmd filled and passed along
+                 * ./iw dev wlan0 vendor recv 0x000319 0x11 0xa */
+                ret = wldev_iovar_getbuf(dev, "randmac", (void *)iov_buf, iov_buf->len,
+                                resp_xtlv, sizeof(resp_xtlv), NULL);
+                if (ret) {
+                        WL_ERR(("Failed to get randmac enable or disable: %d\n", ret));
+			return ret;
+                } else {
+			iov_resp = (wl_randmac_t *)resp_xtlv;
+			if(iov_resp->subcmd_id == WL_RANDMAC_SUBCMD_ENABLE) {
+				result_data = 1;
+			}
+			err = wl_cfgvendor_send_cmd_reply(wiphy, &result_data, sizeof(int));
+			if (unlikely(err)) {
+				WL_ERR(("Vendor Command reply failed ret:%d \n", err));
+				return err;
+			}
+                }
+	}
+        return ret;
+}
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
 #define WL_VENDOR_POLICY_RAW_DATA .policy = VENDOR_CMD_RAW_DATA
@@ -8450,6 +8980,7 @@
 const struct nla_policy brcm_drv_attr_policy[BRCM_ATTR_DRIVER_MAX] = {
 	[BRCM_ATTR_DRIVER_CMD] = {.type = NLA_NUL_STRING},
 	[BRCM_ATTR_DRIVER_KEY_PMK] = {.type = NLA_BINARY},
+	[BRCM_ATTR_DRIVER_MAC_ADDR] = { .type = NLA_BINARY, .len = ETHER_ADDR_LEN },
 };
 
 const struct nla_policy andr_wifi_attr_policy[ANDR_WIFI_ATTRIBUTE_MAX] = {
@@ -8535,6 +9066,52 @@
 	[DEBUG_ATTRIBUTE_HANG_REASON] = {.type = NLA_BINARY},
 };
 
+#ifdef DHD_LOG_DUMP
+const struct nla_policy google_file_dump_event_policy[DUMP_EVENT_ATTR_MAX] = {
+	[DUMP_LEN_ATTR_MEMDUMP]							= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_SSSR_C0_D11_BEFORE]				= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_SSSR_C0_D11_AFTER]				= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_SSSR_C1_D11_BEFORE]				= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_SSSR_C1_D11_AFTER]				= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_SSSR_C2_D11_BEFORE]				= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_SSSR_C2_D11_AFTER]				= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_SSSR_DIG_BEFORE]					= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_SSSR_DIG_AFTER]					= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_TIMESTAMP]						= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_GENERAL_LOG]						= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_ECNTRS]							= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_SPECIAL_LOG]						= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_DHD_DUMP]						= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_EXT_TRAP]						= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_HEALTH_CHK]						= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_PRESERVE_LOG]					= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_COOKIE]							= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_FLOWRING_DUMP]					= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_PKTLOG]							= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_PKTLOG_DEBUG]					= {.type = NLA_BINARY},
+	[DUMP_FILENAME_ATTR_DEBUG_DUMP]					= {.type = NLA_BINARY},
+	[DUMP_FILENAME_ATTR_MEM_DUMP]					= {.type = NLA_BINARY},
+	[DUMP_FILENAME_ATTR_SSSR_CORE_0_BEFORE_DUMP]	= {.type = NLA_BINARY},
+	[DUMP_FILENAME_ATTR_SSSR_CORE_0_AFTER_DUMP]		= {.type = NLA_BINARY},
+	[DUMP_FILENAME_ATTR_SSSR_CORE_1_BEFORE_DUMP]	= {.type = NLA_BINARY},
+	[DUMP_FILENAME_ATTR_SSSR_CORE_1_AFTER_DUMP]		= {.type = NLA_BINARY},
+	[DUMP_FILENAME_ATTR_SSSR_CORE_2_BEFORE_DUMP]	= {.type = NLA_BINARY},
+	[DUMP_FILENAME_ATTR_SSSR_CORE_2_AFTER_DUMP]		= {.type = NLA_BINARY},
+	[DUMP_FILENAME_ATTR_SSSR_DIG_BEFORE_DUMP]		= {.type = NLA_BINARY},
+	[DUMP_FILENAME_ATTR_SSSR_DIG_AFTER_DUMP]		= {.type = NLA_BINARY},
+	[DUMP_FILENAME_ATTR_PKTLOG_DUMP]				= {.type = NLA_BINARY},
+	[DUMP_FILENAME_ATTR_PKTLOG_DEBUG_DUMP]			= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_STATUS_LOG]						= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_AXI_ERROR]						= {.type = NLA_BINARY},
+	[DUMP_FILENAME_ATTR_AXI_ERROR_DUMP]				= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_RTT_LOG]							= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_SDTC_ETB_DUMP]					= {.type = NLA_BINARY},
+	[DUMP_FILENAME_ATTR_SDTC_ETB_DUMP]				= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_PKTID_MAP_LOG]					= {.type = NLA_BINARY},
+	[DUMP_LEN_ATTR_PKTID_UNMAP_LOG]					= {.type = NLA_BINARY}
+};
+#endif /* DHD_LOG_DUMP */
+
 const struct nla_policy hal_start_attr_policy[SET_HAL_START_ATTRIBUTE_MAX] = {
 	[SET_HAL_START_ATTRIBUTE_DEINIT] = {.type = NLA_UNSPEC},
 	[SET_HAL_START_ATTRIBUTE_PRE_INIT] = {.type = NLA_NUL_STRING},
@@ -8601,6 +9178,45 @@
 #define WL_VENDOR_POLICY_RAW_DATA
 #endif /* LINUX_VER >= 5.3 */
 
+#ifdef WL11AX
+const struct nla_policy
+ifx_vendor_attr_twt_param_policy[IFX_VENDOR_ATTR_TWT_PARAM_MAX + 1] = {
+	[IFX_VENDOR_ATTR_TWT_PARAM_UNSPEC] = {.type = NLA_U8},
+	[IFX_VENDOR_ATTR_TWT_PARAM_NEGO_TYPE] = {.type = NLA_U8},
+	[IFX_VENDOR_ATTR_TWT_PARAM_SETUP_CMD_TYPE] = {.type = NLA_U8},
+	[IFX_VENDOR_ATTR_TWT_PARAM_DIALOG_TOKEN] = {.type = NLA_U8},
+	[IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME] = {.type = NLA_U64},
+	[IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME_OFFSET] = {.type = NLA_U64},
+	[IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION] = {.type = NLA_U8},
+	[IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_EXPONENT] = {.type = NLA_U8},
+	[IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_MANTISSA] = {.type = NLA_U16},
+	[IFX_VENDOR_ATTR_TWT_PARAM_REQUESTOR] = {.type = NLA_U8},
+	[IFX_VENDOR_ATTR_TWT_PARAM_TRIGGER] = {.type = NLA_U8},
+	[IFX_VENDOR_ATTR_TWT_PARAM_IMPLICIT] = {.type = NLA_U8},
+	[IFX_VENDOR_ATTR_TWT_PARAM_FLOW_TYPE] = {.type = NLA_U8},
+	[IFX_VENDOR_ATTR_TWT_PARAM_FLOW_ID] = {.type = NLA_U8},
+	[IFX_VENDOR_ATTR_TWT_PARAM_BCAST_TWT_ID] = {.type = NLA_U8},
+	[IFX_VENDOR_ATTR_TWT_PARAM_PROTECTION] = {.type = NLA_U8},
+	[IFX_VENDOR_ATTR_TWT_PARAM_CHANNEL] = {.type = NLA_U8},
+	[IFX_VENDOR_ATTR_TWT_PARAM_TWT_INFO_FRAME_DISABLED] = {.type = NLA_U8},
+	[IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION_UNIT] = {.type = NLA_U8},
+	[IFX_VENDOR_ATTR_TWT_PARAM_TEARDOWN_ALL_TWT] = {.type = NLA_U8},
+	[IFX_VENDOR_ATTR_TWT_PARAM_MAX] = {.type = NLA_U8},
+};
+
+const struct nla_policy ifx_vendor_attr_twt_policy[IFX_VENDOR_ATTR_TWT_MAX + 1] = {
+	[IFX_VENDOR_ATTR_TWT_UNSPEC] = {.type = NLA_U8},
+	[IFX_VENDOR_ATTR_TWT_OPER] = {.type = NLA_U8},
+	[IFX_VENDOR_ATTR_TWT_PARAMS] =
+		NLA_POLICY_NESTED(ifx_vendor_attr_twt_param_policy),
+	[IFX_VENDOR_ATTR_TWT_MAX] = {.type = NLA_U8},
+};
+#endif /* WL11AX */
+
+const struct nla_policy ifx_vendor_attr_policy[IFX_VENDOR_ATTR_MAX + 1] = {
+	[IFX_VENDOR_ATTR_MAC_ADDR] = {.type = NLA_BINARY, .len = ETHER_ADDR_LEN},
+};
+
 static const struct wiphy_vendor_command wl_vendor_cmds [] = {
 	{
 		{
@@ -8669,6 +9285,33 @@
 #endif // endif
 	},
 #endif /* WL_SAE */
+#ifdef P2P_RAND
+	{
+		{
+			.vendor_id = OUI_BRCM,
+			.subcmd = BRCM_VENDOR_SCMD_SET_MAC
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV,
+		.doit = wl_cfgvendor_set_p2p_rand_mac,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = brcm_drv_attr_policy,
+		.maxattr = BRCM_ATTR_DRIVER_MAX
+#endif /* LINUX_VERSION >= 5.3 */
+	},
+
+	{
+                {
+                        .vendor_id = OUI_IFX,
+                        .subcmd = IFX_VENDOR_SCMD_SET_P2P_RAND_MAC
+                },
+                .flags = WIPHY_VENDOR_CMD_NEED_WDEV,
+                .doit = wl_cfgvendor_set_p2p_rand_mac,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+                .policy = ifx_vendor_attr_policy,
+                .maxattr = IFX_VENDOR_ATTR_MAX
+#endif /* LINUX_VERSION >= 5.3 */
+        },
+#endif /* P2P_RAND */
 	{
 		{
 			.vendor_id = OUI_GOOGLE,
@@ -8988,7 +9631,12 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_dbg_file_dump,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = google_file_dump_event_policy,
+		.maxattr = DUMP_EVENT_ATTR_MAX
+#else
 		WL_VENDOR_POLICY_RAW_DATA
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) */
 	},
 #endif /* DHD_LOG_DUMP */
 	{
@@ -9108,7 +9756,12 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_start_mkeep_alive,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = mkeep_alive_attr_policy,
+		.maxattr = MKEEP_ALIVE_ATTRIBUTE_MAX
+#else
 		WL_VENDOR_POLICY_RAW_DATA
+#endif  /* (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) */
 	},
 	{
 		{
@@ -9117,7 +9770,12 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_stop_mkeep_alive,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+                .policy = mkeep_alive_attr_policy,
+                .maxattr = MKEEP_ALIVE_ATTRIBUTE_MAX
+#else
 		WL_VENDOR_POLICY_RAW_DATA
+#endif  /* (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) */
 	},
 #endif /* KEEP_ALIVE */
 #ifdef WL_NAN
@@ -9490,8 +10148,77 @@
 		.maxattr = BRCM_VENDOR_ATTR_ACS_LAST
 #endif /* LINUX_VERSION >= 5.3 */
 	},
+#endif /* WL_SUPPORT_ACS_OFFLOAD */
+	{
+		{
+			.vendor_id = OUI_IFX,
+			.subcmd = IFX_VENDOR_SCMD_FRAMEBURST
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = wl_cfgvendor_priv_frameburst,
+		WL_VENDOR_POLICY_RAW_DATA
+	},
+#ifdef WL11AX
+        {
+                {
+                        .vendor_id = OUI_IFX,
+                        .subcmd = IFX_VENDOR_SCMD_MUEDCA_OPT_ENABLE
+                },
+                .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+                .doit = wl_cfgvendor_priv_muedca_opt_enable,
+                WL_VENDOR_POLICY_RAW_DATA
+        },
+#endif /* WL11AX */
+	{
+                {
+                        .vendor_id = OUI_IFX,
+                        .subcmd = IFX_VENDOR_SCMD_LDPC_CAP
+                },
+                .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+                .doit = wl_cfgvendor_priv_ldpc_cap,
+                WL_VENDOR_POLICY_RAW_DATA
+        },
+	{
+                {
+                        .vendor_id = OUI_IFX,
+                        .subcmd = IFX_VENDOR_SCMD_AMSDU
+                },
+                .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+                .doit = wl_cfgvendor_priv_amsdu,
+                WL_VENDOR_POLICY_RAW_DATA
+        },
+#ifdef WL11AX
+	{
+		{
+			.vendor_id = OUI_IFX,
+			.subcmd = IFX_VENDOR_SCMD_TWT
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = wl_cfgvendor_twt,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = ifx_vendor_attr_twt_policy,
+		.maxattr = IFX_VENDOR_ATTR_TWT_MAX
 #endif // endif
-
+	},
+#endif /* WL11AX */
+        {
+                {
+                        .vendor_id = OUI_IFX,
+                        .subcmd = IFX_VENDOR_SCMD_OCE_ENABLE
+                },
+                .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+                .doit = wl_cfgvendor_oce_enable,
+                WL_VENDOR_POLICY_RAW_DATA
+        },
+	{
+                {
+                        .vendor_id = OUI_IFX,
+                        .subcmd = IFX_VENDOR_SCMD_RANDMAC
+                },
+                .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+                .doit = wl_cfgvendor_randmac,
+                WL_VENDOR_POLICY_RAW_DATA
+        },
 };
 
 static const struct  nl80211_vendor_cmd_info wl_vendor_events [] = {
@@ -9539,13 +10266,14 @@
 		{ OUI_BRCM, BRCM_VENDOR_EVENT_RCC_INFO},
 		{ OUI_BRCM, BRCM_VENDOR_EVENT_ACS},
 		{ OUI_BRCM, BRCM_VENDOR_EVENT_OVERTEMP},
+		{ OUI_IFX, IFX_VENDOR_SCMD_TWT},
 };
 
 int wl_cfgvendor_attach(struct wiphy *wiphy, dhd_pub_t *dhd)
 {
 
-	WL_INFORM_MEM(("Vendor: Register BRCM cfg80211 vendor cmd(0x%x) interface \n",
-		NL80211_CMD_VENDOR));
+	WL_INFORM_MEM(("Vendor: Register BRCM,GOOGLE,IFX cfg80211 vendor cmd(0x%x) interface \n",
+		       NL80211_CMD_VENDOR));
 
 	wiphy->vendor_commands	= wl_vendor_cmds;
 	wiphy->n_vendor_commands = ARRAY_SIZE(wl_vendor_cmds);
@@ -9560,6 +10288,8 @@
 	dhd_os_dbg_register_urgent_notifier(dhd, wl_cfgvendor_dbg_send_file_dump_evt);
 #endif /* DHD_LOG_DUMP */
 
+	BCM_REFERENCE(wl_cfgvendor_set_random_mac);
+
 	return 0;
 }
 
@@ -9568,7 +10298,7 @@
 #ifdef WL_SUPPORT_ACS_OFFLOAD
 	struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
 #endif // endif
-	WL_INFORM_MEM(("Vendor: Unregister BRCM cfg80211 vendor interface \n"));
+	WL_INFORM_MEM(("Vendor: Unregister BRCM,GOOGLE,IFX cfg80211 vendor interface \n"));
 
 	wiphy->vendor_commands  = NULL;
 	wiphy->vendor_events    = NULL;
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgvendor.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgvendor.h
index c275efa..1dafa23 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgvendor.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_cfgvendor.h
@@ -1,9 +1,9 @@
 /*
  * Linux cfg80211 Vendor Extension Code
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -39,12 +39,15 @@
 #define VENDOR_ID_OVERHEAD                 ATTRIBUTE_U32_LEN
 #define VENDOR_SUBCMD_OVERHEAD             ATTRIBUTE_U32_LEN
 #define VENDOR_DATA_OVERHEAD               (NLA_HDRLEN)
+#define ETHERTYPE_IP            0x0800          /* IP */
+#define ETHERTYPE_IPV6          0x86dd          /* IP protocol version 6 */
 
 enum brcm_vendor_attr {
 	BRCM_ATTR_DRIVER_CMD		= 0,
 	BRCM_ATTR_DRIVER_KEY_PMK	= 1,
 	BRCM_ATTR_DRIVER_FEATURE_FLAGS	= 2,
-	BRCM_ATTR_DRIVER_MAX		= 3
+	BRCM_ATTR_DRIVER_MAC_ADDR       = 3,
+	BRCM_ATTR_DRIVER_MAX		= 4
 };
 
 enum brcm_wlan_vendor_features {
@@ -235,7 +238,10 @@
 	DEBUG_SET_HAL_START,
 	DEBUG_SET_HAL_STOP,
 	DEBUG_SET_HAL_PID,
-
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 13)
+	DEBUG_SET_TPUT_DEBUG_DUMP_CMD,
+	DEBUG_GET_BUF_RING_MAP,
+#endif // endif
 	WIFI_OFFLOAD_SUBCMD_START_MKEEP_ALIVE = ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START,
 	WIFI_OFFLOAD_SUBCMD_STOP_MKEEP_ALIVE,
 
@@ -422,6 +428,9 @@
 };
 
 enum rtt_attributes {
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 12)
+	RTT_ATTRIBUTE_TARGET_INVALID,
+#endif // endif
 	RTT_ATTRIBUTE_TARGET_CNT,
 	RTT_ATTRIBUTE_TARGET_INFO,
 	RTT_ATTRIBUTE_TARGET_MAC,
@@ -446,7 +455,7 @@
 };
 
 enum wifi_rssi_monitor_attr {
-#ifdef ANDROID12_SUPPORT
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 12)
 	RSSI_MONITOR_ATTRIBUTE_INVALID,
 #endif // endif
 	RSSI_MONITOR_ATTRIBUTE_MAX_RSSI,
@@ -462,7 +471,7 @@
 };
 
 enum debug_attributes {
-#ifdef ANDROID12_SUPPORT
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 12)
 	DEBUG_ATTRIBUTE_INVALID,
 #endif // endif
 	DEBUG_ATTRIBUTE_GET_DRIVER,
@@ -495,6 +504,8 @@
 	DUMP_LEN_ATTR_SSSR_C0_D11_AFTER,
 	DUMP_LEN_ATTR_SSSR_C1_D11_BEFORE,
 	DUMP_LEN_ATTR_SSSR_C1_D11_AFTER,
+	DUMP_LEN_ATTR_SSSR_C2_D11_BEFORE,
+	DUMP_LEN_ATTR_SSSR_C2_D11_AFTER,
 	DUMP_LEN_ATTR_SSSR_DIG_BEFORE,
 	DUMP_LEN_ATTR_SSSR_DIG_AFTER,
 	DUMP_LEN_ATTR_TIMESTAMP,
@@ -508,19 +519,29 @@
 	DUMP_LEN_ATTR_COOKIE,
 	DUMP_LEN_ATTR_FLOWRING_DUMP,
 	DUMP_LEN_ATTR_PKTLOG,
+	DUMP_LEN_ATTR_PKTLOG_DEBUG,
 	DUMP_FILENAME_ATTR_DEBUG_DUMP,
 	DUMP_FILENAME_ATTR_MEM_DUMP,
 	DUMP_FILENAME_ATTR_SSSR_CORE_0_BEFORE_DUMP,
 	DUMP_FILENAME_ATTR_SSSR_CORE_0_AFTER_DUMP,
 	DUMP_FILENAME_ATTR_SSSR_CORE_1_BEFORE_DUMP,
 	DUMP_FILENAME_ATTR_SSSR_CORE_1_AFTER_DUMP,
+	DUMP_FILENAME_ATTR_SSSR_CORE_2_BEFORE_DUMP,
+	DUMP_FILENAME_ATTR_SSSR_CORE_2_AFTER_DUMP,
 	DUMP_FILENAME_ATTR_SSSR_DIG_BEFORE_DUMP,
 	DUMP_FILENAME_ATTR_SSSR_DIG_AFTER_DUMP,
 	DUMP_FILENAME_ATTR_PKTLOG_DUMP,
+	DUMP_FILENAME_ATTR_PKTLOG_DEBUG_DUMP,
 	DUMP_LEN_ATTR_STATUS_LOG,
 	DUMP_LEN_ATTR_AXI_ERROR,
 	DUMP_FILENAME_ATTR_AXI_ERROR_DUMP,
-	DUMP_LEN_ATTR_RTT_LOG
+	DUMP_LEN_ATTR_RTT_LOG,
+	DUMP_LEN_ATTR_SDTC_ETB_DUMP,
+	DUMP_FILENAME_ATTR_SDTC_ETB_DUMP,
+	DUMP_LEN_ATTR_PKTID_MAP_LOG,
+	DUMP_LEN_ATTR_PKTID_UNMAP_LOG,
+	/*  Please add new attributes from here to sync up old DHD */
+	DUMP_EVENT_ATTR_MAX
 } EWP_DUMP_EVENT_ATTRIBUTE;
 
 /* Attributes associated with DEBUG_GET_DUMP_BUF */
@@ -531,6 +552,8 @@
 	DUMP_BUF_ATTR_SSSR_C0_D11_AFTER,
 	DUMP_BUF_ATTR_SSSR_C1_D11_BEFORE,
 	DUMP_BUF_ATTR_SSSR_C1_D11_AFTER,
+	DUMP_BUF_ATTR_SSSR_C2_D11_BEFORE,
+	DUMP_BUF_ATTR_SSSR_C2_D11_AFTER,
 	DUMP_BUF_ATTR_SSSR_DIG_BEFORE,
 	DUMP_BUF_ATTR_SSSR_DIG_AFTER,
 	DUMP_BUF_ATTR_TIMESTAMP,
@@ -544,13 +567,19 @@
 	DUMP_BUF_ATTR_COOKIE,
 	DUMP_BUF_ATTR_FLOWRING_DUMP,
 	DUMP_BUF_ATTR_PKTLOG,
+	DUMP_BUF_ATTR_PKTLOG_DEBUG,
 	DUMP_BUF_ATTR_STATUS_LOG,
 	DUMP_BUF_ATTR_AXI_ERROR,
-	DUMP_BUF_ATTR_RTT_LOG
+	DUMP_BUF_ATTR_RTT_LOG,
+	DUMP_BUF_ATTR_SDTC_ETB_DUMP,
+	DUMP_BUF_ATTR_PKTID_MAP_LOG,
+	DUMP_BUF_ATTR_PKTID_UNMAP_LOG,
+	/*  Please add new attributes from here to sync up old DHD */
+	DUMP_BUF_ATTR_MAX
 } EWP_DUMP_CMD_ATTRIBUTE;
 
 enum mkeep_alive_attributes {
-#ifdef ANDROID12_SUPPORT
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 12)
 	MKEEP_ALIVE_ATTRIBUTE_INVALID,
 #endif // endif
 	MKEEP_ALIVE_ATTRIBUTE_ID,
@@ -618,7 +647,7 @@
 } wl_vendor_event_t;
 
 enum andr_wifi_attr {
-#ifdef ANDROID12_SUPPORT
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 12)
 	ANDR_WIFI_ATTRIBUTE_INVALID,
 #endif // endif
 	ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET,
@@ -676,7 +705,7 @@
 
 #ifdef DHD_WAKE_STATUS
 enum wake_stat_attributes {
-#ifdef ANDROID12_SUPPORT
+#if defined(CONFIG_ANDROID_VERSION) && (CONFIG_ANDROID_VERSION >= 12)
 	WAKE_STAT_ATTRIBUTE_INVALID,
 #endif // endif
 	WAKE_STAT_ATTRIBUTE_TOTAL_CMD_EVENT,
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_dbg.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_dbg.h
old mode 100644
new mode 100755
index 56fa7ad..3e61e82
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_dbg.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_dbg.h
@@ -2,9 +2,9 @@
  * Minimal debug/trace/assert driver definitions for
  * Broadcom 802.11 Networking Adapter.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_iw.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_iw.c
index c16478f..cd5e759 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_iw.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_iw.c
@@ -1,9 +1,9 @@
 /*
  * Linux Wireless Extensions support
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_linux_mon.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_linux_mon.c
old mode 100644
new mode 100755
index 643bfe4..13d1a86
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_linux_mon.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_linux_mon.c
@@ -1,9 +1,9 @@
 /*
  * Broadcom Dongle Host Driver (DHD), Linux monitor network interface
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_roam.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_roam.c
index e3be4aa..5a95976 100755
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_roam.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_roam.c
@@ -1,9 +1,9 @@
 /*
  * Linux roam cache
  *
- * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_twt.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_twt.c
new file mode 100755
index 0000000..e0438d3
--- /dev/null
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_twt.c
@@ -0,0 +1,754 @@
+/*
+ * Target Wake Time Module which is responsible for acting as an
+ * interface between the userspace and firmware.
+ *
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation,
+ * an Infineon company
+ *
+ * This program is the proprietary software of infineon and/or
+ * its licensors, and may only be used, duplicated, modified or distributed
+ * pursuant to the terms and conditions of a separate, written license
+ * agreement executed between you and infineon (an "Authorized License").
+ * Except as set forth in an Authorized License, infineon grants no license
+ * (express or implied), right to use, or waiver of any kind with respect to
+ * the Software, and infineon expressly reserves all rights in and to the
+ * Software and all intellectual property rights therein.  IF YOU HAVE NO
+ * AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY
+ * WAY, AND SHOULD IMMEDIATELY NOTIFY INFINEON AND DISCONTINUE ALL USE OF
+ * THE SOFTWARE.
+ *
+ * Except as expressly set forth in the Authorized License,
+ *
+ * 1. This program, including its structure, sequence and organization,
+ * constitutes the valuable trade secrets of infineon, and you shall use
+ * all reasonable efforts to protect the confidentiality thereof, and to
+ * use this information only in connection with your use of infineon
+ * integrated circuit products.
+ *
+ * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED
+ * "AS IS" AND WITH ALL FAULTS AND INFINEON MAKES NO PROMISES,
+ * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR
+ * OTHERWISE, WITH RESPECT TO THE SOFTWARE.  INFINEON SPECIFICALLY
+ * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+ * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+ * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+ * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING
+ * OUT OF USE OR PERFORMANCE OF THE SOFTWARE.
+ *
+ * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL
+ * INFINEON OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL,
+ * SPECIAL, INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR
+ * IN ANY WAY RELATING TO YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN
+ * IF INFINEON HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR (ii)
+ * ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE ITSELF
+ * OR U.S. $1, WHICHEVER IS GREATER. THESE LIMITATIONS SHALL APPLY
+ * NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.
+ *
+ *
+ * <<Infineon-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#ifdef WL11AX
+
+#include "wl_twt.h"
+
+static DEFINE_SPINLOCK(twt_session_list_lock);
+
+/*
+ * Nominal Minimum Wake Duration derivation from Wake Duration
+ */
+static inline void
+wl_twt_wake_dur_to_min_twt(uint32 wake_dur, uint8 *min_twt, uint8 *min_twt_unit)
+{
+	*min_twt = wake_dur / 102400;
+}
+
+/*
+ * Wake Duration derivation from Nominal Minimum Wake Duration
+ */
+static inline uint32
+wl_twt_min_twt_to_wake_dur(uint8 min_twt, uint8 min_twt_unit)
+{
+	uint32 wake_dur;
+
+	if (min_twt_unit == 1) {
+		/*
+		 * If min_twt_unit is 1, then min_twt is
+		 * in units of TUs (i.e) 102400 usecs.
+		 */
+		wake_dur = (uint32)min_twt * 102400;
+	} else if (min_twt_unit == 0) {
+		/*
+		 * If min_twt_unit is 0, then min_twt is
+		 * in units of 256 usecs.
+		 */
+		wake_dur = (uint32)min_twt * 256;
+	} else {
+		/* Invalid min_twt */
+		wake_dur = 0;
+	}
+
+	return wake_dur;
+}
+
+/*
+ * Wake Interval Mantissa & Exponent derivation from Wake Interval
+ */
+static inline void
+wl_twt_uint32_to_float(uint32 val, uint8 *exp, uint16 *mant)
+{
+	uint8 lzs = (uint8)CLZ(val); /* leading 0's */
+	uint8 shift = lzs < 16 ? 16 - lzs : 0;
+
+	*mant = (uint16)(val >> shift);
+	*exp = shift;
+}
+
+/*
+ * Wake Interval derivation from Wake Interval Mantissa & Exponent
+ */
+static inline uint32
+wl_twt_float_to_uint32(uint8 exponent, uint16 mantissa)
+{
+	return (uint32)mantissa << exponent;
+}
+
+wl_twt_session_t* wl_twt_lookup_session_by_flow_id(struct list_head *twt_session_list,
+						   uint8 flow_id)
+{
+	wl_twt_session_t *iter = NULL;
+
+	list_for_each_entry(iter, twt_session_list, list) {
+		if (iter->twt_param.negotiation_type != IFX_TWT_PARAM_NEGO_TYPE_ITWT)
+			continue;
+
+		if (iter->twt_param.flow_id == flow_id)
+			return iter;
+	}
+
+	return NULL;
+}
+
+int wl_twt_add_session_to_list(struct list_head *twt_session_list, dhd_pub_t *dhd,
+			       uint8 ifidx, wl_twt_param_t twt_param)
+{
+	int ret = BCME_OK;
+	wl_twt_session_t *new_twt_session;
+
+	new_twt_session = (wl_twt_session_t *)MALLOCZ(dhd->osh,
+						      sizeof(wl_twt_session_t));
+	if (!new_twt_session) {
+		WL_ERR(("TWT: Failed to alloc memory for new session"));
+		ret = BCME_NOMEM;
+		goto exit;
+	}
+
+	new_twt_session->ifidx = ifidx;
+	new_twt_session->twt_param = twt_param;
+	new_twt_session->state = TWT_SESSION_SETUP_COMPLETE;
+
+	spin_lock_bh(&twt_session_list_lock);
+	WL_INFORM(("TWT: Adding TWT session with flow ID: %d", twt_param.flow_id));
+	list_add_tail(&new_twt_session->list, twt_session_list);
+exit:
+	spin_unlock_bh(&twt_session_list_lock);
+	return ret;
+}
+
+int wl_twt_del_session_by_flow_id(struct list_head *twt_session_list, uint8 flow_id)
+{
+	int ret = BCME_OK;
+	wl_twt_session_t *twt_session = NULL;
+
+	spin_lock_bh(&twt_session_list_lock);
+	twt_session = wl_twt_lookup_session_by_flow_id(twt_session_list, flow_id);
+	if (twt_session) {
+		WL_INFORM(("TWT: Deleting TWT session with flow ID: %d", flow_id));
+		list_del(&twt_session->list);
+		kfree(twt_session);
+	} else {
+		WL_INFORM(("TWT: TWT session with flow ID: %d is not found to be deleted",
+			 flow_id));
+		ret = -1;
+		goto exit;
+	}
+exit:
+	spin_unlock_bh(&twt_session_list_lock);
+	return ret;
+}
+
+int wl_twt_count_session(struct list_head *twt_session_list)
+{
+	wl_twt_session_t *twt_session = NULL;
+	int ct = 0;
+
+	list_for_each_entry(twt_session, twt_session_list, list) {
+		if (twt_session->twt_param.negotiation_type ==
+		    IFX_TWT_PARAM_NEGO_TYPE_ITWT)
+			ct++;
+	}
+
+	return ct;
+}
+
+void wl_twt_flush_session_list(struct list_head *twt_session_list, u8 ifidx)
+{
+	wl_twt_session_t *entry = NULL, *next = NULL;
+
+	spin_lock_bh(&twt_session_list_lock);
+	list_for_each_entry_safe(entry, next, twt_session_list, list) {
+		if ((ifidx != 0xFF) &&
+		    (ifidx != entry->ifidx))
+			continue;
+
+		WL_INFORM(("TWT: Deleting TWT session with flow ID: %d",
+			 entry->twt_param.flow_id));
+		list_del(&entry->list);
+		kfree(entry);
+	}
+	spin_unlock_bh(&twt_session_list_lock);
+}
+
+int wl_twt_cleanup_session_records(dhd_pub_t *dhd, u8 ifidx)
+{
+	wl_twt_ctx_t *twt_ctx = (wl_twt_ctx_t *)dhd->twt_ctx;
+	int ret = BCME_OK;
+
+	NULL_CHECK(twt_ctx,
+		   "TWT: Failed to cleanup session records, Module not initialized",
+		   ret);
+
+	wl_twt_flush_session_list(&twt_ctx->twt_session_list, ifidx);
+
+	return ret;
+}
+
+int wl_twt_setup(wl_twt_ctx_t *twt_ctx, struct wireless_dev *wdev,
+		 wl_twt_param_t twt_param)
+{
+	wl_twt_setup_t val;
+	s32 bw = BCME_OK;
+	u8 mybuf[WLC_IOCTL_SMLEN] = {0};
+	u8 resp_buf[WLC_IOCTL_SMLEN] = {0};
+	uint8 *rem = mybuf;
+	uint16 rem_len = sizeof(mybuf);
+	wl_twt_session_t *twt_session = NULL;
+
+	bzero(&val, sizeof(val));
+	val.version = WL_TWT_SETUP_VER;
+	val.length = sizeof(val.version) + sizeof(val.length);
+
+	/* Default values, Override Below */
+	val.desc.flow_flags = 0x0;
+	val.desc.wake_dur = 0xFFFFFFFF;
+	val.desc.wake_int = 0xFFFFFFFF;
+	val.desc.wake_int_max = 0xFFFFFFFF;
+
+	/* TWT Negotiation_type */
+	val.desc.negotiation_type = (uint8)twt_param.negotiation_type;
+
+	switch (val.desc.negotiation_type) {
+	case IFX_TWT_PARAM_NEGO_TYPE_ITWT:
+		/* Flow ID */
+		val.desc.flow_id = twt_param.flow_id;
+
+		if (val.desc.flow_id == 0xFF) {
+			/* Let the FW choose the Flow ID */
+			break;
+		}
+
+		/* Lookup the active session list for the requested flow ID */
+		twt_session =
+			wl_twt_lookup_session_by_flow_id(&twt_ctx->twt_session_list,
+							 twt_param.flow_id);
+		if (twt_session) {
+			WL_ERR(("TWT: Setup REQ: flow ID: %d is already active",
+				twt_param.flow_id));
+			bw = BCME_ERROR;
+			goto exit;
+		}
+		break;
+	case IFX_TWT_PARAM_NEGO_TYPE_BTWT:
+		/* Broadcast TWT ID */
+		val.desc.bid = twt_param.bcast_twt_id;
+
+		/* TODO: Handle the Broadcast TWT Setup REQ */
+
+		/* FALLTHRU */
+	default:
+		WL_ERR(("TWT: Setup REQ: Negotiation Type %d not handled",
+			twt_param.negotiation_type));
+		bw = BCME_UNSUPPORTED;
+		goto exit;
+	}
+
+	/* Setup command */
+	val.desc.setup_cmd = twt_param.setup_cmd;
+
+	/* Flow flags */
+	val.desc.flow_flags |= ((twt_param.negotiation_type & 0x02) >> 1 ?
+				WL_TWT_FLOW_FLAG_BROADCAST : 0);
+	val.desc.flow_flags |= (twt_param.implicit ? WL_TWT_FLOW_FLAG_IMPLICIT : 0);
+	val.desc.flow_flags |= (twt_param.flow_type ? WL_TWT_FLOW_FLAG_UNANNOUNCED : 0);
+	val.desc.flow_flags |= (twt_param.trigger ? WL_TWT_FLOW_FLAG_TRIGGER : 0);
+	val.desc.flow_flags |= ((twt_param.negotiation_type & 0x01) ?
+				WL_TWT_FLOW_FLAG_WAKE_TBTT_NEGO : 0);
+	val.desc.flow_flags |= (twt_param.requestor ? WL_TWT_FLOW_FLAG_REQUEST : 0);
+	val.desc.flow_flags |= (twt_param.protection ? WL_TWT_FLOW_FLAG_PROTECT : 0);
+
+	if (twt_param.twt) {
+		/* Target Wake Time parameter */
+		val.desc.wake_time_h = htod32((uint32)(twt_param.twt >> 32));
+		val.desc.wake_time_l = htod32((uint32)(twt_param.twt));
+		val.desc.wake_type = WL_TWT_TIME_TYPE_BSS;
+	} else if (twt_param.twt_offset) {
+		/* Target Wake Time offset parameter */
+		val.desc.wake_time_h = htod32((uint32)(twt_param.twt_offset >> 32));
+		val.desc.wake_time_l = htod32((uint32)(twt_param.twt_offset));
+		val.desc.wake_type = WL_TWT_TIME_TYPE_OFFSET;
+	} else {
+		/* Let the FW choose the Target Wake Time */
+		val.desc.wake_time_h = 0x0;
+		val.desc.wake_time_l = 0x0;
+		val.desc.wake_type = WL_TWT_TIME_TYPE_AUTO;
+	}
+
+	/* Wake Duration or Service Period */
+	val.desc.wake_dur = htod32(wl_twt_min_twt_to_wake_dur(twt_param.min_twt,
+							      twt_param.min_twt_unit));
+
+	/* Wake Interval or Service Interval */
+	val.desc.wake_int = htod32(wl_twt_float_to_uint32(twt_param.exponent,
+							  twt_param.mantissa));
+
+	bw = bcm_pack_xtlv_entry(&rem, &rem_len, WL_TWT_CMD_SETUP, sizeof(val),
+				 (uint8 *)&val, BCM_XTLV_OPTION_ALIGN32);
+	if (bw != BCME_OK) {
+		WL_ERR(("TWT: Setup REQ: Failed to pack IOVAR, ret: %d", bw));
+		goto exit;
+	}
+
+	bw = wldev_iovar_setbuf(wdev_to_ndev(wdev), "twt", mybuf,
+				sizeof(mybuf) - rem_len, resp_buf,
+				WLC_IOCTL_SMLEN, NULL);
+	if (bw != BCME_OK) {
+		WL_ERR(("TWT: Setup REQ: Failed, ret: %d", bw));
+		goto exit;
+	}
+
+	WL_INFORM(("TWT: Setup REQ: Initiated\n"
+		   "Setup command	: %u\n"
+		   "Flow flags		: 0x %02x\n"
+		   "Flow ID		: %u\n"
+		   "Broadcast TWT ID	: %u\n"
+		   "Wake Time H,L	: 0x %08x %08x\n"
+		   "Wake Type		: %u\n"
+		   "Wake Dururation	: %u usecs\n"
+		   "Wake Interval	: %u usecs\n"
+		   "Negotiation type	: %u\n",
+		   val.desc.setup_cmd,
+		   val.desc.flow_flags,
+		   val.desc.flow_id,
+		   val.desc.bid,
+		   val.desc.wake_time_h,
+		   val.desc.wake_time_l,
+		   val.desc.wake_type,
+		   val.desc.wake_dur,
+		   val.desc.wake_int,
+		   val.desc.negotiation_type));
+exit:
+	return bw;
+}
+
+int wl_twt_teardown(wl_twt_ctx_t *twt_ctx, struct wireless_dev *wdev,
+		    wl_twt_param_t twt_param)
+{
+	wl_twt_teardown_t val;
+	s32 bw = BCME_OK;
+	u8 mybuf[WLC_IOCTL_SMLEN] = {0};
+	u8 resp_buf[WLC_IOCTL_SMLEN] = {0};
+	uint8 *rem = mybuf;
+	uint16 rem_len = sizeof(mybuf);
+	wl_twt_session_t *twt_session = NULL;
+
+	bzero(&val, sizeof(val));
+	val.version = WL_TWT_TEARDOWN_VER;
+	val.length = sizeof(val.version) + sizeof(val.length);
+
+	/* TWT Negotiation_type */
+	val.teardesc.negotiation_type = (uint8)twt_param.negotiation_type;
+
+	switch (val.teardesc.negotiation_type) {
+	case IFX_TWT_PARAM_NEGO_TYPE_ITWT:
+		/* Teardown all Negotiated TWT */
+		val.teardesc.alltwt = twt_param.teardown_all_twt;
+
+		if (val.teardesc.alltwt) {
+			int sess_ct =
+			wl_twt_count_session(&twt_ctx->twt_session_list);
+			if (!sess_ct) {
+				WL_ERR(("TWT: Teardown REQ: No active sessions"));
+				bw = BCME_ERROR;
+				goto exit;
+			}
+			break;
+		}
+
+		/* Flow ID */
+		if (twt_param.flow_id >= 0 && twt_param.flow_id <= 0x7) {
+			val.teardesc.flow_id = twt_param.flow_id;
+		} else {
+			WL_ERR(("TWT: Teardown REQ: flow ID: %d is invalid",
+				twt_param.flow_id));
+			bw = BCME_ERROR;
+			goto exit;
+		}
+
+		/* Lookup the active session list for the same flow ID */
+		twt_session =
+			wl_twt_lookup_session_by_flow_id(&twt_ctx->twt_session_list,
+							 twt_param.flow_id);
+		if (!twt_session) {
+			WL_ERR(("TWT: Teardown REQ: flow ID: %d is not active",
+				twt_param.flow_id));
+			bw = BCME_ERROR;
+			goto exit;
+		}
+		break;
+	case IFX_TWT_PARAM_NEGO_TYPE_BTWT:
+		/* Broadcast TWT ID */
+		val.teardesc.bid = twt_param.bcast_twt_id;
+
+		/* TODO: Handle the Broadcast TWT Teardown REQ */
+
+		/* FALLTHRU */
+	default:
+		WL_ERR(("TWT: Teardown REQ: Negotiation Type %d not handled",
+			twt_param.negotiation_type));
+		bw = BCME_UNSUPPORTED;
+		goto exit;
+	}
+
+	bw = bcm_pack_xtlv_entry(&rem, &rem_len, WL_TWT_CMD_TEARDOWN, sizeof(val),
+				 (uint8 *)&val, BCM_XTLV_OPTION_ALIGN32);
+	if (bw != BCME_OK) {
+		WL_ERR(("TWT: Teardown REQ: Failed to pack IOVAR, ret: %d", bw));
+		goto exit;
+	}
+
+	bw = wldev_iovar_setbuf(wdev_to_ndev(wdev), "twt", mybuf,
+				sizeof(mybuf) - rem_len, resp_buf,
+				WLC_IOCTL_SMLEN, NULL);
+	if (bw != BCME_OK) {
+		WL_ERR(("TWT: Teardown REQ: Failed, ret: %d", bw));
+		goto exit;
+	}
+
+	WL_INFORM(("TWT: Teardown REQ: Initiated\n"
+		   "Flow ID		: %u\n"
+		   "Broadcast TWT ID	: %u\n"
+		   "Negotiation type	: %u\n"
+		   "Teardown all TWT	: %u\n",
+		   val.teardesc.flow_id,
+		   val.teardesc.bid,
+		   val.teardesc.negotiation_type,
+		   val.teardesc.alltwt));
+exit:
+	return bw;
+}
+
+int wl_twt_oper(struct net_device *pri_ndev,
+		struct wireless_dev *wdev, wl_twt_param_t twt_param)
+{
+	int ret = -1;
+	dhd_info_t *dhd_inf = *(dhd_info_t **)netdev_priv(pri_ndev);
+	dhd_pub_t *dhd = &dhd_inf->pub;
+	wl_twt_ctx_t *twt_ctx = NULL;
+
+	NULL_CHECK(dhd, "dhd is NULL", ret);
+
+	twt_ctx = (wl_twt_ctx_t *)dhd->twt_ctx;
+	NULL_CHECK(twt_ctx, "TWT: REQ: Failed, Module not initialized", ret);
+
+	switch (twt_param.twt_oper) {
+		case IFX_TWT_OPER_SETUP:
+			ret = wl_twt_setup(twt_ctx, wdev, twt_param);
+			break;
+		case IFX_TWT_OPER_TEARDOWN:
+			ret = wl_twt_teardown(twt_ctx, wdev, twt_param);
+			break;
+		default:
+			WL_ERR(("TWT: REQ: Requested operation %d not supported",
+				twt_param.twt_oper));
+			ret = BCME_UNSUPPORTED;
+			goto exit;
+	}
+exit:
+	return ret;
+}
+
+int wl_twt_setup_event(wl_twt_ctx_t *twt_ctx, struct wireless_dev *wdev,
+		       wl_event_msg_t *event, void *event_data)
+{
+	wl_twt_setup_cplt_t *setup_complete;
+	wl_twt_sdesc_t *setup_desc;
+	wl_twt_param_t twt_param;
+	int ret = BCME_OK;
+
+	setup_complete = (wl_twt_setup_cplt_t *)event_data;
+	setup_desc = (wl_twt_sdesc_t *)(event_data + sizeof(wl_twt_setup_cplt_t));
+
+	/* TWT Negotiation_type */
+	twt_param.negotiation_type = setup_desc->negotiation_type;
+
+	switch (twt_param.negotiation_type) {
+		case IFX_TWT_PARAM_NEGO_TYPE_ITWT:
+			/* Flow ID */
+			twt_param.flow_id = setup_desc->flow_id;
+			break;
+		case IFX_TWT_PARAM_NEGO_TYPE_BTWT:
+			/* Broadcast TWT ID */
+			twt_param.bcast_twt_id = setup_desc->bid;
+
+			/* TODO: Handle the Broadcast TWT Setup Event */
+
+			/* FALLTHRU */
+		default:
+			WL_ERR(("TWT: Setup EVT: Negotiation Type %d not handled",
+				twt_param.negotiation_type));
+			ret = BCME_UNSUPPORTED;
+			goto exit;
+	}
+
+	/* Setup command */
+	if (setup_desc->setup_cmd != TWT_SETUP_CMD_ACCEPT_TWT) {
+		WL_ERR(("TWT: Setup EVT: Request not accepted by the AP"));
+		ret = BCME_ERROR;
+		goto exit;
+	}
+	twt_param.setup_cmd = setup_desc->setup_cmd;
+
+	/* Flow flags */
+	twt_param.implicit = (setup_desc->flow_flags & WL_TWT_FLOW_FLAG_IMPLICIT) ? 1 : 0;
+	twt_param.flow_type = (setup_desc->flow_flags & WL_TWT_FLOW_FLAG_UNANNOUNCED) ? 1 : 0;
+	twt_param.trigger = (setup_desc->flow_flags & WL_TWT_FLOW_FLAG_TRIGGER) ? 1 : 0;
+	twt_param.requestor = (setup_desc->flow_flags & WL_TWT_FLOW_FLAG_REQUEST) ? 1 : 0;
+	twt_param.protection = (setup_desc->flow_flags & WL_TWT_FLOW_FLAG_PROTECT) ? 1 : 0;
+
+	/* Target Wake Time */
+	twt_param.twt = dtoh64((uint64)setup_desc->wake_time_h << 32) |
+			dtoh64((uint64)setup_desc->wake_time_l);
+
+	/* Wake Duration or Service Period */
+	wl_twt_wake_dur_to_min_twt(htod32(setup_desc->wake_dur),
+				   &twt_param.min_twt,
+				   &twt_param.min_twt_unit);
+
+	/* Wake Interval or Service Interval */
+	wl_twt_uint32_to_float(dtoh32(setup_desc->wake_int),
+				      &twt_param.exponent,
+				      &twt_param.mantissa);
+
+	ret = wl_twt_add_session_to_list(&twt_ctx->twt_session_list,
+					 twt_ctx->dhd, event->ifidx, twt_param);
+	if (ret) {
+		WL_ERR(("TWT: Setup EVT: Failed to add new session to list"));
+		goto exit;
+	}
+
+	WL_INFORM(("TWT: Setup EVT: Succeeded\n"
+		   "Setup command	: %u\n"
+		   "Flow flags		: 0x %02x\n"
+		   "Flow ID		: %u\n"
+		   "Broadcast TWT ID	: %u\n"
+		   "Wake Time H,L	: 0x %08x %08x\n"
+		   "Wake Type		: %u\n"
+		   "Wake Dururation	: %u usecs\n"
+		   "Wake Interval	: %u usecs\n"
+		   "Negotiation type	: %u\n",
+		   setup_desc->setup_cmd,
+		   setup_desc->flow_flags,
+		   setup_desc->flow_id,
+		   setup_desc->bid,
+		   setup_desc->wake_time_h,
+		   setup_desc->wake_time_l,
+		   setup_desc->wake_type,
+		   setup_desc->wake_dur,
+		   setup_desc->wake_int,
+		   setup_desc->negotiation_type));
+exit:
+	return ret;
+}
+
+int wl_twt_teardown_event(wl_twt_ctx_t *twt_ctx, struct wireless_dev *wdev,
+			  wl_event_msg_t *event, void *event_data)
+{
+	dhd_pub_t *dhd = twt_ctx->dhd;
+	wl_twt_teardown_cplt_t *teardown_complete;
+	wl_twt_teardesc_t *teardown_desc;
+	wl_twt_param_t twt_param;
+	int ret = BCME_OK;
+	s32 ifidx = DHD_BAD_IF;
+
+	ifidx = dhd_net2idx(dhd->info, wdev_to_ndev(wdev));
+	if (ifidx == DHD_BAD_IF) {
+		ret = BCME_ERROR;
+		goto exit;
+	}
+
+	teardown_complete = (wl_twt_teardown_cplt_t *)event_data;
+	teardown_desc = (wl_twt_teardesc_t *)(event_data + sizeof(teardown_complete));
+
+	/* TWT Negotiation_type */
+	twt_param.negotiation_type = teardown_desc->negotiation_type;
+
+	/* Teardown all Negotiated TWT */
+	twt_param.teardown_all_twt = teardown_desc->alltwt;
+	if (twt_param.teardown_all_twt) {
+		wl_twt_flush_session_list(&twt_ctx->twt_session_list,
+					  (u8)ifidx);
+	} else {
+		switch (twt_param.negotiation_type) {
+			case IFX_TWT_PARAM_NEGO_TYPE_ITWT:
+				/* Flow ID */
+				twt_param.flow_id = teardown_desc->flow_id;
+				ret = wl_twt_del_session_by_flow_id(&twt_ctx->twt_session_list,
+								    twt_param.flow_id);
+				if (ret) {
+					WL_ERR(("TWT: Failed to del session from list"));
+					goto exit;
+				}
+				break;
+			case IFX_TWT_PARAM_NEGO_TYPE_BTWT:
+				/* Broadcast TWT ID */
+				twt_param.bcast_twt_id = teardown_desc->bid;
+				/* TODO */
+				/* FALLTHRU */
+			default:
+				WL_ERR(("TWT: Negotiation Type not handled\n"));
+				ret = BCME_UNSUPPORTED;
+				goto exit;
+		}
+	}
+
+	WL_INFORM(("TWT: Teardown EVT: Succeeded\n"
+		   "Flow ID		: %u\n"
+		   "Broadcast TWT ID	: %u\n"
+		   "Negotiation type	: %u\n"
+		   "Teardown all TWT	: %u\n",
+		   teardown_desc->flow_id,
+		   teardown_desc->bid,
+		   teardown_desc->negotiation_type,
+		   teardown_desc->alltwt));
+
+exit:
+	return ret;
+}
+
+int wl_twt_event(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data)
+{
+	int ret = BCME_OK;
+	wl_twt_ctx_t *twt_ctx = NULL;
+	uint32 event_type;
+	dhd_if_t *ifp = NULL;
+	struct net_device *ndev;
+	struct wireless_dev *wdev;
+
+	NULL_CHECK(dhd, "TWT: EVT: Failed, dhd is NULL", ret);
+
+	twt_ctx = (wl_twt_ctx_t *)dhd->twt_ctx;
+	NULL_CHECK(twt_ctx, "TWT: EVT: Failed, Module not initialized", ret);
+
+	ifp = dhd_get_ifp(dhd, event->ifidx);
+	NULL_CHECK(ifp, "TWT: EVT: Failed, ifp is NULL", ret);
+
+	ndev = ifp->net;
+	NULL_CHECK(ndev, "TWT: EVT: Failed, ndev is NULL", ret);
+
+	wdev = ndev_to_wdev(ndev);
+	NULL_CHECK(wdev, "TWT: EVT: Failed, wdev is NULL", ret);
+
+	NULL_CHECK(event_data, "TWT: EVT: Failed, event_data is NULL", ret);
+
+	event_type = ntoh32_ua((void *)&event->event_type);
+	switch(event_type) {
+		case WLC_E_TWT_SETUP:
+			ret = wl_twt_setup_event(twt_ctx, wdev, event, event_data);
+			if (ret) {
+				WL_ERR(("TWT: EVT: Failed to handle TWT Setup event"));
+				goto exit;
+			}
+			break;
+		case WLC_E_TWT_TEARDOWN:
+			ret = wl_twt_teardown_event(twt_ctx, wdev, event, event_data);
+			if (ret) {
+				WL_ERR(("TWT: EVT: Failed to handle TWT Teardown event"));
+				goto exit;
+			}
+			break;
+		default:
+			WL_ERR(("TWT: EVT: Received event %d not handeled",
+				event_type));
+			ret = BCME_UNSUPPORTED;
+			goto exit;
+	}
+
+exit:
+	return ret;
+}
+
+int wl_twt_init(dhd_pub_t *dhd)
+{
+	int ret = BCME_OK;
+	wl_twt_ctx_t *twt_ctx;
+
+	NULL_CHECK(dhd, "TWT: INIT: Failed, dhd is NULL", ret);
+
+	if (dhd->twt_ctx) {
+		WL_ERR(("TWT: INIT: Failed, Module already initialized"));
+		ret = BCME_ERROR;
+	        goto exit;
+	}
+
+	dhd->twt_ctx = (wl_twt_ctx_t *)MALLOCZ(dhd->osh, sizeof(wl_twt_ctx_t));
+	if (dhd->twt_ctx == NULL) {
+		ret = BCME_NOMEM;
+	        WL_ERR(("TWT: INIT: Failed to create TWT context"));
+		goto exit;
+	}
+	bzero(dhd->twt_ctx, sizeof(wl_twt_ctx_t));
+
+	twt_ctx = (wl_twt_ctx_t *)dhd->twt_ctx;
+	twt_ctx->dhd = dhd;
+
+	INIT_LIST_HEAD(&twt_ctx->twt_session_list);
+
+	WL_INFORM(("TWT: INIT: Module Initialized"));
+exit:
+	return ret;
+}
+
+int wl_twt_deinit(dhd_pub_t *dhd)
+{
+	int ret = BCME_OK;
+	wl_twt_ctx_t *twt_ctx;
+
+	NULL_CHECK(dhd, "TWT: DEINIT: Failed, dhd is NULL", ret);
+
+	twt_ctx = dhd->twt_ctx;
+	NULL_CHECK(twt_ctx,
+		   "TWT: DEINIT: Failed, Module not Initialized to De-initialize", ret);
+
+	wl_twt_flush_session_list(&twt_ctx->twt_session_list, 0xFF);
+
+	kfree(twt_ctx);
+	dhd->twt_ctx = NULL;
+
+	WL_INFORM(("TWT: DEINIT: Module De-initialized"));
+
+	return ret;
+}
+
+#endif /* WL11AX */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_twt.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_twt.h
new file mode 100755
index 0000000..53fc3aa
--- /dev/null
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wl_twt.h
@@ -0,0 +1,115 @@
+/*
+ * Target Wake Time header
+ *
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation,
+ * an Infineon company
+ *
+ * This program is the proprietary software of infineon and/or
+ * its licensors, and may only be used, duplicated, modified or distributed
+ * pursuant to the terms and conditions of a separate, written license
+ * agreement executed between you and infineon (an "Authorized License").
+ * Except as set forth in an Authorized License, infineon grants no license
+ * (express or implied), right to use, or waiver of any kind with respect to
+ * the Software, and infineon expressly reserves all rights in and to the
+ * Software and all intellectual property rights therein.  IF YOU HAVE NO
+ * AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY
+ * WAY, AND SHOULD IMMEDIATELY NOTIFY INFINEON AND DISCONTINUE ALL USE OF
+ * THE SOFTWARE.
+ *
+ * Except as expressly set forth in the Authorized License,
+ *
+ * 1. This program, including its structure, sequence and organization,
+ * constitutes the valuable trade secrets of infineon, and you shall use
+ * all reasonable efforts to protect the confidentiality thereof, and to
+ * use this information only in connection with your use of infineon
+ * integrated circuit products.
+ *
+ * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED
+ * "AS IS" AND WITH ALL FAULTS AND INFINEON MAKES NO PROMISES,
+ * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR
+ * OTHERWISE, WITH RESPECT TO THE SOFTWARE.  INFINEON SPECIFICALLY
+ * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+ * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+ * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+ * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING
+ * OUT OF USE OR PERFORMANCE OF THE SOFTWARE.
+ *
+ * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL
+ * INFINEON OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL,
+ * SPECIAL, INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR
+ * IN ANY WAY RELATING TO YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN
+ * IF INFINEON HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR (ii)
+ * ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE ITSELF
+ * OR U.S. $1, WHICHEVER IS GREATER. THESE LIMITATIONS SHALL APPLY
+ * NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.
+ *
+ *
+ * <<Infineon-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+#ifndef _wl_twt_h_
+#define _wl_twt_h_
+
+#include <typedefs.h>
+#include <bcmendian.h>
+#include <net/cfg80211.h>
+#include <dhd_dbg.h>
+#include <dhd_linux.h>
+#include <802.11ah.h>
+#include "dhd_linux_priv.h"
+#include "wlioctl.h"
+#include "wldev_common.h"
+#include "wl_cfg80211.h"
+#include "wl_cfgvendor.h"
+#include "bcmutils.h"
+#include "ifx_nl80211.h"
+
+enum wl_twt_session_state {
+	TWT_SESSION_SETUP_COMPLETE,
+	TWT_SESSION_TEARDOWN_COMPLETE
+};
+
+typedef struct wl_twt_param {
+	uint8 twt_oper;
+	enum ifx_twt_param_nego_type negotiation_type;
+	enum ifx_twt_oper_setup_cmd_type setup_cmd;
+	uint8 dialog_token;
+	uint64 twt;
+	uint64 twt_offset;
+	uint8 min_twt;
+	uint8 exponent;
+	uint16 mantissa;
+	uint8 requestor;
+	uint8 trigger;
+	uint8 implicit;
+	uint8 flow_type;
+	uint8 flow_id;
+	uint8 bcast_twt_id;
+	uint8 protection;
+	uint8 twt_channel;
+	uint8 twt_info_frame_disabled;
+	uint8 min_twt_unit;
+	uint8 teardown_all_twt;
+} wl_twt_param_t;
+
+typedef struct wl_twt_session {
+	uint8 ifidx;
+	uint8 state;
+	wl_twt_param_t twt_param;
+	struct list_head list;
+} wl_twt_session_t;
+
+typedef struct wl_twt_ctx {
+	dhd_pub_t *dhd;
+	struct list_head twt_session_list;
+} wl_twt_ctx_t;
+
+int wl_twt_cleanup_session_records(dhd_pub_t *dhd, u8 ifidx);
+int wl_twt_oper(struct net_device *pri_ndev,
+		struct wireless_dev *wdev, wl_twt_param_t twt_param);
+int wl_twt_event(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data);
+int wl_twt_init(dhd_pub_t *dhd);
+int wl_twt_deinit(dhd_pub_t *dhd);
+
+#endif /* _wl_twt_h_ */
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wldev_common.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wldev_common.c
old mode 100644
new mode 100755
index f25adf1..8722def
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wldev_common.c
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wldev_common.c
@@ -1,9 +1,9 @@
 /*
  * Common function shared by Linux WEXT, cfg80211 and p2p drivers
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wldev_common.h b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wldev_common.h
old mode 100644
new mode 100755
index 98996fc..7e7899f
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wldev_common.h
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/wldev_common.h
@@ -1,9 +1,9 @@
 /*
  * Common function shared by Linux WEXT, cfg80211 and p2p drivers
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2023 Cypress Semiconductor Corporation
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2016, Broadcom Corporation
  *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/src/kernel/linux/v4.19/include/uapi/linux/nl80211.h b/src/kernel/linux/v4.19/include/uapi/linux/nl80211.h
old mode 100644
new mode 100755
index 8d2479c..1e47749
--- a/src/kernel/linux/v4.19/include/uapi/linux/nl80211.h
+++ b/src/kernel/linux/v4.19/include/uapi/linux/nl80211.h
@@ -2250,6 +2250,135 @@
  *	association request when used with NL80211_CMD_NEW_STATION). Can be set
  *	only if %NL80211_STA_FLAG_WME is set.
  *
+ * @NL80211_ATTR_FTM_RESPONDER: nested attribute which user-space can include
+ *	in %NL80211_CMD_START_AP or %NL80211_CMD_SET_BEACON for fine timing
+ *	measurement (FTM) responder functionality and containing parameters as
+ *	possible, see &enum nl80211_ftm_responder_attr
+ *
+ * @NL80211_ATTR_FTM_RESPONDER_STATS: Nested attribute with FTM responder
+ *	statistics, see &enum nl80211_ftm_responder_stats.
+ *
+ * @NL80211_ATTR_TIMEOUT: Timeout for the given operation in milliseconds (u32),
+ *	if the attribute is not given no timeout is requested. Note that 0 is an
+ *	invalid value.
+ *
+ * @NL80211_ATTR_PEER_MEASUREMENTS: peer measurements request (and result)
+ *	data, uses nested attributes specified in
+ *	&enum nl80211_peer_measurement_attrs.
+ *	This is also used for capability advertisement in the wiphy information,
+ *	with the appropriate sub-attributes.
+ *
+ * @NL80211_ATTR_AIRTIME_WEIGHT: Station's weight when scheduled by the airtime
+ *	scheduler.
+ *
+ * @NL80211_ATTR_STA_TX_POWER_SETTING: Transmit power setting type (u8) for
+ *	station associated with the AP. See &enum nl80211_tx_power_setting for
+ *	possible values.
+ * @NL80211_ATTR_STA_TX_POWER: Transmit power level (s16) in dBm units. This
+ *	allows to set Tx power for a station. If this attribute is not included,
+ *	the default per-interface tx power setting will be overriding. Driver
+ *	should be picking up the lowest tx power, either tx power per-interface
+ *	or per-station.
+ *
+ * @NL80211_ATTR_SAE_PASSWORD: attribute for passing SAE password material. It
+ *	is used with %NL80211_CMD_CONNECT to provide password for offloading
+ *	SAE authentication for WPA3-Personal networks.
+ *
+ * @NL80211_ATTR_TWT_RESPONDER: Enable target wait time responder support.
+ *
+ * @NL80211_ATTR_HE_OBSS_PD: nested attribute for OBSS Packet Detection
+ *	functionality.
+ *
+ * @NL80211_ATTR_WIPHY_EDMG_CHANNELS: bitmap that indicates the 2.16 GHz
+ *	channel(s) that are allowed to be used for EDMG transmissions.
+ *	Defined by IEEE P802.11ay/D4.0 section 9.4.2.251. (u8 attribute)
+ * @NL80211_ATTR_WIPHY_EDMG_BW_CONFIG: Channel BW Configuration subfield encodes
+ *	the allowed channel bandwidth configurations. (u8 attribute)
+ *	Defined by IEEE P802.11ay/D4.0 section 9.4.2.251, Table 13.
+ *
+ * @NL80211_ATTR_VLAN_ID: VLAN ID (1..4094) for the station and VLAN group key
+ *	(u16).
+ *
+ * @NL80211_ATTR_HE_BSS_COLOR: nested attribute for BSS Color Settings.
+ *
+ * @NL80211_ATTR_IFTYPE_AKM_SUITES: nested array attribute, with each entry
+ *	using attributes from &enum nl80211_iftype_akm_attributes. This
+ *	attribute is sent in a response to %NL80211_CMD_GET_WIPHY indicating
+ *	supported AKM suites capability per interface. AKMs advertised in
+ *	%NL80211_ATTR_AKM_SUITES are default capabilities if AKM suites not
+ *	advertised for a specific interface type.
+ *
+ * @NL80211_ATTR_TID_CONFIG: TID specific configuration in a
+ *	nested attribute with &enum nl80211_tid_config_attr sub-attributes;
+ *	on output (in wiphy attributes) it contains only the feature sub-
+ *	attributes.
+ *
+ * @NL80211_ATTR_CONTROL_PORT_NO_PREAUTH: disable preauth frame rx on control
+ *	port in order to forward/receive them as ordinary data frames.
+ *
+ * @NL80211_ATTR_PMK_LIFETIME: Maximum lifetime for PMKSA in seconds (u32,
+ *	dot11RSNAConfigPMKReauthThreshold; 0 is not a valid value).
+ *	An optional parameter configured through %NL80211_CMD_SET_PMKSA.
+ *	Drivers that trigger roaming need to know the lifetime of the
+ *	configured PMKSA for triggering the full vs. PMKSA caching based
+ *	authentication. This timeout helps authentication methods like SAE,
+ *	where PMK gets updated only by going through a full (new SAE)
+ *	authentication instead of getting updated during an association for EAP
+ *	authentication. No new full authentication within the PMK expiry shall
+ *	result in a disassociation at the end of the lifetime.
+ *
+ * @NL80211_ATTR_PMK_REAUTH_THRESHOLD: Reauthentication threshold time, in
+ *	terms of percentage of %NL80211_ATTR_PMK_LIFETIME
+ *	(u8, dot11RSNAConfigPMKReauthThreshold, 1..100). This is an optional
+ *	parameter configured through %NL80211_CMD_SET_PMKSA. Requests the
+ *	driver to trigger a full authentication roam (without PMKSA caching)
+ *	after the reauthentication threshold time, but before the PMK lifetime
+ *	has expired.
+ *
+ *	Authentication methods like SAE need to be able to generate a new PMKSA
+ *	entry without having to force a disconnection after the PMK timeout. If
+ *	no roaming occurs between the reauth threshold and PMK expiration,
+ *	disassociation is still forced.
+ * @NL80211_ATTR_RECEIVE_MULTICAST: multicast flag for the
+ *	%NL80211_CMD_REGISTER_FRAME command, see the description there.
+ * @NL80211_ATTR_WIPHY_FREQ_OFFSET: offset of the associated
+ *	%NL80211_ATTR_WIPHY_FREQ in positive KHz. Only valid when supplied with
+ *	an %NL80211_ATTR_WIPHY_FREQ_OFFSET.
+ * @NL80211_ATTR_CENTER_FREQ1_OFFSET: Center frequency offset in KHz for the
+ *	first channel segment specified in %NL80211_ATTR_CENTER_FREQ1.
+ * @NL80211_ATTR_SCAN_FREQ_KHZ: nested attribute with KHz frequencies
+ *
+ * @NL80211_ATTR_HE_6GHZ_CAPABILITY: HE 6 GHz Band Capability element (from
+ *	association request when used with NL80211_CMD_NEW_STATION).
+ *
+ * @NL80211_ATTR_FILS_DISCOVERY: Optional parameter to configure FILS
+ *	discovery. It is a nested attribute, see
+ *	&enum nl80211_fils_discovery_attributes.
+ *
+ * @NL80211_ATTR_UNSOL_BCAST_PROBE_RESP: Optional parameter to configure
+ *	unsolicited broadcast probe response. It is a nested attribute, see
+ *	&enum nl80211_unsol_bcast_probe_resp_attributes.
+ *
+ * @NL80211_ATTR_S1G_CAPABILITY: S1G Capability information element (from
+ *	association request when used with NL80211_CMD_NEW_STATION)
+ * @NL80211_ATTR_S1G_CAPABILITY_MASK: S1G Capability Information element
+ *	override mask. Used with NL80211_ATTR_S1G_CAPABILITY in
+ *	NL80211_CMD_ASSOCIATE or NL80211_CMD_CONNECT.
+ *
+ * @NL80211_ATTR_SAE_PWE: Indicates the mechanism(s) allowed for SAE PWE
+ *	derivation in WPA3-Personal networks which are using SAE authentication.
+ *	This is a u8 attribute that encapsulates one of the values from
+ *	&enum nl80211_sae_pwe_mechanism.
+ *
+ * @NL80211_ATTR_SAR_SPEC: SAR power limitation specification when
+ *	used with %NL80211_CMD_SET_SAR_SPECS. The message contains fields
+ *	of %nl80211_sar_attrs which specifies the sar type and related
+ *	sar specs. Sar specs contains array of %nl80211_sar_specs_attrs.
+ *
+ * @NL80211_ATTR_RECONNECT_REQUESTED: flag attribute, used with deauth and
+ *	disassoc events to indicate that an immediate reconnect to the AP
+ *	is desired.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2691,10 +2820,65 @@
 
 	NL80211_ATTR_HE_CAPABILITY,
 
+	NL80211_ATTR_FTM_RESPONDER,
+
+	NL80211_ATTR_FTM_RESPONDER_STATS,
+
+	NL80211_ATTR_TIMEOUT,
+
+	NL80211_ATTR_PEER_MEASUREMENTS,
+
+	NL80211_ATTR_AIRTIME_WEIGHT,
+	NL80211_ATTR_STA_TX_POWER_SETTING,
+	NL80211_ATTR_STA_TX_POWER,
+
+
 //tianyan@2021.7.27 modify for add wifi6 module start
 	NL80211_ATTR_SAE_PASSWORD,
 //tianyan@2021.7.27 modify for add wifi6 module end
 
+	NL80211_ATTR_TWT_RESPONDER,
+
+	NL80211_ATTR_HE_OBSS_PD,
+
+	NL80211_ATTR_WIPHY_EDMG_CHANNELS,
+	NL80211_ATTR_WIPHY_EDMG_BW_CONFIG,
+
+	NL80211_ATTR_VLAN_ID,
+
+	NL80211_ATTR_HE_BSS_COLOR,
+
+	NL80211_ATTR_IFTYPE_AKM_SUITES,
+
+	NL80211_ATTR_TID_CONFIG,
+
+	NL80211_ATTR_CONTROL_PORT_NO_PREAUTH,
+
+	NL80211_ATTR_PMK_LIFETIME,
+	NL80211_ATTR_PMK_REAUTH_THRESHOLD,
+
+	NL80211_ATTR_RECEIVE_MULTICAST,
+	NL80211_ATTR_WIPHY_FREQ_OFFSET,
+	NL80211_ATTR_CENTER_FREQ1_OFFSET,
+	NL80211_ATTR_SCAN_FREQ_KHZ,
+
+	NL80211_ATTR_HE_6GHZ_CAPABILITY,
+
+	NL80211_ATTR_FILS_DISCOVERY,
+
+	NL80211_ATTR_UNSOL_BCAST_PROBE_RESP,
+
+	NL80211_ATTR_S1G_CAPABILITY,
+	NL80211_ATTR_S1G_CAPABILITY_MASK,
+
+	NL80211_ATTR_SAE_PWE,
+
+	NL80211_ATTR_RECONNECT_REQUESTED,
+
+	NL80211_ATTR_SAR_SPEC,
+
+	NL80211_ATTR_DISABLE_HE,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -5239,6 +5423,93 @@
  * @NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT: Driver/device can omit all data
  *	except for supported rates from the probe request content if requested
  *	by the %NL80211_SCAN_FLAG_MIN_PREQ_CONTENT flag.
+ * @NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER: Driver supports enabling fine
+ *	timing measurement responder role.
+ *
+ * @NL80211_EXT_FEATURE_CAN_REPLACE_PTK0: Driver/device confirm that they are
+ *      able to rekey an in-use key correctly. Userspace must not rekey PTK keys
+ *      if this flag is not set. Ignoring this can leak clear text packets and/or
+ *      freeze the connection.
+ * @NL80211_EXT_FEATURE_EXT_KEY_ID: Driver supports "Extended Key ID for
+ *      Individually Addressed Frames" from IEEE802.11-2016.
+ *
+ * @NL80211_EXT_FEATURE_AIRTIME_FAIRNESS: Driver supports getting airtime
+ *	fairness for transmitted packets and has enabled airtime fairness
+ *	scheduling.
+ *
+ * @NL80211_EXT_FEATURE_AP_PMKSA_CACHING: Driver/device supports PMKSA caching
+ *	(set/del PMKSA operations) in AP mode.
+ *
+ * @NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD: Driver supports
+ *	filtering of sched scan results using band specific RSSI thresholds.
+ *
+ * @NL80211_EXT_FEATURE_STA_TX_PWR: This driver supports controlling tx power
+ *	to a station.
+ *
+ * @NL80211_EXT_FEATURE_SAE_OFFLOAD: Device wants to do SAE authentication in
+ *	station mode (SAE password is passed as part of the connect command).
+ *
+ * @NL80211_EXT_FEATURE_VLAN_OFFLOAD: The driver supports a single netdev
+ *	with VLAN tagged frames and separate VLAN-specific netdevs added using
+ *	vconfig similarly to the Ethernet case.
+ *
+ * @NL80211_EXT_FEATURE_AQL: The driver supports the Airtime Queue Limit (AQL)
+ *	feature, which prevents bufferbloat by using the expected transmission
+ *	time to limit the amount of data buffered in the hardware.
+ *
+ * @NL80211_EXT_FEATURE_BEACON_PROTECTION: The driver supports Beacon protection
+ *	and can receive key configuration for BIGTK using key indexes 6 and 7.
+ * @NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT: The driver supports Beacon
+ *	protection as a client only and cannot transmit protected beacons.
+ *
+ * @NL80211_EXT_FEATURE_CONTROL_PORT_NO_PREAUTH: The driver can disable the
+ *	forwarding of preauth frames over the control port. They are then
+ *	handled as ordinary data frames.
+ *
+ * @NL80211_EXT_FEATURE_PROTECTED_TWT: Driver supports protected TWT frames
+ *
+ * @NL80211_EXT_FEATURE_DEL_IBSS_STA: The driver supports removing stations
+ *      in IBSS mode, essentially by dropping their state.
+ *
+ * @NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS: management frame registrations
+ *	are possible for multicast frames and those will be reported properly.
+ *
+ * @NL80211_EXT_FEATURE_SCAN_FREQ_KHZ: This driver supports receiving and
+ *	reporting scan request with %NL80211_ATTR_SCAN_FREQ_KHZ. In order to
+ *	report %NL80211_ATTR_SCAN_FREQ_KHZ, %NL80211_SCAN_FLAG_FREQ_KHZ must be
+ *	included in the scan request.
+ *
+ * @NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS: The driver
+ *	can report tx status for control port over nl80211 tx operations.
+ *
+ * @NL80211_EXT_FEATURE_OPERATING_CHANNEL_VALIDATION: Driver supports Operating
+ *	Channel Validation (OCV) when using driver's SME for RSNA handshakes.
+ *
+ * @NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK: Device wants to do 4-way
+ *	handshake with PSK in AP mode (PSK is passed as part of the start AP
+ *	command).
+ *
+ * @NL80211_EXT_FEATURE_SAE_OFFLOAD_AP: Device wants to do SAE authentication
+ *	in AP mode (SAE password is passed as part of the start AP command).
+ *
+ * @NL80211_EXT_FEATURE_FILS_DISCOVERY: Driver/device supports FILS discovery
+ *	frames transmission
+ *
+ * @NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP: Driver/device supports
+ *	unsolicited broadcast probe response transmission
+ *
+ * @NL80211_EXT_FEATURE_BEACON_RATE_HE: Driver supports beacon rate
+ *	configuration (AP/mesh) with HE rates.
+ *
+ * @NL80211_EXT_FEATURE_SECURE_LTF: Device supports secure LTF measurement
+ *      exchange protocol.
+ *
+ * @NL80211_EXT_FEATURE_SECURE_RTT: Device supports secure RTT measurement
+ *      exchange protocol.
+ *
+ * @NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE: Device supports management
+ *      frame protection for all management frames exchanged during the
+ *      negotiation and range measurement procedure.
  *
  * @NUM_NL80211_EXT_FEATURES: number of extended features.
  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -5271,15 +5542,42 @@
 	NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN,
 	NL80211_EXT_FEATURE_DFS_OFFLOAD,
 	NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211,
-	NL80211_EXT_FEATURE_DATA_ACK_SIGNAL_SUPPORT,
+	NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT,
+	/* we renamed this - stay compatible */
+	NL80211_EXT_FEATURE_DATA_ACK_SIGNAL_SUPPORT = NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT,
 	NL80211_EXT_FEATURE_TXQS,
 	NL80211_EXT_FEATURE_SCAN_RANDOM_SN,
 	NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT,
+	NL80211_EXT_FEATURE_CAN_REPLACE_PTK0,
+	NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER,
+	NL80211_EXT_FEATURE_AIRTIME_FAIRNESS,
+	NL80211_EXT_FEATURE_AP_PMKSA_CACHING,
+	NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD,
+	NL80211_EXT_FEATURE_EXT_KEY_ID,
+	NL80211_EXT_FEATURE_STA_TX_PWR,
 
 //tianyan@2021.7.27 modify for add wifi6 module start
 	NL80211_EXT_FEATURE_SAE_OFFLOAD,
-	NL80211_EXT_FEATURE_AP_PMKSA_CACHING,
 //tianyan@2021.7.27 modify for add wifi6 module end
+	NL80211_EXT_FEATURE_VLAN_OFFLOAD,
+	NL80211_EXT_FEATURE_AQL,
+	NL80211_EXT_FEATURE_BEACON_PROTECTION,
+	NL80211_EXT_FEATURE_CONTROL_PORT_NO_PREAUTH,
+	NL80211_EXT_FEATURE_PROTECTED_TWT,
+	NL80211_EXT_FEATURE_DEL_IBSS_STA,
+	NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS,
+	NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT,
+	NL80211_EXT_FEATURE_SCAN_FREQ_KHZ,
+	NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS,
+	NL80211_EXT_FEATURE_OPERATING_CHANNEL_VALIDATION,
+	NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK,
+	NL80211_EXT_FEATURE_SAE_OFFLOAD_AP,
+	NL80211_EXT_FEATURE_FILS_DISCOVERY,
+	NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP,
+	NL80211_EXT_FEATURE_BEACON_RATE_HE,
+	NL80211_EXT_FEATURE_SECURE_LTF,
+	NL80211_EXT_FEATURE_SECURE_RTT,
+	NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE,
 
 	/* add new features before the definition below */
 	NUM_NL80211_EXT_FEATURES,
@@ -5531,6 +5829,10 @@
  * Used by cfg80211_rx_mgmt()
  *
  * @NL80211_RXMGMT_FLAG_ANSWERED: frame was answered by device/driver.
+ * @NL80211_RXMGMT_FLAG_EXTERNAL_AUTH: Host driver intends to offload
+ *	the authentication. Exclusively defined for host drivers that
+ *	advertises the SME functionality but would like the userspace
+ *	to handle certain authentication algorithms (e.g. SAE).
  */
 enum nl80211_rxmgmt_flags {
 	NL80211_RXMGMT_FLAG_ANSWERED = 1 << 0,
diff --git a/src/lynq/framework/lynq-ril-service/src/atci/atci_lynq_data_cmd.cpp b/src/lynq/framework/lynq-ril-service/src/atci/atci_lynq_data_cmd.cpp
index e0b8321..2994ca3 100755
--- a/src/lynq/framework/lynq-ril-service/src/atci/atci_lynq_data_cmd.cpp
+++ b/src/lynq/framework/lynq-ril-service/src/atci/atci_lynq_data_cmd.cpp
@@ -10,7 +10,8 @@
 #include <vendor-ril/telephony/ril.h>
 #include <string.h>
 #include <log/log.h>
-
+#include <vector>
+#include "Radio_capability_switch_util.h"
 #include "ATCI.h"
 #include "atci_util.h"
 #include "atci_at_util.h"
@@ -20,6 +21,7 @@
 #include "common.h"
 #include "sim.h"
 
+
 #undef LOG_TAG
 #define LOG_TAG "DEMO_ATCI_DATA"
 #define LINE __LINE__
@@ -139,6 +141,51 @@
     return SYS_SUCC;
 }
 
+int check_sim_state(void)
+{
+    char buf[16];
+    //send request
+    char* argv[1] = { 0 };
+    argv[0] = "RIL_REQUEST_GET_SIM_STATUS";
+    android::lynqSendToRil(1,argv,1024);
+    //wait response from callback
+    if(lynq_wait_result_comeback(2000))
+    {
+        sprintf(buf,"%s","+CME ERROR: 14");//sim busy
+        if(atci_send_data(buf)!=0)
+        {
+            RLOGD("send data fail");
+            return SYS_FAIL;
+        }
+        RLOGD("[%d][%s] wait sim state timeout",LINE,FUNC);
+        return SYS_FAIL;
+    }
+    //judge result
+    if(g_lynq_sim_state != 1)
+    {
+        RLOGD("SIM card absent");
+        sprintf(buf,"%s","+CME ERROR: 10");
+        if(atci_send_data(buf)!=0)
+        {
+            RLOGD("send data fail");
+            return SYS_FAIL;
+        }
+        return SYS_FAIL;
+    }
+    if(checkDataRegistration(1024))
+    {
+        RLOGD("[%d][%s] data registion fail",LINE,FUNC);
+        sprintf(buf,"%s","+CME ERROR: 1");
+        if(atci_send_data(buf)!=0)
+        {
+            RLOGD("send data fail");
+            return SYS_FAIL;
+        }
+        return SYS_FAIL;
+    }
+    return SYS_SUCC;
+}
+
 int atci_data_enable_pdp_hdlr(char *cmd, int op_mode, int target, char *response)
 {
     int ret;
@@ -151,7 +198,6 @@
             //send to target handle
             //ex: at+lapnact=int
             RLOGD("input cmd[%s]", cmd);
-
             if (SYS_FAIL == atci_at_to_equal(&cmd))
             {
                 //input error
@@ -171,9 +217,12 @@
 
             //wrire data to target
             atci_data_req_t req;
-
             if(state==1)
             {
+                if(check_sim_state())
+                {
+                    return SYS_FAIL;
+                }
                 req.request_id = RIL_REQUEST_SETUP_DATA_CALL;
             }
             else if(state == 0)
@@ -185,8 +234,6 @@
                 ATCIResponseNoToken(100,NULL,RIL_REQUEST_SETUP_DATA_CALL);
                 return SYS_FAIL;
             }
-            
-
             char reqStr[RIL_REQUEST_STRING_LENGTH] = {0};
             memcpy(reqStr, request2RILStr(req.request_id),strlen(request2RILStr(req.request_id)) + 1);
             RLOGD("request is %s", reqStr);
@@ -204,6 +251,31 @@
             ATCIResponseNoToken(0,buf,RIL_REQUEST_SETUP_DATA_CALL);
             break;
         }
+        case AT_READ_MODE:
+        {
+            for(int i = 0;i < LYNQ_APN_CHANNEL_MAX; i ++)
+            {
+                if(!apn_table[i].used)
+                {
+                    continue;
+                }
+                memset(buf,0,sizeof(buf));
+                sprintf(buf,"+LAPNACT: %s,%s,%d,%s,%s\n", apn_table[i].apn, apn_table[i].apntype ,apn_table[i].pdpstate, apn_table[i].ifaceName, apn_table[i].address);
+                if(atci_send_data(buf)!=0)
+                {
+                    RLOGD("send data fail");
+                    return SYS_FAIL;
+                }
+            }
+            if(apn_count == 0)
+            {
+                memset(buf,0,sizeof(buf));
+                ATCIResponseNoToken(0,buf,RIL_REQUEST_SETUP_DATA_CALL);
+                return SYS_SUCC;
+            }
+            atci_send_result(0);
+            break;
+        }
         default:
         {
             RLOGD("set mute error");
@@ -236,7 +308,6 @@
             //send to target handle
             //ex: at+lapnact=int
             RLOGD("input cmd[%s]", cmd);
-
             if (SYS_FAIL == atci_at_to_equal(&cmd))
             {
               //input error
@@ -320,6 +391,10 @@
             atci_data_req_t req;
             if(state==1)
             {
+                if(check_sim_state())
+                {
+                    return SYS_FAIL;
+                }
                 req.request_id = RIL_REQUEST_SETUP_DATA_CALL;
             }
             else if(state == 0)
@@ -357,7 +432,7 @@
                     continue;
                 }
                 memset(buf,0,sizeof(buf));
-                sprintf(buf,"+ELAPNACT:%s,%s,%d,%s,%s\n", apn_table[i].apn, apn_table[i].apntype ,apn_table[i].pdpstate, apn_table[i].ifaceName, apn_table[i].address);
+                sprintf(buf,"+ELAPNACT: %s,%s,%d,%s,%s\n", apn_table[i].apn, apn_table[i].apntype ,apn_table[i].pdpstate, apn_table[i].ifaceName, apn_table[i].address);
                 if(atci_send_data(buf)!=0)
                 {
                     RLOGD("send data fail");
diff --git a/src/lynq/framework/lynq-ril-service/src/common.cpp b/src/lynq/framework/lynq-ril-service/src/common.cpp
index c1d35f0..9132652 100755
--- a/src/lynq/framework/lynq-ril-service/src/common.cpp
+++ b/src/lynq/framework/lynq-ril-service/src/common.cpp
@@ -95,6 +95,7 @@
 */
 extern int current_data_reg = -1;
 extern int modemStatus = 0;
+int g_lynq_sim_state = -1;
 
 /*Warren add for SZZT 2021/11/14 end*/
 
@@ -370,22 +371,26 @@
     pthread_mutex_unlock(&s_state_change_mutex);
 }
 
-void lynq_wait_result_comeback(int mtime)
+int lynq_wait_result_comeback(int mtime)
 {
     RLOGD("wait_call_state");
     int sec = 0;
-    int usec = 0;
+    int ms = 0;
     struct timeval now;
     struct timespec timeout;
     gettimeofday(&now,NULL);
     sec = mtime/1000;
-    usec = mtime%1000;
+    ms = mtime%1000;
     timeout.tv_sec = now.tv_sec+sec;
-    timeout.tv_nsec = now.tv_usec*1000+usec*1000000;
+    unsigned long long ns;
+    ns = now.tv_usec*1000ull + ms*1000000ull;
+    timeout.tv_sec += ns/1000000000;
+    timeout.tv_nsec = ns % 1000000000;
     pthread_mutex_lock(&s_state_change_mutex);
-    pthread_cond_timedwait(&s_state_change_cond,&s_state_change_mutex,&timeout);
+    int ret = pthread_cond_timedwait(&s_state_change_cond,&s_state_change_mutex,&timeout);
     pthread_mutex_unlock(&s_state_change_mutex);
     RLOGD("wait_call_state end");
+    return ret;
 }
 
 int get_default_sim_voice(){
diff --git a/src/lynq/framework/lynq-ril-service/src/common.h b/src/lynq/framework/lynq-ril-service/src/common.h
index 4167da6..b0bdb3e 100755
--- a/src/lynq/framework/lynq-ril-service/src/common.h
+++ b/src/lynq/framework/lynq-ril-service/src/common.h
@@ -149,6 +149,7 @@
 */
 extern int current_data_reg;
 extern int modemStatus;
+extern int g_lynq_sim_state;
 /*Warren add for SZZT 2021/11/14 end*/
 
 // extern int lynq_output_LINFO_enable;
@@ -172,7 +173,7 @@
 void lynq_output_info(const char* format,...);
 
 void lynq_send_result_already(void);
-void lynq_wait_result_comeback(int mtime);
+int lynq_wait_result_comeback(int mtime);
 
 void updateCardStatusV6(RIL_CardStatus_v6 *card_status,int slot);
 char* getAid(int slot);
diff --git a/src/lynq/framework/lynq-ril-service/src/lynq_common.cpp b/src/lynq/framework/lynq-ril-service/src/lynq_common.cpp
index 418fe86..a5338bc 100755
--- a/src/lynq/framework/lynq-ril-service/src/lynq_common.cpp
+++ b/src/lynq/framework/lynq-ril-service/src/lynq_common.cpp
@@ -390,8 +390,11 @@
     char *argv_temp[3]={};
     argv_temp[0] = "RIL_REQUEST_DATA_REGISTRATION_STATE";
     android::lynqSendToRil(1,argv_temp,uToken);
-    ret = lynqATWaitWithTime(10);
-    printf("ret=%d\n,current_data_reg=%d\n",ret,current_data_reg);
+    if(lynqATWaitWithTime(2000))
+    {
+        RLOGD("function %s line %d time out", __FUNCTION__, __LINE__);
+        return -1;
+    }
     /*
     if(ret == ETIMEDOUT)
     {
@@ -405,11 +408,6 @@
     */
     if(current_data_reg!=0)
     {
-        int n = write(ttyGS3_fd,"+CME ERROR: 1\n",strlen("+CME ERROR: 1\n"));
-        if(n<0)
-        {
-            perror("lynq resp write:");
-        }
         return -1;
     }
     return 0;
@@ -887,21 +885,24 @@
     return 0;
 }
 
-int lynqATWaitWithTime(int time)
+int lynqATWaitWithTime(int mtime)
 {
-    int ret = 0;
-    struct timespec start_tm;
-    //struct timespec end_tm;
-    //int timeout_ms = 2500;
-    clock_gettime(CLOCK_MONOTONIC, &start_tm);
-    //struct timeval now;
-    struct timespec outTime;
-    //gettimeofday(&now, NULL);//now.tv_sec(s),now.tv_usec(Micro s)
-    outTime.tv_sec = start_tm.tv_sec + time;
+    RLOGD("wait_call_state");
+    int sec = 0;
+    int usec = 0;
+    struct timeval now;
+    struct timespec outtime;
+    gettimeofday(&now,NULL);
+    sec = mtime/1000;
+    outtime.tv_sec = now.tv_sec+sec;
+    unsigned long long ns;
+    ns = now.tv_usec*1000ull + (mtime%1000)*1000000ull;
+    outtime.tv_sec += ns/1000000000;
+    outtime.tv_nsec = ns%1000000000;
     pthread_mutex_lock(&lynq_at_mutex);
-    //ret = pthread_cond_timedwait(&lynq_at_cond,&lynq_at_mutex,&outTime);
-    pthread_cond_wait(&lynq_at_cond,&lynq_at_mutex);
+    int ret = pthread_cond_timedwait(&lynq_at_cond,&lynq_at_mutex,&outtime);
     pthread_mutex_unlock(&lynq_at_mutex);
+    RLOGD("wait_call_state end");
     return ret;
 }
 void lynqAtRespWatingEvent()
diff --git a/src/lynq/framework/lynq-ril-service/src/lynq_common.h b/src/lynq/framework/lynq-ril-service/src/lynq_common.h
index ec1e9e2..16b6403 100755
--- a/src/lynq/framework/lynq-ril-service/src/lynq_common.h
+++ b/src/lynq/framework/lynq-ril-service/src/lynq_common.h
@@ -122,4 +122,5 @@
 int lynq_modify_apn_info(int argc,char*argv[],char *rilReq, int uToken);
 void sendSignalApnChange();
 int waitApnResult();
+int checkDataRegistration(int uToken);
 #endif
diff --git a/src/lynq/framework/lynq-ril-service/src/ril.cpp b/src/lynq/framework/lynq-ril-service/src/ril.cpp
index d8d86b0..6bce06e 100755
--- a/src/lynq/framework/lynq-ril-service/src/ril.cpp
+++ b/src/lynq/framework/lynq-ril-service/src/ril.cpp
@@ -4029,6 +4029,11 @@
     }
 }
 
+static void lynq_get_sim_state(RIL_CardStatus_v6 *card_status)
+{
+    g_lynq_sim_state = card_status->card_state;
+}
+
 extern "C" void
 RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen) {
     RequestInfo *pRI;
@@ -4213,7 +4218,9 @@
                    if (responselen == sizeof (RIL_CardStatus_v6)) {
                        RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response);
                        updateCardStatusV6(p_cur, socket_id);
+                       lynq_get_sim_state(p_cur);
                    }
+                   lynq_send_result_already();
                    break;
                }
                case RIL_REQUEST_VOICE_RADIO_TECH:
diff --git a/src/lynq/framework/lynq-ril-service/src/sms/lynqSmsManager/lynq_sms_manager.cpp b/src/lynq/framework/lynq-ril-service/src/sms/lynqSmsManager/lynq_sms_manager.cpp
index 4b51c0d..95b5d13 100755
--- a/src/lynq/framework/lynq-ril-service/src/sms/lynqSmsManager/lynq_sms_manager.cpp
+++ b/src/lynq/framework/lynq-ril-service/src/sms/lynqSmsManager/lynq_sms_manager.cpp
@@ -341,6 +341,7 @@
     {

         sms_list->index[sms_indexs[i]-1]=sms_indexs[i];

         LYVERBLOG("test index =%d\n", sms_list->index[i]);

+        RLOGD("test index =%d   sms_indexs %d i %d\n", sms_list->index[sms_indexs[i]-1], sms_indexs[i], i);

     }

     sms_list->num_of_indexs = next_index;

     LYVERBLOG("list sms successfully");

diff --git a/src/lynq/framework/lynq-ril-service/src/sms/sms.cpp b/src/lynq/framework/lynq-ril-service/src/sms/sms.cpp
index da62829..e1e6919 100755
--- a/src/lynq/framework/lynq-ril-service/src/sms/sms.cpp
+++ b/src/lynq/framework/lynq-ril-service/src/sms/sms.cpp
@@ -1006,6 +1006,7 @@
     int error = -1;
     char indexBuf[256]={0};
     lynq_sms_list_t sms_list;
+    memset(&sms_list, 0, sizeof(lynq_sms_list_t));
     if(argc<1)
     {
         RLOGE("%s parameter error!",__func__);
@@ -1023,11 +1024,14 @@
     indexBuf[255]='\0';
     if(error==0)
     {
-        for(int i = 0;i < sms_list.num_of_indexs;i++)
+        int valid = 0;
+        for(int i = 0;valid < sms_list.num_of_indexs && i < 255;i++)
         {
             if(sms_list.index[i] != 0 && sms_list.index[i] < 255)
             {
+                RLOGD("TEST %d i %d", sms_list.index[i], i);
                 indexBuf[i]='1';
+                valid++;
             }
         }
         //writeStringToParcel(p,indexBuf);
diff --git a/src/lynq/lib/liblynq-call/include/libcall/lynq_call.h b/src/lynq/lib/liblynq-call/include/libcall/lynq_call.h
index 0b1b86e..21de03b 100755
--- a/src/lynq/lib/liblynq-call/include/libcall/lynq_call.h
+++ b/src/lynq/lib/liblynq-call/include/libcall/lynq_call.h
@@ -9,7 +9,8 @@
 #define LYNQ_CALL_MAX 3

 #define LYNQ_CALL_FAIL_VENDOR_CAUSE 64

 #define MAX_IP_LENGTH 128

-#define MAX_VLAN_INFO_LENGTH 128

+#define MAX_VLAN_INFO_LENGTH 32

+#define MAX_SSRC_INFO_LENGTH 10   /*2^32=4294967296, 10 digit*/

 

 typedef enum {

     LYNQ_CALL_FAIL_UNOBTAINABLE_NUMBER = 1,

@@ -148,18 +149,26 @@
     RTP_MODE_MAX

 }LYNQ_Rtp_Mode;

 

+typedef enum{

+    Rtp_Ssrc_random = 0,     

+    RTP_Ssrc_specific =1,   

+}LYNQ_Rtp_Ssrc_Mode;

+

 /*set*/

 int lynq_set_voice_audio_mode(const LYNQ_Audio_Mode audio_mode); 

 int lynq_set_remote_rtp_ip(const char* ip, const int ip_length);

 int lynq_set_vlan_info(const char* vlan_info, const int vlan_info_length);

 int lynq_set_rtp_port(const LYNQ_Rtp_Mode rtp_mode, const int port);

 int lynq_set_rtp_param(const int clock_rate,const int channels,const int latency); //only for client

+int lynq_set_call_rtp_ssrc(const LYNQ_Rtp_Ssrc_Mode ssrc_mode, const unsigned int ssrc);

+

 /*get*/

 LYNQ_Audio_Mode lynq_get_voice_audio_mode();

 int lynq_get_remote_rtp_ip(char* ip, const int ip_length);

 int lynq_get_vlan_info(char* vlan_info, const int vlan_info_length);

 int lynq_get_rtp_port(const LYNQ_Rtp_Mode rtp_mode, int* port);

 int lynq_get_rtp_param(int* clock_rate,int* channels, int* latency);//only for client

+int lynq_get_call_rtp_ssrc(LYNQ_Rtp_Ssrc_Mode* ssrc_mod, unsigned int* ssrc);

 /*Audio Path setting end*/

 

 void lynq_set_test_mode(const int test_mode);

diff --git a/src/lynq/lib/liblynq-call/lynq_call.cpp b/src/lynq/lib/liblynq-call/lynq_call.cpp
index 678b0f5..d973bc7 100755
--- a/src/lynq/lib/liblynq-call/lynq_call.cpp
+++ b/src/lynq/lib/liblynq-call/lynq_call.cpp
@@ -386,9 +386,10 @@
     pthread_cond_signal(&call_state_change_cond);

     pthread_mutex_unlock(&call_state_change_mutex);

 }

-void send_call_state_change()

+void send_call_state_change(int callid)

 {

     LYINFLOG("send call state change");

+    s_CallId = callid;

     pthread_mutex_lock(&s_call_state_change_mutex);

     pthread_cond_signal(&s_call_state_change_cond);

     pthread_mutex_unlock(&s_call_state_change_mutex);

@@ -418,6 +419,7 @@
 #endif

     pthread_mutex_lock(&s_notice_get_call_list_mutex);

     pthread_cleanup_push(cleanup_call_list_mutex, NULL); // thread cleanup handler

+    int tmp_call_id;

     while(s_call_list_loop)

     {

         update=0;       

@@ -458,10 +460,10 @@
                 {

                     LYINFLOG("MT/MO hungup,then clean call info local idx is %d id is %d",i, s_call_lists[i].call_id);

                     //update_end_state(i);//lei modify for:update end state for this call

+                    tmp_call_id = s_call_lists[i].call_id;

                     cleanCallList(i);

                     //Release the end handle

-                    //s_CallId = 

-                    send_call_state_change();//means mt/mo call is end

+                    send_call_state_change(tmp_call_id);//means mt/mo call is end

                     //cleanCallList(i);

                 }

             } //fix bug API-54

@@ -508,8 +510,7 @@
                 {

                     n = addAddr(call_list[i].addr,call_list[i].call_id);

                     updateCallList(&s_call_lists[n],call_list[i].call_id,call_list[i].call_state,call_list[i].toa,call_list[i].direction);

-                    s_CallId = call_list[i].call_id;

-                    send_call_state_change();

+                    send_call_state_change(call_list[i].call_id);

                 }

                 else if(s_call_lists[n].call_state == call_list[i].call_state)

                 {

@@ -521,7 +522,7 @@
                         **fix bug API-54

                         */

                         LYINFLOG("resend incoming call signal");

-                        send_call_state_change();

+                        send_call_state_change(call_list[i].call_id);

                     }

                 }

                 else 

@@ -529,7 +530,7 @@
                     LYINFLOG("state changed from %d to %d",s_call_lists[n].call_state,call_list[i].call_state);

                     

                     updateCallList(&s_call_lists[n],call_list[i].call_id,call_list[i].call_state,call_list[i].toa,call_list[i].direction);//update mt call

-                    send_call_state_change();

+                    send_call_state_change(call_list[i].call_id);

                 }                            

             }

             else

@@ -544,12 +545,11 @@
                         {

                             LYINFLOG("add a call id");

                             update=1;//for send sigal

-                            s_CallId = call_list[i].call_id;

                         }

                         LYINFLOG("local idx %d updated, original call id is %d origial addr is %s original state is %d",n,s_call_lists[n].call_id,s_call_lists[n].addr,s_call_lists[n].call_state);                    

                         updateCallList(&s_call_lists[n],call_list[i].call_id,call_list[i].call_state,call_list[i].toa,call_list[i].direction);

                         call_end = 1;

-                        send_call_state_change();//means mo call is success

+                        send_call_state_change(call_list[i].call_id);//means mo call is success

                         break;

                     }                    

                 }

@@ -890,14 +890,17 @@
     LYINFLOG("wait Call state Change");

     int ret = 0;

     int sec = 0;

-    int usec = 0;

+    int ms  = 0;

     struct timeval now;

     struct timespec timeout;

     gettimeofday(&now,NULL);

     sec = mtime/1000;

-    usec = mtime%1000;

+    ms  = mtime%1000;

     timeout.tv_sec = now.tv_sec+sec;

-    timeout.tv_nsec = now.tv_usec*1000+usec*1000000;

+    unsigned long long ns;

+    ns = now.tv_usec*1000ull + ms*1000000ull;

+    timeout.tv_sec += ns/1000000000;

+    timeout.tv_nsec = ns % 1000000000;

     pthread_mutex_lock(&call_state_change_mutex);

     ret = pthread_cond_timedwait(&call_state_change_cond,&call_state_change_mutex,&timeout);

     pthread_mutex_unlock(&call_state_change_mutex);

@@ -956,7 +959,6 @@
         s_module_isDial = 0;      

         LYERRLOG("lynq_call timeout:wait Call state fail!!! clear local idx %d",lynq_call_id);

         cleanCallList(lynq_call_id);

-        send_call_state_change();

         return LYNQ_E_TIME_OUT;

     }

     s_module_isDial = 0;

@@ -970,7 +972,6 @@
     {   

         LYERRLOG("lynq_call dial addr %s fail, invalid id",addr);

         cleanCallList(lynq_call_id);

-        send_call_state_change();

         return LYNQ_E_INVALID_ID_ANONALY;

     }        

 }

@@ -1011,17 +1012,16 @@
     if(ret!=0)

     {

         return ret; 

-    }     

+    }

     delete p; 

 

     int lynq_call_id=find_call_id_with_call_id(call_id);

-    /* lei  modify for API-857

     if(lynq_call_id!=INVALID_ID)

     {

+        //lei  modify for API-857

         cleanCallList(lynq_call_id);

+        send_call_state_change(call_id);

     }

-    */

-    

     return RESULT_OK;

 }

 int lynq_call_hungup_all()

@@ -1092,20 +1092,17 @@
         LYERRLOG("handle is NULL");

         return LYNQ_E_PARAMETER_ANONALY;

     }

+    if((*handle) <= 0)

+    {

+        LYINFLOG("lynq_get_current_call_state input error %d\n ", *handle);

+        return LYNQ_E_INVALID_ID_ANONALY;

+    }

     LYINFLOG("lynq_get_current_call_state %d\n ", *handle);

     lynq_call_id = find_call_id_with_call_id(*handle);

     if(lynq_call_id==INVALID_ID)

     {

-        //find end state

-        if((*handle) >= 0)

-        {

-            *call_state = (int)LYNQ_CALL_END;

-            return RESULT_OK; 

-        }

-        else

-        {

-            return LYNQ_E_INVALID_ID_ANONALY;

-        }

+        *call_state = (int)LYNQ_CALL_END;

+        return RESULT_OK;

     }

     *call_state = s_call_lists[lynq_call_id].call_state;

     *toa = s_call_lists[lynq_call_id].toa;

diff --git a/src/lynq/lib/liblynq-call/lynq_call_rtp.cpp b/src/lynq/lib/liblynq-call/lynq_call_rtp.cpp
index e22b016..9e0d546 100755
--- a/src/lynq/lib/liblynq-call/lynq_call_rtp.cpp
+++ b/src/lynq/lib/liblynq-call/lynq_call_rtp.cpp
@@ -19,14 +19,18 @@
 #include "lynq_call_common.h"

 

 #define RTP_FROM_CMD "gst-launch-1.0 -v udpsrc port=%d caps=\'application/x-rtp, media=(string)audio, clock-rate=(int)%d, channels=(int)%d\' ! rtpjitterbuffer latency=%d ! rtppcmadepay ! alawdec ! audioresample ! audioconvert ! alsasink device=\'hw:0,2\'"

-#define RTP_TO_CMD   "gst-launch-1.0 -v alsasrc device=\'hw:0,6\' ! audioconvert ! audioresample ! alawenc ! rtppcmapay ! udpsink host=%s %s auto-multicast=true port=%d"

+#define RTP_TO_CMD   "gst-launch-1.0 -v alsasrc device=\'hw:0,6\' ! audioconvert ! audioresample ! alawenc ! rtppcmapay ! %s udpsink host=%s %s auto-multicast=true port=%d"

 #define RTP_VLAN_INFO_FORMAT "multicast-iface=\"%s\""

+#define RTP_SSRC_INFO_FORMAT " rtpmux name=mux ssrc=%u !"

+

 #define USER_LOG_TAG "LYNQ_CALL"

 

 typedef struct

 {   

     char ip[MAX_IP_LENGTH];

     int port;   

+    LYNQ_Rtp_Ssrc_Mode ssrc_mode;

+    unsigned int ssrc;

     char vlan_info[MAX_VLAN_INFO_LENGTH];

 }lynq_rtp_server_info;

 

@@ -105,6 +109,7 @@
     int* rtp_mode= (int*) arg;

     char cmd[384];

     char vlan_para_string[sizeof(RTP_VLAN_INFO_FORMAT)+MAX_VLAN_INFO_LENGTH-2/*sizeof "%s"*/]={0};

+    char ssrc_para_string[sizeof(RTP_SSRC_INFO_FORMAT)+MAX_SSRC_INFO_LENGTH-2/*sizeof "%u"*/]={0};

     LYINFLOG("lynq_start_rtp_cmd: rtp_mode is %d",(*rtp_mode));    

     if ((*rtp_mode) == RTP_CLIENT)

     {

@@ -120,10 +125,15 @@
         {

            sprintf(vlan_para_string,RTP_VLAN_INFO_FORMAT,g_rtp_server_info.vlan_info);

         }

+

+        if(g_rtp_server_info.ssrc_mode == RTP_Ssrc_specific)

+        {

+           sprintf(ssrc_para_string,RTP_SSRC_INFO_FORMAT,g_rtp_server_info.ssrc);

+        }

         sprintf(cmd,RTP_TO_CMD,   \

-        g_rtp_server_info.ip,vlan_para_string,g_rtp_server_info.port);       

+        ssrc_para_string, g_rtp_server_info.ip,vlan_para_string,g_rtp_server_info.port);       

         

-    //  LYINFLOG("start to rtp play: cmd is %s",cmd);

+        LYINFLOG("start to rtp play: cmd is %s",cmd);

         system(cmd);    

     }

     return NULL;

@@ -275,6 +285,17 @@
     LYINFLOG("lynq_set_rtp_param suc: clockrate is %d, channels is %d, latency is %d", clock_rate, channels, latency);

     return RESULT_OK;  

 }

+int lynq_set_call_rtp_ssrc(const LYNQ_Rtp_Ssrc_Mode ssrc_mode,const unsigned int ssrc)

+{

+    if(ssrc_mode < Rtp_Ssrc_random || ssrc_mode > RTP_Ssrc_specific)

+    {

+        return LYNQ_E_PARAMETER_ANONALY;

+    }

+    g_rtp_server_info.ssrc_mode = ssrc_mode;

+    g_rtp_server_info.ssrc = ssrc ;

+    LYINFLOG("%s suc: param is %d %d", __func__, ssrc_mode, ssrc);

+    return RESULT_OK;

+}

 /*get*/

 LYNQ_Audio_Mode lynq_get_voice_audio_mode()

 {

@@ -355,3 +376,16 @@
 

     return RESULT_OK;  

 }

+int lynq_get_call_rtp_ssrc(LYNQ_Rtp_Ssrc_Mode* ssrc_mode, unsigned int* ssrc)

+{

+    if(ssrc_mode == NULL || ssrc ==NULL)

+    {

+        LYERRLOG("input parameter is NULL");

+        return LYNQ_E_PARAMETER_ANONALY;

+    }

+    

+    *ssrc_mode = g_rtp_server_info.ssrc_mode;

+    *ssrc = g_rtp_server_info.ssrc ;   

+    

+    return RESULT_OK;

+}

diff --git a/src/lynq/lib/liblynq-data/lynq_data.cpp b/src/lynq/lib/liblynq-data/lynq_data.cpp
index 6772e2d..c0af733 100755
--- a/src/lynq/lib/liblynq-data/lynq_data.cpp
+++ b/src/lynq/lib/liblynq-data/lynq_data.cpp
@@ -74,6 +74,8 @@
 
 static int data_waiting_status = 0;
 
+static int data_invaild_error = 0;
+
 /**g_lynq_data_init_flag
 * @brief mark data initialization state
 * 0:deinit status
@@ -102,9 +104,11 @@
 int getLynqApnID(char apnType[])
 {
     int ret = 0;
+    int len = 0;
     for(ret;ret<LYNQ_APN_CHANNEL_MAX;ret++)
     {
-        if(strcmp(lynq_apn_table[ret].apnType,apnType)==0)
+        len = strlen(lynq_apn_table[ret].apnType)<strlen(apnType) ? strlen(lynq_apn_table[ret].apnType):strlen(apnType);
+        if(strncmp(lynq_apn_table[ret].apnType,apnType,len)==0)
         {
             return ret;
         }
@@ -145,6 +149,11 @@
 }
 int getUnusedElement()
 {
+	if (lynq_apn_table == NULL)
+	{
+		LYERRLOG("get UnusedElemnt apn_table is null");
+		return -1;
+	}
     for(int i=0;i < LYNQ_APN_CHANNEL_MAX; i++)
     {
         if(lynq_apn_table[i].hasUsed!=1)
@@ -152,6 +161,7 @@
             return i;
         }
     }
+	LYERRLOG("None of get unused Element");
     return -1;
 }
 int updateApn(char apnType[])
@@ -347,6 +357,24 @@
     }    
 }
 
+int printf_apn_table()
+{
+    int ret = 0;
+	if (lynq_apn_table == NULL)
+	{
+		LYERRLOG("apn table is null");
+		return -1;
+	}	
+    for(ret;ret<LYNQ_APN_CHANNEL_MAX;ret++)
+    {
+        LYINFLOG("[Typethree test info]apn=%s ;apntype=%s ;ifname=%s ;hasTimeout = %d ; hasUsed = %d", \
+        lynq_apn_table[ret].apn,lynq_apn_table[ret].apnType,lynq_apn_table[ret].ifaceName, \
+        lynq_apn_table[ret].hasTimeout,lynq_apn_table[ret].hasUsed);
+    }
+    return 0;
+}
+
+
 void urc_msg_process(Parcel *p)
 {
     int len;
@@ -394,19 +422,23 @@
                 }
                 //sendSignalDataCallStateChange();
                 int apnId = getLynqApnID(apnType);
+                LYINFLOG("URC apnType:%s,ifaceName:%s,apn:%s pdnState:%d",apnType,ifaceName,apn,pdnState);
                 if(apnId >= 0)
                 {
                     if(lynq_apn_table[apnId].hasTimeout==1)
                     {
+                        /*whether timeout?,real or not,*/
+                        printf_apn_table();
                         LYERRLOG("apn:%s has time out,deacive this apn",lynq_apn_table[apnId].apn);
                         if (NULL != lynq_apn_table[apnId].apn && NULL != lynq_apn_table[apnId].apnType && strlen(lynq_apn_table[apnId].apn)>0)
                         {
                             LYERRLOG("deactive this time out APN");
                             lynq_deactive_data_call(&apnId);
                         }
-                        else 
+                        else
                         {
-                            LYERRLOG("this table is invalid");
+                            /*if apn lose,update apn and deactive all apn*/
+                            LYERRLOG("this table is invalid update APN table");
                         }
                         break;
                     }
@@ -415,7 +447,9 @@
                 /*To be completed*/
                 else
                 {
-                    LYERRLOG("invalid apnId");
+					data_invaild_error = 1;
+                    printf_apn_table();
+                    LYERRLOG("invalid apnId:%d",apnId);
                     break;
                 }
                 pthread_mutex_lock(&s_lynq_urc_vector_mutex);
@@ -587,6 +621,13 @@
     client.paramLen = 0;
     bzero(client.param,LYNQ_REQUEST_PARAM_BUF);
     LYINFLOG("uToken=%d,request=%d,paralen=%d,param=%s",client.uToken,client.request,client.paramLen,client.param);
+    lynq_data_call_id = updateApn("default");
+    if (lynq_data_call_id < 0)
+    {
+        LYERRLOG("update apn table fail error id = %d",lynq_data_call_id);
+        return -1;
+    }
+    lynq_data_call = 1;
     pthread_mutex_lock(&g_lynq_data_sendto_mutex);
     if(send_request(lynq_client_sockfd,&client)==-1)
     {
@@ -598,8 +639,6 @@
     pthread_mutex_unlock(&g_lynq_data_sendto_mutex);
     JumpHeader(p,&resp_type,&request,&slot_id,&error);
     LYINFLOG("resp_type=%d,request=%d,slot_id=%d,error_code=%d",resp_type,request,slot_id,error);
-    lynq_data_call_id = updateApn("default");
-    lynq_data_call = 1;
     if(error==0)
     {
         if (waitDataCallstateChange(60000) == ETIMEDOUT) // 60s
@@ -607,6 +646,12 @@
             error = LYNQ_E_TIME_OUT;
             LYERRLOG("timeout:wait data Call state fail!!!");
             lynq_apn_table[lynq_data_call_id].hasTimeout = 1;
+			if (data_invaild_error == 1)
+			{
+				data_invaild_error = 0;
+				LYERRLOG("urc apn info error!!!");
+				return 8085;
+			}
             return error;
         }
         *handle = lynq_data_call_id;
@@ -725,6 +770,13 @@
     bzero(client.param,LYNQ_REQUEST_PARAM_BUF);
     sprintf(client.param,"%s %s %s %s %s %s %s",apn,apnType,argv[1],argv[2],argv[3],argv[4],argv[5]);
     LYINFLOG("uToken=%d,request=%d,paralen=%d,param=%s",client.uToken,client.request,client.paramLen,client.param);
+    lynq_data_call_id = updateApn(apnType);
+    if (lynq_data_call_id < 0)
+    {
+        LYERRLOG("update apn table fail error id = %d",lynq_data_call_id);
+        return -1;
+    }
+    lynq_data_call = 1;
     pthread_mutex_lock(&g_lynq_data_sendto_mutex);
     if(send_request(lynq_client_sockfd,&client)==-1)
     {
@@ -736,8 +788,6 @@
     pthread_mutex_unlock(&g_lynq_data_sendto_mutex);
     JumpHeader(p,&resp_type,&request,&slot_id,&error);
     LYINFLOG("resp_type=%d,request=%d,slot_id=%d,error_code=%d",resp_type,request,slot_id,error);
-    lynq_data_call_id = updateApn(apnType);
-    lynq_data_call = 1;
     if(error==0)
     {
         if(waitDataCallstateChange(60000)==ETIMEDOUT)//60s
@@ -745,6 +795,12 @@
             error = LYNQ_E_TIME_OUT;
             LYERRLOG("timeout:wait data Call state fail!!!");
             lynq_apn_table[lynq_data_call_id].hasTimeout = 1;
+			if (data_invaild_error == 1)
+			{
+				data_invaild_error = 0;
+				LYERRLOG("urc apn info error!!!");
+				return 8085;
+			}
             return error;
         }
         *handle = lynq_data_call_id;
diff --git a/src/lynq/lib/liblynq-data/makefile b/src/lynq/lib/liblynq-data/makefile
index 53ed1d4..5d8598d 100755
--- a/src/lynq/lib/liblynq-data/makefile
+++ b/src/lynq/lib/liblynq-data/makefile
@@ -5,11 +5,7 @@
                 -std=gnu++14 \
                 -g -Os \
                 -flto \
-                -DRIL_SHLIB \
-                -DATCI_PARSE \
                 -fPIC \
-                -DKEEP_ALIVE \
-                -DECALL_SUPPORT \
                 -fpermissive \
 
 
diff --git a/src/lynq/lib/liblynq-network/include/lynq_network/lynq_network.h b/src/lynq/lib/liblynq-network/include/lynq_network/lynq_network.h
index 5b2ce3c..ba7c1f4 100755
--- a/src/lynq/lib/liblynq-network/include/lynq_network/lynq_network.h
+++ b/src/lynq/lib/liblynq-network/include/lynq_network/lynq_network.h
@@ -52,6 +52,12 @@
                       * Range [-23, 40], INT_MAX means invalid/unreported.*/

 }signalStrength_t;

 

+typedef enum { 

+    NETWORK_RADIO_ON_TYPE_CFUN_0=0,  

+    NETWORK_RADIO_ON_TYPE_NORMAL_MODE=1,

+    NETWORK_RADIO_ON_TYPE_FLIGHT_MODE=4,

+}lynq_network_radio_on_type;  

+

 int lynq_network_init(int utoken);

 int lynq_network_deinit(void);

 int lynq_query_operater(char *OperatorFN,char *OperatorSH,char *MccMnc);

@@ -65,7 +71,7 @@
 int lynq_set_unsol_cell_info_listrate(const int rate);

 int lynq_set_band_mode(const int bandmode);

 int lynq_query_available_bandmode(int availBanMode[]);

-int lynq_radio_on(const int data);

+int lynq_radio_on(const lynq_network_radio_on_type type);

 int lynq_query_radio_state(int *radio_state);

 int lynq_query_radio_tech(int* radioTech);

 int lynq_solicited_signal_strength(signalStrength_t *solSigStren);

diff --git a/src/lynq/lib/liblynq-network/lynq_network.cpp b/src/lynq/lib/liblynq-network/lynq_network.cpp
index 98e33f6..dd45fdc 100755
--- a/src/lynq/lib/liblynq-network/lynq_network.cpp
+++ b/src/lynq/lib/liblynq-network/lynq_network.cpp
@@ -757,21 +757,30 @@
     return RESULT_OK;                

 }

 

-int lynq_radio_on(const int data)

+int lynq_radio_on(const lynq_network_radio_on_type type)

 {     

     if(g_module_init_flag != MODULE_RUNNING)

     {

         LYERRLOG("%s module state %d error",__func__,g_module_init_flag);

         return LYNQ_E_CONFLICT;

     }

-    if (data < 0 || data > 1)

+    if (type != NETWORK_RADIO_ON_TYPE_CFUN_0  && type != NETWORK_RADIO_ON_TYPE_NORMAL_MODE && type!=NETWORK_RADIO_ON_TYPE_FLIGHT_MODE)

     {

-        LYERRLOG("%s parameter %d error",__func__,data);  

+        LYERRLOG("%s parameter %d error",__func__,type);  

         return LYNQ_E_PARAMETER_ANONALY;

     }     

     

     Parcel* p=NULL;      

-    int ret=lynq_send_common_request(p,65,RIL_REQUEST_RADIO_POWER,1,"%d",data);

+    int ret;

+

+    if(type==NETWORK_RADIO_ON_TYPE_CFUN_0)

+    {

+        ret=lynq_send_common_request(p,g_wait_time,RIL_REQUEST_OEM_HOOK_RAW,1,"%s","AT+CFUN=0");

+    }

+    else 

+    {

+        ret=lynq_send_common_request(p,65,RIL_REQUEST_RADIO_POWER,1,"%d",(type==NETWORK_RADIO_ON_TYPE_NORMAL_MODE));

+    }

 

     if(ret!=RESULT_OK)

     {

@@ -779,7 +788,7 @@
         return ret;  

     }       

 

-    LYINFLOG("%s set %d suc",__func__,data);  

+    LYINFLOG("%s set %d suc",__func__,type);  

     delete p;

     return RESULT_OK;  

 }

diff --git a/src/lynq/lib/liblynq-wifi6/include/libwifi6.h b/src/lynq/lib/liblynq-wifi6/include/libwifi6.h
index 7e429bc..0a2771d 100755
--- a/src/lynq/lib/liblynq-wifi6/include/libwifi6.h
+++ b/src/lynq/lib/liblynq-wifi6/include/libwifi6.h
@@ -18,9 +18,11 @@
 
 typedef enum {
     LYNQ_WIFI_AUTH_OPEN = 0,
-    LYNQ_WIFI_AUTH_WEP,
+    LYNQ_WIFI_AUTH_WEP,            // not support WEP
     LYNQ_WIFI_AUTH_WPA_PSK,
     LYNQ_WIFI_AUTH_WPA2_PSK,
+    LYNQ_WIFI_AUTH_WPA2_WPA3_PSK,
+    LYNQ_WIFI_AUTH_WPA3_PSK,
 }lynq_wifi_auth_s;
 
 typedef enum {
@@ -53,7 +55,7 @@
 {
     char ap_ip[32];
     char ap_mac[32];
-    char ap_ssid[32];
+    char ap_ssid[64];
     char psw[64];                      //password 
     lynq_wifi_auth_s auth;
     lynq_wifi_band_m band;
@@ -70,7 +72,7 @@
 typedef struct scan_info
 {
     char mac[32];
-    char ssid[32];
+    char ssid[64];
     lynq_wifi_band_m band;
     lynq_wifi_auth_s auth;
     int rssi;
diff --git a/src/lynq/lib/liblynq-wifi6/libwifi6.c b/src/lynq/lib/liblynq-wifi6/libwifi6.c
index 25e429b..6c45654 100755
--- a/src/lynq/lib/liblynq-wifi6/libwifi6.c
+++ b/src/lynq/lib/liblynq-wifi6/libwifi6.c
@@ -21,6 +21,7 @@
 #include <arpa/inet.h>
 #include <netdb.h>
 #include <ifaddrs.h>
+#include "log/log.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -29,6 +30,8 @@
 }
 #endif
 
+#undef LOG_TAG
+#define LOG_TAG "LYNQ_WIFI"
 #define MAX_CMD 128
 #define MAX_RET 4096
 #define MODE_LEN 10
@@ -89,7 +92,7 @@
 {
     int ret;
     if (ctrl->ctrl == NULL) {
-        printf("local_wpa_ctrl_request ctrl is null\n");
+        RLOGE("local_wpa_ctrl_request ctrl is null\n");
         return -1;
     }
     pthread_mutex_lock(&ctrl->mutex);
@@ -102,7 +105,7 @@
     int repeat_cnt;
     struct local_wpa_ctrl *lynq_wpa_ctrl = NULL;
     pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
-    printf("inner_get_wpa_ctrl\n");
+    RLOGD("inner_get_wpa_ctrl\n");
     for (repeat_cnt = 0; repeat_cnt < 5 && NULL == g_lynq_wpa_ctrl[index]; repeat_cnt++) {
         pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
 //        printf("wait enable finish\n");
@@ -110,13 +113,13 @@
         pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
     }
     if (NULL == g_lynq_wpa_ctrl[index]) {
-        printf("NULL == g_lynq_wpa_ctrl[index]\n");
+        RLOGE("NULL == g_lynq_wpa_ctrl[index]");
         goto out_addr;
     }
     if (NULL == g_lynq_wpa_ctrl[index]->ctrl) {
         g_lynq_wpa_ctrl[index]->ctrl = wpa_ctrl_open(CTRL_PATH[index]);
         if (NULL == g_lynq_wpa_ctrl[index]->ctrl) {
-            printf("wpa_ctrl_open fail\n");
+            RLOGE("wpa_ctrl_open fail\n");
             goto out_addr;
         }
         pthread_mutex_init(&g_lynq_wpa_ctrl[index]->mutex, NULL);
@@ -136,7 +139,7 @@
 #define CHECK_IDX(idx, type) do { \
         if ( (idx == LYNQ_WIFI_INTERFACE_0 && type != CTRL_STA) || (idx == LYNQ_WIFI_INTERFACE_1 && type != CTRL_AP) \
                 || idx < LYNQ_WIFI_INTERFACE_0 || idx > LYNQ_WIFI_INTERFACE_1 ) { \
-            printf("not support create [%s] on interface [%d]\n", (type == CTRL_STA ? "station" : "ap"), idx); \
+            RLOGE("not support create [%s] on interface [%d]\n", (type == CTRL_STA ? "station" : "ap"), idx); \
             return -1; \
         } \
     }while (0)
@@ -153,23 +156,23 @@
 #define DO_REQUEST(cmd_str) do { \
         reply_len = MAX_RET;\
         cmd_reply[0] = '\0'; \
-        printf("to call [%s]\n", cmd_str);  \
+        RLOGD("to call [%s]\n", cmd_str);  \
         ret = local_wpa_ctrl_request(lynq_wpa_ctrl, cmd_str, strlen(cmd_str), cmd_reply, &reply_len, NULL); \
         if (ret != 0) { \
-            printf("call "#cmd_str" fail %d\n", ret); \
+            RLOGE("call "#cmd_str" fail %d\n", ret); \
             return ret; \
         } \
         cmd_reply[reply_len+1] = '\0'; \
-        printf("cmd replay [ %s ]\n", cmd_reply); \
+        RLOGD("cmd replay [ %s ]\n", cmd_reply); \
     }while(0)
 
 #define DO_OK_FAIL_REQUEST(cmd_str) do { \
         DO_REQUEST(cmd_str); \
         if (reply_len >=4 && memcmp(cmd_reply, "FAIL", 4) == 0 ) {\
-            printf("cmd "#cmd_str" return FAIL\n"); \
+            RLOGE("cmd "#cmd_str" return FAIL\n"); \
             return -1; \
         } else if (reply_len >=2 && memcmp(cmd_reply, "OK", 2) != 0) { \
-            printf("cmd "#cmd_str" return not OK|FAIL\n"); \
+            RLOGE("cmd "#cmd_str" return not OK|FAIL\n"); \
             return -1; \
         } \
     }while (0)
@@ -184,10 +187,13 @@
     struct wpa_ctrl *lynq_wpa_ctrl = NULL;
     g_ap_watcher_stop_flag = 0;
 
-    while (g_ap_watcher_stop_flag == 0) {
-        if (lynq_wpa_ctrl == NULL) {
+    while (g_ap_watcher_stop_flag == 0)
+    {
+        if (lynq_wpa_ctrl == NULL)
+	{
             lynq_wpa_ctrl = wpa_ctrl_open(CTRL_PATH[CTRL_AP]); //@todo temp change
-            if (lynq_wpa_ctrl == NULL) {
+            if (lynq_wpa_ctrl == NULL)
+	    {
                 usleep(100*1000);
                 continue;
             }
@@ -196,32 +202,40 @@
             g_ap_watcher_started_flag = 1;
         }
 
-        if ( 0 == wpa_ctrl_pending(lynq_wpa_ctrl)) {
+        if ( 0 == wpa_ctrl_pending(lynq_wpa_ctrl))
+	{
             usleep(100*1000);
             continue;
         }
         memset(msg_notify, 0, MAX_RET);
         len = MAX_RET;
-        if (!wpa_ctrl_recv(lynq_wpa_ctrl, msg_notify, &len)) {
+        if (!wpa_ctrl_recv(lynq_wpa_ctrl, msg_notify, &len))
+	{
             msg_notify[len+1] = '\0';
-            printf("ap------> %s\n", msg_notify);
+            RLOGD("STAWatcherThreadProc ap------> %s\n", msg_notify);
 //you.chen change for tv-box start
-            if (strstr(msg_notify, "AP-STA-DISCONNECTED") != NULL) {
+            if (strstr(msg_notify, "AP-STA-DISCONNECTED") != NULL)
+	    {
                 if (g_ap_callback_func != NULL)
                     g_ap_callback_func(g_ap_callback_priv, LYNQ_WIFI_STATUS_DISCONNECT);
-                if (g_gbw_enabled == 1 && g_gbw_mac != NULL) {
-                    printf("disconect %d, %s ,%s\n", g_gbw_enabled, g_gbw_mac, strstr(msg_notify, (const char*)g_gbw_mac));
-                    if (strstr(msg_notify, (const char*)g_gbw_mac) != NULL) {
+                if (g_gbw_enabled == 1 && g_gbw_mac != NULL)
+		{
+                    RLOGD("disconect %d, %s ,%s\n", g_gbw_enabled, g_gbw_mac, strstr(msg_notify, (const char*)g_gbw_mac));
+                    if (strstr(msg_notify, (const char*)g_gbw_mac) != NULL)
+		    {
                         stopGBW();
                     }
                 }
             }
-            else if (strstr(msg_notify, "AP-STA-CONNECTED") != NULL) {
+            else if (strstr(msg_notify, "AP-STA-CONNECTED") != NULL)
+	    {
                 if (g_ap_callback_func != NULL)
                     g_ap_callback_func(g_ap_callback_priv, LYNQ_WIFI_STATUS_CONNECT);
-                if (g_gbw_enabled == 1 && g_gbw_mac != NULL) {
-                    printf("conect %d, %s ,%s\n", g_gbw_enabled, g_gbw_mac, strstr(msg_notify, (const char*)g_gbw_mac));
-                    if (strstr(msg_notify, (const char*)g_gbw_mac) != NULL) {
+                if (g_gbw_enabled == 1 && g_gbw_mac != NULL)
+		{
+                    RLOGD("conect %d, %s ,%s\n", g_gbw_enabled, g_gbw_mac, strstr(msg_notify, (const char*)g_gbw_mac));
+                    if (strstr(msg_notify, (const char*)g_gbw_mac) != NULL)
+		    {
                         startGBW();
                     }
                 }
@@ -229,7 +243,8 @@
 //you.chen add for tv-box end
         } // end if (!wpa_ctrl_recv(lynq_wpa_ctrl, msg_notify, &len))
     } // end while (g_ap_watcher_stop_flag == 0)
-    if (lynq_wpa_ctrl != NULL) {
+    if (lynq_wpa_ctrl != NULL)
+    {
         wpa_ctrl_detach(lynq_wpa_ctrl);
         wpa_ctrl_close(lynq_wpa_ctrl);
     }
@@ -244,10 +259,13 @@
     struct wpa_ctrl *lynq_wpa_ctrl = NULL;
     g_sta_watcher_stop_flag = 0;
 
-    while (g_sta_watcher_stop_flag == 0) {
-        if (lynq_wpa_ctrl == NULL) {
+    while (g_sta_watcher_stop_flag == 0)
+    {
+        if (lynq_wpa_ctrl == NULL)
+	{
             lynq_wpa_ctrl = wpa_ctrl_open(CTRL_PATH[CTRL_STA]);
-            if (lynq_wpa_ctrl == NULL) {
+            if (lynq_wpa_ctrl == NULL)
+	    {
                 usleep(100*1000);
                 continue;
             }
@@ -256,51 +274,64 @@
             g_sta_watcher_started_flag = 1;
         }
 
-        if ( 0 == wpa_ctrl_pending(lynq_wpa_ctrl)) {
+        if ( 0 == wpa_ctrl_pending(lynq_wpa_ctrl))
+	{
             usleep(100*1000);
             continue;
         }
         memset(msg_notify, 0, MAX_RET);
         len = MAX_RET;
-        if (!wpa_ctrl_recv(lynq_wpa_ctrl, msg_notify, &len)) {
+        if (!wpa_ctrl_recv(lynq_wpa_ctrl, msg_notify, &len))
+	{
             msg_notify[len+1] = '\0';
-            printf("sta ------> %s\n", msg_notify);
-            if (strstr(msg_notify, state_scan_result) != NULL) {
+            RLOGD("STAWatcherThreadProc sta ------> %s\n", msg_notify);
+            if (strstr(msg_notify, state_scan_result) != NULL)
+	    {
                 g_sta_scan_finish_flag = 1;
             }
 
-            if (g_sta_callback_func == NULL) {
+            if (g_sta_callback_func == NULL)
+	    {
                 continue;
             }
             error = -1;
-            if (strstr(msg_notify, "CTRL-EVENT-SCAN-RESULTS") != NULL) {
+            if (strstr(msg_notify, "CTRL-EVENT-SCAN-RESULTS") != NULL)
+	    {
                 g_sta_callback_func(g_ap_callback_priv, LYNQ_WIFI_STA_STATUS_SCAN_RESULT, error);
             }
-            else if (strstr(msg_notify, "CTRL-EVENT-CONNECTED") != NULL) {
+            else if (strstr(msg_notify, "CTRL-EVENT-CONNECTED") != NULL)
+	    {
                 g_sta_callback_func(g_ap_callback_priv, LYNQ_WIFI_STA_STATUS_CONNECT, error);
             }
-            else if (strstr(msg_notify, "CTRL-EVENT-SSID-TEMP-DISABLED") != NULL) {
+            else if (strstr(msg_notify, "CTRL-EVENT-SSID-TEMP-DISABLED") != NULL)
+	    {
                 pReason = strstr(msg_notify, "reason=");
-                if (pReason != NULL) {
+                if (pReason != NULL)
+		{
                     pReason += strlen("reason=");
-                    if (memcmp(pReason, "CONN_FAILED", 11) == 0) {
+                    if (memcmp(pReason, "CONN_FAILED", 11) == 0)
+		    {
                         error = LYNQ_TIME_OUT;
                     }
-                    else if (memcmp(pReason, "WRONG_KEY", 9) == 0) {
+                    else if (memcmp(pReason, "WRONG_KEY", 9) == 0)
+		    {
                         error = LYNQ_PSW_ERROR;
                     }
                     g_sta_callback_func(g_ap_callback_priv, LYNQ_WIFI_STA_STATUS_DISCONNECT, error);
                 }
             }
-            else if (strstr(msg_notify, "CTRL-EVENT-DISCONNECTED") != NULL) {
+            else if (strstr(msg_notify, "CTRL-EVENT-DISCONNECTED") != NULL)
+	    {
                 g_sta_callback_func(g_ap_callback_priv, LYNQ_WIFI_STA_STATUS_DISCONNECT, error);
             }
-            else if (strstr(msg_notify, "CTRL-EVENT-NETWORK-NOT-FOUND") != NULL) {
+            else if (strstr(msg_notify, "CTRL-EVENT-NETWORK-NOT-FOUND") != NULL)
+	    {
                 g_sta_callback_func(g_ap_callback_priv, LYNQ_WIFI_STA_STATUS_DISCONNECT, LYNQ_NOT_FIND_AP);
             }
         }
     }
-    if (lynq_wpa_ctrl != NULL) {
+    if (lynq_wpa_ctrl != NULL)
+    {
         wpa_ctrl_detach(lynq_wpa_ctrl);
         wpa_ctrl_close(lynq_wpa_ctrl);
     }
@@ -310,13 +341,14 @@
 {
     int ret = 0;
     int i;
+    RLOGD("enter lynq_wifi_enable");
     pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
 
-    if (g_lynq_wpa_ctrl[0] != NULL && g_lynq_wpa_ctrl[1] != NULL) {
+    if (g_lynq_wpa_ctrl[0] != NULL && g_lynq_wpa_ctrl[1] != NULL)
+    {
         goto out_enable;
     }
 
-    printf("lynq_wifi_enable1\n");
     const char * cmd_check_service =
             "state=`systemctl is-active wg870_drv_insmod.service`\n"
             "[ \"\"$state == \"active\" ] && exit 0\n"
@@ -326,20 +358,26 @@
 //    }
 
     ret = system(cmd_check_service);
-    if (ret != 0) {
-        printf("service state %d\n", ret);
+    if (ret != 0)
+    {
+        //printf("service state %d\n", ret);
+        RLOGE("[wifi error]service state %d",ret);
         ret = -1;
         goto out_enable;
     }
 
-    for (i=0; i<10; i++) {
+    RLOGD("check service state is OK");
+    for (i=0; i<10; i++)
+    {
         if (system("connmanctl technologies | grep -q \"/net/connman/technology/wifi\"") == 0) {
             break;
         }
         usleep(300*1000);
     }
 
-    if (i >= 10) {
+    if (i >= 10)
+    {
+	RLOGE("[wifi error] check connman technologies no wifi");
         ret = -1;
         goto out_enable;
     }
@@ -360,7 +398,8 @@
     }
     //@todo delete add temp check for socket avilable end (20220606)
 
-    if (0 != system("ifconfig | grep -q ap0")) {
+    if (0 != system("ifconfig | grep -q ap0"))
+    {
         system("connmanctl enable wifi");
         usleep(300*1000);
         system("wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 disconnect");
@@ -370,30 +409,34 @@
         usleep(300*1000);
         system("wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=ap0 disconnect");
     }
-    ret = system("wl -i wlan0 PM 0");
-    if( ret != 0)
+    if (g_ap_watcher_pid == 0 )
     {
-        printf("Set sta PM work mode to 0 fail,ret is%d",ret);
-    }
-    if (g_ap_watcher_pid == 0 ) {
         ret=pthread_create(&g_ap_watcher_pid,NULL,APWatcherThreadProc,NULL);
-        if(ret<0){
+        if(ret<0)
+	{
+            RLOGE("[wifi error]creat APWatcherThreadProc fail");
             ret = -1;
             goto out_enable;
         }
     }
-
+    
+    RLOGD("creat APWatcherTheradProc susccs");
     if (g_sta_watcher_pid == 0 ) {
         ret=pthread_create(&g_sta_watcher_pid,NULL,STAWatcherThreadProc,NULL);
-        if(ret<0){
+        if(ret<0)
+	{
+            RLOGE("[wifi error]creat STAWatcherThreadProc fail");
             ret = -1;
             goto out_enable;
         }
     }
 
-    for (i=0; i<10; i++) {
+    RLOGD("creat STAWatcherTheradProc susccs");
+    for (i=0; i<10; i++)
+    {
         usleep(300*1000);
-        if (g_ap_watcher_started_flag == 1 && g_sta_watcher_started_flag == 1) {
+        if (g_ap_watcher_started_flag == 1 && g_sta_watcher_started_flag == 1)
+	{
             break;
         }
     }
@@ -409,6 +452,7 @@
 
 int lynq_wifi_disable(void)
 {
+    RLOGD("enter lynq_wifi_disable");
     pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
     g_ap_watcher_stop_flag = 1;
     g_sta_watcher_stop_flag = 1;
@@ -515,17 +559,20 @@
 static int inner_get_param(int interface, int net_no, char* param_name, char * out_put) {
     int i, ssid_len;
     char lynq_cmd_get[128]={0};
-
-    if (out_put == NULL) {
-        printf("output ptr is null\n");
+    RLOGD("enter inner_get_param");
+    if (out_put == NULL)
+    {
+        RLOGE("output ptr is null");
         return -1;
     }
-    if (param_name == NULL) {
-        printf("param ptr is null");
+    if (param_name == NULL)
+    {
+        RLOGE("param ptr is null");
         return -1;
     }
-    if (param_name[0] == '\0') {
-        printf("param is empty");
+    if (param_name[0] == '\0')
+    {
+        RLOGE("param is empty");
         return -1;
     }
 
@@ -535,14 +582,17 @@
 
     DO_REQUEST(lynq_cmd_get);
 
-    if (memcmp(cmd_reply, "FAIL", 4) == 0) {
+    if (memcmp(cmd_reply, "FAIL", 4) == 0)
+    {
+        RLOGE("wpa_supplicant return cmd_reply is FAIL");
         return -1;
     }
 
 //    printf("reply len %d, %08x\n", reply_len, (int)out_put);
     if (strcmp(param_name, "ssid") == 0)
     {
-        if (cmd_reply[0] == '\"') {
+        if (cmd_reply[0] == '\"')
+	{
             ssid_len = reply_len - 1;
             memcpy(out_put, cmd_reply + 1, ssid_len);
             if (out_put[ssid_len-1] == '\"')
@@ -554,7 +604,8 @@
                 out_put[ssid_len] = '\0';
             }
         }
-        else{
+        else
+	{
             ssid_len = reply_len / 2;
             for(i=0; i<ssid_len; i++)
             {
@@ -574,15 +625,18 @@
     int ret = 0;
     char * end = str + len - 1;
     results[ret++] = str;
-    while(str < end) {
-        if (*str == delimiter) {
+    while(str < end)
+    {
+        if (*str == delimiter)
+	{
             *str++ = '\0';
             results[ret++] = str;
             continue;
         }
         str++;
     }
-    if (*str == delimiter) {
+    if (*str == delimiter)
+    {
         *str = '\0';
     }
 
@@ -604,7 +658,7 @@
     {
         *p = '\0';
     }
-    printf("inner_get_ip_by_mac %s\n", ip);
+    RLOGD("inner_get_ip_by_mac %s\n", ip);
     return ret;
 }
 
@@ -612,20 +666,24 @@
     struct in_addr addr ={0};
     struct hostent *ht;
 
-    if (ip == NULL || *ip == '\0' || hostname == NULL) {
-        return -1;
+    if (ip == NULL || *ip == '\0' || hostname == NULL)
+    {
+        RLOGE("ip == NULL or hostname == NULL");
+	return -1;
     }
 
     *hostname = '\0';
-    if (inet_aton(ip, &addr) == 0) {
+    if (inet_aton(ip, &addr) == 0)
+    {
         printf("---inet_aton fail\n");
         return -1;
     }
 
     ht = gethostbyaddr(&addr, sizeof(struct in_addr), AF_INET);
 
-    if (ht == NULL) {
-        printf("---gethostbyaddr fail\n");
+    if (ht == NULL)
+    {
+        RLOGE("---gethostbyaddr fail\n");
         herror(NULL);
         return -1;
     }
@@ -642,6 +700,7 @@
     char * split_words[128] = {0};
     char local_ssid[128] = {0};
     const char *lynq_wifi_list_networks = "LIST_NETWORKS";
+    RLOGD("[lynq_get_network_number_list] enter lynq_get_network_number_list api");
 
     CHECK_WPA_CTRL(ap_sta);
 
@@ -652,16 +711,19 @@
     //@todo check ssid field to compatible
 
     ret = 0;
-    for(index=1; index < count; index++) {
+    for(index=1; index < count; index++)
+    {
         words_count = lynq_split(split_lines[index], strlen(split_lines[index]), '\t', split_words);
-        if (words_count > 2) {
+        if (words_count > 2)
+	{
             inner_copy_ssid(local_ssid, split_words[1], sizeof (local_ssid));
-            if (ssid == NULL || strcmp(local_ssid, ssid) == 0) {
+            if (ssid == NULL || strcmp(local_ssid, ssid) == 0)
+	    {
                 net_no_list[ret++] = atoi(split_words[0]);
             }
         }
     }
-
+    RLOGD("[lynq_get_network_number_list] lynq_get_network_number_list return ok");
     return ret;
 }
 
@@ -670,13 +732,18 @@
     CHECK_WPA_CTRL(ap_sta);
     const char *lynq_wifi_add_network = "ADD_NETWORK";
 
+    RLOGD("[lynq_add_network] enter lynq_add_network");
     DO_REQUEST(lynq_wifi_add_network);
-    if (memcmp(cmd_reply, "FAIL", 4) == 0) {
+    if (memcmp(cmd_reply, "FAIL", 4) == 0)
+    {
+        RLOGE("[wifi error]lynq_add_network  cmd_reply FAIL");
         return -1;
     }
 
-    for(i=0;i<reply_len;i++) {
-        if(cmd_reply[i] == '\n') {
+    for(i=0;i<reply_len;i++)
+    {
+        if(cmd_reply[i] == '\n')
+	{
             cmd_reply[i] = '\0';
             break;
         }
@@ -689,10 +756,12 @@
     int count, index;
     int net_no_list[128];
 
-
+    RLOGD("[lynq_check_network_number] enter lynq_check_network_number api");
     count = lynq_get_network_number_list(idx, ap_sta, net_no_list, NULL);
-    for (index=0; index < count; index++) {
-        if (net_no_list[index] == net_no) {
+    for (index=0; index < count; index++)
+    {
+        if (net_no_list[index] == net_no)
+	{
             return 0;
         }
     }
@@ -702,45 +771,59 @@
     else
         index = -1;
 
-    while (index < net_no ) {
+    while (index < net_no )
+    {
         index = lynq_add_network(ap_sta);
-        if (index >= net_no) { // required network no created
+        if (index >= net_no)
+	{ // required network no created
+            RLOGD("required network no created\n");;
             return 0;
         }
-        else if( index < 0) {
-            printf("add network fail\n");
+        else if( index < 0)
+	{
+            RLOGE("[lynq_check_network_number] add network fail");
             return -1;
         }
     }
 
     if (index < 0)
-        return -1;
-
+    {
+        RLOGE("[lynq_check_network_number] network index < 0");
+	return -1;
+    }
+    RLOGD("[lynq_check_network_number] work finished &state is ok");
     return 0;
 }
 
 static lynq_wifi_band_m convert_band_from_freq(int freq) { //@todo
-    if (freq > 5000 && freq < 6000) {
+    if (freq > 5000 && freq < 6000)
+    {
         return LYNQ_WIFI_5G_band;
     }
-    else if (freq > 2000 && freq <  3000) {
+    else if (freq > 2000 && freq <  3000)
+    {
         return LYNQ_WIFI_2G_band;
     }
     return LYNQ_WIFI_2_and_5G_band;
 }
 
 static lynq_wifi_auth_s convert_auth_from_key_mgmt(char * key_mgmt) {
-    if (key_mgmt != NULL) {
-        if (memcmp( key_mgmt, "NONE", 4) == 0) {
+    if (key_mgmt != NULL)
+    {
+        if (memcmp( key_mgmt, "NONE", 4) == 0)
+	{
             return LYNQ_WIFI_AUTH_OPEN;
         }
-        else if (memcmp( key_mgmt, "WEP", 3) == 0){
+        else if (memcmp( key_mgmt, "WEP", 3) == 0)
+	{
             return LYNQ_WIFI_AUTH_WEP;
         }
-        else if (memcmp( key_mgmt, "WPA-PSK", 7) == 0){
+        else if (memcmp( key_mgmt, "WPA-PSK", 7) == 0)
+	{
             return LYNQ_WIFI_AUTH_WPA_PSK;
         }
-        else if (memcmp( key_mgmt, "WPA2-PSK", 8) == 0){
+        else if (memcmp( key_mgmt, "WPA2-PSK", 8) == 0)
+	{
             return LYNQ_WIFI_AUTH_WPA2_PSK;
         }
     }
@@ -749,20 +832,32 @@
 }
 
 static lynq_wifi_auth_s convert_max_auth_from_flag(char * flag) {
-    if (flag != NULL) {
-        if (strstr( flag, "WPA2-PSK") != NULL){
+    if (flag != NULL)
+    {
+        if ( strstr(flag, "SHA256") != NULL || strstr(flag,"WPA2-SAE") != NULL || strstr(flag,"SAE-H2E") != NULL)
+        {
+            return LYNQ_WIFI_AUTH_WPA3_PSK;
+        }else if ( strstr( flag,"SAE-CCMP") != NULL )
+        {
+            return LYNQ_WIFI_AUTH_WPA2_WPA3_PSK;
+        }else if (strstr( flag, "WPA2-PSK") != NULL)
+        {
             return LYNQ_WIFI_AUTH_WPA2_PSK;
         }
-        else if (strstr( flag, "WPA-PSK") != NULL){
+        else if (strstr( flag, "WPA-PSK") != NULL)
+        {
             return LYNQ_WIFI_AUTH_WPA_PSK;
         }
-        else if (strstr( flag, "WEP") != NULL){
+        else if (strstr( flag, "WEP") != NULL)
+        {
             return LYNQ_WIFI_AUTH_WEP;
         }
-        else if (strstr( flag, "NONE") != NULL) {
+        else if (strstr( flag, "NONE") != NULL)
+        {
             return LYNQ_WIFI_AUTH_OPEN;
         }
-        else if (strcmp( flag, "[ESS]") == 0 || strcmp( flag,"[WPS][ESS]") == 0) {
+        else if (strcmp( flag, "[ESS]") == 0 || strcmp( flag,"[WPS][ESS]") == 0)
+        {
             return LYNQ_WIFI_AUTH_OPEN;
         }
     }
@@ -806,7 +901,9 @@
 
     CHECK_WPA_CTRL(interface);
 
-    if (curr_state == NULL) {
+    if (curr_state == NULL)
+    {
+        RLOGE("[wifi error][inner_get_status_info]curr_state is NULL");
         return -1;
     }
 
@@ -816,53 +913,63 @@
 
     curr_state->net_no = -1;
     ret = -1;
-    for(i=0; i < count; i++) {
-        if (curr_state->ap != NULL) {
+    for(i=0; i < count; i++)
+    {
+        if (curr_state->ap != NULL)
+	{
             p = strstr(split_lines[i], FLAG_SBSID);
-            if (p != NULL) {
+            if (p != NULL)
+	    {
                 strncpy(curr_state->ap->ap_mac, p + strlen(FLAG_SBSID), sizeof(curr_state->ap->ap_mac));
                 ret = 0;
                 continue;
             }
             p = strstr(split_lines[i], FLAG_SSID);
-            if (p != NULL) {
+            if (p != NULL)
+	    {
                 inner_copy_ssid(curr_state->ap->ap_ssid, p + strlen(FLAG_SSID), sizeof (curr_state->ap->ap_ssid));
                 ret = 0;
                 continue;
             }
             p = strstr(split_lines[i], FLAG_KEY_MGMT);
-            if (p != NULL) {
+            if (p != NULL)
+	    {
                 curr_state->ap->auth = convert_auth_from_key_mgmt(p + strlen(FLAG_KEY_MGMT));
-                printf("key_mgmt %d, -- %s\n", curr_state->ap->auth, p);
+                RLOGD("inner_get_status_info: key_mgmt %d, -- %s\n", curr_state->ap->auth, p);
                 ret = 0;
                 continue;
             }
             p = strstr(split_lines[i], FLAG_FREQ);
-            if (p != NULL) {
+            if (p != NULL)
+	    {
                 curr_state->ap->band = convert_band_from_freq(atoi( p + strlen(FLAG_FREQ)));
                 ret = 0;
                 continue;
             }
             p = strstr(split_lines[i], FLAG_IPADDR);
-            if (p != NULL) {
+            if (p != NULL)
+	    {
                 strncpy(curr_state->ap->ap_ip, p + strlen(FLAG_IPADDR), sizeof(curr_state->ap->ap_ip));
                 ret = 0;
                 continue;
             }
         } // end  if (ap != NULL)
-        if (curr_state->state != NULL) {
+        if (curr_state->state != NULL)
+	{
             p = strstr(split_lines[i], FLAG_STATE);
-            if (p != NULL) {
+            if (p != NULL)
+	    {
                 strcpy(curr_state->state, p + strlen(FLAG_STATE));
                 ret = 0;
                 continue;
             }
 
         } //end else if (state != NULL)
-        if ((p = strstr(split_lines[i], FLAG_ID)) == split_lines[i]) {
+        if ((p = strstr(split_lines[i], FLAG_ID)) == split_lines[i])
+	{
             ret = 0;
             curr_state->net_no = atoi(p + strlen(FLAG_ID));
-            printf("net_no %d, -- %s\n", curr_state->net_no, p);
+            RLOGD("inner_get_status_info:net_no %d, -- %s\n", curr_state->net_no, p);
         }
     }
 
@@ -872,17 +979,22 @@
 
 int lynq_wifi_ap_ssid_set(lynq_wifi_index_e idx,char *ap_ssid)
 {
+    RLOGD("enter lynq_wifi_ap_ssid_set");
     char lynq_wifi_ssid_cmd[80]={0};
 
-    if (ap_ssid == NULL) {
-        printf("ap_ssid is null\n");
+    if (ap_ssid == NULL)
+    {
+        RLOGE("Input ap_ssid is NULL");
         return -1;
     }
-    else {
-        printf("idx:%d ap_ssid : %s\n", idx, ap_ssid);
+    else
+    {
+        RLOGD("[lynq_wifi_ap_ssid_set]idx:%d ap_ssid : %s\n", idx, ap_ssid);
     }
 
-    if (lynq_check_network_number(idx, CTRL_AP, AP_NETWORK_0) != 0) {
+    if (lynq_check_network_number(idx, CTRL_AP, AP_NETWORK_0) != 0)
+    {
+        RLOGE("Do check ap network_number fail");
         return -1;
     }
 
@@ -894,13 +1006,14 @@
 
     DO_OK_FAIL_REQUEST(lynq_wifi_ssid_cmd);
     DO_OK_FAIL_REQUEST(cmd_save_config);
-
-	return 0;
+    RLOGD("[lynq_wifi_ap_ssid_set] set ssid sucss");
+    return 0;
 
 }
 
 int lynq_wifi_ap_ssid_get(lynq_wifi_index_e idx, char* ap_ssid)
 {
+    RLOGD("enter lynq_wifi_ap_ssid_get");
     CHECK_IDX(idx, CTRL_AP);
     return inner_get_param(CTRL_AP, AP_NETWORK_0, "ssid", ap_ssid);
 }
@@ -928,7 +1041,7 @@
 
     if(i == arr_len)
     {
-        printf("input frequency is eero--->%d,please check it\n", input_frequency);
+        RLOGE("[lynq_check_set_frequency]input frequency is --->%d,please check it\n", input_frequency);
         return -1;
     }
 
@@ -942,7 +1055,7 @@
 
     if( lynq_get_country_code(1,str_dest) != 0 )
     {
-        printf("get country_code error\n");
+        RLOGE("get country_code error\n");
 	return -1;
     }
     if( strncmp(str_dest,str_cnc,2) != 0 )
@@ -950,7 +1063,7 @@
         return 0;
     }else if( 2473 < input_frequency && input_frequency < 5744)
     {
-        printf("input frequency is bad\n");
+        RLOGE("input frequency is bad\n");
 	return -1;
     } 
     return 0;
@@ -961,23 +1074,24 @@
     char lynq_wifi_frequency_cmd[128]={0};
     char lynq_cmd_mode[128]={0};
     char lynq_cmd_slect[128]={0};
-
+    RLOGD("enter lynq_wifi_ap_frequency_set and input frequency is:%d", lynq_wifi_frequency);
     //@do check input frequency
     check = lynq_check_set_frequency(lynq_wifi_frequency);
     if(check != 0)
     {
-        printf("do check frequency error\n");
+        RLOGE("do check frequency error");
         return -1;
     }
     check = lynq_check_frequencyby_country_code(lynq_wifi_frequency);
     if(check != 0)
     {
-        printf("do check frequency error\n");
+        RLOGE("do check frequency error");
         return -1;
     }
 
     if (lynq_check_network_number(idx, CTRL_AP, AP_NETWORK_0) != 0)
     {
+        RLOGE("[set ap frequecny][lynq_check_network_number] error");
         return -1;
     }
 
@@ -994,67 +1108,76 @@
     DO_OK_FAIL_REQUEST(lynq_cmd_mode);
     DO_OK_FAIL_REQUEST(cmd_save_config);
 
-	return 0;
+    return 0;
 }
 
 int lynq_wifi_ap_frequency_get(lynq_wifi_index_e idx,int *lynq_wifi_frequency)
 {
     char lynq_frequency_str[MAX_RET] = {0};
-
+    RLOGD("enter lynq_wifi_ap_frequency_get and input idx is %d",idx);
     CHECK_IDX(idx, CTRL_AP);
 
-    if (inner_get_param(CTRL_AP, AP_NETWORK_0, "frequency", lynq_frequency_str) != 0) {
+    if (inner_get_param(CTRL_AP, AP_NETWORK_0, "frequency", lynq_frequency_str) != 0)
+    {
+        RLOGE("[wifi error][lynq_wifi_ap_frequency_get]get frequency from device fail");
         return -1;
     }
     *lynq_wifi_frequency = atoi(lynq_frequency_str);
 
-	return 0;
+    return 0;
 }
 
 int lynq_wifi_ap_bandwidth_set(lynq_wifi_index_e idx,lynq_wifi_bandwidth_type_m bandwidth)
 {
+    RLOGD("enter lynq_wifi_ap_bandwidth_set");
     CHECK_IDX(idx, CTRL_AP);
     switch(bandwidth){
-		case LYNQ_WIFI_BANDWIDTH_HT10:
-		{
-            printf("bandwith  [%d] not support now\n", bandwidth);
-			return -1;
-		}
-		case LYNQ_WIFI_BANDWIDTH_HT20:
+        case LYNQ_WIFI_BANDWIDTH_HT10:
+	{
+            RLOGE("bandwith  [%d] not support now\n", bandwidth);
+	    return -1;
+	}
+        case LYNQ_WIFI_BANDWIDTH_HT20:
         {
             char lynq_cmd_bandwith[MAX_CMD]="wl chanspec 6";
             system("wl down");
-            if (system(lynq_cmd_bandwith) != 0 ){
+            if (system(lynq_cmd_bandwith) != 0 )
+	    {
+                RLOGE("lynq_wifi_ap_bandwidth_set erro");
                 return -1;
             }
             system("wl up");
             break;
         }
         case LYNQ_WIFI_BANDWIDTH_HT40:
-		{
+        {
             char lynq_cmd_bandwith[MAX_CMD]="wl chanspec 149/40";
             sprintf(lynq_cmd_bandwith, "wl chanspec ");
             system("wl down");
-            if (system(lynq_cmd_bandwith) != 0 ){
+            if (system(lynq_cmd_bandwith) != 0 )
+	    {
+                RLOGE("lynq_wifi_ap_bandwidth_set erro");
                 return -1;
             }
             system("wl up");
             break;
-		}
+        }
         case LYNQ_WIFI_BANDWIDTH_HT80:
-		{
+        {
             char lynq_cmd_bandwith[MAX_CMD]="wl chanspec 149/80";
             system("wl down");
-            if (system(lynq_cmd_bandwith) != 0 ){
+            if (system(lynq_cmd_bandwith) != 0 )
+	    {
+                RLOGE("lynq_wifi_ap_bandwidth_set erro");
                 return -1;
             }
             system("wl up");
             break;
-		}				
-		default:
+        }				
+        default:
         {
-            printf("auth type [%d] not support now\n", bandwidth);
-			return -1;
+            RLOGE("auth type [%d] not support now\n", bandwidth);
+            return -1;
         }
     }
 
@@ -1068,7 +1191,7 @@
     int index = 0;
     char *split_words[128] = {0};
     const char *lynq_chanspec_cmd = "DRIVER chanspec\n";
-
+    RLOGD("enter lynq_wifi_ap_bandwidth_get");
     CHECK_IDX(idx, CTRL_AP);
 
     CHECK_WPA_CTRL(CTRL_AP);
@@ -1086,28 +1209,30 @@
             return -1;
         }
 
-        printf("bw %s\n", split_words[index]);
+        RLOGD("bw %s\n", split_words[index]);
         *bandwidth = convert_bandwidth_from_bw(atoi(split_words[index]));
         return 0;
     }
-
+    RLOGE("[wifi error]lynq_wifi_ap_bandwidth_get");
     return -1;
 }
 
 int lynq_wifi_ap_channel_set( lynq_wifi_index_e idx,int channel)
 {
     char lynq_cmd_channel[MAX_CMD]={0};
-
+    RLOGD("enter lynq_wifi_ap_channel_set and input channel is %d",channel);
     CHECK_IDX(idx, CTRL_AP);
 
     sprintf(lynq_cmd_channel, "wl channel %d", channel);
 
-    if (lynq_check_network_number(idx, CTRL_AP, AP_NETWORK_0) != 0) {
+    if (lynq_check_network_number(idx, CTRL_AP, AP_NETWORK_0) != 0) 
+    {
         return -1;
     }
 
     system("wl down");
     if (system(lynq_cmd_channel) != 0 ){
+        RLOGE("lynq_wifi_ap_channel_set erro");
         return -1;
     }
     system("wl up");
@@ -1120,7 +1245,7 @@
     int index = 0;
     char *split_words[128] = {0};
     char lynq_chanspec_cmd[]="DRIVER chanspec\n";
-
+    RLOGD("enter lynq_wifi_ap_channel_get");
     CHECK_IDX(idx, CTRL_AP);
 
     CHECK_WPA_CTRL(CTRL_AP);
@@ -1128,21 +1253,23 @@
     DO_REQUEST(lynq_chanspec_cmd);
 
     count = lynq_split(cmd_reply, reply_len, ' ', split_words);
-    for(;index < count; index++) {
-        printf("---- %s\n",split_words[index]);
+    for(;index < count; index++) 
+    {
+        RLOGD("[lynq_wifi_ap_channel_get]---- %s\n",split_words[index]);
         if (strncmp(split_words[index], "channel", 2) != 0) {
             continue;
         }
 
         index++;
-        if (index >= count) {
+        if (index >= count) 
+	{
             return -1;
         }
 
         *channel = atoi(split_words[index]);
         return 0;
     }
-
+    RLOGE("[lynq_wifi_ap_channel_get] function fail");
     return -1;
 }
 
@@ -1155,17 +1282,22 @@
     char lynq_auth_alg_cmd[64]={0};
     char lynq_psk_cmd[64]={0};
     char lynq_pairwise_cmd[64]={0};
+    char lynq_ieee80211_cmd[64]={0};
+    RLOGD("enter lynq_wifi_ap_auth_set and input idx is:%d,auth is:%d",idx,auth);
     lynq_wifi_auth_s org_auth;
     CHECK_IDX(idx, CTRL_AP);
 
     CHECK_WPA_CTRL(CTRL_AP);
 
-    if (lynq_check_network_number(idx, CTRL_AP, AP_NETWORK_0) != AP_NETWORK_0) {
+    if (lynq_check_network_number(idx, CTRL_AP, AP_NETWORK_0) != AP_NETWORK_0) 
+    {
+        RLOGE("[wifi error][lynq_wifi_ap_auth_set] check network fail\n");
         return -1;
     }
 
     if (0 == lynq_wifi_ap_auth_get(idx, &org_auth) && org_auth != -1) {
         if (org_auth == auth) {
+            RLOGD("org_auth --- is %d\n",org_auth);
             return 0;
         }
         else {
@@ -1185,17 +1317,18 @@
         }
     }
 
-	switch(auth){
-		case LYNQ_WIFI_AUTH_OPEN:
+    switch(auth){
+	case LYNQ_WIFI_AUTH_OPEN:
         {
+            RLOGD("auth == is LYNQ_WIFI_AUTH_OPEN\n");
             sprintf(lynq_auth_cmd,"SET_NETWORK %d key_mgmt NONE", AP_NETWORK_0);
             sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise NONE", AP_NETWORK_0);
-
             DO_OK_FAIL_REQUEST(lynq_auth_cmd);
-			break;
-		}
+	    break;
+	}
         case LYNQ_WIFI_AUTH_WEP:
         {
+            RLOGD("auth == is LYNQ_WIFI_AUTH_WEP\n");
             sprintf(lynq_auth_cmd,"SET_NETWORK %d key_mgmt NONE", AP_NETWORK_0);
             sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise NONE", AP_NETWORK_0);
             sprintf(lynq_auth_alg_cmd,"SET_NETWORK %d auth_alg  SHARED", AP_NETWORK_0);
@@ -1204,14 +1337,27 @@
             DO_OK_FAIL_REQUEST(lynq_auth_alg_cmd);
             break;
         }
-		case LYNQ_WIFI_AUTH_WPA_PSK:
+	case LYNQ_WIFI_AUTH_WPA_PSK:
+        {
+            sprintf(lynq_auth_cmd,"SET_NETWORK %d proto WPA", AP_NETWORK_0);
+            sprintf(lynq_psk_cmd,"SET_NETWORK %d key_mgmt WPA-PSK", AP_NETWORK_0);
+            sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", AP_NETWORK_0);
+
+            DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+            DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+            DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+            break;
+
+	}
         case LYNQ_WIFI_AUTH_WPA2_PSK:
-		{
-            if (auth == LYNQ_WIFI_AUTH_WPA_PSK) {
+	{
+            if (auth == LYNQ_WIFI_AUTH_WPA_PSK)
+	    {
                 sprintf(lynq_auth_cmd,"SET_NETWORK %d proto WPA", AP_NETWORK_0);
                 sprintf(lynq_psk_cmd,"SET_NETWORK %d key_mgmt WPA-PSK", AP_NETWORK_0);
             }
-            else if (auth == LYNQ_WIFI_AUTH_WPA2_PSK) {
+            else if (auth == LYNQ_WIFI_AUTH_WPA2_PSK)
+	    {
                 sprintf(lynq_auth_cmd,"SET_NETWORK %d proto RSN", AP_NETWORK_0);
                 sprintf(lynq_psk_cmd,"SET_NETWORK %d key_mgmt WPA-PSK", AP_NETWORK_0);
             }
@@ -1222,17 +1368,43 @@
             DO_OK_FAIL_REQUEST(lynq_auth_cmd);
             DO_OK_FAIL_REQUEST(lynq_psk_cmd);
             DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
-			break;
-		}		
-		default:
+	    break;
+	}		
+        case LYNQ_WIFI_AUTH_WPA2_WPA3_PSK:
+	{
+            sprintf(lynq_auth_cmd,"SET_NETWORK %d proto WPA2", AP_NETWORK_0);
+            sprintf(lynq_ieee80211_cmd,"SET_NETWORK %d ieee80211w 1", AP_NETWORK_0);
+            sprintf(lynq_psk_cmd,"SET_NETWORK %d key_mgmt WPA-PSK SAE", AP_NETWORK_0);
+            sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", AP_NETWORK_0);
+
+            DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+            DO_OK_FAIL_REQUEST(lynq_ieee80211_cmd);
+            DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+            DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+	    break;
+	}		
+        case LYNQ_WIFI_AUTH_WPA3_PSK:
+	{
+            sprintf(lynq_auth_cmd,"SET_NETWORK %d proto WPA2", AP_NETWORK_0);
+            sprintf(lynq_ieee80211_cmd,"SET_NETWORK %d ieee80211w 2", AP_NETWORK_0);
+            sprintf(lynq_psk_cmd,"SET_NETWORK %d key_mgmt SAE", AP_NETWORK_0);
+            sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", AP_NETWORK_0);
+
+            DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+            DO_OK_FAIL_REQUEST(lynq_ieee80211_cmd);
+            DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+            DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+	    break;
+	}		
+	default:
         {
-            printf("auth type [%d] not support now\n", auth);
-			return -1;
+            RLOGE("auth type [%d] not support now\n", auth);
+            return -1;
         }
     }
     DO_OK_FAIL_REQUEST(cmd_save_config);
 
-	return 0;
+    return 0;
 }
 
 int lynq_wifi_ap_auth_get(lynq_wifi_index_e idx, lynq_wifi_auth_s *auth)
@@ -1240,36 +1412,77 @@
     char lynq_auth_str[MAX_RET] = {0};
     char lynq_auth_alg_str[MAX_RET] = {0};
     char lynq_proto_str[MAX_RET] = {0};
-
+    RLOGD("enter lynq_wifi_ap_auth_get");
     CHECK_IDX(idx, CTRL_AP);
 
-    if (inner_get_param(CTRL_AP, AP_NETWORK_0, "key_mgmt", lynq_auth_str) != 0) {
+    if (inner_get_param(CTRL_AP, AP_NETWORK_0, "key_mgmt", lynq_auth_str) != 0)
+    {
+        RLOGE("[wifi error][lynq_wifi_ap_auth_get] check network fail");
         return -1;
     }
 
-    if (memcmp( lynq_auth_str, "NONE", 4) == 0) {
-        if (inner_get_param(CTRL_AP, AP_NETWORK_0, "auth_alg", lynq_auth_alg_str) != 0) {
+    if (memcmp( lynq_auth_str, "NONE", 4) == 0)
+    {
+        if (inner_get_param(CTRL_AP, AP_NETWORK_0, "auth_alg", lynq_auth_alg_str) != 0)
+	{
+            RLOGD("---auth is OPEN\n");
             *auth = LYNQ_WIFI_AUTH_OPEN;
+            return 0;
         }
-        else if (memcmp(lynq_auth_alg_str, "SHARED", 6) == 0){
+        else if (memcmp(lynq_auth_alg_str, "SHARED", 6) == 0)
+	{
+            RLOGD("---auth is WEP\n");
             *auth = LYNQ_WIFI_AUTH_WEP;
+            return 0;
         }
-        else {
+        else
+	{
+            RLOGD("---auth is OPEN\n");
             *auth = LYNQ_WIFI_AUTH_OPEN;
+            return 0;
         }
     }
-    else if(strcmp( lynq_auth_str, "WPA-PSK") == 0 ) {
-        if (inner_get_param(CTRL_AP, AP_NETWORK_0, "proto", lynq_proto_str) != 0) {
+    else if(strcmp( lynq_auth_str, "WPA-PSK") == 0 )
+    {
+        if (inner_get_param(CTRL_AP, AP_NETWORK_0, "proto", lynq_proto_str) != 0)
+	{
+            RLOGE("---auth is -1\n");
             *auth = -1;
         }
-        else if (memcmp(lynq_proto_str, "RSN", 3) == 0) {
+        else if (memcmp(lynq_proto_str, "RSN", 3) == 0)
+	{
+            RLOGD("---auth WPA2_PSK\n");
             *auth = LYNQ_WIFI_AUTH_WPA2_PSK;
+            return 0;
         }
-        else {
+        else
+	{
+            RLOGD("---auth WPA_PSK\n");
             *auth = LYNQ_WIFI_AUTH_WPA_PSK;
+	    return 0;
         }
     }
-    else {
+    
+    if (inner_get_param(CTRL_AP, AP_NETWORK_0, "ieee80211w", lynq_auth_str) != 0)
+    {
+        RLOGE("[wifi error][lynq_wifi_ap_auth_get] check network auth ieee80211w fail");
+        return -1;
+    }
+    
+    if (memcmp(lynq_auth_str,"1",1) == 0 )
+    {
+	RLOGD("auth : LYNQ_WIFI_AUTH_WPA2_WPA3_PSK\n");
+        *auth = LYNQ_WIFI_AUTH_WPA2_WPA3_PSK;
+        return 0;
+    }else if (memcmp(lynq_auth_str,"2",1) == 0 )
+    {
+	RLOGD("auth : LYNQ_WIFI_AUTH_WPA3_PSK\n");
+        *auth = LYNQ_WIFI_AUTH_WPA3_PSK;
+        return 0;
+    }
+    else
+    {
+	RLOGE("---auth -- -1\n");
         *auth = -1;
     }
 
@@ -1282,7 +1495,7 @@
     char LYNQ_WIFI_CMD[128]={0};
     //const char *lynq_remove_all_cmd = "REMOVE_NETWORK all";
     //const char *lynq_reconfig_cmd = "RECONFIGURE /data/wifi/wg870/wpa_supplicant.conf";
-
+    RLOGD("enter lynq_wifi_ap_channel_get");
     CHECK_IDX(idx, CTRL_AP);
 
     CHECK_WPA_CTRL(CTRL_AP);
@@ -1299,7 +1512,7 @@
     sprintf(LYNQ_WIFI_CMD,"SELECT_NETWORK %d",AP_NETWORK_0);
     DO_OK_FAIL_REQUEST(LYNQ_WIFI_CMD);
 
-	return 0;
+    return 0;
 }
 
 int lynq_wifi_ap_restart(lynq_wifi_index_e idx)
@@ -1321,7 +1534,7 @@
 
 //    system("connmanctl tether wifi off");
 	
-	return 0;
+    return 0;
 }
 
 int lynq_wifi_ap_hide_ssid(lynq_wifi_index_e idx)
@@ -1329,11 +1542,10 @@
     char lynq_disable_cmd[128] = {0};
     char lynq_select_cmd[128] = {0};
     const char *lynq_hide_cmd = "SET HIDE_SSID 1";
-
+    RLOGD("enter lynq_wifi_ap_hide_ssid");
     CHECK_IDX(idx, CTRL_AP);
 
     CHECK_WPA_CTRL(CTRL_AP);
-	
     sprintf(lynq_disable_cmd,"DISABLE_NETWORK %d", AP_NETWORK_0);
     sprintf(lynq_select_cmd,"SELECT_NETWORK %d", AP_NETWORK_0);
 
@@ -1341,7 +1553,7 @@
     DO_OK_FAIL_REQUEST(lynq_hide_cmd);
     DO_OK_FAIL_REQUEST(lynq_select_cmd);
 
-	return 0;
+    return 0;
 }
 
 int lynq_wifi_ap_unhide_ssid(lynq_wifi_index_e idx)
@@ -1349,7 +1561,7 @@
     char lynq_disable_cmd[128] = {0};
     char lynq_select_cmd[128] = {0};
     const char *lynq_unhide_cmd = "SET HIDE_SSID 0";
-
+    RLOGD("enter lynq_wifi_ap_unhide_ssid");
     CHECK_IDX(idx, CTRL_AP);
 
     CHECK_WPA_CTRL(CTRL_AP);
@@ -1361,51 +1573,77 @@
     DO_OK_FAIL_REQUEST(lynq_unhide_cmd);
     DO_OK_FAIL_REQUEST(lynq_select_cmd);
 
-	return 0;
+    return 0;
 }
 
 int lynq_ap_password_set(lynq_wifi_index_e idx,char *password)
 {
-	int pass_len;
+    int pass_len;
     char lynq_tmp_cmd[MAX_CMD] = {0};
+    char lynq_wpa2_wpa3[64] = {0};
     char lynq_wep_tx_keyidx_cmd[MAX_CMD] = {0};
-    if( password == NULL ){
+    RLOGD("enter lynq_ap_password_set");
+    if( password == NULL )
+    {
+        RLOGE("[lynq_ap_password_set]input password is NULL");
         return -1;
     }
     pass_len=strlen(password);
     lynq_wifi_auth_s auth = -1;
-    if(pass_len < 8 || pass_len >= 64){
-		return -1;
+    if(pass_len < 8 || pass_len >= 64)
+    {
+        RLOGE("[lynq_ap_password_set]input password len not in rage");
+        return -1;
     }
 
     CHECK_IDX(idx, CTRL_AP);
 
-    if (0 != lynq_wifi_ap_auth_get(idx, &auth)) {
+    if (0 != lynq_wifi_ap_auth_get(idx, &auth))
+    {
+        RLOGE("[lynq_ap_password_set] get ap auth info error\n");
         return -1;
     }
-    else if (auth == LYNQ_WIFI_AUTH_OPEN) {
-        return -1;
+    else if (auth == LYNQ_WIFI_AUTH_OPEN)
+    {
+        RLOGD("ap auth :LYNQ_WIFI_AUTH_OPEN\n");
+        return 0;
     }
 
     CHECK_WPA_CTRL(CTRL_AP);
 
-    if (auth == LYNQ_WIFI_AUTH_WEP) {
+    if (auth == LYNQ_WIFI_AUTH_WEP)
+    {
+        RLOGD("[lynq_ap_password_set]ap auth : LYNQ_WIFI_AUTH_WEP\n");
         sprintf(lynq_tmp_cmd,"SET_NETWORK %d wep_key0 \"%s\"",AP_NETWORK_0, password);
         sprintf(lynq_wep_tx_keyidx_cmd,"SET_NETWORK %d wep_tx_keyidx 0",AP_NETWORK_0);
         DO_OK_FAIL_REQUEST(lynq_tmp_cmd);
         DO_OK_FAIL_REQUEST(lynq_wep_tx_keyidx_cmd);
     }
-    else if (auth == LYNQ_WIFI_AUTH_WPA_PSK || auth == LYNQ_WIFI_AUTH_WPA2_PSK) {
+    else if (auth == LYNQ_WIFI_AUTH_WPA_PSK || auth == LYNQ_WIFI_AUTH_WPA2_PSK)
+    {
+        RLOGD("[lynq_ap_password_set]ap auth :LYNQ_WIFI_AUTH_WPA_PSK  LYNQ_WIFI_AUTH_WPA2_PSK\n");
         sprintf(lynq_tmp_cmd,"SET_NETWORK %d psk \"%s\"",AP_NETWORK_0, password);
         DO_OK_FAIL_REQUEST(lynq_tmp_cmd);
     }
-    else {
+    else if (auth == LYNQ_WIFI_AUTH_WPA2_WPA3_PSK || auth == LYNQ_WIFI_AUTH_WPA3_PSK)
+    {
+        
+        RLOGD("[lynq_ap_password_set]ap auth :LYNQ_WIFI_AUTH_WPA2_WPA3  LYNQ_WIFI_AUTH_WPA3_PSK\n");
+        sprintf(lynq_tmp_cmd,"SET_NETWORK %d psk \"%s\"",AP_NETWORK_0, password);
+        sprintf(lynq_wpa2_wpa3,"SET_NETWORK %d sae_password \"%s\"",AP_NETWORK_0, password);
+        DO_OK_FAIL_REQUEST(lynq_tmp_cmd);
+        DO_OK_FAIL_REQUEST(lynq_wpa2_wpa3);
+
+    }
+    else
+    {   
+        RLOGD("[lynq_ap_password_set]ap auth :get ap auth error\n");
         return -1;
     }
 
     DO_OK_FAIL_REQUEST(cmd_save_config);
 
-	return 0;
+    return 0;
 }
 
 int lynq_ap_password_get(lynq_wifi_index_e idx, char *password)
@@ -1415,13 +1653,15 @@
     int count, index;
     char *split_lines[128] = {0};
     char *buff, *p;
+    RLOGD("enter lynq_ap_password_get");
 
     CHECK_IDX(idx, CTRL_AP);
 
     fp = fopen("/data/wifi/wg870/wpa_supplicant_ap.conf", "rb");
 //    fp = fopen("/data/wifi/wg870/wpa_supplicant.conf", "rb");
-    if (NULL == fp) {
-        printf("open file fail\n");
+    if (NULL == fp)
+    {
+        RLOGE("open file fail\n");
         return  -1;
     }
 
@@ -1430,13 +1670,17 @@
     len = fread(buff, 1, MAX_RET, fp);
     fclose(fp);
 
-    for(index=0; index < len; index ++) {
-        if (memcmp(buff + index, "network={", 9) != 0) {
+    for(index=0; index < len; index ++)
+    {
+        if (memcmp(buff + index, "network={", 9) != 0)
+	{
             continue;
         }
          p = buff + index + 9;
-         for (; index < len; index ++ ) {
-             if (buff[index] != '}') {
+         for (; index < len; index ++ )
+	 {
+             if (buff[index] != '}')
+	     {
                  continue;
              }
              buff[index] = '\0';
@@ -1448,28 +1692,36 @@
     count = lynq_split(p, len, '\n', split_lines);
 
     ret = -1;
-    for(index=0; index < count; index++) {
+    for(index=0; index < count; index++)
+    {
         p = strstr(split_lines[index], "psk=");
-        if (p != NULL) {
+        if (p != NULL)
+	{
             p += 4;
-            if (*p == '\"') {
+            if (*p == '\"')
+	    {
                 p++;
             }
         }
-        else if (NULL != (p = strstr(split_lines[index], "wep_key0="))) {
+        else if (NULL != (p = strstr(split_lines[index], "wep_key0=")))
+	{
             p += 9;
-            if (*p == '\"') {
+            if (*p == '\"')
+	    {
                 p++;
             }
         }
-        else {
+        else
+	{
             continue;
         }
 
         strcpy(password, p);
 
-        while(*password != '\0') {
-            if (*password == '\"') {
+        while(*password != '\0')
+	{
+            if (*password == '\"')
+	    {
                 *password = '\0';
                 break;
             }
@@ -1486,30 +1738,58 @@
     char lynq_auth_str[MAX_RET] = {0};
     char lynq_proto_str[MAX_RET] = {0};
 
-    if (inner_get_param(interface, net_no, "key_mgmt", lynq_auth_str) != 0) {
+    if (inner_get_param(interface, net_no, "key_mgmt", lynq_auth_str) != 0)
+    {
         return -1;
     }
 
     *auth = convert_auth_from_key_mgmt(lynq_auth_str);
 
-    if (*auth == LYNQ_WIFI_AUTH_WPA_PSK) {
-        if (inner_get_param(interface, net_no, "proto", lynq_proto_str) == 0) {
-            if (strcmp(lynq_proto_str, "RSN") == 0) {
+    if (*auth == LYNQ_WIFI_AUTH_WPA_PSK)
+    {
+        if (inner_get_param(interface, net_no, "proto", lynq_proto_str) == 0)
+	{
+            if (strcmp(lynq_proto_str, "RSN") == 0)
+	    {
                 *auth = LYNQ_WIFI_AUTH_WPA2_PSK;
+                return 0;
             }
         }
     }
+    if (inner_get_param(interface, net_no,"ieee80211w",lynq_auth_str) !=0)
+    {
+	RLOGE("check ieee80211w error\n");
+        return -1;
+    }
+    if ( strncmp(lynq_auth_str,"1",1) == 0 )
+    {
+
+       *auth = LYNQ_WIFI_AUTH_WPA2_WPA3_PSK;
+       return 0;
+    }else if( strncmp(lynq_auth_str,"2",1) == 0 )
+    {
+
+        *auth = LYNQ_WIFI_AUTH_WPA3_PSK;
+        return 0;
+    }else
+    {
+        *auth = -1;
+        return -1;
+    }
     return 0;
 }
 
 int lynq_sta_ssid_password_set(lynq_wifi_index_e idx, ap_info_s *ap, char *password)
 {
+    RLOGD("enter lynq_sta_ssid_password_set");
     int pass_len, net_no, count, index;
     char lynq_tmp_cmd[300]={0};
     int net_no_list[128];
     lynq_wifi_auth_s net_auth;
     pass_len=strlen(password);
-    if(pass_len < 8 || pass_len >= 64){
+    if(pass_len < 8 || pass_len >= 64)
+    {
+        RLOGE("[lynq_sta_ssid_password_set]input psw error");
         return -1;
     }
 
@@ -1518,15 +1798,18 @@
     net_no = -1;
     count = lynq_get_network_number_list(idx, CTRL_STA, net_no_list, ap->ap_ssid);
 
-    for (index=0; index < count; index++) {
+    for (index=0; index < count; index++)
+    {
         net_auth = -1;
-        if (0 == inner_get_network_auth(CTRL_STA, net_no_list[index], &net_auth) && net_auth == ap->auth) {
+        if (0 == inner_get_network_auth(CTRL_STA, net_no_list[index], &net_auth) && net_auth == ap->auth)
+	{
             net_no = net_no_list[index];
             break;
         }
     }
 
-    if (net_no < 0) {
+    if (net_no < 0)
+    {
         return -1;
     }
 
@@ -1548,20 +1831,23 @@
     char *split_lines[128] = {0};
     char *buff, *p, *ssid, *ssid_end_flag;
     char tmp_ssid[128]={0};
+	RLOGD("enter lynq_sta_ssid_password_get");
 
     network_len = 0;
     p = NULL;
 
     CHECK_IDX(idx, CTRL_STA);
 
-    if (NULL == password) {
-        printf("bad param\n");
+    if (NULL == password)
+    {
+        RLOGE("bad param\n");
         return -1;
     }
 
     fp = fopen("/data/wifi/wg870/wpa_supplicant.conf", "rb");
-    if (NULL == fp) {
-        printf("open file fail\n");
+    if (NULL == fp)
+    {
+        RLOGE("[lynq_sta_ssid_password_get] open file fail\n");
         return  -1;
     }
 
@@ -1570,14 +1856,19 @@
     len = fread(buff, 1, MAX_RET, fp);
     fclose(fp);
 
-    for(index=0; index < len; index ++) {
-        for(; index < len; index ++) {
-            if (memcmp(buff + index, "network={", 9) != 0) {
+    for(index=0; index < len; index ++)
+    {
+        for(; index < len; index ++)
+	{
+            if (memcmp(buff + index, "network={", 9) != 0)
+	    {
                 continue;
             }
              p = buff + index + 9;
-             for (; index < len; index ++ ) {
-                 if (buff[index] != '}') {
+             for (; index < len; index ++ )
+	     {
+                 if (buff[index] != '}')
+		 {
                      continue;
                  }
                  buff[index] = '\0';
@@ -1593,11 +1884,13 @@
         ssid = strstr(p, "ssid=");
         if (ssid != NULL) {
             ssid += strlen("ssid=");
-            if (ssid[0] == '\"') {
+            if (ssid[0] == '\"')
+	    {
                 if (memcmp(ssid + 1, ap->ap_ssid, strlen(ap->ap_ssid)) == 0 && ssid[strlen(ap->ap_ssid) + 1] == '\"')
                     break;
             }
-            else{
+            else
+	    {
                 ssid_end_flag = strstr(ssid, "\n");
                 if (ssid_end_flag != NULL)
                 {
@@ -1614,28 +1907,35 @@
 
     }
 
-    if (index >= len || NULL == p || network_len <= 0) {
+    if (index >= len || NULL == p || network_len <= 0)
+    {
         return -1;
     }
 
     count = lynq_split(p, network_len, '\n', split_lines);
 
     ret = -1;
-    for(index=0; index < count; index++) {
+    for(index=0; index < count; index++)
+    {
         p = strstr(split_lines[index], "psk=");
-        if (p != NULL) {
+        if (p != NULL)
+	{
             p += 4;
-            if (*p == '\"') {
+            if (*p == '\"')
+	    {
                 p++;
             }
         }
-        else if (NULL != (p = strstr(split_lines[index], "wep_key0="))) {
+        else if (NULL != (p = strstr(split_lines[index], "wep_key0=")))
+	{
             p += 9;
-            if (*p == '\"') {
+            if (*p == '\"')
+	    {
                 p++;
             }
         }
-        else {
+        else
+	{
             continue;
         }
 
@@ -1644,8 +1944,10 @@
         strncpy(password, p, 64);
 
         p = password;
-        while(password - p < 64 && *password != '\0') {
-            if (*password == '\"') {
+        while(password - p < 64 && *password != '\0')
+	{
+            if (*password == '\"')
+	    {
                 *password = '\0';
                 break;
             }
@@ -1660,21 +1962,22 @@
 
 static int inner_set_sta_ssid(int net_no, char *sta_ssid)
 {
-	char lynq_wifi_ssid_cmd[80]={0};
+    char lynq_wifi_ssid_cmd[80]={0};
 
-	if (sta_ssid == NULL) {
-		printf("sta_ssid is null\n");
-		return -1;
+    if (sta_ssid == NULL)
+    {
+        RLOGE("sta_ssid is null\n");
+        return -1;
     }
 
-	CHECK_WPA_CTRL(CTRL_STA);
+    CHECK_WPA_CTRL(CTRL_STA);
 
     sprintf(lynq_wifi_ssid_cmd,"SET_NETWORK %d ssid \"%s\"", net_no, sta_ssid);
 
     DO_OK_FAIL_REQUEST(lynq_wifi_ssid_cmd);
 //    DO_OK_FAIL_REQUEST(cmd_save_config);
 
-	return 0;
+    return 0;
 
 }
 
@@ -1685,7 +1988,8 @@
 
     CHECK_WPA_CTRL(CTRL_STA);
 
-    if (save != 0) {
+    if (save != 0)
+    {
         if (start_flag != 0)
         {
             sprintf(lynq_select_cmd,"ENABLE_NETWORK %d", net_no);
@@ -1699,11 +2003,13 @@
         DO_OK_FAIL_REQUEST(cmd_save_config);
     }
 
-    if (start_flag == 0) {
+    if (start_flag == 0)
+    {
         sprintf(lynq_disable_cmd,"DISCONNECT");
         DO_OK_FAIL_REQUEST(lynq_disable_cmd);
     }
-    else {
+    else
+    {
         sprintf(lynq_select_cmd,"SELECT_NETWORK %d", net_no);
         DO_OK_FAIL_REQUEST(lynq_select_cmd);
     }
@@ -1713,6 +2019,7 @@
 
 int lynq_wifi_get_sta_ssid(lynq_wifi_index_e idx, char* sta_ssid)
 {
+    RLOGD("enter lynq_sta_ssid_password_set");
     CHECK_IDX(idx, CTRL_STA);
 
     curr_status_info curr_state;
@@ -1720,7 +2027,8 @@
     curr_state.ap = &ap_info;
     curr_state.state = NULL;
 
-    if (0 == inner_get_status_info(CTRL_STA, &curr_state)) {
+    if (0 == inner_get_status_info(CTRL_STA, &curr_state))
+    {
         strncpy(sta_ssid, ap_info.ap_ssid, sizeof (ap_info.ap_ssid));
         return 0;
     }
@@ -1742,7 +2050,8 @@
     ret = -1;
 
     CHECK_IDX(idx, CTRL_STA);
-    if (info == NULL) {
+    if (info == NULL)
+    {
         return -1;
     }
 
@@ -1756,7 +2065,8 @@
     curr_state.ap = &ap_info;
     curr_state.state = status;
 
-    if (0 == inner_get_status_info(CTRL_STA, &curr_state) && curr_state.net_no >= 0) {
+    if (0 == inner_get_status_info(CTRL_STA, &curr_state) && curr_state.net_no >= 0)
+    {
         memcpy(&info->base_info, &ap_info, sizeof (ap_info_s));
         if (strcmp(status, STATE_COMPLETED) == 0)
         {
@@ -1772,8 +2082,9 @@
     }
 
     lynq_wifi_sta_start_scan(idx);
-
-    if (0 != lynq_get_scan_list(0, &scan_list, &scan_len)) {
+    sleep(2);
+    if (0 != lynq_get_scan_list(0, &scan_list, &scan_len))
+    {
         if (NULL != scan_list)
         {
             free(scan_list);
@@ -1781,7 +2092,8 @@
         return -1;
     }
 
-    if (0 != lynq_get_sta_saved_ap(0, &save_list, &save_len)) {
+    if (0 != lynq_get_sta_saved_ap(0, &save_list, &save_len))
+    {
         if (NULL != scan_list)
         {
             free(scan_list);
@@ -1793,15 +2105,20 @@
         return -1;
     }
 
-    for (i=0; i < save_len; i++) {
-        for (j=0; j < scan_len; j++) {
+    for (i=0; i < save_len; i++)
+    {
+        for (j=0; j < scan_len; j++)
+	{
             if (strcmp(save_list[i].base_info.ap_ssid, scan_list[j].ssid) == 0 //@todo not finished
-                    && save_list[i].base_info.auth == scan_list[j].auth) {
-                if (best_rssi == 0) {
+                    && save_list[i].base_info.auth == scan_list[j].auth)
+	    {
+                if (best_rssi == 0)
+		{
                     best_index = i;
                     best_rssi = scan_list[j].rssi;
                 }
-                else if (best_rssi > scan_list[j].rssi) {
+                else if (best_rssi > scan_list[j].rssi)
+		{
                     best_index = i;
                     best_scan_index = j;
                     best_rssi = scan_list[j].rssi;
@@ -1812,7 +2129,8 @@
         }
     }
 
-    if (best_index >= 0) {
+    if (best_index >= 0)
+    {
         memcpy(&info->base_info, &save_list[best_index].base_info, sizeof (ap_info_s));
         inner_get_ip_by_mac( info->base_info.ap_mac, info->base_info.ap_ip, sizeof (info->base_info.ap_ip));
         info->status = LYNQ_WIFI_AP_STATUS_DISABLE;
@@ -1834,29 +2152,32 @@
 
 static int inner_set_sta_auth_psw(int net_no, lynq_wifi_auth_s auth, char *password)
 {
-    char lynq_auth_cmd[64]={0};
+    char lynq_auth_cmd[128]={0};
     char lynq_ket_mgmt_cmd[64]={0};
     char lynq_pairwise_cmd[64]={0};
     char lynq_psk_cmd[64]={0};
 
     CHECK_WPA_CTRL(CTRL_STA);
 
-	switch(auth){
-		case LYNQ_WIFI_AUTH_OPEN:
+    switch(auth)
+    {
+        case LYNQ_WIFI_AUTH_OPEN:
         {
             sprintf(lynq_auth_cmd,"SET_NETWORK %d key_mgmt NONE", net_no);
 
             DO_OK_FAIL_REQUEST(lynq_auth_cmd);
-//            DO_OK_FAIL_REQUEST(cmd_save_config);
-			break;
-		}
-		case LYNQ_WIFI_AUTH_WPA_PSK:
+//          DO_OK_FAIL_REQUEST(cmd_save_config);
+            break;
+        }
+        case LYNQ_WIFI_AUTH_WPA_PSK:
         case LYNQ_WIFI_AUTH_WPA2_PSK:
-		{
-            if (auth == LYNQ_WIFI_AUTH_WPA_PSK) {
+	{
+            if (auth == LYNQ_WIFI_AUTH_WPA_PSK)
+	    {
                 sprintf(lynq_auth_cmd,"SET_NETWORK %d proto WPA", net_no);
             }
-            else if (auth == LYNQ_WIFI_AUTH_WPA2_PSK) {
+            else if (auth == LYNQ_WIFI_AUTH_WPA2_PSK)
+	    {
                 sprintf(lynq_auth_cmd,"SET_NETWORK %d proto RSN", net_no);
             }
             sprintf(lynq_ket_mgmt_cmd,"SET_NETWORK %d key_mgmt WPA-PSK", net_no);
@@ -1866,19 +2187,49 @@
             DO_OK_FAIL_REQUEST(lynq_ket_mgmt_cmd);
             DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
 
-            if (password != NULL) {
+            if (password != NULL)
+	    {
                 sprintf(lynq_psk_cmd, "SET_NETWORK %d psk \"%s\"", net_no, password);
                 DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+                sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", net_no);
             }
 
 //            DO_OK_FAIL_REQUEST(cmd_save_config);
-			break;
-		}		
-		default:
-			return -1;
+            break;
+        }	
+	case LYNQ_WIFI_AUTH_WPA2_WPA3_PSK:
+	{
+            sprintf(lynq_auth_cmd,"SET_NETWORK %d ieee80211w 1",net_no);
+            sprintf(lynq_ket_mgmt_cmd,"SET_NETWORK %d key_mgmt SAE WPA-PSK",net_no);
+            sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", net_no);
+            sprintf(lynq_psk_cmd, "SET_NETWORK %d psk \"%s\"", net_no, password);
+            
+	    DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+            DO_OK_FAIL_REQUEST(lynq_ket_mgmt_cmd);
+            DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+            DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+
+	    break;
+	}
+	case LYNQ_WIFI_AUTH_WPA3_PSK:
+	{
+            sprintf(lynq_auth_cmd,"SET_NETWORK %d ieee80211w 2",net_no);
+            sprintf(lynq_ket_mgmt_cmd,"SET_NETWORk %d key_mgmt SAE",net_no);
+            sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", net_no);
+            sprintf(lynq_psk_cmd, "SET_NETWORK %d psk \"%s\"", net_no, password);
+            
+	    DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+            DO_OK_FAIL_REQUEST(lynq_ket_mgmt_cmd);
+            DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+            DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+
+	    break;
+	}
+	default:
+            return -1;
     }
 
-	return 0;
+    return 0;
 }
 
 static int inner_get_curr_net_no(int interface) {
@@ -1886,7 +2237,8 @@
     curr_state.ap = NULL;
     curr_state.state = NULL;
 
-    if (0 != inner_get_status_info(interface, &curr_state)) {
+    if (0 != inner_get_status_info(interface, &curr_state))
+    {
         return -1;
     }
 
@@ -1900,7 +2252,8 @@
 
     net_no = inner_get_curr_net_no(CTRL_STA);
 
-    if (net_no < 0) {
+    if (net_no < 0)
+    {
         return -1;
     }
 
@@ -1913,14 +2266,17 @@
     int net_no_list[128];
     lynq_wifi_auth_s net_auth;
 
-    if (ssid == NULL || *ssid == '\0') {
-        printf("bad ssid\n");
+    if (ssid == NULL || *ssid == '\0')
+    {
+        RLOGE("bad ssid\n");
         return -1;
     }
 
-    if (LYNQ_WIFI_AUTH_OPEN != auth) {
-        if (psw == NULL || strlen(psw) < 8 || strlen(psw) >= 64) {
-            printf("bad password\n");
+    if (LYNQ_WIFI_AUTH_OPEN != auth)
+    {
+        if (psw == NULL || strlen(psw) < 8 || strlen(psw) >= 64)
+	{
+            RLOGE("bad password\n");
             return -1;
         }
     }
@@ -1930,27 +2286,33 @@
     net_no = -1;
     count = lynq_get_network_number_list(idx, CTRL_STA, net_no_list, ssid);
 
-    for (index=0; index < count; index++) {
+    for (index=0; index < count; index++)
+    {
         net_auth = -1;
-        if (0 == inner_get_network_auth(CTRL_STA, net_no_list[index], &net_auth) && net_auth == auth) {
+        if (0 == inner_get_network_auth(CTRL_STA, net_no_list[index], &net_auth) && net_auth == auth)
+	{
             net_no = net_no_list[index];
             break;
         }
     }
 
-    if (net_no < 0) {
+    if (net_no < 0)
+    {
         net_no = lynq_add_network(CTRL_STA);
-        if (net_no == -1) {
+        if (net_no == -1)
+	{
             return -1;
         }
 
-        printf("net no is %d\n", net_no);
-        if (0 != inner_set_sta_ssid(net_no, ssid)) {
+        RLOGD("net no is %d\n", net_no);
+        if (0 != inner_set_sta_ssid(net_no, ssid))
+	{
             return -1;
         }
     }
 
-    if (0 != inner_set_sta_auth_psw(net_no, auth, psw)) {
+    if (0 != inner_set_sta_auth_psw(net_no, auth, psw))
+    {
         return -1;
     }
 
@@ -1963,7 +2325,9 @@
     curr_status_info curr_state;
     ap.ap_ssid[0] = '\0';
 
-    if (ssid == NULL || *ssid == '\0') {
+    if (ssid == NULL || *ssid == '\0')
+    {
+        RLOGE("input ssid is NULL\n");
         return -1;
     }
 
@@ -1972,11 +2336,13 @@
     curr_state.ap = &ap;
     curr_state.state = NULL;
 
-    if (inner_get_status_info(CTRL_STA, &curr_state) != 0) {
+    if (inner_get_status_info(CTRL_STA, &curr_state) != 0)
+    {
         return 0;
     }
 
-    if (strcmp(ap.ap_ssid, ssid) != 0) {
+    if (strcmp(ap.ap_ssid, ssid) != 0)
+    {
         return 0;
     }
 
@@ -2091,8 +2457,9 @@
 
 //    ap_info_s * tmp_ap;
 //    device_info_s * tmp_list;
-    if (ap == NULL || list == NULL || len == NULL) {
-        printf("bad input param");
+    if (ap == NULL || list == NULL || len == NULL)
+    {
+        RLOGE("bad input param");
         return -1;
     }
 
@@ -2100,7 +2467,9 @@
 //    list = &tmp_list;
     *ap = malloc(sizeof (ap_info_s));
 
-    if (inner_get_status_info_ap (CTRL_AP, *ap) != 0) {
+    if (inner_get_status_info_ap (CTRL_AP, *ap) != 0)
+    {
+	RLOGE("inner_get_status_info_ap !=0\n");
         return -1;
     }
 
@@ -2110,8 +2479,10 @@
     DO_REQUEST(lynq_first_sta_cmd);
 
     index = 0;
-    while (reply_len > 0) {
-        if (memcmp(cmd_reply, "FAIL", 4) == 0) {
+    while (reply_len > 0)
+    {
+        if (memcmp(cmd_reply, "FAIL", 4) == 0)
+	{
             break;
         }
         line_count = lynq_split(cmd_reply, reply_len, '\n', split_lines);
@@ -2122,8 +2493,9 @@
         reply_len = MAX_RET;
         cmd_reply[0] = '\0';
         ret = local_wpa_ctrl_request(lynq_wpa_ctrl, lynq_next_sta_cmd, strlen(lynq_next_sta_cmd), cmd_reply, &reply_len, NULL);
-        if (ret != 0 || memcmp(cmd_reply, "FAIL", 4) == 0) {
-            printf("run %s fail \n", lynq_next_sta_cmd);
+        if (ret != 0 || memcmp(cmd_reply, "FAIL", 4) == 0)
+	{
+            RLOGD("run %s fail \n", lynq_next_sta_cmd);
             break;
         }
     }
@@ -2131,7 +2503,8 @@
     *len = index;
 
     *list = malloc(sizeof(device_info_s) * (*len));
-    for (index=0; index < *len; index++) {
+    for (index=0; index < *len; index++)
+    {
         dev_info = &(*list)[index];
         memset(dev_info, 0, sizeof(device_info_s));
         strncpy(dev_info->sta_mac, bssid[index], sizeof (dev_info->sta_mac));
@@ -2152,7 +2525,8 @@
     char *split_words[128] = {0};
     scan_info_s * p;
 
-    if (list == NULL || len == NULL) {
+    if (list == NULL || len == NULL)
+    {
         return -1;
     }
 
@@ -2172,16 +2546,18 @@
     *list = malloc(sizeof (scan_info_s) * *len);
 
     count_words = lynq_split(split_lines[0], strlen(split_lines[0]), '/', split_words); //@todo get with header
-    for (index=0; index <count_words; index++) {
-        printf("----header: %s\n", split_words[index]);
+    for (index=0; index <count_words; index++)
+    {
+        RLOGD("----header: %s\n", split_words[index]);
     }
 
-    for(index = 1;index < count; index++) {
-        printf("---- %s\n",split_lines[index]);
+    for(index = 1;index < count; index++)
+    {
+        RLOGD("---- %s\n",split_lines[index]);
         count_words = lynq_split(split_lines[index], strlen(split_lines[index]), '\t', split_words);
         if (count_words < 4)
             continue;
-        printf("count: %d, %s\n", count_words, split_words[0]);
+        RLOGD("count: %d, %s\n", count_words, split_words[0]);
         //bssid / frequency / signal level / flags / ssid
         p = (*list) + index - 1;
         strcpy(p->mac, split_words[0]);
@@ -2201,8 +2577,9 @@
     lynq_wifi_auth_s net_auth;
     char lynq_remove_cmd[MAX_CMD];
 
-    if (ssid == NULL || *ssid == '\0') {
-        printf("bad ssid\n");
+    if (ssid == NULL || *ssid == '\0')
+    {
+        RLOGD("bad ssid\n");
         return -1;
     }
 
@@ -2213,15 +2590,18 @@
     net_no = -1;
     count = lynq_get_network_number_list(idx, CTRL_STA, net_no_list, ssid);
 
-    for (index=0; index < count; index++) {
+    for (index=0; index < count; index++)
+    {
         net_auth = -1;
-        if (0 == inner_get_network_auth(CTRL_STA, net_no_list[index], &net_auth) && net_auth == auth) {
+        if (0 == inner_get_network_auth(CTRL_STA, net_no_list[index], &net_auth) && net_auth == auth)
+	{
             net_no = net_no_list[index];
             break;
         }
     }
 
-    if (net_no < 0) {
+    if (net_no < 0)
+    {
         return 0;
     }
 
@@ -2234,13 +2614,14 @@
 }
 
 int lynq_get_sta_saved_ap(lynq_wifi_index_e idx, saved_ap_info_s ** list, int * len)
-{    
+{
     int count, index;
     int net_no_list[128];
     char freq[16];
-
-    if (list == NULL || len == NULL) {
-        printf("bad param\n");
+    RLOGD("enter lynq_get_sta_saved_ap api\n");
+    if (list == NULL || len == NULL)
+    {
+        RLOGE("bad param,please check!");
         return -1;
     }
 
@@ -2249,43 +2630,54 @@
 //    CHECK_WPA_CTRL(CTRL_STA);
 
     count = lynq_get_network_number_list(idx, CTRL_STA, net_no_list, NULL);
-    printf("count is %d\n", count);
+    RLOGD("[lynq_get_sta_saved_ap]count is %d\n", count);
 
     *list = malloc(sizeof (saved_ap_info_s) * count);
     memset(*list, 0, sizeof (saved_ap_info_s) * count);
     *len = count;
 
-    for (index=0; index < count; index++) {
-        printf("to get ssid %d\n", index);
+    for (index=0; index < count; index++)
+    {
+	RLOGD("[lynq_get_sta_saved_ap]to get ssid %d", index);
+	RLOGD("[lynq_get_sta_saved_ap][inner_get_param]to get ssid");
         inner_get_param(CTRL_STA, net_no_list[index], "ssid", (*list)[index].base_info.ap_ssid);
+	RLOGD("[lynq_get_sta_saved_ap][inner_get_param]to get mac");
         inner_get_param(CTRL_STA, net_no_list[index], "bssid", (*list)[index].base_info.ap_mac);
+	RLOGD("[lynq_get_sta_saved_ap][inner_get_param]to get auth");
         inner_get_network_auth(CTRL_STA, net_no_list[index], &(*list)[index].base_info.auth);
-        if (inner_get_param(CTRL_STA, net_no_list[index], "frequency", freq) == 0) {
+	RLOGD("[lynq_get_sta_saved_ap][inner_get_param]to get band");
+        if (inner_get_param(CTRL_STA, net_no_list[index], "frequency", freq) == 0)
+	{
             (*list)[index].base_info.band = convert_band_from_freq(atoi(freq));
         }
-        else {
+        else
+	{
             (*list)[index].base_info.band = -1;
         }
-
+	RLOGD("[lynq_get_sta_saved_ap][inner_get_param]to get psw");
         lynq_sta_ssid_password_get(idx, & (*list)[index].base_info, (*list)[index].base_info.psw);
     }
-
+    RLOGD("[lynq_get_sta_saved_ap] return ok");
     return 0;
 }
 
 int lynq_wifi_sta_start_scan(lynq_wifi_index_e idx)
 {
+    const char *clean_last_re ="wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 bss_flush";
     const char *lynq_scan_cmd = "SCAN";
 
     CHECK_IDX(idx, CTRL_STA);
 
     CHECK_WPA_CTRL(CTRL_STA);
 
+    system(clean_last_re);
     g_sta_scan_finish_flag = 0;
     DO_REQUEST(lynq_scan_cmd);
-    if (reply_len >=9 && memcmp(cmd_reply, "FAIL-BUSY", 9) == 0 ) {
+    if (reply_len >=9 && memcmp(cmd_reply, "FAIL-BUSY", 9) == 0 )
+    {
         return 0;
-    } else if (reply_len >=2 && memcmp(cmd_reply, "OK", 2) != 0) {
+    } else if (reply_len >=2 && memcmp(cmd_reply, "OK", 2) != 0)
+    {
         g_sta_scan_finish_flag = 1;
         return -1;
     }
@@ -2294,7 +2686,9 @@
 }
 
 int lynq_reg_ap_event_callback(void * priv, AP_CALLBACK_FUNC_PTR cb) {
-    if (cb == NULL) {
+    if (cb == NULL) 
+    {
+        RLOGE("lynq_reg_ap_event_callback ptr is NULL,plese check!\n");
         return -1;
     }
 
@@ -2305,7 +2699,8 @@
 }
 
 int lynq_unreg_ap_event_callback(void * priv) {
-    if (g_ap_callback_priv == priv) {
+    if (g_ap_callback_priv == priv)
+    {
         g_ap_callback_func = NULL;
         g_ap_callback_priv = NULL;
         return 0;
@@ -2314,7 +2709,9 @@
 }
 
 int lynq_reg_sta_event_callback(void * priv, STA_CALLBACK_FUNC_PTR cb){
-    if (cb == NULL) {
+    if (cb == NULL) 
+    {
+        RLOGE("lynq_reg_sta_event_callback ptr is NULL,plese check!\n");
         return -1;
     }
 
@@ -2325,7 +2722,8 @@
 }
 
 int lynq_unreg_sta_event_callback(void * priv) {
-    if (g_sta_callback_priv == priv) {
+    if (g_sta_callback_priv == priv)
+    {
         g_sta_callback_func = NULL;
         g_sta_callback_priv = NULL;
         return 0;
@@ -2344,17 +2742,21 @@
 int lynq_get_ap_status(lynq_wifi_index_e idx, lynq_wifi_ap_run_status_s * ap_status)
 {
     char state[MAX_CMD];
+    RLOGD("enter lynq_get_ap_status\n");
     CHECK_IDX(idx, CTRL_AP);
 
-    if (inner_get_status_info_state(CTRL_AP, state) != 0) {
+    if (inner_get_status_info_state(CTRL_AP, state) != 0)
+    {
         *ap_status = LYNQ_WIFI_AP_STATUS_DISABLE;
         return 0;
     }
 
-    if (memcmp(state, STATE_COMPLETED, strlen (STATE_COMPLETED)) == 0) {
+    if (memcmp(state, STATE_COMPLETED, strlen (STATE_COMPLETED)) == 0)
+    {
         *ap_status = LYNQ_WIFI_AP_STATUS_ENABLE;
     }
-    else {
+    else
+    {
         *ap_status = LYNQ_WIFI_AP_STATUS_DISABLE;
     }
 
@@ -2363,17 +2765,21 @@
 
 int lynq_get_sta_status(lynq_wifi_index_e idx, lynq_wifi_sta_run_status_s * sta_status) {
     char state[MAX_CMD];
+    RLOGD("enter lynq_get_sta_status\n");
     CHECK_IDX(idx, CTRL_STA);
 
-    if (inner_get_status_info_state(CTRL_STA, state) != 0) {
+    if (inner_get_status_info_state(CTRL_STA, state) != 0)
+    {
         *sta_status = LYNQ_WIFI_STA_STATUS_DISABLE;
         return 0;
     }
 
-    if (memcmp(state, STATE_COMPLETED, strlen (STATE_COMPLETED)) == 0) {
+    if (memcmp(state, STATE_COMPLETED, strlen (STATE_COMPLETED)) == 0)
+    {
         *sta_status = LYNQ_WIFI_STA_STATUS_ENABLE;
     }
-    else {
+    else
+    {
         *sta_status = LYNQ_WIFI_STA_STATUS_DISABLE;
     }
 
@@ -2403,11 +2809,11 @@
 //        printf("to call [%s]\n", cmd_str);
 //        ret = local_wpa_ctrl_request(s_lynq_wpa_ctrl, cmd_str, strlen(cmd_str), cmd_reply, &reply_len, NULL);
 //        if (ret != 0) {
-//            printf("call ##cmd_str fail %d\n", ret);
+//            RLOGE("call ##cmd_str fail %d\n", ret);
 //            return ret;
 //        }
 //        cmd_reply[reply_len+1] = '\0';
-//        printf("cmd replay [ %s ]\n", cmd_reply);
+//        RLOGD("cmd replay [ %s ]\n", cmd_reply);
 //    }while(0);
 
     FILE *fp;
@@ -2417,25 +2823,27 @@
 //    CHECK_IDX(idx, CTRL_AP);
 
     if((fp=popen("wl country","r"))==NULL)
-        {
-            perror("popen error!");
-            return -1;
-        }
+    {
+        perror("popen error!");
+        return -1;
+    }
     if((fread(lynq_cmd_ret,sizeof(lynq_cmd_ret),1,fp))<0)
     {
         perror("fread fail!");
         return -1;
     }
 
-    for(i=0; i < strlen(lynq_cmd_ret); i++) {
-        if (lynq_cmd_ret[i] == ' ') {
+    for(i=0; i < strlen(lynq_cmd_ret); i++)
+    {
+        if (lynq_cmd_ret[i] == ' ')
+	{
             lynq_cmd_ret[i] = '\0';
             break;
         }
     }
 
     strcpy(country_code,lynq_cmd_ret);
-    printf("---country code %s\n", country_code);
+    RLOGD("---country code %s\n", country_code);
 
     int ret=pclose(fp);
     if(ret==-1)
@@ -2454,14 +2862,16 @@
 //    DO_REQUEST(cmd_str);
 //    printf("result %s\n", cmd_reply);
 
-    if (country_code == NULL || *country_code == '\0') {
-        printf("bad country code\n");
+    if (country_code == NULL || *country_code == '\0')
+    {
+        RLOGD("bad country code\n");
         return -1;
     }
 
     char lynq_country_cmd[MAX_CMD];
     sprintf(lynq_country_cmd, "wl country %s", country_code);
-    if (system(lynq_country_cmd) == 0) {
+    if (system(lynq_country_cmd) == 0)
+    {
         return 0;
     }
 
@@ -2470,7 +2880,10 @@
 
 int lynq_get_connect_ap_mac(lynq_wifi_index_e idx,char *mac)
 {
-    if (mac == NULL) {
+    RLOGD("enter lynq_get_connect_ap_mac\n");
+    if (mac == NULL) 
+    {
+        RLOGE("input ptr is NULL,please check\n");
         return -1;
     }
 
@@ -2478,7 +2891,8 @@
     ap_info_s ap;
     ap.ap_mac[0] = '\0';
 
-    if (inner_get_status_info_ap(CTRL_STA, &ap) != 0) {
+    if (inner_get_status_info_ap(CTRL_STA, &ap) != 0)
+    {
         return -1;
     }
     strcpy(mac, ap.ap_mac);
@@ -2488,18 +2902,22 @@
 
 int lynq_get_interface_ip(lynq_wifi_index_e idx, char *ip)
 {
+    RLOGD("enter lynq_get_interface_ip\n");
     struct ifaddrs *ifaddr_header, *ifaddr;
     struct in_addr * ifa;
     const char * ifaName = "wlan0";
     if (ip == NULL)
     {
+       RLOGE("[lynq_get_interface_ip]input erro,input is NULL ptr,please check\n");
        return -1;
     }
 
-    if (idx == 1) {
+    if (idx == 1)
+    {
        ifaName = "tether";
     }
-    else if (idx != 0) {
+    else if (idx != 0)
+    {
        return -1;
     }
 
@@ -2522,19 +2940,21 @@
                // is a valid IP4 Address
                ifa=&((struct sockaddr_in *)ifaddr->ifa_addr)->sin_addr;
                inet_ntop(AF_INET, ifa, ip, INET_ADDRSTRLEN);
-               printf("%s IP Address %s/n", ifaddr->ifa_name, ip);
+               RLOGD("[lynq_get_interface_ip]:%s IP Address %s/n", ifaddr->ifa_name, ip);
                freeifaddrs(ifaddr_header);
-               printf("ip %s\n", ip);
+               RLOGD("ip %s\n", ip);
                return 0;
             }
         }
     }
     freeifaddrs(ifaddr_header);
+    RLOGE("[lynq_get_interface_ip] can't find interface | other erro\n");
     return -1;
 }
 
 int lynq_get_interface_mac(lynq_wifi_index_e idx,char *mac)
 {
+    RLOGD("enter lynq_get_interface_mac\n");
     int count;
     size_t i;
     char *split_words[128] = {0};
@@ -2544,18 +2964,23 @@
 
     DO_REQUEST(lynq_get_mac_cmd);
 
-    if (memcmp(cmd_reply, "FAIL", 4) == 0) {
+    if (memcmp(cmd_reply, "FAIL", 4) == 0)
+    {
+        RLOGE("[lynq_get_interface_mac]do request cmd --DRIVER MACADDR-- reply FAIL\n");
         return -1;
     }
 
     count = lynq_split(cmd_reply, reply_len, '=', split_words);
 
-    if (count < 2) {
+    if (count < 2)
+    {
         return -1;
     }
 
-    for (i=0; i < strlen(split_words[1]); i++ ) {
-        if (split_words[1][i] != ' ') {
+    for (i=0; i < strlen(split_words[1]); i++ )
+    {
+        if (split_words[1][i] != ' ')
+	{
             break;
         }
     }
@@ -2604,10 +3029,10 @@
  *
  ***** change by qs.xiong 20221011*******/
     if((fp=popen("wl -i wlan0 rssi","r"))==NULL)
-        {
-            perror("popen error!");
-            return -1;
-        }
+    {
+        perror("popen error!");
+        return -1;
+    }
     if((fread(lynq_cmd_ret,sizeof(lynq_cmd_ret),1,fp))<0)
     {
         perror("fread fail!");
@@ -2617,7 +3042,8 @@
 /****** if got rssi is 0,means sta didn't connected any device****/
     if(*rssi == 0)
     {
-        printf("sta didn't connected any ap device,please check connection\n");
+        RLOGE("[lynq_get_connect_ap_rssi]sta didn't connected any ap device,please check connection\n");
+	return -1;
     }
 
     return 0;
@@ -2625,7 +3051,9 @@
 
 int lynq_get_connect_ap_band(lynq_wifi_index_e idx, lynq_wifi_band_m * band)
 {
-    if (band == NULL) {
+    RLOGD("enter lynq_get_connect_ap_band\n");
+    if (band == NULL)
+    {
         return -1;
     }
 
@@ -2633,7 +3061,8 @@
     ap_info_s ap;
     ap.band = -1;
 
-    if (inner_get_status_info_ap(CTRL_STA, &ap) != 0) {
+    if (inner_get_status_info_ap(CTRL_STA, &ap) != 0)
+    {
         return -1;
     }
     *band = ap.band;
@@ -2647,7 +3076,7 @@
 
     if (ip == NULL)
     {
-        printf("invalid param");
+        RLOGE("[lynq_get_connect_ap_ip]invalid param ptr ip,input ptr is NULL\n");
         return -1;
     }
 
@@ -2665,14 +3094,16 @@
 {
     char lynq_limit_cmd[32]={0};
     int ret;
-    if((sta_number < 1 ) && (sta_number > 15)){
-        printf("sta_number: not in range\n",sta_number);
+    if((sta_number < 1 ) && (sta_number > 15))
+    {
+        RLOGE("sta_number: not in range\n",sta_number);
         return -1;
     }
     sprintf(lynq_limit_cmd,"wl maxassoc  %d", sta_number);
     ret = system(lynq_limit_cmd);
-    if(ret != 0){
-        printf("cmd of limit ap devices number error\n");
+    if(ret != 0)
+    {
+        RLOGE("cmd of limit ap devices number error\n");
     }
     return 0;
 }
@@ -2684,11 +3115,13 @@
     char lynq_cmd_mode[128]={0};
     char lynq_cmd_slect[128]={0};
 
-    if((acs_mode != 2) && (acs_mode != 5)){
+    if((acs_mode != 2) && (acs_mode != 5))
+    {
         PRINT_AND_RETURN_VALUE("set acs_mode is error",-1);
     }
 
-    if (lynq_check_network_number(idx, CTRL_AP, AP_NETWORK_0) != 0) {
+    if (lynq_check_network_number(idx, CTRL_AP, AP_NETWORK_0) != 0)
+    {
         return -1;
     }
 
@@ -2741,7 +3174,8 @@
     if( inet_aton(mask, &ip_addr) )
     {
         netmask = ntohl(ip_addr.s_addr);
-    }else{
+    }else
+    {
         netmask = 0;
         return 0;
     }
@@ -2796,7 +3230,7 @@
     nmax = 6;
     ncheckcount = nidlecount = 0;
 
-    printf("------gbw thread run\n");
+    RLOGD("------gbw thread run\n");
     sprintf(str_cmd, "ip neigh | grep %s | awk '{print $1}'", g_gbw_mac);
     while (dest_ip[0] == '\0') {
         sleep(1);
@@ -2819,7 +3253,7 @@
     system("tc class add dev tether parent 1:  classid 1:1  htb rate 50Mbit ceil 70Mbit prio 2 quantum 3000");
     if (get_tether_route_str(str_cmd_ret, sizeof (str_cmd_ret)) != 0)
     {
-        printf("not get tether info\n");
+        RLOGD("not get tether info\n");
         return;
     }
     sprintf(str_cmd, "tc filter add dev tether parent 1: protocol ip prio 16 u32 match ip dst %s flowid 1:1", str_cmd_ret);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/Android.mk b/src/lynq/packages/thirdpart/lynq-wg870/Android.mk
index 0b73419..cbb1167 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/Android.mk
+++ b/src/lynq/packages/thirdpart/lynq-wg870/Android.mk
@@ -6,7 +6,10 @@
 # end of each Android.mk, so that one Android.mk doesn't depend on variables
 # set up in the other Android.mk.
 #include $(call all-makefiles-under,$(LOCAL_PATH))
-include $(LOCAL_PATH)/hostapd/Android.mk \
+include \
+        $(LOCAL_PATH)/hostapd/Android.mk \
         $(LOCAL_PATH)/wpa_supplicant/Android.mk \
-        $(LOCAL_PATH)/libbcmdhd/Android.mk
+        $(LOCAL_PATH)/libbcmdhd/Android.mk \
+        $(LOCAL_PATH)/wapilib_softap/Android.mk \
+        $(LOCAL_PATH)/wapilib/src/Android.mk
 endif
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/CONTRIBUTIONS b/src/lynq/packages/thirdpart/lynq-wg870/CONTRIBUTIONS
index c81ad64..b2064dc 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/CONTRIBUTIONS
+++ b/src/lynq/packages/thirdpart/lynq-wg870/CONTRIBUTIONS
@@ -56,6 +56,9 @@
 is by committing the changes to a cloned git repository and using git
 format-patch. The patch can then be sent, e.g., with git send-email.
 
+A list of pending patches waiting for review is available in
+Patchwork: https://patchwork.ozlabs.org/project/hostap/list/
+
 
 History of license and contributions terms
 ------------------------------------------
@@ -140,7 +143,7 @@
 
 Modified BSD license (no advertisement clause):
 
-Copyright (c) 2002-2019, Jouni Malinen <j@w1.fi> and contributors
+Copyright (c) 2002-2022, Jouni Malinen <j@w1.fi> and contributors
 All Rights Reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/COPYING b/src/lynq/packages/thirdpart/lynq-wg870/COPYING
index 5d0115c..7ca3030 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/COPYING
+++ b/src/lynq/packages/thirdpart/lynq-wg870/COPYING
@@ -1,7 +1,7 @@
 wpa_supplicant and hostapd
 --------------------------
 
-Copyright (c) 2002-2019, Jouni Malinen <j@w1.fi> and contributors
+Copyright (c) 2002-2022, Jouni Malinen <j@w1.fi> and contributors
 All Rights Reserved.
 
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/README b/src/lynq/packages/thirdpart/lynq-wg870/README
index a9f8069..1470c4f 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/README
+++ b/src/lynq/packages/thirdpart/lynq-wg870/README
@@ -1,7 +1,7 @@
 wpa_supplicant and hostapd
 --------------------------
 
-Copyright (c) 2002-2019, Jouni Malinen <j@w1.fi> and contributors
+Copyright (c) 2002-2022, Jouni Malinen <j@w1.fi> and contributors
 All Rights Reserved.
 
 These programs are licensed under the BSD license (the one with
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/conf/wpa_supplicant.conf b/src/lynq/packages/thirdpart/lynq-wg870/conf/wpa_supplicant.conf
index 833ae20..c288e9b 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/conf/wpa_supplicant.conf
+++ b/src/lynq/packages/thirdpart/lynq-wg870/conf/wpa_supplicant.conf
@@ -10,4 +10,4 @@
 hs20=1
 interworking=1
 sae_groups=19
-sae_pwe=2
+sae_pwe=2
\ No newline at end of file
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/doc/code_structure.doxygen b/src/lynq/packages/thirdpart/lynq-wg870/doc/code_structure.doxygen
index 454f179..927ea4e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/doc/code_structure.doxygen
+++ b/src/lynq/packages/thirdpart/lynq-wg870/doc/code_structure.doxygen
@@ -62,7 +62,7 @@
 	Definitions shared by multiple files
 
 \ref l2_packet.h, \ref l2_packet_linux.c, and \ref l2_packet_pcap.c
-	Layer 2 (link) access wrapper (includes native Linux implementation
+	Layer 2 (link) access wrapper (includes Linux packet socket
 	and wrappers for libdnet/libpcap). A new l2_packet implementation
 	may need to be added when porting to new operating systems that are
 	not supported by libdnet/libpcap. Makefile can be used to select which
@@ -130,7 +130,7 @@
 	Definition of TLS library wrapper
 
 \ref tls_none.c
-	Dummy implementation of TLS library wrapper for cases where TLS
+	Stub implementation of TLS library wrapper for cases where TLS
 	functionality is not included.
 
 \ref tls_openssl.c
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/doc/dbus.doxygen b/src/lynq/packages/thirdpart/lynq-wg870/doc/dbus.doxygen
index 06e53b9..f6ab820 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/doc/dbus.doxygen
+++ b/src/lynq/packages/thirdpart/lynq-wg870/doc/dbus.doxygen
@@ -553,6 +553,32 @@
 	<p>Abort ongoing scan operation.</p>
       </li>
       <li>
+	<h3>AddCred ( a{sv} : args ) -->  o : path</h3>
+	<p>Add an Interworking/Hotspot 2.0 credential.</p>
+	<h4>Arguments</h4>
+	<dl>
+	  <dt>a{sv} : args</dt>
+	  <dd>A dictionary with credential configuration. Dictionary entries are equivalent to entries in the "cred" block in wpa_supplicant configuration file.</dd>
+	</dl>
+	<h4>Returns</h4>
+	<dl>
+	  <dt>o : path</dt>
+	  <dd>A D-Bus path to an object representing the added credential</dd>
+	</dl>
+      </li>
+      <li>
+	<h3>RemoveCred ( o : path ) --> nothing</h3>
+	<p>Remove the specified Interworking/Hotspot 2.0 credential.</p>
+      </li>
+      <li>
+	<h3>RemoveAllCreds ( ) --> nothing</h3>
+	<p>Remove all configured Interworking/Hotspot 2.0 credentials.</p>
+      </li>
+      <li>
+	<h3>InterworkingSelect ( ) --> nothing</h3>
+	<p>Perform Interworking (Hotspot 2.0) network selection.</p>
+      </li>
+      <li>
 	<h3>EAPLogoff ( ) --> nothing</h3>
 	<p>IEEE 802.1X EAPOL state machine logoff.</p>
       </li>
@@ -669,7 +695,7 @@
 	  <tr><td>Pairwise</td><td>as</td><td>Possible array elements: "ccmp-256", "gcmp-256", "ccmp", "gcmp", "tkip", "none"</td>
 	  <tr><td>Group</td><td>as</td><td>Possible array elements: "ccmp-256", "gcmp-256", "ccmp", "gcmp", "tkip", "wep104", "wep40"</td>
 	  <tr><td>GroupMgmt</td><td>as</td><td>Possible array elements: "aes-128-cmac", "bip-gmac-128", "bip-gmac-256", "bip-cmac-256"</td>
-	  <tr><td>KeyMgmt</td><td>as</td><td>Possible array elements: "wpa-psk", "wpa-ft-psk", "wpa-psk-sha256", "wpa-eap", "wpa-ft-eap", "wpa-eap-sha256", "sae", "ieee8021x", "wpa-none", "wps", "none"</td>
+	  <tr><td>KeyMgmt</td><td>as</td><td>Possible array elements: "wpa-psk", "wpa-ft-psk", "wpa-psk-sha256", "wpa-eap", "wpa-ft-eap", "wpa-eap-sha256", "sae", "owe", "ieee8021x", "wpa-none", "wps", "none"</td>
 	  <tr><td>Protocol</td><td>as</td><td>Possible array elements: "rsn", "wpa"</td>
 	  <tr><td>AuthAlg</td><td>as</td><td>Possible array elements: "open", "shared", "leap"</td>
 	  <tr><td>Scan</td><td>as</td><td>Possible array elements: "active", "passive", "ssid"</td>
@@ -1261,6 +1287,14 @@
 	  <dd>A dictionary with pairs of field names and their values. Possible dictionary keys are: "addr", "dst", "bssid", "ies", "signal".</dd>
 	</dl>
       </li>
+
+      <li>
+	<h3>InterworkingAPAdded ( o : bss, o : cred, a{sv} : args )</h3>
+      </li>
+
+      <li>
+	<h3>InterworkingSelectDone ( )</h3>
+      </li>
     </ul>
 
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/doc/doxygen.conf b/src/lynq/packages/thirdpart/lynq-wg870/doc/doxygen.conf
index 3f01173..54a77ec 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/doc/doxygen.conf
+++ b/src/lynq/packages/thirdpart/lynq-wg870/doc/doxygen.conf
@@ -31,7 +31,7 @@
 # This could be handy for archiving the generated documentation or
 # if some version control system is used.
 
-PROJECT_NUMBER         = 2.9
+PROJECT_NUMBER         = 2.10
 
 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
 # base path where the generated documentation will be put.
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/doc/p2p.doxygen b/src/lynq/packages/thirdpart/lynq-wg870/doc/p2p.doxygen
index d4d86e3..6ab6e9e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/doc/p2p.doxygen
+++ b/src/lynq/packages/thirdpart/lynq-wg870/doc/p2p.doxygen
@@ -274,8 +274,8 @@
 P2P protocol includes service discovery functionality that can be used
 to discover which services are provided by the peers before forming a
 group. This leverages the Generic Advertisement Service (GAS) protocol
-from IEEE 802.11u and P2P vendor-specific contents inside the Native
-GAS messages.
+from IEEE 802.11u and P2P vendor-specific contents inside the GAS
+messages.
 
 The P2P module takes care of GAS encapsulation, fragmentation, and
 actual transmission and reception of the Action frames needed for
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostap/Android.mk b/src/lynq/packages/thirdpart/lynq-wg870/hostap/Android.mk
index ffa7e79..bd7a409 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/hostap/Android.mk
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostap/Android.mk
Binary files differ
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostap/hostapd/Android.mk b/src/lynq/packages/thirdpart/lynq-wg870/hostap/hostapd/Android.mk
index 26a0f13..2a8e942 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/hostap/hostapd/Android.mk
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostap/hostapd/Android.mk
Binary files differ
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostap/hs20/client/Android.mk b/src/lynq/packages/thirdpart/lynq-wg870/hostap/hs20/client/Android.mk
index 5c1fa26..e4db322 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/hostap/hs20/client/Android.mk
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostap/hs20/client/Android.mk
Binary files differ
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostap/libbcmdhd/Android.mk b/src/lynq/packages/thirdpart/lynq-wg870/hostap/libbcmdhd/Android.mk
index 0e2edea..e44619a 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/hostap/libbcmdhd/Android.mk
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostap/libbcmdhd/Android.mk
Binary files differ
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostap/src/drivers/drivers.mk b/src/lynq/packages/thirdpart/lynq-wg870/hostap/src/drivers/drivers.mk
index 45e93dd..599a0b5 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/hostap/src/drivers/drivers.mk
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostap/src/drivers/drivers.mk
Binary files differ
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/.config b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/.config
index 1c02c16..a0866b0 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/.config
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/.config
@@ -391,6 +391,10 @@
 # Opportunistic Wireless Encryption (OWE)
 # Experimental implementation of draft-harkins-owe-07.txt
 #CONFIG_OWE=y
+
+# Set SAE Auth status early
+CONFIG_WPA3_SAE_AUTH_EARLY_SET=y
+
 CONFIG_DPP=y
 CONFIG_IEEE80211W=y
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/Android.mk b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/Android.mk
index ba4a3da..ab496b9 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/Android.mk
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/Android.mk
@@ -52,7 +52,7 @@
 
 # Disable unused parameter warnings
 L_CFLAGS += -Wno-unused-parameter
-ifneq ($(filter O P 8.0.0 8.1.0 9 10 11 12,$(PLATFORM_VERSION)),)
+ifneq ($(filter O P 8.0.0 8.1.0 9 10 11 12 13,$(PLATFORM_VERSION)),)
 L_CFLAGS += \
 	-Wno-date-time \
 	-Wno-implicit-function-declaration \
@@ -61,7 +61,7 @@
 	-Wno-tautological-pointer-compare
 endif
 
-ifneq ($(filter 12, $(PLATFORM_VERSION)),12)
+ifeq ($(filter 12 13, $(PLATFORM_VERSION)),)
 L_CFLAGS += -Wno-error-deprecated-declarations
 endif
 
@@ -75,6 +75,10 @@
 L_CFLAGS += -DANDROID_LIB_STUB
 endif
 
+ifneq ($(BOARD_HOSTAPD_PRIVATE_LIB_EVENT),)
+L_CFLAGS += -DANDROID_LIB_EVENT
+endif
+
 ifneq ($(filter O 8.0.0 8.1.0,$(PLATFORM_VERSION)),)
 # for Android O and Oreo master
 L_CFLAGS += -DOREO
@@ -117,6 +121,17 @@
 HIDL_INTERFACE_VERSION=1.3
 endif
 
+ifneq ($(findstring 13,$(PLATFORM_VERSION)),)
+L_CFLAGS += -DABOVE_8_1
+L_CFLAGS += -DABOVE_13
+ABOVE_8_1=y
+ABOVE_10=y
+ABOVE_11=y
+ABOVE_12=y
+ABOVE_13=y
+HIDL_INTERFACE_VERSION=1.3
+endif
+
 L_CFLAGS += -DSUP_SRC_BASE=\"$(LOCAL_PATH)\"
 ifeq ($(BOARD_WLAN_DEVICE), bcmdhd)
 L_CFLAGS += -DSUP_SRC_BASE=\"$(LOCAL_PATH)\"
@@ -161,6 +176,11 @@
 INCLUDES += $(LOCAL_PATH)/src/utils
 INCLUDES += external/openssl/include
 INCLUDES += system/security/keystore/include
+
+ifdef ABOVE_13
+INCLUDES += external/boringssl/src/crypto/
+endif
+
 ifdef CONFIG_DRIVER_NL80211
 ifneq ($(wildcard external/libnl),)
 INCLUDES += external/libnl/include
@@ -699,6 +719,19 @@
 ifdef CONFIG_DPP2
 L_CFLAGS += -DCONFIG_DPP2
 endif
+ifdef CONFIG_DPP3
+L_CFLAGS += -DCONFIG_DPP3
+endif
+endif
+
+ifdef CONFIG_PASN
+L_CFLAGS += -DCONFIG_PASN
+L_CFLAGS += -DCONFIG_PTKSA_CACHE
+NEED_HMAC_SHA256_KDF=y
+NEED_HMAC_SHA384_KDF=y
+NEED_SHA256=y
+NEED_SHA384=y
+OBJS += src/common/ptksa_cache.c
 endif
 
 ifdef CONFIG_EAP_IKEV2
@@ -1265,7 +1298,17 @@
 # Broadcom merges
 L_CPPFLAGS += -DCONFIG_BRCM_MERGES
 endif # CONFIG_DRIVER_NL80211_IFX == y
-endif
+endif # CONFIG_CTRL_IFACE_HIDL
+ifdef CONFIG_CTRL_IFACE_AIDL
+HOSTAPD_USE_AIDL=y
+L_CFLAGS += -DCONFIG_CTRL_IFACE_AIDL
+L_CPPFLAGS = -Wall -Werror
+ifdef CONFIG_DRIVER_NL80211_IFX
+L_CPPFLAGS += -DCONFIG_DRIVER_NL80211_IFX
+# Broadcom merges
+L_CPPFLAGS += -DCONFIG_BRCM_MERGES
+endif # CONFIG_DRIVER_NL80211_IFX == y
+endif # CONFIG_CTRL_IFACE_AIDL
 endif
 
 ########################
@@ -1297,6 +1340,8 @@
 endif
 
 ifdef CONFIG_WAPI_AP
+INCLUDES += $(LOCAL_PATH)/../wapilib_softap
+LOCAL_STATIC_LIBRARIES += libwapi
 LOCAL_STATIC_LIBRARIES += libwapi_softap
 endif
 
@@ -1342,13 +1387,22 @@
 endif
 LOCAL_SHARED_LIBRARIES += libbase libhidlbase libhidltransport libhwbinder libutils
 LOCAL_STATIC_LIBRARIES += libhostapd_hidl
+LOCAL_INIT_RC := hostapd.android.rc
 
 endif
 
+ifeq ($(HOSTAPD_USE_AIDL), y)
+LOCAL_SHARED_LIBRARIES += android.hardware.wifi.hostapd-V1-ndk
+LOCAL_SHARED_LIBRARIES += libbase libutils
+LOCAL_SHARED_LIBRARIES += libbinder_ndk
+LOCAL_STATIC_LIBRARIES += libhostapd_aidl
+LOCAL_INIT_RC := aidl/hostapd.android.rc
+LOCAL_VINTF_FRAGMENTS := aidl/android.hardware.wifi.hostapd.xml
+endif
+
 LOCAL_CFLAGS := $(L_CFLAGS)
 LOCAL_SRC_FILES := $(OBJS)
 LOCAL_C_INCLUDES := $(INCLUDES)
-LOCAL_INIT_RC := hostapd.android.rc
 include $(BUILD_EXECUTABLE)
 
 ifeq ($(HOSTAPD_USE_HIDL), y)
@@ -1370,6 +1424,10 @@
 ifneq ($(findstring 12,$(PLATFORM_VERSION)),)
     HIDL_INTERFACE_VERSION = 1.3
 endif
+ifneq ($(findstring 13,$(PLATFORM_VERSION)),)
+    HIDL_INTERFACE_VERSION = 1.3
+endif
+
 LOCAL_SRC_FILES := \
     hidl/$(HIDL_INTERFACE_VERSION)/hidl.cpp \
     hidl/$(HIDL_INTERFACE_VERSION)/hostapd.cpp
@@ -1400,4 +1458,31 @@
     $(LOCAL_PATH)/hidl/$(HIDL_INTERFACE_VERSION)
 include $(BUILD_STATIC_LIBRARY)
 endif # HOSTAPD_USE_HIDL == y
+
+ifeq ($(HOSTAPD_USE_AIDL), y)
+### Aidl service library ###
+########################
+include $(CLEAR_VARS)
+LOCAL_MODULE := libhostapd_aidl
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-BSD SPDX-license-identifier-BSD-3-Clause SPDX-license-identifier-ISC legacy_unencumbered
+LOCAL_LICENSE_CONDITIONS := notice unencumbered
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../COPYING $(LOCAL_PATH)/../NOTICE
+LOCAL_VENDOR_MODULE := true
+LOCAL_CPPFLAGS := $(L_CPPFLAGS)
+LOCAL_CFLAGS := $(L_CFLAGS)
+LOCAL_C_INCLUDES := $(INCLUDES)
+LOCAL_SRC_FILES := \
+    aidl/aidl.cpp \
+    aidl/hostapd.cpp
+LOCAL_SHARED_LIBRARIES := \
+    android.hardware.wifi.hostapd-V1-ndk \
+    libbinder_ndk \
+    libbase \
+    libutils \
+    liblog
+LOCAL_EXPORT_C_INCLUDE_DIRS := \
+    $(LOCAL_PATH)/aidl
+include $(BUILD_STATIC_LIBRARY)
+endif # HOSTAPD_USE_AIDL == y
+
 endif # ifeq ($(WPA_BUILD_HOSTAPD),true)
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/ChangeLog b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/ChangeLog
index 34a8a08..279298e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/ChangeLog
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/ChangeLog
@@ -1,5 +1,48 @@
 ChangeLog for hostapd
 
+2022-01-16 - v2.10
+	* SAE changes
+	  - improved protection against side channel attacks
+	    [https://w1.fi/security/2022-1/]
+	  - added option send SAE Confirm immediately (sae_config_immediate=1)
+	    after SAE Commit
+	  - added support for the hash-to-element mechanism (sae_pwe=1 or
+	    sae_pwe=2)
+	  - fixed PMKSA caching with OKC
+	  - added support for SAE-PK
+	* EAP-pwd changes
+	  - improved protection against side channel attacks
+	    [https://w1.fi/security/2022-1/]
+	* fixed WPS UPnP SUBSCRIBE handling of invalid operations
+	  [https://w1.fi/security/2020-1/]
+	* fixed PMF disconnection protection bypass
+	  [https://w1.fi/security/2019-7/]
+	* added support for using OpenSSL 3.0
+	* fixed various issues in experimental support for EAP-TEAP server
+	* added configuration (max_auth_rounds, max_auth_rounds_short) to
+	  increase the maximum number of EAP message exchanges (mainly to
+	  support cases with very large certificates) for the EAP server
+	* added support for DPP release 2 (Wi-Fi Device Provisioning Protocol)
+	* extended HE (IEEE 802.11ax) support, including 6 GHz support
+	* removed obsolete IAPP functionality
+	* fixed EAP-FAST server with TLS GCM/CCM ciphers
+	* dropped support for libnl 1.1
+	* added support for nl80211 control port for EAPOL frame TX/RX
+	* fixed OWE key derivation with groups 20 and 21; this breaks backwards
+	  compatibility for these groups while the default group 19 remains
+	  backwards compatible; owe_ptk_workaround=1 can be used to enabled a
+	  a workaround for the group 20/21 backwards compatibility
+	* added support for Beacon protection
+	* added support for Extended Key ID for pairwise keys
+	* removed WEP support from the default build (CONFIG_WEP=y can be used
+	  to enable it, if really needed)
+	* added a build option to remove TKIP support (CONFIG_NO_TKIP=y)
+	* added support for Transition Disable mechanism to allow the AP to
+	  automatically disable transition mode to improve security
+	* added support for PASN
+	* added EAP-TLS server support for TLS 1.3 (disabled by default for now)
+	* a large number of other fixes, cleanup, and extensions
+
 2019-08-07 - v2.9
 	* SAE changes
 	  - disable use of groups using Brainpool curves
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/Makefile b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/Makefile
index fe76045..b596901 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/Makefile
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/Makefile
@@ -319,6 +319,10 @@
 
 endif # CONFIG_DRIVER_NL80211_IFX == y
 
+ifdef CONFIG_WPA3_SAE_AUTH_EARLY_SET
+CFLAGS += -DCONFIG_WPA3_SAE_AUTH_EARLY_SET
+endif
+
 ifdef CONFIG_SAE
 CFLAGS += -DCONFIG_SAE
 OBJS += ../src/common/sae.o
@@ -623,6 +627,19 @@
 ifdef CONFIG_DPP2
 CFLAGS += -DCONFIG_DPP2
 endif
+ifdef CONFIG_DPP3
+CFLAGS += -DCONFIG_DPP3
+endif
+endif
+
+ifdef CONFIG_PASN
+CFLAGS += -DCONFIG_PASN
+CFLAGS += -DCONFIG_PTKSA_CACHE
+NEED_HMAC_SHA256_KDF=y
+NEED_HMAC_SHA384_KDF=y
+NEED_SHA256=y
+NEED_SHA384=y
+OBJS += ../src/common/ptksa_cache.o
 endif
 
 ifdef CONFIG_EAP_IKEV2
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/README b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/README
index 1f30d7e..739c964 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/README
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/README
@@ -2,7 +2,7 @@
 	  Authenticator and RADIUS authentication server
 ================================================================
 
-Copyright (c) 2002-2019, Jouni Malinen <j@w1.fi> and contributors
+Copyright (c) 2002-2022, Jouni Malinen <j@w1.fi> and contributors
 All Rights Reserved.
 
 This program is licensed under the BSD license (the one with
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/aidl/.clang-format b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/aidl/.clang-format
new file mode 100755
index 0000000..42fadb5
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/aidl/.clang-format
@@ -0,0 +1,9 @@
+BasedOnStyle: Google
+IndentWidth: 8
+UseTab: Always
+BreakBeforeBraces: Mozilla
+AllowShortIfStatementsOnASingleLine: false
+IndentCaseLabels: false
+AccessModifierOffset: -8
+AlignAfterOpenBracket: AlwaysBreak
+SortIncludes: false
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/aidl/aidl.cpp b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/aidl/aidl.cpp
new file mode 100755
index 0000000..e02708c
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/aidl/aidl.cpp
@@ -0,0 +1,73 @@
+/*
+ * aidl interface for wpa_supplicant daemon
+ * Copyright (c) 2004-2018, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2018, Roshan Pius <rpius@google.com>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "hostapd.h"
+#include <android/binder_process.h>
+#include <android/binder_manager.h>
+
+extern "C"
+{
+#include "aidl.h"
+#include "utils/common.h"
+#include "utils/eloop.h"
+#include "utils/includes.h"
+}
+
+using aidl::android::hardware::wifi::hostapd::Hostapd;
+
+// This file is a bridge between the hostapd code written in 'C' and the aidl
+// interface in C++. So, using "C" style static globals here!
+static int aidl_fd = -1;
+static std::shared_ptr<Hostapd> service;
+
+void hostapd_aidl_sock_handler(
+    int /* sock */, void * /* eloop_ctx */, void * /* sock_ctx */)
+{
+	ABinderProcess_handlePolledCommands();
+}
+
+int hostapd_aidl_init(struct hapd_interfaces *interfaces)
+{
+	wpa_printf(MSG_DEBUG, "Initializing aidl control");
+	std::string instance;   // declared here to allow use of goto
+
+	ABinderProcess_setupPolling(&aidl_fd);
+	if (aidl_fd < 0)
+		goto err;
+
+	wpa_printf(MSG_INFO, "Processing aidl events on FD %d", aidl_fd);
+	// Look for read events from the aidl socket in the eloop.
+	if (eloop_register_read_sock(
+		aidl_fd, hostapd_aidl_sock_handler, interfaces, NULL) < 0)
+		goto err;
+
+	wpa_printf(MSG_DEBUG, "Make service");
+	service = ndk::SharedRefBase::make<Hostapd>(interfaces);
+	if (!service)
+		goto err;
+	wpa_printf(MSG_DEBUG, "Add service");
+	instance = std::string() + Hostapd::descriptor + "/default";
+	if (AServiceManager_addService(service->asBinder().get(), instance.c_str()) != STATUS_OK)
+		goto err;
+	return 0;
+err:
+	hostapd_aidl_deinit(interfaces);
+	return -1;
+}
+
+void hostapd_aidl_deinit(struct hapd_interfaces *interfaces)
+{
+	wpa_printf(MSG_INFO, "Deiniting aidl control");
+	// Before aidl deinit, make sure call terminate to clear callback_
+	if (service) {
+		service->terminate();
+	}
+	eloop_unregister_read_sock(aidl_fd);
+	aidl_fd = -1;
+}
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/aidl/aidl.h b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/aidl/aidl.h
new file mode 100755
index 0000000..f82013d
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/aidl/aidl.h
@@ -0,0 +1,27 @@
+/*
+ * aidl interface for wpa_supplicant daemon
+ * Copyright (c) 2004-2018, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2018, Roshan Pius <rpius@google.com>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif  // _cplusplus
+#include "ap/hostapd.h"
+
+/**
+ * This is the aidl RPC interface entry point to the hostapd core.
+ * This initializes the aidl driver & IHostapd instance.
+ */
+int hostapd_aidl_init(struct hapd_interfaces *interfaces);
+void hostapd_aidl_deinit(struct hapd_interfaces *interfaces);
+
+#ifdef __cplusplus
+}
+#endif  // _cplusplus
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/aidl/android.hardware.wifi.hostapd.xml b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/aidl/android.hardware.wifi.hostapd.xml
new file mode 100755
index 0000000..eb91ee2
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/aidl/android.hardware.wifi.hostapd.xml
@@ -0,0 +1,6 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.wifi.hostapd</name>
+        <fqname>IHostapd/default</fqname>
+    </hal>
+</manifest>
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/aidl/hostapd.android.rc b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/aidl/hostapd.android.rc
new file mode 100755
index 0000000..4b6b17b
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/aidl/hostapd.android.rc
@@ -0,0 +1,21 @@
+#
+# init.rc fragment for hostapd on Android
+# Copyright (c) 2002-2016, Jouni Malinen <j@w1.fi>
+#
+# This software may be distributed under the terms of the BSD license.
+# See README for more details.
+#
+
+on post-fs-data
+    mkdir /data/vendor/wifi 0770 wifi wifi
+    mkdir /data/vendor/wifi/hostapd 0770 wifi wifi
+    mkdir /data/vendor/wifi/hostapd/sockets 0770 wifi wifi
+
+service hostapd /vendor/bin/hw/hostapd
+    interface aidl android.hardware.wifi.hostapd.IHostapd/default
+    class main
+    capabilities NET_ADMIN NET_RAW
+    user wifi
+    group wifi net_raw net_admin
+    disabled
+    oneshot
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/aidl/hostapd.cpp b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/aidl/hostapd.cpp
new file mode 100755
index 0000000..11d1290
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/aidl/hostapd.cpp
@@ -0,0 +1,1128 @@
+/*
+ * aidl interface for wpa_hostapd daemon
+ * Copyright (c) 2004-2018, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2018, Roshan Pius <rpius@google.com>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+#include <iomanip>
+#include <sstream>
+#include <string>
+#include <vector>
+#include <net/if.h>
+#include <sys/socket.h>
+#include <linux/if_bridge.h>
+
+#include <android-base/file.h>
+#include <android-base/stringprintf.h>
+#include <android-base/unique_fd.h>
+
+#include "hostapd.h"
+#include <aidl/android/hardware/wifi/hostapd/ApInfo.h>
+#include <aidl/android/hardware/wifi/hostapd/BandMask.h>
+#include <aidl/android/hardware/wifi/hostapd/ChannelParams.h>
+#include <aidl/android/hardware/wifi/hostapd/ClientInfo.h>
+#include <aidl/android/hardware/wifi/hostapd/EncryptionType.h>
+#include <aidl/android/hardware/wifi/hostapd/HostapdStatusCode.h>
+#include <aidl/android/hardware/wifi/hostapd/IfaceParams.h>
+#include <aidl/android/hardware/wifi/hostapd/NetworkParams.h>
+#include <aidl/android/hardware/wifi/hostapd/ParamSizeLimits.h>
+
+extern "C"
+{
+#include "common/wpa_ctrl.h"
+#include "drivers/linux_ioctl.h"
+}
+
+// The AIDL implementation for hostapd creates a hostapd.conf dynamically for
+// each interface. This file can then be used to hook onto the normal config
+// file parsing logic in hostapd code.  Helps us to avoid duplication of code
+// in the AIDL interface.
+// TOOD(b/71872409): Add unit tests for this.
+namespace {
+constexpr char kConfFileNameFmt[] = "/data/vendor/wifi/hostapd/hostapd_%s.conf";
+
+using android::base::RemoveFileIfExists;
+using android::base::StringPrintf;
+using android::base::WriteStringToFile;
+using aidl::android::hardware::wifi::hostapd::BandMask;
+using aidl::android::hardware::wifi::hostapd::ChannelBandwidth;
+using aidl::android::hardware::wifi::hostapd::ChannelParams;
+using aidl::android::hardware::wifi::hostapd::EncryptionType;
+using aidl::android::hardware::wifi::hostapd::Generation;
+using aidl::android::hardware::wifi::hostapd::HostapdStatusCode;
+using aidl::android::hardware::wifi::hostapd::IfaceParams;
+using aidl::android::hardware::wifi::hostapd::NetworkParams;
+using aidl::android::hardware::wifi::hostapd::ParamSizeLimits;
+
+int band2Ghz = (int)BandMask::BAND_2_GHZ;
+int band5Ghz = (int)BandMask::BAND_5_GHZ;
+int band6Ghz = (int)BandMask::BAND_6_GHZ;
+int band60Ghz = (int)BandMask::BAND_60_GHZ;
+
+#define MAX_PORTS 1024
+bool GetInterfacesInBridge(std::string br_name,
+                           std::vector<std::string>* interfaces) {
+	android::base::unique_fd sock(socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0));
+	if (sock.get() < 0) {
+		wpa_printf(MSG_ERROR, "Failed to create sock (%s) in %s",
+			strerror(errno), __FUNCTION__);
+		return false;
+	}
+
+	struct ifreq request;
+	int i, ifindices[MAX_PORTS];
+	char if_name[IFNAMSIZ];
+	unsigned long args[3];
+
+	memset(ifindices, 0, MAX_PORTS * sizeof(int));
+
+	args[0] = BRCTL_GET_PORT_LIST;
+	args[1] = (unsigned long) ifindices;
+	args[2] = MAX_PORTS;
+
+	strlcpy(request.ifr_name, br_name.c_str(), IFNAMSIZ);
+	request.ifr_data = (char *)args;
+
+	if (ioctl(sock.get(), SIOCDEVPRIVATE, &request) < 0) {
+		wpa_printf(MSG_ERROR, "Failed to ioctl SIOCDEVPRIVATE in %s",
+			__FUNCTION__);
+		return false;
+	}
+
+	for (i = 0; i < MAX_PORTS; i ++) {
+		memset(if_name, 0, IFNAMSIZ);
+		if (ifindices[i] == 0 || !if_indextoname(ifindices[i], if_name)) {
+			continue;
+		}
+		interfaces->push_back(if_name);
+	}
+	return true;
+}
+
+std::string WriteHostapdConfig(
+    const std::string& interface_name, const std::string& config)
+{
+	const std::string file_path =
+	    StringPrintf(kConfFileNameFmt, interface_name.c_str());
+	if (WriteStringToFile(
+		config, file_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+		getuid(), getgid())) {
+		return file_path;
+	}
+	// Diagnose failure
+	int error = errno;
+	wpa_printf(
+		MSG_ERROR, "Cannot write hostapd config to %s, error: %s",
+		file_path.c_str(), strerror(error));
+	struct stat st;
+	int result = stat(file_path.c_str(), &st);
+	if (result == 0) {
+		wpa_printf(
+			MSG_ERROR, "hostapd config file uid: %d, gid: %d, mode: %d",
+			st.st_uid, st.st_gid, st.st_mode);
+	} else {
+		wpa_printf(
+			MSG_ERROR,
+			"Error calling stat() on hostapd config file: %s",
+			strerror(errno));
+	}
+	return "";
+}
+
+/*
+ * Get the op_class for a channel/band
+ * The logic here is based on Table E-4 in the 802.11 Specification
+ */
+int getOpClassForChannel(int channel, int band, bool support11n, bool support11ac) {
+	// 2GHz Band
+	if ((band & band2Ghz) != 0) {
+		if (channel == 14) {
+			return 82;
+		}
+		if (channel >= 1 && channel <= 13) {
+			if (!support11n) {
+				//20MHz channel
+				return 81;
+			}
+			if (channel <= 9) {
+				// HT40 with secondary channel above primary
+				return 83;
+			}
+			// HT40 with secondary channel below primary
+			return 84;
+		}
+		// Error
+		return 0;
+	}
+
+	// 5GHz Band
+	if ((band & band5Ghz) != 0) {
+		if (support11ac) {
+			switch (channel) {
+				case 42:
+				case 58:
+				case 106:
+				case 122:
+				case 138:
+				case 155:
+					// 80MHz channel
+					return 128;
+				case 50:
+				case 114:
+					// 160MHz channel
+					return 129;
+			}
+		}
+
+		if (!support11n) {
+			if (channel >= 36 && channel <= 48) {
+				return 115;
+			}
+			if (channel >= 52 && channel <= 64) {
+				return 118;
+			}
+			if (channel >= 100 && channel <= 144) {
+				return 121;
+			}
+			if (channel >= 149 && channel <= 161) {
+				return 124;
+			}
+			if (channel >= 165 && channel <= 169) {
+				return 125;
+			}
+		} else {
+			switch (channel) {
+				case 36:
+				case 44:
+					// HT40 with secondary channel above primary
+					return 116;
+				case 40:
+				case 48:
+					// HT40 with secondary channel below primary
+					return 117;
+				case 52:
+				case 60:
+					// HT40 with secondary channel above primary
+					return  119;
+				case 56:
+				case 64:
+					// HT40 with secondary channel below primary
+					return 120;
+				case 100:
+				case 108:
+				case 116:
+				case 124:
+				case 132:
+				case 140:
+					// HT40 with secondary channel above primary
+					return 122;
+				case 104:
+				case 112:
+				case 120:
+				case 128:
+				case 136:
+				case 144:
+					// HT40 with secondary channel below primary
+					return 123;
+				case 149:
+				case 157:
+					// HT40 with secondary channel above primary
+					return 126;
+				case 153:
+				case 161:
+					// HT40 with secondary channel below primary
+					return 127;
+			}
+		}
+		// Error
+		return 0;
+	}
+
+	// 6GHz Band
+	if ((band & band6Ghz) != 0) {
+		// Channels 1, 5. 9, 13, ...
+		if ((channel & 0x03) == 0x01) {
+			// 20MHz channel
+			return 131;
+		}
+		// Channels 3, 11, 19, 27, ...
+		if ((channel & 0x07) == 0x03) {
+			// 40MHz channel
+			return 132;
+		}
+		// Channels 7, 23, 39, 55, ...
+		if ((channel & 0x0F) == 0x07) {
+			// 80MHz channel
+			return 133;
+		}
+		// Channels 15, 47, 69, ...
+		if ((channel & 0x1F) == 0x0F) {
+			// 160MHz channel
+			return 134;
+		}
+		if (channel == 2) {
+			// 20MHz channel
+			return 136;
+		}
+		// Error
+		return 0;
+	}
+
+	if ((band & band60Ghz) != 0) {
+		if (1 <= channel && channel <= 8) {
+			return 180;
+		} else if (9 <= channel && channel <= 15) {
+			return 181;
+		} else if (17 <= channel && channel <= 22) {
+			return 182;
+		} else if (25 <= channel && channel <= 29) {
+			return 183;
+		}
+		// Error
+		return 0;
+	}
+
+	return 0;
+}
+
+bool validatePassphrase(int passphrase_len, int min_len, int max_len)
+{
+	if (min_len != -1 && passphrase_len < min_len) return false;
+	if (max_len != -1 && passphrase_len > max_len) return false;
+	return true;
+}
+
+std::string CreateHostapdConfig(
+	const IfaceParams& iface_params,
+	const ChannelParams& channelParams,
+	const NetworkParams& nw_params,
+	const std::string br_name,
+	const std::string owe_transition_ifname)
+{
+	if (nw_params.ssid.size() >
+		static_cast<uint32_t>(
+		ParamSizeLimits::SSID_MAX_LEN_IN_BYTES)) {
+		wpa_printf(
+			MSG_ERROR, "Invalid SSID size: %zu", nw_params.ssid.size());
+		return "";
+	}
+
+	// SSID string
+	std::stringstream ss;
+	ss << std::hex;
+	ss << std::setfill('0');
+	for (uint8_t b : nw_params.ssid) {
+		ss << std::setw(2) << static_cast<unsigned int>(b);
+	}
+	const std::string ssid_as_string = ss.str();
+
+	// Encryption config string
+	uint32_t band = 0;
+	band |= static_cast<uint32_t>(channelParams.bandMask);
+	bool is_2Ghz_band_only = band == static_cast<uint32_t>(band2Ghz);
+	bool is_6Ghz_band_only = band == static_cast<uint32_t>(band6Ghz);
+	bool is_60Ghz_band_only = band == static_cast<uint32_t>(band60Ghz);
+	std::string encryption_config_as_string;
+	switch (nw_params.encryptionType) {
+	case EncryptionType::NONE:
+		// no security params
+		break;
+	case EncryptionType::WPA:
+		if (!validatePassphrase(
+			nw_params.passphrase.size(),
+			static_cast<uint32_t>(ParamSizeLimits::
+				WPA2_PSK_PASSPHRASE_MIN_LEN_IN_BYTES),
+			static_cast<uint32_t>(ParamSizeLimits::
+				WPA2_PSK_PASSPHRASE_MAX_LEN_IN_BYTES))) {
+			return "";
+		}
+		encryption_config_as_string = StringPrintf(
+			"wpa=3\n"
+			"wpa_pairwise=%s\n"
+			"wpa_passphrase=%s",
+			is_60Ghz_band_only ? "GCMP" : "TKIP CCMP",
+			nw_params.passphrase.c_str());
+		break;
+	case EncryptionType::WPA2:
+		if (!validatePassphrase(
+			nw_params.passphrase.size(),
+			static_cast<uint32_t>(ParamSizeLimits::
+				WPA2_PSK_PASSPHRASE_MIN_LEN_IN_BYTES),
+			static_cast<uint32_t>(ParamSizeLimits::
+				WPA2_PSK_PASSPHRASE_MAX_LEN_IN_BYTES))) {
+			return "";
+		}
+		encryption_config_as_string = StringPrintf(
+			"wpa=2\n"
+			"rsn_pairwise=%s\n"
+#ifdef ENABLE_HOSTAPD_CONFIG_80211W_MFP_OPTIONAL
+			"ieee80211w=1\n"
+#endif
+			"wpa_passphrase=%s",
+			is_60Ghz_band_only ? "GCMP" : "CCMP",
+			nw_params.passphrase.c_str());
+		break;
+	case EncryptionType::WPA3_SAE_TRANSITION:
+		if (!validatePassphrase(
+			nw_params.passphrase.size(),
+			static_cast<uint32_t>(ParamSizeLimits::
+				WPA2_PSK_PASSPHRASE_MIN_LEN_IN_BYTES),
+			static_cast<uint32_t>(ParamSizeLimits::
+				WPA2_PSK_PASSPHRASE_MAX_LEN_IN_BYTES))) {
+			return "";
+		}
+		encryption_config_as_string = StringPrintf(
+			"wpa=2\n"
+			"rsn_pairwise=%s\n"
+			"wpa_key_mgmt=WPA-PSK SAE\n"
+			"ieee80211w=1\n"
+			"sae_require_mfp=1\n"
+			"wpa_passphrase=%s\n"
+			"sae_password=%s",
+			is_60Ghz_band_only ? "GCMP" : "CCMP",
+			nw_params.passphrase.c_str(),
+			nw_params.passphrase.c_str());
+		break;
+	case EncryptionType::WPA3_SAE:
+		if (!validatePassphrase(nw_params.passphrase.size(), 1, -1)) {
+			return "";
+		}
+		encryption_config_as_string = StringPrintf(
+			"wpa=2\n"
+			"rsn_pairwise=%s\n"
+			"wpa_key_mgmt=SAE\n"
+			"ieee80211w=2\n"
+			"sae_require_mfp=2\n"
+			"sae_pwe=%d\n"
+			"sae_password=%s",
+			is_60Ghz_band_only ? "GCMP" : "CCMP",
+			is_6Ghz_band_only ? 1 : 2,
+			nw_params.passphrase.c_str());
+		break;
+	case EncryptionType::WPA3_OWE_TRANSITION:
+		encryption_config_as_string = StringPrintf(
+			"wpa=2\n"
+			"rsn_pairwise=%s\n"
+			"wpa_key_mgmt=OWE\n"
+			"ieee80211w=2",
+			is_60Ghz_band_only ? "GCMP" : "CCMP");
+		break;
+	case EncryptionType::WPA3_OWE:
+		encryption_config_as_string = StringPrintf(
+			"wpa=2\n"
+			"rsn_pairwise=%s\n"
+			"wpa_key_mgmt=OWE\n"
+			"ieee80211w=2",
+			is_60Ghz_band_only ? "GCMP" : "CCMP");
+		break;
+	default:
+		wpa_printf(MSG_ERROR, "Unknown encryption type");
+		return "";
+	}
+
+	std::string channel_config_as_string;
+	bool isFirst = true;
+	if (channelParams.enableAcs) {
+		std::string freqList_as_string;
+		for (const auto &range :
+			channelParams.acsChannelFreqRangesMhz) {
+			if (!isFirst) {
+				freqList_as_string += ",";
+			}
+			isFirst = false;
+
+			if (range.startMhz != range.endMhz) {
+				freqList_as_string +=
+					StringPrintf("%d-%d", range.startMhz, range.endMhz);
+			} else {
+				freqList_as_string += StringPrintf("%d", range.startMhz);
+			}
+		}
+		channel_config_as_string = StringPrintf(
+			"channel=0\n"
+			"acs_exclude_dfs=%d\n"
+			"freqlist=%s",
+			channelParams.acsShouldExcludeDfs,
+			freqList_as_string.c_str());
+	} else {
+		int op_class = getOpClassForChannel(
+			channelParams.channel,
+			band,
+			iface_params.hwModeParams.enable80211N,
+			iface_params.hwModeParams.enable80211AC);
+		channel_config_as_string = StringPrintf(
+			"channel=%d\n"
+			"op_class=%d",
+			channelParams.channel, op_class);
+	}
+
+	std::string hw_mode_as_string;
+	std::string enable_edmg_as_string;
+	std::string edmg_channel_as_string;
+	bool is_60Ghz_used = false;
+
+	if (((band & band60Ghz) != 0)) {
+		hw_mode_as_string = "hw_mode=ad";
+		if (iface_params.hwModeParams.enableEdmg) {
+			enable_edmg_as_string = "enable_edmg=1";
+			edmg_channel_as_string = StringPrintf(
+				"edmg_channel=%d",
+				channelParams.channel);
+		}
+		is_60Ghz_used = true;
+	} else if ((band & band2Ghz) != 0) {
+		if (((band & band5Ghz) != 0)
+		    || ((band & band6Ghz) != 0)) {
+			hw_mode_as_string = "hw_mode=any";
+		} else {
+			hw_mode_as_string = "hw_mode=g";
+		}
+	} else if (((band & band5Ghz) != 0)
+		    || ((band & band6Ghz) != 0)) {
+			hw_mode_as_string = "hw_mode=a";
+	} else {
+		wpa_printf(MSG_ERROR, "Invalid band");
+		return "";
+	}
+
+	std::string he_params_as_string;
+#ifdef CONFIG_IEEE80211AX
+	if (iface_params.hwModeParams.enable80211AX && !is_60Ghz_used) {
+		he_params_as_string = StringPrintf(
+			"ieee80211ax=1\n"
+			"he_su_beamformer=%d\n"
+			"he_su_beamformee=%d\n"
+			"he_mu_beamformer=%d\n"
+			"he_twt_required=%d\n",
+			iface_params.hwModeParams.enableHeSingleUserBeamformer ? 1 : 0,
+			iface_params.hwModeParams.enableHeSingleUserBeamformee ? 1 : 0,
+			iface_params.hwModeParams.enableHeMultiUserBeamformer ? 1 : 0,
+			iface_params.hwModeParams.enableHeTargetWakeTime ? 1 : 0);
+	} else {
+		he_params_as_string = "ieee80211ax=0";
+	}
+#endif /* CONFIG_IEEE80211AX */
+
+	std::string ht_cap_vht_oper_he_oper_chwidth_as_string;
+	switch (iface_params.hwModeParams.maximumChannelBandwidth) {
+	case ChannelBandwidth::BANDWIDTH_20:
+		ht_cap_vht_oper_he_oper_chwidth_as_string = StringPrintf(
+#ifdef CONFIG_IEEE80211AX
+			"he_oper_chwidth=0\n"
+#endif
+			"vht_oper_chwidth=0");
+		break;
+	case ChannelBandwidth::BANDWIDTH_40:
+		ht_cap_vht_oper_he_oper_chwidth_as_string = StringPrintf(
+			"ht_capab=[HT40+]\n"
+#ifdef CONFIG_IEEE80211AX
+			"he_oper_chwidth=0\n"
+#endif
+			"vht_oper_chwidth=0");
+		break;
+	case ChannelBandwidth::BANDWIDTH_80:
+		ht_cap_vht_oper_he_oper_chwidth_as_string = StringPrintf(
+			"ht_capab=[HT40+]\n"
+#ifdef CONFIG_IEEE80211AX
+			"he_oper_chwidth=%d\n"
+#endif
+			"vht_oper_chwidth=%d",
+#ifdef CONFIG_IEEE80211AX
+			(iface_params.hwModeParams.enable80211AX && !is_60Ghz_used) ? 1 : 0,
+#endif
+			iface_params.hwModeParams.enable80211AC ? 1 : 0);
+		break;
+	case ChannelBandwidth::BANDWIDTH_160:
+		ht_cap_vht_oper_he_oper_chwidth_as_string = StringPrintf(
+			"ht_capab=[HT40+]\n"
+#ifdef CONFIG_IEEE80211AX
+			"he_oper_chwidth=%d\n"
+#endif
+			"vht_oper_chwidth=%d",
+#ifdef CONFIG_IEEE80211AX
+			(iface_params.hwModeParams.enable80211AX && !is_60Ghz_used) ? 2 : 0,
+#endif
+			iface_params.hwModeParams.enable80211AC ? 2 : 0);
+		break;
+	default:
+		if (!is_2Ghz_band_only && !is_60Ghz_used
+		    && iface_params.hwModeParams.enable80211AC) {
+			ht_cap_vht_oper_he_oper_chwidth_as_string =
+					"ht_capab=[HT40+]\n"
+					"vht_oper_chwidth=1\n";
+		}
+#ifdef CONFIG_IEEE80211AX
+		if (iface_params.hwModeParams.enable80211AX && !is_60Ghz_used) {
+			ht_cap_vht_oper_he_oper_chwidth_as_string += "he_oper_chwidth=1";
+		}
+#endif
+		break;
+	}
+
+#ifdef CONFIG_INTERWORKING
+	std::string access_network_params_as_string;
+	if (nw_params.isMetered) {
+		access_network_params_as_string = StringPrintf(
+			"interworking=1\n"
+			"access_network_type=2\n"); // CHARGEABLE_PUBLIC_NETWORK
+	} else {
+	    access_network_params_as_string = StringPrintf(
+			"interworking=0\n");
+	}
+#endif /* CONFIG_INTERWORKING */
+
+	std::string bridge_as_string;
+	if (!br_name.empty()) {
+		bridge_as_string = StringPrintf("bridge=%s", br_name.c_str());
+	}
+
+	// vendor_elements string
+	std::string vendor_elements_as_string;
+	if (nw_params.vendorElements.size() > 0) {
+		std::stringstream ss;
+		ss << std::hex;
+		ss << std::setfill('0');
+		for (uint8_t b : nw_params.vendorElements) {
+			ss << std::setw(2) << static_cast<unsigned int>(b);
+		}
+		vendor_elements_as_string = StringPrintf("vendor_elements=%s", ss.str().c_str());
+	}
+
+	std::string owe_transition_ifname_as_string;
+	if (!owe_transition_ifname.empty()) {
+		owe_transition_ifname_as_string = StringPrintf(
+			"owe_transition_ifname=%s", owe_transition_ifname.c_str());
+	}
+
+	return StringPrintf(
+		"interface=%s\n"
+		"driver=nl80211\n"
+		"ctrl_interface=/data/vendor/wifi/hostapd/ctrl\n"
+		// ssid2 signals to hostapd that the value is not a literal value
+		// for use as a SSID.  In this case, we're giving it a hex
+		// std::string and hostapd needs to expect that.
+		"ssid2=%s\n"
+		"%s\n"
+		"ieee80211n=%d\n"
+		"ieee80211ac=%d\n"
+		"%s\n"
+		"%s\n"
+		"%s\n"
+		"ignore_broadcast_ssid=%d\n"
+		"wowlan_triggers=any\n"
+#ifdef CONFIG_INTERWORKING
+		"%s\n"
+#endif /* CONFIG_INTERWORKING */
+		"%s\n"
+		"%s\n"
+		"%s\n"
+		"%s\n"
+		"%s\n"
+		"%s\n",
+		iface_params.name.c_str(), ssid_as_string.c_str(),
+		channel_config_as_string.c_str(),
+		iface_params.hwModeParams.enable80211N ? 1 : 0,
+		iface_params.hwModeParams.enable80211AC ? 1 : 0,
+		he_params_as_string.c_str(),
+		hw_mode_as_string.c_str(), ht_cap_vht_oper_he_oper_chwidth_as_string.c_str(),
+		nw_params.isHidden ? 1 : 0,
+#ifdef CONFIG_INTERWORKING
+		access_network_params_as_string.c_str(),
+#endif /* CONFIG_INTERWORKING */
+		encryption_config_as_string.c_str(),
+		bridge_as_string.c_str(),
+		owe_transition_ifname_as_string.c_str(),
+		enable_edmg_as_string.c_str(),
+		edmg_channel_as_string.c_str(),
+		vendor_elements_as_string.c_str());
+}
+
+Generation getGeneration(hostapd_hw_modes *current_mode)
+{
+	wpa_printf(MSG_DEBUG, "getGeneration hwmode=%d, ht_enabled=%d,"
+		   " vht_enabled=%d, he_supported=%d",
+		   current_mode->mode, current_mode->ht_capab != 0,
+		   current_mode->vht_capab != 0, current_mode->he_capab->he_supported);
+	switch (current_mode->mode) {
+	case HOSTAPD_MODE_IEEE80211B:
+		return Generation::WIFI_STANDARD_LEGACY;
+	case HOSTAPD_MODE_IEEE80211G:
+		return current_mode->ht_capab == 0 ?
+				Generation::WIFI_STANDARD_LEGACY : Generation::WIFI_STANDARD_11N;
+	case HOSTAPD_MODE_IEEE80211A:
+		if (current_mode->he_capab->he_supported) {
+			return Generation::WIFI_STANDARD_11AX;
+		}
+		return current_mode->vht_capab == 0 ?
+		       Generation::WIFI_STANDARD_11N : Generation::WIFI_STANDARD_11AC;
+	case HOSTAPD_MODE_IEEE80211AD:
+		return Generation::WIFI_STANDARD_11AD;
+	default:
+		return Generation::WIFI_STANDARD_UNKNOWN;
+	}
+}
+
+ChannelBandwidth getChannelBandwidth(struct hostapd_config *iconf)
+{
+	wpa_printf(MSG_DEBUG, "getChannelBandwidth %d, isHT=%d, isHT40=%d",
+		   iconf->vht_oper_chwidth, iconf->ieee80211n,
+		   iconf->secondary_channel);
+	switch (iconf->vht_oper_chwidth) {
+	case CHANWIDTH_80MHZ:
+		return ChannelBandwidth::BANDWIDTH_80;
+	case CHANWIDTH_80P80MHZ:
+		return ChannelBandwidth::BANDWIDTH_80P80;
+		break;
+	case CHANWIDTH_160MHZ:
+		return ChannelBandwidth::BANDWIDTH_160;
+		break;
+	case CHANWIDTH_USE_HT:
+		if (iconf->ieee80211n) {
+			return iconf->secondary_channel != 0 ?
+				ChannelBandwidth::BANDWIDTH_40 : ChannelBandwidth::BANDWIDTH_20;
+		}
+		return ChannelBandwidth::BANDWIDTH_20_NOHT;
+	case CHANWIDTH_2160MHZ:
+		return ChannelBandwidth::BANDWIDTH_2160;
+	case CHANWIDTH_4320MHZ:
+		return ChannelBandwidth::BANDWIDTH_4320;
+	case CHANWIDTH_6480MHZ:
+		return ChannelBandwidth::BANDWIDTH_6480;
+	case CHANWIDTH_8640MHZ:
+		return ChannelBandwidth::BANDWIDTH_8640;
+	default:
+		return ChannelBandwidth::BANDWIDTH_INVALID;
+	}
+}
+
+bool forceStaDisconnection(struct hostapd_data* hapd,
+			   const std::vector<uint8_t>& client_address,
+			   const uint16_t reason_code) {
+	struct sta_info *sta;
+	for (sta = hapd->sta_list; sta; sta = sta->next) {
+		int res;
+		res = memcmp(sta->addr, client_address.data(), ETH_ALEN);
+		if (res == 0) {
+			wpa_printf(MSG_INFO, "Force client:" MACSTR " disconnect with reason: %d",
+			    MAC2STR(client_address.data()), reason_code);
+			ap_sta_disconnect(hapd, sta, sta->addr, reason_code);
+			return true;
+		}
+	}
+	return false;
+}
+
+// hostapd core functions accept "C" style function pointers, so use global
+// functions to pass to the hostapd core function and store the corresponding
+// std::function methods to be invoked.
+//
+// NOTE: Using the pattern from the vendor HAL (wifi_legacy_hal.cpp).
+//
+// Callback to be invoked once setup is complete
+std::function<void(struct hostapd_data*)> on_setup_complete_internal_callback;
+void onAsyncSetupCompleteCb(void* ctx)
+{
+	struct hostapd_data* iface_hapd = (struct hostapd_data*)ctx;
+	if (on_setup_complete_internal_callback) {
+		on_setup_complete_internal_callback(iface_hapd);
+		// Invalidate this callback since we don't want this firing
+		// again in single AP mode.
+		if (strlen(iface_hapd->conf->bridge) > 0) {
+			on_setup_complete_internal_callback = nullptr;
+		}
+	}
+}
+
+// Callback to be invoked on hotspot client connection/disconnection
+std::function<void(struct hostapd_data*, const u8 *mac_addr, int authorized,
+		const u8 *p2p_dev_addr)> on_sta_authorized_internal_callback;
+void onAsyncStaAuthorizedCb(void* ctx, const u8 *mac_addr, int authorized,
+		const u8 *p2p_dev_addr)
+{
+	struct hostapd_data* iface_hapd = (struct hostapd_data*)ctx;
+	if (on_sta_authorized_internal_callback) {
+		on_sta_authorized_internal_callback(iface_hapd, mac_addr,
+			authorized, p2p_dev_addr);
+	}
+}
+
+std::function<void(struct hostapd_data*, int level,
+			enum wpa_msg_type type, const char *txt,
+			size_t len)> on_wpa_msg_internal_callback;
+
+void onAsyncWpaEventCb(void *ctx, int level,
+			enum wpa_msg_type type, const char *txt,
+			size_t len)
+{
+	struct hostapd_data* iface_hapd = (struct hostapd_data*)ctx;
+	if (on_wpa_msg_internal_callback) {
+		on_wpa_msg_internal_callback(iface_hapd, level,
+					type, txt, len);
+	}
+}
+
+inline ndk::ScopedAStatus createStatus(HostapdStatusCode status_code) {
+	return ndk::ScopedAStatus::fromServiceSpecificError(
+		static_cast<int32_t>(status_code));
+}
+
+inline ndk::ScopedAStatus createStatusWithMsg(
+	HostapdStatusCode status_code, std::string msg)
+{
+	return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+		static_cast<int32_t>(status_code), msg.c_str());
+}
+
+// Method called by death_notifier_ on client death.
+void onDeath(void* cookie) {
+	wpa_printf(MSG_ERROR, "Client died. Terminating...");
+	eloop_terminate();
+}
+
+}  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace hostapd {
+
+Hostapd::Hostapd(struct hapd_interfaces* interfaces)
+	: interfaces_(interfaces)
+{
+	death_notifier_ = AIBinder_DeathRecipient_new(onDeath);
+}
+
+::ndk::ScopedAStatus Hostapd::addAccessPoint(
+	const IfaceParams& iface_params, const NetworkParams& nw_params)
+{
+	return addAccessPointInternal(iface_params, nw_params);
+}
+
+::ndk::ScopedAStatus Hostapd::removeAccessPoint(const std::string& iface_name)
+{
+	return removeAccessPointInternal(iface_name);
+}
+
+::ndk::ScopedAStatus Hostapd::terminate()
+{
+	wpa_printf(MSG_INFO, "Terminating...");
+	// Clear the callback to avoid IPCThreadState shutdown during the
+	// callback event.
+	callbacks_.clear();
+	eloop_terminate();
+	return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Hostapd::registerCallback(
+	const std::shared_ptr<IHostapdCallback>& callback)
+{
+	return registerCallbackInternal(callback);
+}
+
+::ndk::ScopedAStatus Hostapd::forceClientDisconnect(
+	const std::string& iface_name, const std::vector<uint8_t>& client_address,
+	Ieee80211ReasonCode reason_code)
+{
+	return forceClientDisconnectInternal(iface_name, client_address, reason_code);
+}
+
+::ndk::ScopedAStatus Hostapd::setDebugParams(DebugLevel level)
+{
+	return setDebugParamsInternal(level);
+}
+
+::ndk::ScopedAStatus Hostapd::addAccessPointInternal(
+	const IfaceParams& iface_params,
+	const NetworkParams& nw_params)
+{
+	int channelParamsSize = iface_params.channelParams.size();
+	if (channelParamsSize == 1) {
+		// Single AP
+		wpa_printf(MSG_INFO, "AddSingleAccessPoint, iface=%s",
+			iface_params.name.c_str());
+		return addSingleAccessPoint(iface_params, iface_params.channelParams[0],
+		    nw_params, "", "");
+	} else if (channelParamsSize == 2) {
+		// Concurrent APs
+		wpa_printf(MSG_INFO, "AddDualAccessPoint, iface=%s",
+			iface_params.name.c_str());
+		return addConcurrentAccessPoints(iface_params, nw_params);
+	}
+	return createStatus(HostapdStatusCode::FAILURE_ARGS_INVALID);
+}
+
+std::vector<uint8_t>  generateRandomOweSsid()
+{
+	u8 random[8] = {0};
+	os_get_random(random, 8);
+
+	std::string ssid = StringPrintf("Owe-%s", random);
+	wpa_printf(MSG_INFO, "Generated OWE SSID: %s", ssid.c_str());
+	std::vector<uint8_t> vssid(ssid.begin(), ssid.end());
+
+	return vssid;
+}
+
+::ndk::ScopedAStatus Hostapd::addConcurrentAccessPoints(
+	const IfaceParams& iface_params, const NetworkParams& nw_params)
+{
+	int channelParamsListSize = iface_params.channelParams.size();
+	// Get available interfaces in bridge
+	std::vector<std::string> managed_interfaces;
+	std::string br_name = StringPrintf(
+		"%s", iface_params.name.c_str());
+	if (!GetInterfacesInBridge(br_name, &managed_interfaces)) {
+		return createStatusWithMsg(HostapdStatusCode::FAILURE_UNKNOWN,
+			"Get interfaces in bridge failed.");
+	}
+	if (managed_interfaces.size() < channelParamsListSize) {
+		return createStatusWithMsg(HostapdStatusCode::FAILURE_UNKNOWN,
+			"Available interfaces less than requested bands");
+	}
+	// start BSS on specified bands
+	for (std::size_t i = 0; i < channelParamsListSize; i ++) {
+		IfaceParams iface_params_new = iface_params;
+		NetworkParams nw_params_new = nw_params;
+		iface_params_new.name = managed_interfaces[i];
+
+		std::string owe_transition_ifname = "";
+		if (nw_params.encryptionType == EncryptionType::WPA3_OWE_TRANSITION) {
+			if (i == 0 && i+1 < channelParamsListSize) {
+				owe_transition_ifname = managed_interfaces[i+1];
+				nw_params_new.encryptionType = EncryptionType::NONE;
+			} else {
+				owe_transition_ifname = managed_interfaces[0];
+				nw_params_new.isHidden = true;
+				nw_params_new.ssid = generateRandomOweSsid();
+			}
+		}
+
+		ndk::ScopedAStatus status = addSingleAccessPoint(
+		    iface_params_new, iface_params.channelParams[i], nw_params_new,
+		    br_name, owe_transition_ifname);
+		if (!status.isOk()) {
+			wpa_printf(MSG_ERROR, "Failed to addAccessPoint %s",
+				   managed_interfaces[i].c_str());
+			return status;
+		}
+	}
+	// Save bridge interface info
+	br_interfaces_[br_name] = managed_interfaces;
+	return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Hostapd::addSingleAccessPoint(
+	const IfaceParams& iface_params,
+	const ChannelParams& channelParams,
+	const NetworkParams& nw_params,
+	const std::string br_name,
+	const std::string owe_transition_ifname)
+{
+	if (hostapd_get_iface(interfaces_, iface_params.name.c_str())) {
+		wpa_printf(
+			MSG_ERROR, "Interface %s already present",
+			iface_params.name.c_str());
+		return createStatus(HostapdStatusCode::FAILURE_IFACE_EXISTS);
+	}
+	const auto conf_params = CreateHostapdConfig(iface_params, channelParams, nw_params,
+					br_name, owe_transition_ifname);
+	if (conf_params.empty()) {
+		wpa_printf(MSG_ERROR, "Failed to create config params");
+		return createStatus(HostapdStatusCode::FAILURE_ARGS_INVALID);
+	}
+	const auto conf_file_path =
+		WriteHostapdConfig(iface_params.name, conf_params);
+	if (conf_file_path.empty()) {
+		wpa_printf(MSG_ERROR, "Failed to write config file");
+		return createStatus(HostapdStatusCode::FAILURE_UNKNOWN);
+	}
+	std::string add_iface_param_str = StringPrintf(
+		"%s config=%s", iface_params.name.c_str(),
+		conf_file_path.c_str());
+	std::vector<char> add_iface_param_vec(
+		add_iface_param_str.begin(), add_iface_param_str.end() + 1);
+	if (hostapd_add_iface(interfaces_, add_iface_param_vec.data()) < 0) {
+		wpa_printf(
+			MSG_ERROR, "Adding interface %s failed",
+			add_iface_param_str.c_str());
+		return createStatus(HostapdStatusCode::FAILURE_UNKNOWN);
+	}
+	struct hostapd_data* iface_hapd =
+	    hostapd_get_iface(interfaces_, iface_params.name.c_str());
+	WPA_ASSERT(iface_hapd != nullptr && iface_hapd->iface != nullptr);
+	// Register the setup complete callbacks
+	on_setup_complete_internal_callback =
+		[this](struct hostapd_data* iface_hapd) {
+			wpa_printf(
+			MSG_INFO, "AP interface setup completed - state %s",
+			hostapd_state_text(iface_hapd->iface->state));
+			if (iface_hapd->iface->state == HAPD_IFACE_DISABLED) {
+				// Invoke the failure callback on all registered
+				// clients.
+				for (const auto& callback : callbacks_) {
+					callback->onFailure(strlen(iface_hapd->conf->bridge) > 0 ?
+						iface_hapd->conf->bridge : iface_hapd->conf->iface,
+							    iface_hapd->conf->iface);
+				}
+			}
+		};
+
+	// Register for new client connect/disconnect indication.
+	on_sta_authorized_internal_callback =
+		[this](struct hostapd_data* iface_hapd, const u8 *mac_addr,
+			int authorized, const u8 *p2p_dev_addr) {
+		wpa_printf(MSG_DEBUG, "notify client " MACSTR " %s",
+				MAC2STR(mac_addr),
+				(authorized) ? "Connected" : "Disconnected");
+		ClientInfo info;
+		info.ifaceName = strlen(iface_hapd->conf->bridge) > 0 ?
+			iface_hapd->conf->bridge : iface_hapd->conf->iface;
+		info.apIfaceInstance = iface_hapd->conf->iface;
+		info.clientAddress.assign(mac_addr, mac_addr + ETH_ALEN);
+		info.isConnected = authorized;
+		for (const auto &callback : callbacks_) {
+			callback->onConnectedClientsChanged(info);
+		}
+		};
+
+	// Register for wpa_event which used to get channel switch event
+	on_wpa_msg_internal_callback =
+		[this](struct hostapd_data* iface_hapd, int level,
+			enum wpa_msg_type type, const char *txt,
+			size_t len) {
+		wpa_printf(MSG_DEBUG, "Receive wpa msg : %s", txt);
+		if (os_strncmp(txt, AP_EVENT_ENABLED,
+					strlen(AP_EVENT_ENABLED)) == 0 ||
+			os_strncmp(txt, WPA_EVENT_CHANNEL_SWITCH,
+					strlen(WPA_EVENT_CHANNEL_SWITCH)) == 0) {
+			ApInfo info;
+			info.ifaceName = strlen(iface_hapd->conf->bridge) > 0 ?
+				iface_hapd->conf->bridge : iface_hapd->conf->iface,
+			info.apIfaceInstance = iface_hapd->conf->iface;
+			info.freqMhz = iface_hapd->iface->freq;
+			info.channelBandwidth = getChannelBandwidth(iface_hapd->iconf);
+			info.generation = getGeneration(iface_hapd->iface->current_mode);
+			info.apIfaceInstanceMacAddress.assign(iface_hapd->own_addr,
+				iface_hapd->own_addr + ETH_ALEN);
+			for (const auto &callback : callbacks_) {
+				callback->onApInstanceInfoChanged(info);
+			}
+		} else if (os_strncmp(txt, AP_EVENT_DISABLED, strlen(AP_EVENT_DISABLED)) == 0
+                           || os_strncmp(txt, INTERFACE_DISABLED, strlen(INTERFACE_DISABLED)) == 0)
+		{
+			// Invoke the failure callback on all registered clients.
+			for (const auto& callback : callbacks_) {
+				callback->onFailure(strlen(iface_hapd->conf->bridge) > 0 ?
+					iface_hapd->conf->bridge : iface_hapd->conf->iface,
+						    iface_hapd->conf->iface);
+			}
+		}
+	};
+
+	// Setup callback
+	iface_hapd->setup_complete_cb = onAsyncSetupCompleteCb;
+	iface_hapd->setup_complete_cb_ctx = iface_hapd;
+	iface_hapd->sta_authorized_cb = onAsyncStaAuthorizedCb;
+	iface_hapd->sta_authorized_cb_ctx = iface_hapd;
+	wpa_msg_register_cb(onAsyncWpaEventCb);
+
+	if (hostapd_enable_iface(iface_hapd->iface) < 0) {
+		wpa_printf(
+			MSG_ERROR, "Enabling interface %s failed",
+			iface_params.name.c_str());
+		return createStatus(HostapdStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Hostapd::removeAccessPointInternal(const std::string& iface_name)
+{
+	// interfaces to be removed
+	std::vector<std::string> interfaces;
+	bool is_error = false;
+
+	const auto it = br_interfaces_.find(iface_name);
+	if (it != br_interfaces_.end()) {
+		// In case bridge, remove managed interfaces
+		interfaces = it->second;
+		br_interfaces_.erase(iface_name);
+	} else {
+		// else remove current interface
+		interfaces.push_back(iface_name);
+	}
+
+	for (auto& iface : interfaces) {
+		std::vector<char> remove_iface_param_vec(
+		    iface.begin(), iface.end() + 1);
+		if (hostapd_remove_iface(interfaces_, remove_iface_param_vec.data()) <  0) {
+			wpa_printf(MSG_INFO, "Remove interface %s failed", iface.c_str());
+			is_error = true;
+		}
+	}
+	if (is_error) {
+		return createStatus(HostapdStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Hostapd::registerCallbackInternal(
+	const std::shared_ptr<IHostapdCallback>& callback)
+{
+	binder_status_t status = AIBinder_linkToDeath(callback->asBinder().get(),
+			death_notifier_, this /* cookie */);
+	if (status != STATUS_OK) {
+		wpa_printf(
+			MSG_ERROR,
+			"Error registering for death notification for "
+			"hostapd callback object");
+		return createStatus(HostapdStatusCode::FAILURE_UNKNOWN);
+	}
+	callbacks_.push_back(callback);
+	return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Hostapd::forceClientDisconnectInternal(const std::string& iface_name,
+	const std::vector<uint8_t>& client_address, Ieee80211ReasonCode reason_code)
+{
+	struct hostapd_data *hapd = hostapd_get_iface(interfaces_, iface_name.c_str());
+	bool result;
+	if (!hapd) {
+		for (auto const& iface : br_interfaces_) {
+			if (iface.first == iface_name) {
+				for (auto const& instance : iface.second) {
+					hapd = hostapd_get_iface(interfaces_, instance.c_str());
+					if (hapd) {
+						result = forceStaDisconnection(hapd, client_address,
+								(uint16_t) reason_code);
+						if (result) break;
+					}
+				}
+			}
+		}
+	} else {
+		result = forceStaDisconnection(hapd, client_address, (uint16_t) reason_code);
+	}
+	if (!hapd) {
+		wpa_printf(MSG_ERROR, "Interface %s doesn't exist", iface_name.c_str());
+		return createStatus(HostapdStatusCode::FAILURE_IFACE_UNKNOWN);
+	}
+	if (result) {
+		return ndk::ScopedAStatus::ok();
+	}
+	return createStatus(HostapdStatusCode::FAILURE_CLIENT_UNKNOWN);
+}
+
+::ndk::ScopedAStatus Hostapd::setDebugParamsInternal(DebugLevel level)
+{
+	wpa_debug_level = static_cast<uint32_t>(level);
+	return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace hostapd
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/aidl/hostapd.h b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/aidl/hostapd.h
new file mode 100755
index 0000000..ffdbd8e
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/aidl/hostapd.h
@@ -0,0 +1,95 @@
+/*
+ * aidl interface for wpa_hostapd daemon
+ * Copyright (c) 2004-2018, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2018, Roshan Pius <rpius@google.com>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#pragma once
+
+#include <map>
+#include <string>
+
+#include <android-base/macros.h>
+
+#include <aidl/android/hardware/wifi/hostapd/BnHostapd.h>
+
+extern "C"
+{
+#include "utils/common.h"
+#include "utils/eloop.h"
+#include "utils/includes.h"
+#include "utils/wpa_debug.h"
+#include "ap/hostapd.h"
+#include "ap/sta_info.h"
+}
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace hostapd {
+
+/**
+ * Implementation of the hostapd aidl object. This aidl
+ * object is used core for global control operations on
+ * hostapd.
+ */
+class Hostapd : public BnHostapd
+{
+public:
+	Hostapd(hapd_interfaces* interfaces);
+	~Hostapd() override = default;
+
+	// Aidl methods exposed.
+	::ndk::ScopedAStatus addAccessPoint(
+	    const IfaceParams& iface_params, const NetworkParams& nw_params) override;
+	::ndk::ScopedAStatus removeAccessPoint(const std::string& iface_name) override;
+	::ndk::ScopedAStatus terminate() override;
+	::ndk::ScopedAStatus registerCallback(
+	    const std::shared_ptr<IHostapdCallback>& callback) override;
+	::ndk::ScopedAStatus forceClientDisconnect(
+	    const std::string& iface_name,
+	    const std::vector<uint8_t>& client_address,
+	    Ieee80211ReasonCode reason_code) override;
+	::ndk::ScopedAStatus setDebugParams(DebugLevel level) override;
+private:
+	// Corresponding worker functions for the AIDL methods.
+	::ndk::ScopedAStatus addAccessPointInternal(
+	    const IfaceParams& iface_params,
+	    const NetworkParams& nw_params);
+	::ndk::ScopedAStatus addSingleAccessPoint(
+	    const IfaceParams& IfaceParams,
+	    const ChannelParams& channelParams,
+	    const NetworkParams& nw_params,
+	    std::string br_name,
+	    std::string owe_transition_ifname);
+	::ndk::ScopedAStatus addConcurrentAccessPoints(
+	    const IfaceParams& IfaceParams,
+	    const NetworkParams& nw_params);
+	::ndk::ScopedAStatus removeAccessPointInternal(const std::string& iface_name);
+	::ndk::ScopedAStatus registerCallbackInternal(
+	    const std::shared_ptr<IHostapdCallback>& callback);
+	::ndk::ScopedAStatus forceClientDisconnectInternal(
+	    const std::string& iface_name,
+	    const std::vector<uint8_t>& client_address,
+	    Ieee80211ReasonCode reason_code);
+	::ndk::ScopedAStatus setDebugParamsInternal(DebugLevel level);
+
+	// Raw pointer to the global structure maintained by the core.
+	struct hapd_interfaces* interfaces_;
+	// Callbacks registered.
+	std::vector<std::shared_ptr<IHostapdCallback>> callbacks_;
+	// Death notifier.
+	AIBinder_DeathRecipient* death_notifier_;
+	// Bridge and its managed interfaces.
+	std::map<std::string, std::vector<std::string>> br_interfaces_;
+	DISALLOW_COPY_AND_ASSIGN(Hostapd);
+};
+}  // namespace hostapd
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/android.config b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/android.config
index e27cd51..eadfbbc 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/android.config
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/android.config
@@ -25,6 +25,12 @@
 #LIBS += -L$(LIBNL)/lib
 CONFIG_LIBNL20=y
 
+# QCA vendor extensions to nl80211
+#CONFIG_DRIVER_NL80211_QCA=y
+
+# Broadcom vendor extensions to nl80211
+#CONFIG_DRIVER_NL80211_BRCM=y
+
 # Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
 #CONFIG_DRIVER_BSD=y
 #CFLAGS += -I/usr/local/include
@@ -227,11 +233,18 @@
 # be completely removed in a future release.
 CONFIG_WEP=y
 
-ifneq ($(filter $(PLATFORM_VERSION), P 9 10 11 12),)
+# Set SAE Auth status early
+CONFIG_WPA3_SAE_AUTH_EARLY_SET=y
+
+ifneq ($(filter $(PLATFORM_VERSION), P 9 10 11 12 13),)
 # Add support for Hidl control interface
 # Only applicable for Android platforms Pie and above.
 # Need to add more versions in future
-CONFIG_CTRL_IFACE_HIDL=y
+# CONFIG_CTRL_IFACE_HIDL=y
+
+# Add support for Aidl control interface
+# Only applicable for Android platforms.
+CONFIG_CTRL_IFACE_AIDL=y
 endif
 
 
@@ -240,7 +253,6 @@
 
 # WPA3-Personal (SAE)
 CONFIG_SAE=y
-CONFIG_WPA3_SAE_AUTH_EARLY_SET=y
 
 # Host SAE via Vendor commands
 #CONFIG_WL_SAE=y
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/config_file.c b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/config_file.c
index 0d3c6fd..b76e6fa 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/config_file.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/config_file.c
@@ -13,6 +13,7 @@
 
 #include "utils/common.h"
 #include "utils/uuid.h"
+#include "utils/crc32.h"
 #include "common/ieee802_11_defs.h"
 #include "common/sae.h"
 #include "crypto/sha256.h"
@@ -754,6 +755,10 @@
 		else if (os_strcmp(start, "OSEN") == 0)
 			val |= WPA_KEY_MGMT_OSEN;
 #endif /* CONFIG_HS20 */
+#ifdef CONFIG_PASN
+		else if (os_strcmp(start, "PASN") == 0)
+			val |= WPA_KEY_MGMT_PASN;
+#endif /* CONFIG_PASN */
 		else {
 			wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
 				   line, start);
@@ -1216,6 +1221,32 @@
 	return (u8) (mask & (val << find_bit_offset(mask)));
 }
 
+
+static int hostapd_parse_he_srg_bitmap(u8 *bitmap, char *val)
+{
+	int bitpos;
+	char *pos, *end;
+
+	os_memset(bitmap, 0, 8);
+	pos = val;
+	while (*pos != '\0') {
+		end = os_strchr(pos, ' ');
+		if (end)
+			*end = '\0';
+
+		bitpos = atoi(pos);
+		if (bitpos < 0 || bitpos > 64)
+			return -1;
+
+		bitmap[bitpos / 8] |= BIT(bitpos % 8);
+		if (!end)
+			break;
+		pos = end + 1;
+	}
+
+	return 0;
+}
+
 #endif /* CONFIG_IEEE80211AX */
 
 
@@ -2309,6 +2340,22 @@
 #endif /* CONFIG_DPP2 */
 
 
+static int get_hex_config(u8 *buf, size_t max_len, int line,
+			  const char *field, const char *val)
+{
+	size_t hlen = os_strlen(val), len = hlen / 2;
+	u8 tmp[EXT_CAPA_MAX_LEN];
+
+	os_memset(tmp, 0, EXT_CAPA_MAX_LEN);
+	if (hlen & 1 || len > EXT_CAPA_MAX_LEN || hexstr2bin(val, tmp, len)) {
+		wpa_printf(MSG_ERROR, "Line %d: Invalid %s", line, field);
+		return -1;
+	}
+	os_memcpy(buf, tmp, EXT_CAPA_MAX_LEN);
+	return 0;
+}
+
+
 static int hostapd_config_fill(struct hostapd_config *conf,
 			       struct hostapd_bss_config *bss,
 			       const char *buf, char *pos, int line)
@@ -2357,16 +2404,19 @@
 		wpa_printf(MSG_INFO, "Line %d: DEPRECATED: 'dump_file' configuration variable is not used anymore",
 			   line);
 	} else if (os_strcmp(buf, "ssid") == 0) {
-		bss->ssid.ssid_len = os_strlen(pos);
-		if (bss->ssid.ssid_len > SSID_MAX_LEN ||
-		    bss->ssid.ssid_len < 1) {
+		struct hostapd_ssid *ssid = &bss->ssid;
+
+		ssid->ssid_len = os_strlen(pos);
+		if (ssid->ssid_len > SSID_MAX_LEN || ssid->ssid_len < 1) {
 			wpa_printf(MSG_ERROR, "Line %d: invalid SSID '%s'",
 				   line, pos);
 			return 1;
 		}
-		os_memcpy(bss->ssid.ssid, pos, bss->ssid.ssid_len);
-		bss->ssid.ssid_set = 1;
+		os_memcpy(ssid->ssid, pos, ssid->ssid_len);
+		ssid->ssid_set = 1;
+		ssid->short_ssid = crc32(ssid->ssid, ssid->ssid_len);
 	} else if (os_strcmp(buf, "ssid2") == 0) {
+		struct hostapd_ssid *ssid = &bss->ssid;
 		size_t slen;
 		char *str = wpa_config_parse_string(pos, &slen);
 		if (str == NULL || slen < 1 || slen > SSID_MAX_LEN) {
@@ -2375,9 +2425,10 @@
 			os_free(str);
 			return 1;
 		}
-		os_memcpy(bss->ssid.ssid, str, slen);
-		bss->ssid.ssid_len = slen;
-		bss->ssid.ssid_set = 1;
+		os_memcpy(ssid->ssid, str, slen);
+		ssid->ssid_len = slen;
+		ssid->ssid_set = 1;
+		ssid->short_ssid = crc32(ssid->ssid, ssid->ssid_len);
 		os_free(str);
 	} else if (os_strcmp(buf, "utf8_ssid") == 0) {
 		bss->ssid.utf8_ssid = atoi(pos) > 0;
@@ -2435,12 +2486,13 @@
 		bss->ieee802_1x = atoi(pos);
 	} else if (os_strcmp(buf, "eapol_version") == 0) {
 		int eapol_version = atoi(pos);
-
 #ifdef CONFIG_MACSEC
-		if (eapol_version < 1 || eapol_version > 3) {
+		int max_ver = 3;
 #else /* CONFIG_MACSEC */
-		if (eapol_version < 1 || eapol_version > 2) {
+		int max_ver = 2;
 #endif /* CONFIG_MACSEC */
+
+		if (eapol_version < 1 || eapol_version > max_ver) {
 			wpa_printf(MSG_ERROR,
 				   "Line %d: invalid EAPOL version (%d): '%s'.",
 				   line, eapol_version, pos);
@@ -2688,6 +2740,9 @@
 			return 1;
 		}
 		bss->radius->force_client_addr = 1;
+	} else if (os_strcmp(buf, "radius_client_dev") == 0) {
+			os_free(bss->radius->force_client_dev);
+			bss->radius->force_client_dev = os_strdup(pos);
 	} else if (os_strcmp(buf, "auth_server_addr") == 0) {
 		if (hostapd_config_read_radius_addr(
 			    &bss->radius->auth_servers,
@@ -3147,6 +3202,16 @@
 		conf->acs_freq_list_present = 1;
 	} else if (os_strcmp(buf, "acs_exclude_6ghz_non_psc") == 0) {
 		conf->acs_exclude_6ghz_non_psc = atoi(pos);
+	} else if (os_strcmp(buf, "min_tx_power") == 0) {
+		int val = atoi(pos);
+
+		if (val < 0 || val > 255) {
+			wpa_printf(MSG_ERROR,
+				   "Line %d: invalid min_tx_power %d (expected 0..255)",
+				   line, val);
+			return 1;
+		}
+		conf->min_tx_power = val;
 	} else if (os_strcmp(buf, "beacon_int") == 0) {
 		int val = atoi(pos);
 		/* MIB defines range as 1..65535, but very small values
@@ -3268,6 +3333,16 @@
 			}
 			conf->rate_type = BEACON_RATE_VHT;
 			conf->beacon_rate = val;
+		} else if (os_strncmp(pos, "he:", 3) == 0) {
+			val = atoi(pos + 3);
+			if (val < 0 || val > 11) {
+				wpa_printf(MSG_ERROR,
+					   "Line %d: invalid beacon_rate HE-MCS %d",
+					   line, val);
+				return 1;
+			}
+			conf->rate_type = BEACON_RATE_HE;
+			conf->beacon_rate = val;
 		} else {
 			val = atoi(pos);
 			if (val < 10 || val > 10000) {
@@ -3464,8 +3539,12 @@
 		conf->he_op.he_default_pe_duration = atoi(pos);
 	} else if (os_strcmp(buf, "he_twt_required") == 0) {
 		conf->he_op.he_twt_required = atoi(pos);
+	} else if (os_strcmp(buf, "he_twt_responder") == 0) {
+		conf->he_op.he_twt_responder = atoi(pos);
 	} else if (os_strcmp(buf, "he_rts_threshold") == 0) {
 		conf->he_op.he_rts_threshold = atoi(pos);
+	} else if (os_strcmp(buf, "he_er_su_disable") == 0) {
+		conf->he_op.he_er_su_disable = atoi(pos);
 	} else if (os_strcmp(buf, "he_basic_mcs_nss_set") == 0) {
 		conf->he_op.he_basic_mcs_nss_set = atoi(pos);
 	} else if (os_strcmp(buf, "he_mu_edca_qos_info_param_count") == 0) {
@@ -3553,19 +3632,53 @@
 		conf->he_mu_edca.he_mu_ac_vo_param[HE_MU_AC_PARAM_TIMER_IDX] =
 			atoi(pos) & 0xff;
 	} else if (os_strcmp(buf, "he_spr_sr_control") == 0) {
-		conf->spr.sr_control = atoi(pos) & 0xff;
+		conf->spr.sr_control = atoi(pos) & 0x1f;
 	} else if (os_strcmp(buf, "he_spr_non_srg_obss_pd_max_offset") == 0) {
 		conf->spr.non_srg_obss_pd_max_offset = atoi(pos);
 	} else if (os_strcmp(buf, "he_spr_srg_obss_pd_min_offset") == 0) {
 		conf->spr.srg_obss_pd_min_offset = atoi(pos);
 	} else if (os_strcmp(buf, "he_spr_srg_obss_pd_max_offset") == 0) {
 		conf->spr.srg_obss_pd_max_offset = atoi(pos);
+	} else if (os_strcmp(buf, "he_spr_srg_bss_colors") == 0) {
+		if (hostapd_parse_he_srg_bitmap(
+			conf->spr.srg_bss_color_bitmap, pos)) {
+			wpa_printf(MSG_ERROR,
+				   "Line %d: Invalid srg bss colors list '%s'",
+				   line, pos);
+			return 1;
+		}
+	} else if (os_strcmp(buf, "he_spr_srg_partial_bssid") == 0) {
+		if (hostapd_parse_he_srg_bitmap(
+			conf->spr.srg_partial_bssid_bitmap, pos)) {
+			wpa_printf(MSG_ERROR,
+				   "Line %d: Invalid srg partial bssid list '%s'",
+				   line, pos);
+			return 1;
+		}
 	} else if (os_strcmp(buf, "he_oper_chwidth") == 0) {
 		conf->he_oper_chwidth = atoi(pos);
 	} else if (os_strcmp(buf, "he_oper_centr_freq_seg0_idx") == 0) {
 		conf->he_oper_centr_freq_seg0_idx = atoi(pos);
 	} else if (os_strcmp(buf, "he_oper_centr_freq_seg1_idx") == 0) {
 		conf->he_oper_centr_freq_seg1_idx = atoi(pos);
+	} else if (os_strcmp(buf, "he_6ghz_max_mpdu") == 0) {
+		conf->he_6ghz_max_mpdu = atoi(pos);
+	} else if (os_strcmp(buf, "he_6ghz_max_ampdu_len_exp") == 0) {
+		conf->he_6ghz_max_ampdu_len_exp = atoi(pos);
+	} else if (os_strcmp(buf, "he_6ghz_rx_ant_pat") == 0) {
+		conf->he_6ghz_rx_ant_pat = atoi(pos);
+	} else if (os_strcmp(buf, "he_6ghz_tx_ant_pat") == 0) {
+		conf->he_6ghz_tx_ant_pat = atoi(pos);
+	} else if (os_strcmp(buf, "unsol_bcast_probe_resp_interval") == 0) {
+		int val = atoi(pos);
+
+		if (val < 0 || val > 20) {
+			wpa_printf(MSG_ERROR,
+				   "Line %d: invalid unsol_bcast_probe_resp_interval value",
+				   line);
+			return 1;
+		}
+		bss->unsol_bcast_probe_resp_interval = val;
 #endif /* CONFIG_IEEE80211AX */
 	} else if (os_strcmp(buf, "max_listen_interval") == 0) {
 		bss->max_listen_interval = atoi(pos);
@@ -4212,8 +4325,9 @@
 	} else if (os_strcmp(buf, "assocresp_elements") == 0) {
 		if (parse_wpabuf_hex(line, buf, &bss->assocresp_elements, pos))
 			return 1;
-	} else if (os_strcmp(buf, "sae_anti_clogging_threshold") == 0) {
-		bss->sae_anti_clogging_threshold = atoi(pos);
+	} else if (os_strcmp(buf, "sae_anti_clogging_threshold") == 0 ||
+		   os_strcmp(buf, "anti_clogging_threshold") == 0) {
+		bss->anti_clogging_threshold = atoi(pos);
 	} else if (os_strcmp(buf, "sae_sync") == 0) {
 		bss->sae_sync = atoi(pos);
 	} else if (os_strcmp(buf, "sae_groups") == 0) {
@@ -4372,11 +4486,17 @@
 		bss->dhcp_server_port = atoi(pos);
 	} else if (os_strcmp(buf, "dhcp_relay_port") == 0) {
 		bss->dhcp_relay_port = atoi(pos);
+	} else if (os_strcmp(buf, "fils_discovery_min_interval") == 0) {
+		bss->fils_discovery_min_int = atoi(pos);
+	} else if (os_strcmp(buf, "fils_discovery_max_interval") == 0) {
+		bss->fils_discovery_max_int = atoi(pos);
 #endif /* CONFIG_FILS */
 	} else if (os_strcmp(buf, "multicast_to_unicast") == 0) {
 		bss->multicast_to_unicast = atoi(pos);
 	} else if (os_strcmp(buf, "broadcast_deauth") == 0) {
 		bss->broadcast_deauth = atoi(pos);
+	} else if (os_strcmp(buf, "notify_mgmt_frames") == 0) {
+		bss->notify_mgmt_frames = atoi(pos);
 #ifdef CONFIG_DPP
 	} else if (os_strcmp(buf, "dpp_name") == 0) {
 		os_free(bss->dpp_name);
@@ -4467,6 +4587,8 @@
 		conf->rssi_reject_assoc_rssi = atoi(pos);
 	} else if (os_strcmp(buf, "rssi_reject_assoc_timeout") == 0) {
 		conf->rssi_reject_assoc_timeout = atoi(pos);
+	} else if (os_strcmp(buf, "rssi_ignore_probe_request") == 0) {
+		conf->rssi_ignore_probe_request = atoi(pos);
 	} else if (os_strcmp(buf, "pbss") == 0) {
 		bss->pbss = atoi(pos);
 	} else if (os_strcmp(buf, "transition_disable") == 0) {
@@ -4586,6 +4708,39 @@
 		}
 		bss->mka_psk_set |= MKA_PSK_SET_CKN;
 #endif /* CONFIG_MACSEC */
+	} else if (os_strcmp(buf, "disable_11n") == 0) {
+		bss->disable_11n = !!atoi(pos);
+	} else if (os_strcmp(buf, "disable_11ac") == 0) {
+		bss->disable_11ac = !!atoi(pos);
+	} else if (os_strcmp(buf, "disable_11ax") == 0) {
+		bss->disable_11ax = !!atoi(pos);
+#ifdef CONFIG_PASN
+#ifdef CONFIG_TESTING_OPTIONS
+	} else if (os_strcmp(buf, "force_kdk_derivation") == 0) {
+		bss->force_kdk_derivation = atoi(pos);
+	} else if (os_strcmp(buf, "pasn_corrupt_mic") == 0) {
+		bss->pasn_corrupt_mic = atoi(pos);
+#endif /* CONFIG_TESTING_OPTIONS */
+	} else if (os_strcmp(buf, "pasn_groups") == 0) {
+		if (hostapd_parse_intlist(&bss->pasn_groups, pos)) {
+			wpa_printf(MSG_ERROR,
+				   "Line %d: Invalid pasn_groups value '%s'",
+				   line, pos);
+			return 1;
+		}
+	} else if (os_strcmp(buf, "pasn_comeback_after") == 0) {
+		bss->pasn_comeback_after = atoi(pos);
+#endif /* CONFIG_PASN */
+	} else if (os_strcmp(buf, "ext_capa_mask") == 0) {
+		if (get_hex_config(bss->ext_capa_mask, EXT_CAPA_MAX_LEN,
+				   line, "ext_capa_mask", pos))
+			return 1;
+	} else if (os_strcmp(buf, "ext_capa") == 0) {
+		if (get_hex_config(bss->ext_capa, EXT_CAPA_MAX_LEN,
+				   line, "ext_capa", pos))
+			return 1;
+	} else if (os_strcmp(buf, "rnr") == 0) {
+		bss->rnr = atoi(pos);
 	} else {
 		wpa_printf(MSG_ERROR,
 			   "Line %d: unknown configuration item '%s'",
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/ctrl_iface.c b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/ctrl_iface.c
index 0cb7607..68e7b43 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/ctrl_iface.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/ctrl_iface.c
@@ -37,6 +37,7 @@
 #include "common/dpp.h"
 #endif /* CONFIG_DPP */
 #include "common/wpa_ctrl.h"
+#include "common/ptksa_cache.h"
 #include "crypto/tls.h"
 #include "drivers/driver.h"
 #include "eapol_auth/eapol_auth_sm.h"
@@ -839,7 +840,7 @@
 	const char *pos, *end;
 	int disassoc_timer = 0;
 	struct sta_info *sta;
-	u8 req_mode = 0, valid_int = 0x01;
+	u8 req_mode = 0, valid_int = 0x01, dialog_token = 0x01;
 	u8 bss_term_dur[12];
 	char *url = NULL;
 	int ret;
@@ -877,6 +878,12 @@
 		valid_int = atoi(pos);
 	}
 
+	pos = os_strstr(cmd, " dialog_token=");
+	if (pos) {
+		pos += 14;
+		dialog_token = atoi(pos);
+	}
+
 	pos = os_strstr(cmd, " bss_term=");
 	if (pos) {
 		pos += 10;
@@ -983,7 +990,7 @@
 #endif /* CONFIG_MBO */
 
 	ret = wnm_send_bss_tm_req(hapd, sta, req_mode, disassoc_timer,
-				  valid_int, bss_term_dur, url,
+				  valid_int, bss_term_dur, dialog_token, url,
 				  nei_len ? nei_rep : NULL, nei_len,
 				  mbo_len ? mbo : NULL, mbo_len);
 #ifdef CONFIG_MBO
@@ -1222,6 +1229,52 @@
 			return pos - buf;
 		pos += ret;
 	}
+
+	if (hapd->conf->multi_ap) {
+		struct hostapd_ssid *ssid = &hapd->conf->multi_ap_backhaul_ssid;
+
+		ret = os_snprintf(pos, end - pos, "multi_ap=%d\n",
+				  hapd->conf->multi_ap);
+		if (os_snprintf_error(end - pos, ret))
+			return pos - buf;
+		pos += ret;
+
+		if (ssid->ssid_len) {
+			ret = os_snprintf(pos, end - pos,
+					  "multi_ap_backhaul_ssid=%s\n",
+					  wpa_ssid_txt(ssid->ssid,
+						       ssid->ssid_len));
+			if (os_snprintf_error(end - pos, ret))
+				return pos - buf;
+			pos += ret;
+		}
+
+		if (hapd->conf->wps_state && hapd->conf->wpa &&
+			ssid->wpa_passphrase) {
+			ret = os_snprintf(pos, end - pos,
+					  "multi_ap_backhaul_wpa_passphrase=%s\n",
+					  ssid->wpa_passphrase);
+			if (os_snprintf_error(end - pos, ret))
+				return pos - buf;
+			pos += ret;
+		}
+
+		if (hapd->conf->wps_state && hapd->conf->wpa &&
+		    ssid->wpa_psk &&
+		    ssid->wpa_psk->group) {
+			char hex[PMK_LEN * 2 + 1];
+
+			wpa_snprintf_hex(hex, sizeof(hex), ssid->wpa_psk->psk,
+					 PMK_LEN);
+			ret = os_snprintf(pos, end - pos,
+					  "multi_ap_backhaul_wpa_psk=%s\n",
+					  hex);
+			forced_memzero(hex, sizeof(hex));
+			if (os_snprintf_error(end - pos, ret))
+				return pos - buf;
+			pos += ret;
+		}
+	}
 #endif /* CONFIG_WPS */
 
 	if (hapd->conf->wpa) {
@@ -1347,21 +1400,29 @@
 
 
 static int hostapd_ctrl_iface_set_band(struct hostapd_data *hapd,
-				       const char *band)
+				       const char *bands)
 {
 	union wpa_event_data event;
-	enum set_band setband;
+	u32 setband_mask = WPA_SETBAND_AUTO;
 
-	if (os_strcmp(band, "AUTO") == 0)
-		setband = WPA_SETBAND_AUTO;
-	else if (os_strcmp(band, "5G") == 0)
-		setband = WPA_SETBAND_5G;
-	else if (os_strcmp(band, "2G") == 0)
-		setband = WPA_SETBAND_2G;
-	else
-		return -1;
+	/*
+	 * For example:
+	 *  SET setband 2G,6G
+	 *  SET setband 5G
+	 *  SET setband AUTO
+	 */
+	if (!os_strstr(bands, "AUTO")) {
+		if (os_strstr(bands, "5G"))
+			setband_mask |= WPA_SETBAND_5G;
+		if (os_strstr(bands, "6G"))
+			setband_mask |= WPA_SETBAND_6G;
+		if (os_strstr(bands, "2G"))
+			setband_mask |= WPA_SETBAND_2G;
+		if (setband_mask == WPA_SETBAND_AUTO)
+			return -1;
+	}
 
-	if (hostapd_drv_set_band(hapd, setband) == 0) {
+	if (hostapd_drv_set_band(hapd, setband_mask) == 0) {
 		os_memset(&event, 0, sizeof(event));
 		event.channel_list_changed.initiator = REGDOM_SET_BY_USER;
 		event.channel_list_changed.type = REGDOM_TYPE_UNKNOWN;
@@ -1400,10 +1461,10 @@
 				   wps_version_number & 0x0f);
 			hostapd_wps_update_ie(hapd);
 		}
-	} else if (os_strcasecmp(cmd, "wps_testing_dummy_cred") == 0) {
-		wps_testing_dummy_cred = atoi(value);
-		wpa_printf(MSG_DEBUG, "WPS: Testing - dummy_cred=%d",
-			   wps_testing_dummy_cred);
+	} else if (os_strcasecmp(cmd, "wps_testing_stub_cred") == 0) {
+		wps_testing_stub_cred = atoi(value);
+		wpa_printf(MSG_DEBUG, "WPS: Testing - stub_cred=%d",
+			   wps_testing_stub_cred);
 	} else if (os_strcasecmp(cmd, "wps_corrupt_pkhash") == 0) {
 		wps_corrupt_pkhash = atoi(value);
 		wpa_printf(MSG_DEBUG, "WPS: Testing - wps_corrupt_pkhash=%d",
@@ -1414,6 +1475,8 @@
 		hapd->ext_mgmt_frame_handling = atoi(value);
 	} else if (os_strcasecmp(cmd, "ext_eapol_frame_io") == 0) {
 		hapd->ext_eapol_frame_io = atoi(value);
+	} else if (os_strcasecmp(cmd, "force_backlog_bytes") == 0) {
+		hapd->force_backlog_bytes = atoi(value);
 #ifdef CONFIG_DPP
 	} else if (os_strcasecmp(cmd, "dpp_config_obj_override") == 0) {
 		os_free(hapd->dpp_config_obj_override);
@@ -1441,7 +1504,7 @@
 			return -1;
 
 		val = atoi(value);
-		if (val < 0 || val > 1)
+		if (val < 0 || val > MBO_ASSOC_DISALLOW_REASON_LOW_RSSI)
 			return -1;
 
 		hapd->mbo_assoc_disallow = val;
@@ -1456,6 +1519,16 @@
 	} else if (os_strcasecmp(cmd, "dpp_configurator_params") == 0) {
 		os_free(hapd->dpp_configurator_params);
 		hapd->dpp_configurator_params = os_strdup(value);
+	} else if (os_strcasecmp(cmd, "dpp_init_max_tries") == 0) {
+		hapd->dpp_init_max_tries = atoi(value);
+	} else if (os_strcasecmp(cmd, "dpp_init_retry_time") == 0) {
+		hapd->dpp_init_retry_time = atoi(value);
+	} else if (os_strcasecmp(cmd, "dpp_resp_wait_time") == 0) {
+		hapd->dpp_resp_wait_time = atoi(value);
+	} else if (os_strcasecmp(cmd, "dpp_resp_max_tries") == 0) {
+		hapd->dpp_resp_max_tries = atoi(value);
+	} else if (os_strcasecmp(cmd, "dpp_resp_retry_time") == 0) {
+		hapd->dpp_resp_retry_time = atoi(value);
 #endif /* CONFIG_DPP */
 	} else if (os_strcasecmp(cmd, "setband") == 0) {
 		ret = hostapd_ctrl_iface_set_band(hapd, value);
@@ -1879,6 +1952,52 @@
 }
 
 
+static int hostapd_ctrl_iface_eapol_tx(struct hostapd_data *hapd, char *cmd)
+{
+	char *pos, *pos2;
+	u8 dst[ETH_ALEN], *buf;
+	int used, ret;
+	size_t len;
+	unsigned int prev;
+	int encrypt = 0;
+
+	wpa_printf(MSG_DEBUG, "External EAPOL TX: %s", cmd);
+
+	pos = cmd;
+	used = hwaddr_aton2(pos, dst);
+	if (used < 0)
+		return -1;
+	pos += used;
+	while (*pos == ' ')
+		pos++;
+
+	pos2 = os_strchr(pos, ' ');
+	if (pos2) {
+		len = pos2 - pos;
+		encrypt = os_strstr(pos2, "encrypt=1") != NULL;
+	} else {
+		len = os_strlen(pos);
+	}
+	if (len & 1)
+		return -1;
+	len /= 2;
+
+	buf = os_malloc(len);
+	if (!buf || hexstr2bin(pos, buf, len) < 0) {
+		os_free(buf);
+		return -1;
+	}
+
+	prev = hapd->ext_eapol_frame_io;
+	hapd->ext_eapol_frame_io = 0;
+	ret = hostapd_wpa_auth_send_eapol(hapd, dst, buf, len, encrypt);
+	hapd->ext_eapol_frame_io = prev;
+	os_free(buf);
+
+	return ret;
+}
+
+
 static u16 ipv4_hdr_checksum(const void *buf, size_t len)
 {
 	size_t i;
@@ -2457,6 +2576,22 @@
 }
 
 
+static int hostapd_ctrl_rekey_ptk(struct hostapd_data *hapd, const char *cmd)
+{
+	struct sta_info *sta;
+	u8 addr[ETH_ALEN];
+
+	if (hwaddr_aton(cmd, addr))
+		return -1;
+
+	sta = ap_get_sta(hapd, addr);
+	if (!sta || !sta->wpa_sm)
+		return -1;
+
+	return wpa_auth_rekey_ptk(hapd->wpa_auth, sta->wpa_sm);
+}
+
+
 static int hostapd_ctrl_get_pmksa_pmk(struct hostapd_data *hapd, const u8 *addr,
 				      char *buf, size_t buflen)
 {
@@ -2497,6 +2632,34 @@
 	return wpa_snprintf_hex(buf, buflen, pmk, pmk_len);
 }
 
+
+static int hostapd_ctrl_register_frame(struct hostapd_data *hapd,
+				       const char *cmd)
+{
+	u16 type;
+	char *pos, *end;
+	u8 match[10];
+	size_t match_len;
+	bool multicast = false;
+
+	type = strtol(cmd, &pos, 16);
+	if (*pos != ' ')
+		return -1;
+	pos++;
+	end = os_strchr(pos, ' ');
+	if (end) {
+		match_len = end - pos;
+		multicast = os_strstr(end, "multicast") != NULL;
+	} else {
+		match_len = os_strlen(pos) / 2;
+	}
+	if (hexstr2bin(pos, match, match_len))
+		return -1;
+
+	return hostapd_drv_register_frame(hapd, type, match, match_len,
+					  multicast);
+}
+
 #endif /* CONFIG_TESTING_OPTIONS */
 
 
@@ -2671,9 +2834,9 @@
 
 	for (i = 0; i < iface->num_bss; i++) {
 
-		/* Save CHAN_SWITCH VHT config */
-		hostapd_chan_switch_vht_config(
-			iface->bss[i], settings.freq_params.vht_enabled);
+		/* Save CHAN_SWITCH VHT and HE config */
+		hostapd_chan_switch_config(iface->bss[i],
+					   &settings.freq_params);
 
 		ret = hostapd_switch_channel(iface->bss[i], &settings);
 		if (ret) {
@@ -3109,8 +3272,9 @@
 	u8 bssid[ETH_ALEN];
 	struct wpabuf *nr, *lci = NULL, *civic = NULL;
 	int stationary = 0;
+	int bss_parameters = 0;
 	char *tmp;
-	int ret;
+	int ret = -1;
 
 	if (!(hapd->conf->radio_measurements[0] &
 	      WLAN_RRM_CAPS_NEIGHBOR_REPORT)) {
@@ -3164,8 +3328,7 @@
 		if (!lci) {
 			wpa_printf(MSG_ERROR,
 				   "CTRL: SET_NEIGHBOR: Bad LCI subelement");
-			wpabuf_free(nr);
-			return -1;
+			goto fail;
 		}
 	}
 
@@ -3181,9 +3344,7 @@
 		if (!civic) {
 			wpa_printf(MSG_ERROR,
 				   "CTRL: SET_NEIGHBOR: Bad civic subelement");
-			wpabuf_free(nr);
-			wpabuf_free(lci);
-			return -1;
+			goto fail;
 		}
 	}
 
@@ -3193,10 +3354,21 @@
 	if (os_strstr(buf, "stat"))
 		stationary = 1;
 
+	tmp = os_strstr(buf, "bss_parameter=");
+	if (tmp) {
+		bss_parameters = atoi(tmp + 14);
+		if (bss_parameters < 0 || bss_parameters > 0xff) {
+			wpa_printf(MSG_ERROR,
+				   "CTRL: SET_NEIGHBOR: Bad bss_parameters subelement");
+			goto fail;
+		}
+	}
+
 set:
 	ret = hostapd_neighbor_set(hapd, bssid, &ssid, nr, lci, civic,
-				   stationary);
+				   stationary, bss_parameters);
 
+fail:
 	wpabuf_free(nr);
 	wpabuf_free(lci);
 	wpabuf_free(civic);
@@ -3372,7 +3544,9 @@
 	if (os_strcmp(field, "dpp") == 0) {
 		int res;
 
-#ifdef CONFIG_DPP2
+#ifdef CONFIG_DPP3
+		res = os_snprintf(buf, buflen, "DPP=3");
+#elif defined(CONFIG_DPP2)
 		res = os_snprintf(buf, buflen, "DPP=2");
 #else /* CONFIG_DPP2 */
 		res = os_snprintf(buf, buflen, "DPP=1");
@@ -3390,6 +3564,23 @@
 }
 
 
+#ifdef ANDROID
+static int hostapd_ctrl_iface_driver_cmd(struct hostapd_data *hapd, char *cmd,
+					 char *buf, size_t buflen)
+{
+	int ret;
+
+	ret = hostapd_drv_driver_cmd(hapd, cmd, buf, buflen);
+	if (ret == 0) {
+		ret = os_snprintf(buf, buflen, "%s\n", "OK");
+		if (os_snprintf_error(buflen, ret))
+			ret = -1;
+	}
+	return ret;
+}
+#endif /* ANDROID */
+
+
 static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
 					      char *buf, char *reply,
 					      int reply_size,
@@ -3604,6 +3795,9 @@
 	} else if (os_strncmp(buf, "EAPOL_RX ", 9) == 0) {
 		if (hostapd_ctrl_iface_eapol_rx(hapd, buf + 9) < 0)
 			reply_len = -1;
+	} else if (os_strncmp(buf, "EAPOL_TX ", 9) == 0) {
+		if (hostapd_ctrl_iface_eapol_tx(hapd, buf + 9) < 0)
+			reply_len = -1;
 	} else if (os_strncmp(buf, "DATA_TEST_CONFIG ", 17) == 0) {
 		if (hostapd_ctrl_iface_data_test_config(hapd, buf + 17) < 0)
 			reply_len = -1;
@@ -3639,12 +3833,18 @@
 	} else if (os_strncmp(buf, "RESEND_GROUP_M1 ", 16) == 0) {
 		if (hostapd_ctrl_resend_group_m1(hapd, buf + 16) < 0)
 			reply_len = -1;
+	} else if (os_strncmp(buf, "REKEY_PTK ", 10) == 0) {
+		if (hostapd_ctrl_rekey_ptk(hapd, buf + 10) < 0)
+			reply_len = -1;
 	} else if (os_strcmp(buf, "REKEY_GTK") == 0) {
 		if (wpa_auth_rekey_gtk(hapd->wpa_auth) < 0)
 			reply_len = -1;
 	} else if (os_strncmp(buf, "GET_PMK ", 8) == 0) {
 		reply_len = hostapd_ctrl_get_pmk(hapd, buf + 8, reply,
 						 reply_size);
+	} else if (os_strncmp(buf, "REGISTER_FRAME ", 15) == 0) {
+		if (hostapd_ctrl_register_frame(hapd, buf + 16) < 0)
+			reply_len = -1;
 #endif /* CONFIG_TESTING_OPTIONS */
 	} else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) {
 		if (hostapd_ctrl_iface_chan_switch(hapd->iface, buf + 12))
@@ -3712,16 +3912,17 @@
 		eloop_terminate();
 	} else if (os_strncmp(buf, "ACCEPT_ACL ", 11) == 0) {
 		if (os_strncmp(buf + 11, "ADD_MAC ", 8) == 0) {
-			if (!hostapd_ctrl_iface_acl_add_mac(
+			if (hostapd_ctrl_iface_acl_add_mac(
+				    &hapd->conf->accept_mac,
+				    &hapd->conf->num_accept_mac, buf + 19))
+				reply_len = -1;
+		} else if (os_strncmp((buf + 11), "DEL_MAC ", 8) == 0) {
+			if (!hostapd_ctrl_iface_acl_del_mac(
 				    &hapd->conf->accept_mac,
 				    &hapd->conf->num_accept_mac, buf + 19))
 				hostapd_disassoc_accept_mac(hapd);
 			else
 				reply_len = -1;
-		} else if (os_strncmp((buf + 11), "DEL_MAC ", 8) == 0) {
-			hostapd_ctrl_iface_acl_del_mac(
-				&hapd->conf->accept_mac,
-				&hapd->conf->num_accept_mac, buf + 19);
 		} else if (os_strcmp(buf + 11, "SHOW") == 0) {
 			reply_len = hostapd_ctrl_iface_acl_show_mac(
 				hapd->conf->accept_mac,
@@ -3730,6 +3931,7 @@
 			hostapd_ctrl_iface_acl_clear_list(
 				&hapd->conf->accept_mac,
 				&hapd->conf->num_accept_mac);
+			hostapd_disassoc_accept_mac(hapd);
 		}
 	} else if (os_strncmp(buf, "DENY_ACL ", 9) == 0) {
 		if (os_strncmp(buf + 9, "ADD_MAC ", 8) == 0) {
@@ -3737,10 +3939,13 @@
 				    &hapd->conf->deny_mac,
 				    &hapd->conf->num_deny_mac, buf + 17))
 				hostapd_disassoc_deny_mac(hapd);
+			else
+				reply_len = -1;
 		} else if (os_strncmp(buf + 9, "DEL_MAC ", 8) == 0) {
-			hostapd_ctrl_iface_acl_del_mac(
-				&hapd->conf->deny_mac,
-				&hapd->conf->num_deny_mac, buf + 17);
+			if (hostapd_ctrl_iface_acl_del_mac(
+				    &hapd->conf->deny_mac,
+				    &hapd->conf->num_deny_mac, buf + 17))
+				reply_len = -1;
 		} else if (os_strcmp(buf + 9, "SHOW") == 0) {
 			reply_len = hostapd_ctrl_iface_acl_show_mac(
 				hapd->conf->deny_mac,
@@ -3893,6 +4098,15 @@
 	} else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) {
 		reply_len = hostapd_ctrl_iface_get_capability(
 			hapd, buf + 15, reply, reply_size);
+#ifdef CONFIG_PASN
+	} else if (os_strcmp(buf, "PTKSA_CACHE_LIST") == 0) {
+		reply_len = ptksa_cache_list(hapd->ptksa, reply, reply_size);
+#endif /* CONFIG_PASN */
+#ifdef ANDROID
+	} else if (os_strncmp(buf, "DRIVER ", 7) == 0) {
+		reply_len = hostapd_ctrl_iface_driver_cmd(hapd, buf + 7, reply,
+							  reply_size);
+#endif /* ANDROID */
 	} else {
 		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
 		reply_len = 16;
@@ -4364,14 +4578,16 @@
 {
 #ifdef CONFIG_WPS_TESTING
 	wps_version_number = 0x20;
-	wps_testing_dummy_cred = 0;
+	wps_testing_stub_cred = 0;
 	wps_corrupt_pkhash = 0;
 #endif /* CONFIG_WPS_TESTING */
 
 #ifdef CONFIG_TESTING_OPTIONS
 #ifdef CONFIG_DPP
 	dpp_test = DPP_TEST_DISABLED;
-#ifdef CONFIG_DPP2
+#ifdef CONFIG_DPP3
+	dpp_version_override = 3;
+#elif defined(CONFIG_DPP2)
 	dpp_version_override = 2;
 #else /* CONFIG_DPP2 */
 	dpp_version_override = 1;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/defconfig b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/defconfig
index e9f5de7..adf500a 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/defconfig
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/defconfig
@@ -30,6 +30,12 @@
 # Use libnl v2.0 (or 3.0) libraries.
 #CONFIG_LIBNL20=y
 
+# QCA vendor extensions to nl80211
+CONFIG_DRIVER_NL80211_QCA=y
+
+# Broadcom vendor extensions to nl80211
+#CONFIG_DRIVER_NL80211_BRCM=y
+
 # Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored)
 CONFIG_LIBNL32=y
 
@@ -346,7 +352,7 @@
 # * ath10k
 #
 # For more details refer to:
-# http://wireless.kernel.org/en/users/Documentation/acs
+# https://wireless.wiki.kernel.org/en/users/documentation/acs
 #
 #CONFIG_ACS=y
 
@@ -395,3 +401,21 @@
 # build includes this to allow mixed mode WPA+WPA2 networks to be enabled, but
 # that functionality is subject to be removed in the future.
 #CONFIG_NO_TKIP=y
+
+# Pre-Association Security Negotiation (PASN)
+# Experimental implementation based on IEEE P802.11z/D2.6 and the protocol
+# design is still subject to change. As such, this should not yet be enabled in
+# production use.
+# This requires CONFIG_IEEE80211W=y to be enabled, too.
+#CONFIG_PASN=y
+
+# Set SAE Auth status early
+CONFIG_WPA3_SAE_AUTH_EARLY_SET=y
+
+# Device Provisioning Protocol (DPP) (also known as Wi-Fi Easy Connect)
+CONFIG_DPP=y
+# DPP version 2 support
+CONFIG_DPP2=y
+# DPP version 3 support (experimental and still changing; do not enable for
+# production use)
+#CONFIG_DPP3=y
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/defconfig_auto b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/defconfig_auto
index 1c02c16..a0866b0 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/defconfig_auto
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/defconfig_auto
@@ -391,6 +391,10 @@
 # Opportunistic Wireless Encryption (OWE)
 # Experimental implementation of draft-harkins-owe-07.txt
 #CONFIG_OWE=y
+
+# Set SAE Auth status early
+CONFIG_WPA3_SAE_AUTH_EARLY_SET=y
+
 CONFIG_DPP=y
 CONFIG_IEEE80211W=y
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/defconfig_commercial b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/defconfig_commercial
index 9dcf784..dafcf0f 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/defconfig_commercial
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/defconfig_commercial
@@ -399,5 +399,8 @@
 # Simultaneous Authentication of Equals (SAE), WPA3-Personal
 CONFIG_SAE=y
 
+# Set SAE Auth status early
+CONFIG_WPA3_SAE_AUTH_EARLY_SET=y
+
 # Device Provisioning Protocol (DPP)
 CONFIG_DPP=y
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/hidl/1.3/hostapd.cpp b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/hidl/1.3/hostapd.cpp
index 6add761..4a1b280 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/hidl/1.3/hostapd.cpp
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/hidl/1.3/hostapd.cpp
@@ -356,9 +356,11 @@
 		    "wpa_key_mgmt=WPA-PSK SAE\n"
 		    "ieee80211w=1\n"
 		    "sae_require_mfp=1\n"
+		    "sae_pwe=%d\n"
 		    "wpa_passphrase=%s\n"
 		    "sae_password=%s",
 		    is_60Ghz_band_only ? "GCMP" : "CCMP",
+		    is_6Ghz_band_only ? 1 : 2,
 		    nw_params.V1_2.passphrase.c_str(),
 		    nw_params.V1_2.passphrase.c_str());
 		break;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/hlr_auc_gw.milenage_db b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/hlr_auc_gw.milenage_db
index c156a29..a250653 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/hlr_auc_gw.milenage_db
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/hlr_auc_gw.milenage_db
@@ -3,7 +3,7 @@
 # 4.3.20 Test Set 20. SQN is the last used SQN value.
 # These values can be used for both UMTS (EAP-AKA) and GSM (EAP-SIM)
 # authentication. In case of GSM/EAP-SIM, AMF and SQN values are not used, but
-# dummy values will need to be included in this file.
+# stub values will need to be included in this file.
 
 # IMSI Ki OPc AMF SQN [RES_len]
 232010000000000 90dca4eda45b53cf0f12d7c9c3bc6a89 cb9cccc4b9258e6dca4760379fb82581 61df 000000000000
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/hostapd.android.rc b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/hostapd.android.rc
index c8792d6..7cc45bd 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/hostapd.android.rc
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/hostapd.android.rc
@@ -14,6 +14,8 @@
 service hostapd /vendor/bin/hw/hostapd
     interface android.hardware.wifi.hostapd@1.0::IHostapd default
     interface android.hardware.wifi.hostapd@1.1::IHostapd default
+    interface android.hardware.wifi.hostapd@1.2::IHostapd default
+    interface android.hardware.wifi.hostapd@1.3::IHostapd default
     class main
     capabilities NET_ADMIN NET_RAW
     user wifi
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/hostapd.conf b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/hostapd.conf
index 5972a2e..70340db 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/hostapd.conf
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/hostapd.conf
@@ -171,7 +171,7 @@
 #op_class=131
 
 # ACS tuning - Automatic Channel Selection
-# See: http://wireless.kernel.org/en/users/Documentation/acs
+# See: https://wireless.wiki.kernel.org/en/users/documentation/acs
 #
 # You can customize the ACS survey algorithm with following variables:
 #
@@ -225,6 +225,10 @@
 # Default behavior is to include all PSC and non-PSC channels.
 #acs_exclude_6ghz_non_psc=1
 
+# Set minimum permitted max TX power (in dBm) for ACS and DFS channel selection.
+# (default 0, i.e., not constraint)
+#min_tx_power=20
+
 # Beacon interval in kus (1.024 ms) (default: 100; range 15..65535)
 beacon_int=100
 
@@ -279,6 +283,8 @@
 #    beacon_rate=ht:<HT MCS>
 # VHT:
 #    beacon_rate=vht:<VHT MCS>
+# HE:
+#    beacon_rate=he:<HE MCS>
 #
 # For example, beacon_rate=10 for 1 Mbps or beacon_rate=60 for 6 Mbps (OFDM).
 #beacon_rate=10
@@ -571,6 +577,10 @@
 # Default: 1 (enabled)
 #broadcast_deauth=1
 
+# Get notifications for received Management frames on control interface
+# Default: 0 (disabled)
+#notify_mgmt_frames=0
+
 ##### IEEE 802.11n related configuration ######################################
 
 # ieee80211n: Whether IEEE 802.11n (HT) is enabled
@@ -580,6 +590,9 @@
 # Note: hw_mode=g (2.4 GHz) and hw_mode=a (5 GHz) is used to specify the band.
 #ieee80211n=1
 
+# disable_11n: Boolean (0/1) to disable HT for a specific BSS
+#disable_11n=0
+
 # ht_capab: HT capabilities (list of flags)
 # LDPC coding capability: [LDPC] = supported
 # Supported channel width set: [HT40-] = both 20 MHz and 40 MHz with secondary
@@ -632,6 +645,9 @@
 # Note: hw_mode=a is used to specify that 5 GHz band is used with VHT.
 #ieee80211ac=1
 
+# disable_11ac: Boolean (0/1) to disable VHT for a specific BSS
+#disable_11ac=0
+
 # vht_capab: VHT capabilities (list of flags)
 #
 # vht_max_mpdu_len: [MAX-MPDU-7991] [MAX-MPDU-11454]
@@ -786,6 +802,9 @@
 # 1 = enabled
 #ieee80211ax=1
 
+# disable_11ax: Boolean (0/1) to disable HE for a specific BSS
+#disable_11ax=0
+
 #he_su_beamformer: HE single user beamformer support
 # 0 = not supported (default)
 # 1 = supported
@@ -816,12 +835,27 @@
 # 1 = required
 #he_twt_required=0
 
+#he_twt_responder: Whether TWT (HE) responder is enabled
+# 0 = disabled
+# 1 = enabled if supported by the driver (default)
+#he_twt_responder=1
+
 #he_rts_threshold: Duration of STA transmission
 # 0 = not set (default)
 # unsigned integer = duration in units of 16 us
 #he_rts_threshold=0
 
+#he_er_su_disable: Disable 242-tone HE ER SU PPDU reception by the AP
+# 0 = enable reception (default)
+# 1 = disable reception
+#he_er_su_disable=0
+
 # HE operating channel information; see matching vht_* parameters for details.
+# he_oper_centr_freq_seg0_idx field is used to indicate center frequency of 80
+# and 160 MHz bandwidth operation. In 80+80 MHz operation, it is the center
+# frequency of the lower frequency segment. he_oper_centr_freq_seg1_idx field
+# is used only with 80+80 MHz bandwidth operation and it is used to transmit
+# the center frequency of the second segment.
 # On the 6 GHz band the center freq calculation starts from 5.950 GHz offset.
 # For example idx=3 would result in 5965 MHz center frequency. In addition,
 # he_oper_chwidth is ignored, and the channel width is derived from the
@@ -862,10 +896,82 @@
 #he_mu_edca_ac_vo_timer=255
 
 # Spatial Reuse Parameter Set
+#
+# SR Control field value
+# B0 = PSR Disallowed
+# B1 = Non-SRG OBSS PD SR Disallowed
+# B2 = Non-SRG Offset Present
+# B3 = SRG Information Present
+# B4 = HESIGA_Spatial_reuse_value15_allowed
 #he_spr_sr_control
+#
+# Non-SRG OBSS PD Max Offset (included if he_spr_sr_control B2=1)
 #he_spr_non_srg_obss_pd_max_offset
+
+# SRG OBSS PD Min Offset (included if he_spr_sr_control B3=1)
 #he_spr_srg_obss_pd_min_offset
+#
+# SRG OBSS PD Max Offset (included if he_spr_sr_control B3=1)
 #he_spr_srg_obss_pd_max_offset
+#
+# SPR SRG BSS Color (included if he_spr_sr_control B3=1)
+# This config represents SRG BSS Color Bitmap field of Spatial Reuse Parameter
+# Set element that indicates the BSS color values used by members of the
+# SRG of which the transmitting STA is a member. The value is in range of 0-63.
+#he_spr_srg_bss_colors=1 2 10 63
+#
+# SPR SRG Partial BSSID (included if he_spr_sr_control B3=1)
+# This config represents SRG Partial BSSID Bitmap field of Spatial Reuse
+# Parameter Set element that indicates the Partial BSSID values used by members
+# of the SRG of which the transmitting STA is a member. The value range
+# corresponds to one of the 64 possible values of BSSID[39:44], where the lowest
+# numbered bit corresponds to Partial BSSID value 0 and the highest numbered bit
+# corresponds to Partial BSSID value 63.
+#he_spr_srg_partial_bssid=0 1 3 63
+#
+#he_6ghz_max_mpdu: Maximum MPDU Length of HE 6 GHz band capabilities.
+# Indicates maximum MPDU length
+# 0 = 3895 octets
+# 1 = 7991 octets
+# 2 = 11454 octets (default)
+#he_6ghz_max_mpdu=2
+#
+#he_6ghz_max_ampdu_len_exp: Maximum A-MPDU Length Exponent of HE 6 GHz band
+# capabilities. Indicates the maximum length of A-MPDU pre-EOF padding that
+# the STA can receive. This field is an integer in the range of 0 to 7.
+# The length defined by this field is equal to
+# 2 pow(13 + Maximum A-MPDU Length Exponent) -1 octets
+# 0 = AMPDU length of 8k
+# 1 = AMPDU length of 16k
+# 2 = AMPDU length of 32k
+# 3 = AMPDU length of 65k
+# 4 = AMPDU length of 131k
+# 5 = AMPDU length of 262k
+# 6 = AMPDU length of 524k
+# 7 = AMPDU length of 1048k (default)
+#he_6ghz_max_ampdu_len_exp=7
+#
+#he_6ghz_rx_ant_pat: Rx Antenna Pattern Consistency of HE 6 GHz capability.
+# Indicates the possibility of Rx antenna pattern change
+# 0 = Rx antenna pattern might change during the lifetime of an association
+# 1 = Rx antenna pattern does not change during the lifetime of an association
+#     (default)
+#he_6ghz_rx_ant_pat=1
+#
+#he_6ghz_tx_ant_pat: Tx Antenna Pattern Consistency of HE 6 GHz capability.
+# Indicates the possibility of Tx antenna pattern change
+# 0 = Tx antenna pattern might change during the lifetime of an association
+# 1 = Tx antenna pattern does not change during the lifetime of an association
+#     (default)
+#he_6ghz_tx_ant_pat=1
+
+# Unsolicited broadcast Probe Response transmission settings
+# This is for the 6 GHz band only. If the interval is set to a non-zero value,
+# the AP schedules unsolicited broadcast Probe Response frames to be
+# transmitted for in-band discovery. Refer to
+# IEEE P802.11ax/D8.0 26.17.2.3.2, AP behavior for fast passive scanning.
+# Valid range: 0..20 TUs; default is 0 (disabled)
+#unsol_bcast_probe_resp_interval=0
 
 ##### IEEE 802.1X-2004 related configuration ##################################
 
@@ -1307,6 +1413,12 @@
 # used, e.g., when the device has multiple IP addresses.
 #radius_client_addr=127.0.0.1
 
+# RADIUS client forced local interface. Helps run properly with VRF
+# Default is none set which allows the network stack to pick the appropriate
+# interface automatically.
+# Example below binds to eth0
+#radius_client_dev=eth0
+
 # RADIUS authentication server
 #auth_server_addr=127.0.0.1
 #auth_server_port=1812
@@ -1712,7 +1824,8 @@
 #group_mgmt_cipher=AES-128-CMAC
 
 # Beacon Protection (management frame protection for Beacon frames)
-# This depends on management frame protection being enabled (ieee80211w != 0).
+# This depends on management frame protection being enabled (ieee80211w != 0)
+# and beacon protection support indication from the driver.
 # 0 = disabled (default)
 # 1 = enabled
 #beacon_prot=0
@@ -1728,7 +1841,10 @@
 #assoc_sa_query_retry_timeout=201
 
 # ocv: Operating Channel Validation
-# This is a countermeasure against multi-channel man-in-the-middle attacks.
+# This is a countermeasure against multi-channel on-path attacks.
+# Enabling this depends on the driver's support for OCV when the driver SME is
+# used. If hostapd SME is used, this will be enabled just based on this
+# configuration.
 # Enabling this automatically also enables ieee80211w, if not yet enabled.
 # 0 = disabled (default)
 # 1 = enabled
@@ -1802,7 +1918,8 @@
 # SAE threshold for anti-clogging mechanism (dot11RSNASAEAntiCloggingThreshold)
 # This parameter defines how many open SAE instances can be in progress at the
 # same time before the anti-clogging mechanism is taken into use.
-#sae_anti_clogging_threshold=5
+#sae_anti_clogging_threshold=5 (deprecated)
+#anti_clogging_threshold=5
 
 # Maximum number of SAE synchronization errors (dot11RSNASAESync)
 # The offending SAE peer will be disconnected if more than this many
@@ -1921,6 +2038,13 @@
 # default: 30 TUs (= 30.72 milliseconds)
 #fils_hlp_wait_time=30
 
+# FILS Discovery frame transmission minimum and maximum interval settings.
+# If fils_discovery_max_interval is non-zero, the AP enables FILS Discovery
+# frame transmission. These values use TUs as the unit and have allowed range
+# of 0-10000. fils_discovery_min_interval defaults to 20.
+#fils_discovery_min_interval=20
+#fils_discovery_max_interval=0
+
 # Transition Disable indication
 # The AP can notify authenticated stations to disable transition mode in their
 # network profiles when the network has completed transition steps, i.e., once
@@ -1938,6 +2062,21 @@
 # (default: 0 = do not include Transition Disable KDE)
 #transition_disable=0x01
 
+# PASN ECDH groups
+# PASN implementations are required to support group 19 (NIST P-256). If this
+# parameter is not set, only group 19 is supported by default. This
+# configuration parameter can be used to specify a limited set of allowed
+# groups. The group values are listed in the IANA registry:
+# http://www.iana.org/assignments/ipsec-registry/ipsec-registry.xml#ipsec-registry-10
+#pasn_groups=19 20 21
+
+# PASN comeback after time in TUs
+# In case the AP is temporarily unable to handle a PASN authentication exchange
+# due to a too large number of parallel operations, this value indicates to the
+# peer after how many TUs it can try the PASN exchange again.
+# (default: 10 TUs)
+#pasn_comeback_after=10
+
 ##### IEEE 802.11r configuration ##############################################
 
 # Mobility Domain identifier (dot11FTMobilityDomainID, MDID)
@@ -2726,6 +2865,10 @@
 # threshold (range: 0..255, default=30).
 #rssi_reject_assoc_timeout=30
 
+# Ignore Probe Request frames if RSSI is below given threshold (in dBm)
+# Allowed range: -60 to -90 dBm; default = 0 (rejection disabled)
+#rssi_ignore_probe_request=-75
+
 ##### Fast Session Transfer (FST) support #####################################
 #
 # The options in this section are only available when the build configuration
@@ -2782,6 +2925,9 @@
 # that allows sending of such data. Default: 0.
 #stationary_ap=0
 
+# Enable reduced neighbor reporting (RNR)
+#rnr=0
+
 ##### Airtime policy configuration ###########################################
 
 # Set the airtime policy operating mode:
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/hostapd_cli.c b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/hostapd_cli.c
index 58d92a5..1088c75 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/hostapd_cli.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/hostapd_cli.c
@@ -1,6 +1,6 @@
 /*
  * hostapd - command line interface for hostapd daemon
- * Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2022, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -21,7 +21,7 @@
 
 static const char *const hostapd_cli_version =
 "hostapd_cli v" VERSION_STR "\n"
-"Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi> and contributors";
+"Copyright (c) 2004-2022, Jouni Malinen <j@w1.fi> and contributors";
 
 static struct wpa_ctrl *ctrl_conn;
 static int hostapd_cli_quit = 0;
@@ -1048,7 +1048,7 @@
 	int arg = get_cmd_arg_num(str, pos);
 	const char *fields[] = {
 #ifdef CONFIG_WPS_TESTING
-		"wps_version_number", "wps_testing_dummy_cred",
+		"wps_version_number", "wps_testing_stub_cred",
 		"wps_corrupt_pkhash",
 #endif /* CONFIG_WPS_TESTING */
 #ifdef CONFIG_INTERWORKING
@@ -1266,27 +1266,6 @@
 	return wpa_ctrl_command(ctrl, "ERP_FLUSH");
 }
 
-
-#if defined(ANDROID) || defined(BCM_LINUX_BUILD)
-static int hostapd_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
-{
-	char cmd[256];
-	int i;
-	int len;
-
-	if (argc < 1) {
-		printf("Invalid DRIVER command: needs one argument (cmd)\n");
-		return -1;
-	}
-
-	len = os_snprintf(cmd, sizeof(cmd), "DRIVER %s", argv[0]);
-	for (i=1; i < argc; i++)
-		len += os_snprintf(cmd + len, sizeof(cmd) - len, " %s", argv[i]);
-	cmd[sizeof(cmd) - 1] = '\0';
-	printf("%s: %s\n", __func__, cmd);
-	return wpa_ctrl_command(ctrl, cmd);
-}
-#endif /* ANDROID || BCM_LINUX_BUILD */
 static int hostapd_cli_cmd_log_level(struct wpa_ctrl *ctrl, int argc,
 				     char *argv[])
 {
@@ -1511,6 +1490,20 @@
 
 #ifdef CONFIG_DPP2
 
+static int hostapd_cli_cmd_dpp_controller_start(struct wpa_ctrl *ctrl, int argc,
+						char *argv[])
+{
+	return hostapd_cli_cmd(ctrl, "DPP_CONTROLLER_START", 1, argc, argv);
+}
+
+
+static int hostapd_cli_cmd_dpp_controller_stop(struct wpa_ctrl *ctrl, int argc,
+					       char *argv[])
+{
+	return wpa_ctrl_command(ctrl, "DPP_CONTROLLER_STOP");
+}
+
+
 static int hostapd_cli_cmd_dpp_chirp(struct wpa_ctrl *ctrl, int argc,
 				     char *argv[])
 {
@@ -1563,6 +1556,28 @@
 }
 
 
+#if defined(ANDROID) || defined(BCM_LINUX_BUILD)
+static int hostapd_cli_cmd_driver(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+	char cmd[256];
+	int i;
+	int len;
+
+	if (argc < 1) {
+		printf("Invalid DRIVER command: needs one argument (cmd)\n");
+		return -1;
+	}
+
+	len = os_snprintf(cmd, sizeof(cmd), "DRIVER %s", argv[0]);
+	for (i=1; i < argc; i++)
+		len += os_snprintf(cmd + len, sizeof(cmd) - len, " %s", argv[i]);
+	cmd[sizeof(cmd) - 1] = '\0';
+	printf("%s: %s\n", __func__, cmd);
+	return wpa_ctrl_command(ctrl, cmd);
+}
+#endif /* ANDROID || BCM_LINUX_BUILD */
+
+
 struct hostapd_cli_cmd {
 	const char *cmd;
 	int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
@@ -1740,6 +1755,10 @@
 	{ "dpp_pkex_remove", hostapd_cli_cmd_dpp_pkex_remove, NULL,
 	  "*|<id> = remove DPP pkex information" },
 #ifdef CONFIG_DPP2
+	{ "dpp_controller_start", hostapd_cli_cmd_dpp_controller_start, NULL,
+	  "[tcp_port=<port>] [role=..] = start DPP controller" },
+	{ "dpp_controller_stop", hostapd_cli_cmd_dpp_controller_stop, NULL,
+	  "= stop DPP controller" },
 	{ "dpp_chirp", hostapd_cli_cmd_dpp_chirp, NULL,
 	  "own=<BI ID> iter=<count> = start DPP chirp" },
 	{ "dpp_stop_chirp", hostapd_cli_cmd_dpp_stop_chirp, NULL,
@@ -1756,6 +1775,10 @@
 	  "<addr> [req_mode=] <measurement request hexdump>  = send a Beacon report request to a station" },
 	{ "reload_wpa_psk", hostapd_cli_cmd_reload_wpa_psk, NULL,
 	  "= reload wpa_psk_file only" },
+#ifdef ANDROID
+	{ "driver", hostapd_cli_cmd_driver, NULL,
+	  "<driver sub command> [<hex formatted data>] = send driver command data" },
+#endif /* ANDROID */
 	{ NULL, NULL, NULL, NULL }
 };
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/main.c b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/main.c
index 7e385d6..6d7e248 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/hostapd/main.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/hostapd/main.c
@@ -1,6 +1,6 @@
 /*
  * hostapd / main()
- * Copyright (c) 2002-2019, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2022, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -33,6 +33,9 @@
 #ifdef CONFIG_CTRL_IFACE_HIDL
 #include "hidl.h"
 #endif /* CONFIG_CTRL_IFACE_HIDL */
+#ifdef CONFIG_CTRL_IFACE_AIDL
+#include "aidl.h"
+#endif /* CONFIG_CTRL_IFACE_AIDL */
 
 
 struct hapd_global {
@@ -483,7 +486,7 @@
 		"hostapd v%s\n"
 		"User space daemon for IEEE 802.11 AP management,\n"
 		"IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n"
-		"Copyright (c) 2002-2019, Jouni Malinen <j@w1.fi> "
+		"Copyright (c) 2002-2022, Jouni Malinen <j@w1.fi> "
 		"and contributors\n",
 		VERSION_STR);
 }
@@ -794,9 +797,11 @@
 	}
 
 #ifndef CONFIG_CTRL_IFACE_HIDL
+#ifndef CONFIG_CTRL_IFACE_AIDL
 	if (optind == argc && interfaces.global_iface_path == NULL &&
 	    num_bss_configs == 0)
 		usage();
+#endif /* CONFIG_CTRL_IFACE_AIDL */
 #endif /* CONFIG_CTRL_IFACE_HIDL */
 
 	wpa_msg_register_ifname_cb(hostapd_msg_ifname_cb);
@@ -924,6 +929,12 @@
                 goto out;
         }
 #endif /* CONFIG_CTRL_IFACE_HIDL */
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	if (hostapd_aidl_init(&interfaces)) {
+		wpa_printf(MSG_ERROR, "Failed to initialize AIDL interface");
+		goto out;
+	}
+#endif /* CONFIG_CTRL_IFACE_AIDL */
 	hostapd_global_ctrl_iface_init(&interfaces);
 
 	if (hostapd_global_run(&interfaces, daemonize, pid_file)) {
@@ -937,6 +948,9 @@
 #ifdef CONFIG_CTRL_IFACE_HIDL
         hostapd_hidl_deinit(&interfaces);
 #endif /* CONFIG_CTRL_IFACE_HIDL */
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	hostapd_aidl_deinit(&interfaces);
+#endif /* CONFIG_CTRL_IFACE_AIDL */
 	hostapd_global_ctrl_iface_deinit(&interfaces);
 	/* Deinitialize all interfaces */
 	for (i = 0; i < interfaces.count; i++) {
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/libbcmdhd/Android.mk b/src/lynq/packages/thirdpart/lynq-wg870/libbcmdhd/Android.mk
index 63ec0df..a01cc0d 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/libbcmdhd/Android.mk
+++ b/src/lynq/packages/thirdpart/lynq-wg870/libbcmdhd/Android.mk
@@ -30,7 +30,7 @@
 # Disable unused parameter warnings
 L_CFLAGS += -Wno-unused-parameter -Wno-unused-function -Wno-format
 
-ifneq ($(filter 12, $(PLATFORM_VERSION)),12)
+ifeq ($(filter 12 13, $(PLATFORM_VERSION)),)
 L_CFLAGS += -Wno-error-sometimes-uninitialized
 endif
 
@@ -75,6 +75,10 @@
 L_CFLAGS += -DCONFIG_HIDL -DCONFIG_CTRL_IFACE_HIDL
 endif
 
+ifdef CONFIG_CTRL_IFACE_AIDL
+L_CFLAGS += -DCONFIG_AIDL -DCONFIG_CTRL_IFACE_AIDL
+endif
+
 ifdef CONFIG_BRCM_NAN
 L_CFLAGS += -DBCM_GENL
 endif
@@ -171,7 +175,7 @@
 #If you are using Android Oreo Master branch then you will get PLATFORM_VERSION as alphanbet (e.g P,Q)
 #If you are using perticulat tag from android AOSP then you will get PLATFORM_VERSION as a NUMBER (e.g 9 - for Android P)
 #this you can confirm after setting the evnsetup for target device during "lunch" command.
-ifneq ($(filter O P 8.0.0 8.1.0 9 10 11,$(PLATFORM_VERSION)),)
+ifneq ($(filter O P 8.0.0 8.1.0 9 10 11 12 13,$(PLATFORM_VERSION)),)
 L_CFLAGS += -DABOVE_8_1
 ABOVE_8_1=y
 endif
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/acs.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/acs.c
index aa2ceb0..0030edc 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/acs.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/acs.c
@@ -309,8 +309,6 @@
 	else if (survey->filled & SURVEY_HAS_CHAN_TIME_RX)
 		busy = survey->channel_time_rx;
 	else {
-		/* This shouldn't really happen as survey data is checked in
-		 * acs_sanity_check() */
 		wpa_printf(MSG_ERROR, "ACS: Survey data missing");
 		return 0;
 	}
@@ -372,40 +370,47 @@
 }
 
 
-static int acs_usable_ht40_chan(const struct hostapd_channel_data *chan)
+static int acs_usable_bw40_chan(const struct hostapd_channel_data *chan)
 {
-	const int allowed[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149,
-				157, 184, 192 };
+	const int allowed[] = { 5180, 5220, 5260, 5300, 5500, 5540, 5580, 5620,
+				5660, 5745, 5785, 4920, 4960, 5955, 5995, 6035,
+				6075, 6115, 6155, 6195, 6235, 6275, 6315, 6355,
+				6395, 6435, 6475, 6515, 6555, 6595, 6635, 6675,
+				6715, 6755, 6795, 6835, 6875, 6915, 6955, 6995,
+				7035, 7075 };
 	unsigned int i;
 
 	for (i = 0; i < ARRAY_SIZE(allowed); i++)
-		if (chan->chan == allowed[i])
+		if (chan->freq == allowed[i])
 			return 1;
 
 	return 0;
 }
 
 
-static int acs_usable_vht80_chan(const struct hostapd_channel_data *chan)
+static int acs_usable_bw80_chan(const struct hostapd_channel_data *chan)
 {
-	const int allowed[] = { 36, 52, 100, 116, 132, 149 };
+	const int allowed[] = { 5180, 5260, 5500, 5580, 5660, 5745, 5955, 6035,
+				6115, 6195, 6275, 6355, 6435, 6515, 6595, 6675,
+				6755, 6835, 6915, 6995 };
 	unsigned int i;
 
 	for (i = 0; i < ARRAY_SIZE(allowed); i++)
-		if (chan->chan == allowed[i])
+		if (chan->freq == allowed[i])
 			return 1;
 
 	return 0;
 }
 
 
-static int acs_usable_vht160_chan(const struct hostapd_channel_data *chan)
+static int acs_usable_bw160_chan(const struct hostapd_channel_data *chan)
 {
-	const int allowed[] = { 36, 100 };
+	const int allowed[] = { 5180, 5500, 5955, 6115, 6275, 6435, 6595, 6755,
+				6915 };
 	unsigned int i;
 
 	for (i = 0; i < ARRAY_SIZE(allowed); i++)
-		if (chan->chan == allowed[i])
+		if (chan->freq == allowed[i])
 			return 1;
 
 	return 0;
@@ -541,6 +546,9 @@
 		if (!is_in_freqlist(iface, chan))
 			continue;
 
+		if (chan->max_tx_power < iface->conf->min_tx_power)
+			continue;
+
 		wpa_printf(MSG_DEBUG, "ACS: Survey analysis for channel %d (%d MHz)",
 			   chan->chan, chan->freq);
 
@@ -668,6 +676,9 @@
 		if (!is_in_freqlist(iface, chan))
 			continue;
 
+		if (chan->max_tx_power < iface->conf->min_tx_power)
+			continue;
+
 		if (!chan_bw_allowed(chan, bw, 1, 1)) {
 			wpa_printf(MSG_DEBUG,
 				   "ACS: Channel %d: BW %u is not supported",
@@ -678,10 +689,12 @@
 		/* HT40 on 5 GHz has a limited set of primary channels as per
 		 * 11n Annex J */
 		if (mode->mode == HOSTAPD_MODE_IEEE80211A &&
-		    iface->conf->ieee80211n &&
-		    iface->conf->secondary_channel &&
-		    !acs_usable_ht40_chan(chan)) {
-			wpa_printf(MSG_DEBUG, "ACS: Channel %d: not allowed as primary channel for HT40",
+		    ((iface->conf->ieee80211n &&
+		      iface->conf->secondary_channel) ||
+		     is_6ghz_freq(chan->freq)) &&
+		    !acs_usable_bw40_chan(chan)) {
+			wpa_printf(MSG_DEBUG,
+				   "ACS: Channel %d: not allowed as primary channel for 40 MHz bandwidth",
 				   chan->chan);
 			continue;
 		}
@@ -690,18 +703,18 @@
 		    (iface->conf->ieee80211ac || iface->conf->ieee80211ax)) {
 			if (hostapd_get_oper_chwidth(iface->conf) ==
 			    CHANWIDTH_80MHZ &&
-			    !acs_usable_vht80_chan(chan)) {
+			    !acs_usable_bw80_chan(chan)) {
 				wpa_printf(MSG_DEBUG,
-					   "ACS: Channel %d: not allowed as primary channel for VHT80",
+					   "ACS: Channel %d: not allowed as primary channel for 80 MHz bandwidth",
 					   chan->chan);
 				continue;
 			}
 
 			if (hostapd_get_oper_chwidth(iface->conf) ==
 			    CHANWIDTH_160MHZ &&
-			    !acs_usable_vht160_chan(chan)) {
+			    !acs_usable_bw160_chan(chan)) {
 				wpa_printf(MSG_DEBUG,
-					   "ACS: Channel %d: not allowed as primary channel for VHT160",
+					   "ACS: Channel %d: not allowed as primary channel for 160 MHz bandwidth",
 					   chan->chan);
 				continue;
 			}
@@ -832,6 +845,12 @@
 	u32 bw;
 	struct hostapd_hw_modes *mode;
 
+	if (is_6ghz_op_class(iface->conf->op_class)) {
+		bw = op_class_to_bandwidth(iface->conf->op_class);
+		n_chans = bw / 20;
+		goto bw_selected;
+	}
+
 	/* TODO: HT40- support */
 
 	if (iface->conf->ieee80211n &&
@@ -857,6 +876,7 @@
 
 	bw = num_chan_to_bw(n_chans);
 
+bw_selected:
 	/* TODO: VHT/HE80+80. Update acs_adjust_center_freq() too. */
 
 	wpa_printf(MSG_DEBUG,
@@ -1033,6 +1053,9 @@
 		if (!is_in_freqlist(iface, chan))
 			continue;
 
+		if (chan->max_tx_power < iface->conf->min_tx_power)
+			continue;
+
 		*freq++ = chan->freq;
 	}
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/airtime_policy.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/airtime_policy.c
index 1e67f0d..abe817c 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/airtime_policy.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/airtime_policy.c
@@ -79,6 +79,10 @@
 	for (sta = hapd->sta_list; sta; sta = sta->next) {
 		if (hostapd_drv_read_sta_data(hapd, &data, sta->addr))
 			continue;
+#ifdef CONFIG_TESTING_OPTIONS
+		if (hapd->force_backlog_bytes)
+			data.backlog_bytes = 1;
+#endif /* CONFIG_TESTING_OPTIONS */
 
 		if (data.backlog_bytes > 0)
 			set_new_backlog_time(hapd, sta, &now);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ap_config.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ap_config.c
index 04535a1..86b6e09 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ap_config.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ap_config.c
@@ -121,7 +121,7 @@
 
 	bss->radius_das_time_window = 300;
 
-	bss->sae_anti_clogging_threshold = 5;
+	bss->anti_clogging_threshold = 5;
 	bss->sae_sync = 5;
 
 	bss->gas_frag_limit = 1400;
@@ -131,6 +131,7 @@
 	bss->fils_hlp_wait_time = 30;
 	bss->dhcp_server_port = DHCP_SERVER_PORT;
 	bss->dhcp_relay_port = DHCP_SERVER_PORT;
+	bss->fils_discovery_min_int = 20;
 #endif /* CONFIG_FILS */
 
 	bss->broadcast_deauth = 1;
@@ -164,6 +165,11 @@
 #ifdef CONFIG_TESTING_OPTIONS
 	bss->sae_commit_status = -1;
 #endif /* CONFIG_TESTING_OPTIONS */
+
+#ifdef CONFIG_PASN
+	/* comeback after 10 TUs */
+	bss->pasn_comeback_after = 10;
+#endif /* CONFIG_PASN */
 }
 
 
@@ -267,7 +273,12 @@
 	conf->he_op.he_basic_mcs_nss_set = 0xfffc;
 	conf->he_op.he_bss_color_disabled = 1;
 	conf->he_op.he_bss_color_partial = 0;
-	conf->he_op.he_bss_color = 1;
+	conf->he_op.he_bss_color = os_random() % 63 + 1;
+	conf->he_op.he_twt_responder = 1;
+	conf->he_6ghz_max_mpdu = 2;
+	conf->he_6ghz_max_ampdu_len_exp = 7;
+	conf->he_6ghz_rx_ant_pat = 1;
+	conf->he_6ghz_tx_ant_pat = 1;
 #endif /* CONFIG_IEEE80211AX */
 
 	/* The third octet of the country string uses an ASCII space character
@@ -774,6 +785,7 @@
 					   conf->radius->num_auth_servers);
 		hostapd_config_free_radius(conf->radius->acct_servers,
 					   conf->radius->num_acct_servers);
+		os_free(conf->radius->force_client_dev);
 	}
 	hostapd_config_free_radius_attr(conf->radius_auth_req_attr);
 	hostapd_config_free_radius_attr(conf->radius_acct_req_attr);
@@ -955,6 +967,10 @@
 	}
 #endif /* CONFIG_AIRTIME_POLICY */
 
+#ifdef CONFIG_PASN
+	os_free(conf->pasn_groups);
+#endif /* CONFIG_PASN */
+
 	os_free(conf);
 }
 
@@ -1150,10 +1166,54 @@
 #endif /* CONFIG_SAE_PK */
 
 
+static bool hostapd_config_check_bss_6g(struct hostapd_bss_config *bss)
+{
+	if (bss->wpa != WPA_PROTO_RSN) {
+		wpa_printf(MSG_ERROR,
+			   "Pre-RSNA security methods are not allowed in 6 GHz");
+		return false;
+	}
+
+	if (bss->ieee80211w != MGMT_FRAME_PROTECTION_REQUIRED) {
+		wpa_printf(MSG_ERROR,
+			   "Management frame protection is required in 6 GHz");
+		return false;
+	}
+
+	if (bss->wpa_key_mgmt & (WPA_KEY_MGMT_PSK |
+				 WPA_KEY_MGMT_FT_PSK |
+				 WPA_KEY_MGMT_PSK_SHA256)) {
+		wpa_printf(MSG_ERROR, "Invalid AKM suite for 6 GHz");
+		return false;
+	}
+
+	if (bss->rsn_pairwise & (WPA_CIPHER_WEP40 |
+				 WPA_CIPHER_WEP104 |
+				 WPA_CIPHER_TKIP)) {
+		wpa_printf(MSG_ERROR,
+			   "Invalid pairwise cipher suite for 6 GHz");
+		return false;
+	}
+
+	if (bss->wpa_group & (WPA_CIPHER_WEP40 |
+			      WPA_CIPHER_WEP104 |
+			      WPA_CIPHER_TKIP)) {
+		wpa_printf(MSG_ERROR, "Invalid group cipher suite for 6 GHz");
+		return false;
+	}
+
+	return true;
+}
+
+
 static int hostapd_config_check_bss(struct hostapd_bss_config *bss,
 				    struct hostapd_config *conf,
 				    int full_config)
 {
+	if (full_config && is_6ghz_op_class(conf->op_class) &&
+	    !hostapd_config_check_bss_6g(bss))
+		return -1;
+
 	if (full_config && bss->ieee802_1x && !bss->eap_server &&
 	    !bss->radius->auth_servers) {
 		wpa_printf(MSG_ERROR, "Invalid IEEE 802.1X configuration (no "
@@ -1229,7 +1289,7 @@
 
 	if (full_config && conf->ieee80211n &&
 	    conf->hw_mode == HOSTAPD_MODE_IEEE80211B) {
-		bss->disable_11n = 1;
+		bss->disable_11n = true;
 		wpa_printf(MSG_ERROR, "HT (IEEE 802.11n) in 11b mode is not "
 			   "allowed, disabling HT capabilities");
 	}
@@ -1237,7 +1297,7 @@
 #ifdef CONFIG_WEP
 	if (full_config && conf->ieee80211n &&
 	    bss->ssid.security_policy == SECURITY_STATIC_WEP) {
-		bss->disable_11n = 1;
+		bss->disable_11n = true;
 		wpa_printf(MSG_ERROR, "HT (IEEE 802.11n) with WEP is not "
 			   "allowed, disabling HT capabilities");
 	}
@@ -1248,7 +1308,7 @@
 	    !(bss->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP |
 				   WPA_CIPHER_CCMP_256 | WPA_CIPHER_GCMP_256)))
 	{
-		bss->disable_11n = 1;
+		bss->disable_11n = true;
 		wpa_printf(MSG_ERROR, "HT (IEEE 802.11n) with WPA/WPA2 "
 			   "requires CCMP/GCMP to be enabled, disabling HT "
 			   "capabilities");
@@ -1258,7 +1318,7 @@
 #ifdef CONFIG_WEP
 	if (full_config && conf->ieee80211ac &&
 	    bss->ssid.security_policy == SECURITY_STATIC_WEP) {
-		bss->disable_11ac = 1;
+		bss->disable_11ac = true;
 		wpa_printf(MSG_ERROR,
 			   "VHT (IEEE 802.11ac) with WEP is not allowed, disabling VHT capabilities");
 	}
@@ -1269,12 +1329,33 @@
 	    !(bss->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP |
 				   WPA_CIPHER_CCMP_256 | WPA_CIPHER_GCMP_256)))
 	{
-		bss->disable_11ac = 1;
+		bss->disable_11ac = true;
 		wpa_printf(MSG_ERROR,
 			   "VHT (IEEE 802.11ac) with WPA/WPA2 requires CCMP/GCMP to be enabled, disabling VHT capabilities");
 	}
 #endif /* CONFIG_IEEE80211AC */
 
+#ifdef CONFIG_IEEE80211AX
+#ifdef CONFIG_WEP
+	if (full_config && conf->ieee80211ax &&
+	    bss->ssid.security_policy == SECURITY_STATIC_WEP) {
+		bss->disable_11ax = true;
+		wpa_printf(MSG_ERROR,
+			   "HE (IEEE 802.11ax) with WEP is not allowed, disabling HE capabilities");
+	}
+#endif /* CONFIG_WEP */
+
+	if (full_config && conf->ieee80211ax && bss->wpa &&
+	    !(bss->wpa_pairwise & WPA_CIPHER_CCMP) &&
+	    !(bss->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP |
+				   WPA_CIPHER_CCMP_256 | WPA_CIPHER_GCMP_256)))
+	{
+		bss->disable_11ax = true;
+		wpa_printf(MSG_ERROR,
+			   "HE (IEEE 802.11ax) with WPA/WPA2 requires CCMP/GCMP to be enabled, disabling HE capabilities");
+	}
+#endif /* CONFIG_IEEE80211AX */
+
 #ifdef CONFIG_WPS
 	if (full_config && bss->wps_state && bss->ignore_broadcast_ssid) {
 		wpa_printf(MSG_INFO, "WPS: ignore_broadcast_ssid "
@@ -1342,6 +1423,15 @@
 	}
 #endif /* CONFIG_SAE_PK */
 
+#ifdef CONFIG_FILS
+	if (full_config && bss->fils_discovery_min_int &&
+	    bss->unsol_bcast_probe_resp_interval) {
+		wpa_printf(MSG_ERROR,
+			   "Cannot enable both FILS discovery and unsolicited broadcast Probe Response at the same time");
+		return -1;
+	}
+#endif /* CONFIG_FILS */
+
 	return 0;
 }
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ap_config.h b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ap_config.h
index 52c70a1..9bdef45 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ap_config.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ap_config.h
@@ -51,6 +51,7 @@
 	int dot11MeshRetryTimeout; /* msec */
 	int dot11MeshConfirmTimeout; /* msec */
 	int dot11MeshHoldingTimeout; /* msec */
+	int mesh_fwding;
 };
 
 #define MAX_STA_COUNT 2007
@@ -267,6 +268,8 @@
 	u8 addr[ETH_ALEN];
 };
 
+#define EXT_CAPA_MAX_LEN 15
+
 /**
  * struct hostapd_bss_config - Per-BSS configuration
  */
@@ -531,8 +534,9 @@
 #define TDLS_PROHIBIT BIT(0)
 #define TDLS_PROHIBIT_CHAN_SWITCH BIT(1)
 	int tdls;
-	int disable_11n;
-	int disable_11ac;
+	bool disable_11n;
+	bool disable_11ac;
+	bool disable_11ax;
 
 	/* IEEE 802.11v */
 	int time_advertisement;
@@ -654,7 +658,7 @@
 	struct wpabuf *vendor_elements;
 	struct wpabuf *assocresp_elements;
 
-	unsigned int sae_anti_clogging_threshold;
+	unsigned int anti_clogging_threshold;
 	unsigned int sae_sync;
 	int sae_require_mfp;
 	int sae_confirm_immediate;
@@ -693,6 +697,7 @@
 
 #define MESH_ENABLED BIT(0)
 	int mesh;
+	int mesh_fwding;
 
 	u8 radio_measurements[RRM_CAPABILITIES_IE_LEN];
 
@@ -732,12 +737,16 @@
 	unsigned int fils_hlp_wait_time;
 	u16 dhcp_server_port;
 	u16 dhcp_relay_port;
+	u32 fils_discovery_min_int;
+	u32 fils_discovery_max_int;
 #endif /* CONFIG_FILS */
 
 	int multicast_to_unicast;
 
 	int broadcast_deauth;
 
+	int notify_mgmt_frames;
+
 #ifdef CONFIG_DPP
 	char *dpp_name;
 	char *dpp_mud_url;
@@ -864,6 +873,37 @@
 	 */
 	u8 mka_psk_set;
 #endif /* CONFIG_MACSEC */
+
+#ifdef CONFIG_PASN
+#ifdef CONFIG_TESTING_OPTIONS
+	/*
+	 * Normally, KDK should be derived if and only if both sides support
+	 * secure LTF. Allow forcing KDK derivation for testing purposes.
+	 */
+	int force_kdk_derivation;
+
+	/* If set, corrupt the MIC in the 2nd Authentication frame of PASN */
+	int pasn_corrupt_mic;
+#endif /* CONFIG_TESTING_OPTIONS */
+
+	int *pasn_groups;
+
+	/*
+	 * The time in TUs after which the non-AP STA is requested to retry the
+	 * PASN authentication in case there are too many parallel operations.
+	 */
+	u16 pasn_comeback_after;
+#endif /* CONFIG_PASN */
+
+	unsigned int unsol_bcast_probe_resp_interval;
+
+	u8 ext_capa_mask[EXT_CAPA_MAX_LEN];
+	u8 ext_capa[EXT_CAPA_MAX_LEN];
+
+	u8 rnr;
+	/* Refer commit 587411dd62: Fix for PMK expiration issue through
+	 * supplicant
+	 */
 	unsigned int dot11RSNAConfigPMKLifetime;
 };
 
@@ -885,7 +925,9 @@
 	u8 he_bss_color_partial;
 	u8 he_default_pe_duration;
 	u8 he_twt_required;
+	u8 he_twt_responder;
 	u16 he_rts_threshold;
+	u8 he_er_su_disable;
 	u16 he_basic_mcs_nss_set;
 };
 
@@ -897,8 +939,8 @@
 	u8 non_srg_obss_pd_max_offset;
 	u8 srg_obss_pd_min_offset;
 	u8 srg_obss_pd_max_offset;
-	u8 srg_obss_color_bitmap;
-	u8 srg_obss_color_partial_bitmap;
+	u8 srg_bss_color_bitmap[8];
+	u8 srg_partial_bssid_bitmap[8];
 };
 
 /**
@@ -920,6 +962,7 @@
 	struct wpa_freq_range_list acs_freq_list;
 	u8 acs_freq_list_present;
 	int acs_exclude_dfs;
+	u8 min_tx_power;
 	enum hostapd_hw_mode hw_mode; /* HOSTAPD_MODE_IEEE80211A, .. */
 	int acs_exclude_6ghz_non_psc;
 	enum {
@@ -1025,6 +1068,10 @@
 	u8 he_oper_chwidth;
 	u8 he_oper_centr_freq_seg0_idx;
 	u8 he_oper_centr_freq_seg1_idx;
+	u8 he_6ghz_max_mpdu;
+	u8 he_6ghz_max_ampdu_len_exp;
+	u8 he_6ghz_rx_ant_pat;
+	u8 he_6ghz_tx_ant_pat;
 #endif /* CONFIG_IEEE80211AX */
 
 	/* VHT enable/disable config from CHAN_SWITCH */
@@ -1032,8 +1079,14 @@
 #define CH_SWITCH_VHT_DISABLED BIT(1)
 	unsigned int ch_switch_vht_config;
 
+	/* HE enable/disable config from CHAN_SWITCH */
+#define CH_SWITCH_HE_ENABLED BIT(0)
+#define CH_SWITCH_HE_DISABLED BIT(1)
+	unsigned int ch_switch_he_config;
+
 	int rssi_reject_assoc_rssi;
 	int rssi_reject_assoc_timeout;
+	int rssi_ignore_probe_request;
 
 #ifdef CONFIG_AIRTIME_POLICY
 	enum {
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ap_drv_ops.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ap_drv_ops.c
index a1bf445..63bc614 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ap_drv_ops.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ap_drv_ops.c
@@ -899,7 +899,8 @@
 			continue;
 		if (!(chan->flag & HOSTAPD_CHAN_DISABLED) &&
 		    !(hapd->iface->conf->acs_exclude_dfs &&
-		      (chan->flag & HOSTAPD_CHAN_RADAR)))
+		      (chan->flag & HOSTAPD_CHAN_RADAR)) &&
+		    !(chan->max_tx_power < hapd->iface->conf->min_tx_power))
 			int_array_add_unique(freq_list, chan->freq);
 	}
 }
@@ -999,3 +1000,11 @@
 	return hapd->driver->update_dh_ie(hapd->drv_priv, peer, reason_code,
 					  ie, ielen);
 }
+
+
+int hostapd_drv_dpp_listen(struct hostapd_data *hapd, bool enable)
+{
+	if (!hapd->driver || !hapd->driver->dpp_listen || !hapd->drv_priv)
+		return 0;
+	return hapd->driver->dpp_listen(hapd->drv_priv, enable);
+}
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ap_drv_ops.h b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ap_drv_ops.h
index cc7ea07..de9c0c4 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ap_drv_ops.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ap_drv_ops.h
@@ -134,6 +134,7 @@
 int hostapd_drv_do_acs(struct hostapd_data *hapd);
 int hostapd_drv_update_dh_ie(struct hostapd_data *hapd, const u8 *peer,
 			     u16 reason_code, const u8 *ie, size_t ielen);
+int hostapd_drv_dpp_listen(struct hostapd_data *hapd, bool enable);
 
 
 #include "drivers/driver.h"
@@ -385,11 +386,51 @@
 }
 
 static inline int
-hostapd_drv_set_band(struct hostapd_data *hapd, enum set_band band)
+hostapd_drv_set_band(struct hostapd_data *hapd, u32 band_mask)
 {
 	if (!hapd->driver || !hapd->drv_priv || !hapd->driver->set_band)
 		return -1;
-	return hapd->driver->set_band(hapd->drv_priv, band);
+	return hapd->driver->set_band(hapd->drv_priv, band_mask);
 }
 
+#ifdef ANDROID
+static inline int hostapd_drv_driver_cmd(struct hostapd_data *hapd,
+					 char *cmd, char *buf, size_t buf_len)
+{
+	if (!hapd->driver->driver_cmd)
+		return -1;
+	return hapd->driver->driver_cmd(hapd->drv_priv, cmd, buf, buf_len);
+}
+#endif /* ANDROID */
+
+#ifdef CONFIG_TESTING_OPTIONS
+static inline int
+hostapd_drv_register_frame(struct hostapd_data *hapd, u16 type,
+			   const u8 *match, size_t match_len,
+			   bool multicast)
+{
+	if (!hapd->driver || !hapd->drv_priv || !hapd->driver->register_frame)
+		return -1;
+	return hapd->driver->register_frame(hapd->drv_priv, type, match,
+					    match_len, multicast);
+}
+#endif /* CONFIG_TESTING_OPTIONS */
+
+
+static inline int
+hostapd_drv_add_pmkid(struct hostapd_data *hapd, struct wpa_pmkid_params *params)
+{
+	if (!hapd->driver || !hapd->drv_priv || !hapd->driver->add_pmkid)
+		return -1;
+	return hapd->driver->add_pmkid(hapd->drv_priv, params);
+}
+
+
+static inline int
+hostapd_drv_remove_pmkid(struct hostapd_data *hapd, struct wpa_pmkid_params *params)
+{
+	if (!hapd->driver || !hapd->drv_priv || !hapd->driver->remove_pmkid)
+		return -1;
+	return hapd->driver->remove_pmkid(hapd->drv_priv, params);
+}
 #endif /* AP_DRV_OPS */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/beacon.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/beacon.c
index e773615..9e36a47 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/beacon.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/beacon.c
@@ -266,7 +266,7 @@
 }
 
 
-static const u8 * hostapd_wpa_ie(struct hostapd_data *hapd, u8 eid)
+const u8 * hostapd_wpa_ie(struct hostapd_data *hapd, u8 eid)
 {
 	const u8 *ies;
 	size_t ies_len;
@@ -458,7 +458,7 @@
 	}
 
 #ifdef CONFIG_IEEE80211AX
-	if (hapd->iconf->ieee80211ax) {
+	if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
 		buflen += 3 + sizeof(struct ieee80211_he_capabilities) +
 			3 + sizeof(struct ieee80211_he_operation) +
 			3 + sizeof(struct ieee80211_he_mu_edca_parameter_set) +
@@ -469,6 +469,7 @@
 	}
 #endif /* CONFIG_IEEE80211AX */
 
+	buflen += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_PROBE_RESP);
 	buflen += hostapd_mbo_ie_len(hapd);
 	buflen += hostapd_eid_owe_trans_len(hapd);
 	buflen += hostapd_eid_dpp_cc_len(hapd);
@@ -563,15 +564,20 @@
 	}
 #endif /* CONFIG_IEEE80211AC */
 
-	if ((hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) ||
-	    hapd->iconf->ieee80211ax)
-		pos = hostapd_eid_wb_chsw_wrapper(hapd, pos);
+#ifdef CONFIG_IEEE80211AX
+	if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax &&
+	    is_6ghz_op_class(hapd->iconf->op_class))
+		pos = hostapd_eid_txpower_envelope(hapd, pos);
+#endif /* CONFIG_IEEE80211AX */
 
+	pos = hostapd_eid_wb_chsw_wrapper(hapd, pos);
+
+	pos = hostapd_eid_rnr(hapd, pos, WLAN_FC_STYPE_PROBE_RESP);
 	pos = hostapd_eid_fils_indic(hapd, pos, 0);
 	pos = hostapd_get_rsnxe(hapd, pos, epos - pos);
 
 #ifdef CONFIG_IEEE80211AX
-	if (hapd->iconf->ieee80211ax) {
+	if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
 		pos = hostapd_eid_he_capab(hapd, pos, IEEE80211_MODE_AP);
 		pos = hostapd_eid_he_operation(hapd, pos);
 		pos = hostapd_eid_spatial_reuse(hapd, pos);
@@ -636,7 +642,8 @@
 enum ssid_match_result {
 	NO_SSID_MATCH,
 	EXACT_SSID_MATCH,
-	WILDCARD_SSID_MATCH
+	WILDCARD_SSID_MATCH,
+	CO_LOCATED_SSID_MATCH,
 };
 
 static enum ssid_match_result ssid_match(struct hostapd_data *hapd,
@@ -647,7 +654,9 @@
 					 size_t short_ssid_list_len)
 {
 	const u8 *pos, *end;
+	struct hostapd_iface *iface = hapd->iface;
 	int wildcard = 0;
+	size_t i, j;
 
 	if (ssid_len == 0)
 		wildcard = 1;
@@ -681,7 +690,33 @@
 		}
 	}
 
-	return wildcard ? WILDCARD_SSID_MATCH : NO_SSID_MATCH;
+	if (wildcard)
+		return WILDCARD_SSID_MATCH;
+
+	if (!iface->interfaces || iface->interfaces->count <= 1 ||
+	    is_6ghz_op_class(hapd->iconf->op_class))
+		return NO_SSID_MATCH;
+
+	for (i = 0; i < iface->interfaces->count; i++) {
+		struct hostapd_iface *colocated;
+
+		colocated = iface->interfaces->iface[i];
+
+		if (colocated == iface ||
+		    !is_6ghz_op_class(colocated->conf->op_class))
+			continue;
+
+		for (j = 0; j < colocated->num_bss; j++) {
+			struct hostapd_bss_config *conf;
+
+			conf = colocated->bss[j]->conf;
+			if (ssid_len == conf->ssid.ssid_len &&
+			    os_memcmp(ssid, conf->ssid.ssid, ssid_len) == 0)
+				return CO_LOCATED_SSID_MATCH;
+		}
+	}
+
+	return NO_SSID_MATCH;
 }
 
 
@@ -818,6 +853,10 @@
 	size_t csa_offs_len;
 	struct radius_sta rad_info;
 
+	if (hapd->iconf->rssi_ignore_probe_request && ssi_signal &&
+	    ssi_signal < hapd->iconf->rssi_ignore_probe_request)
+		return;
+
 	if (len < IEEE80211_HDRLEN)
 		return;
 	ie = ((const u8 *) mgmt) + IEEE80211_HDRLEN;
@@ -1114,6 +1153,23 @@
 #endif /* NEED_AP_MLME */
 
 
+#ifdef CONFIG_IEEE80211AX
+/* Unsolicited broadcast Probe Response transmission, 6 GHz only */
+static u8 * hostapd_unsol_bcast_probe_resp(struct hostapd_data *hapd,
+					   struct wpa_driver_ap_params *params)
+{
+	if (!is_6ghz_op_class(hapd->iconf->op_class))
+		return NULL;
+
+	params->unsol_bcast_probe_resp_interval =
+		hapd->conf->unsol_bcast_probe_resp_interval;
+
+	return hostapd_gen_probe_resp(hapd, NULL, 0,
+				      &params->unsol_bcast_probe_resp_tmpl_len);
+}
+#endif /* CONFIG_IEEE80211AX */
+
+
 void sta_track_del(struct hostapd_sta_info *info)
 {
 #ifdef CONFIG_TAXONOMY
@@ -1124,6 +1180,247 @@
 }
 
 
+#ifdef CONFIG_FILS
+
+static u16 hostapd_fils_discovery_cap(struct hostapd_data *hapd)
+{
+	u16 cap_info, phy_index = 0;
+	u8 chwidth = FD_CAP_BSS_CHWIDTH_20, mcs_nss_size = 4;
+	struct hostapd_hw_modes *mode = hapd->iface->current_mode;
+
+	cap_info = FD_CAP_ESS;
+	if (hapd->conf->wpa)
+		cap_info |= FD_CAP_PRIVACY;
+
+	if (is_6ghz_op_class(hapd->iconf->op_class)) {
+		phy_index = FD_CAP_PHY_INDEX_HE;
+
+		switch (hapd->iconf->op_class) {
+		case 135:
+			mcs_nss_size += 4;
+			/* fallthrough */
+		case 134:
+			mcs_nss_size += 4;
+			chwidth = FD_CAP_BSS_CHWIDTH_160_80_80;
+			break;
+		case 133:
+			chwidth = FD_CAP_BSS_CHWIDTH_80;
+			break;
+		case 132:
+			chwidth = FD_CAP_BSS_CHWIDTH_40;
+			break;
+		}
+	} else {
+		switch (hostapd_get_oper_chwidth(hapd->iconf)) {
+		case CHANWIDTH_80P80MHZ:
+			mcs_nss_size += 4;
+			/* fallthrough */
+		case CHANWIDTH_160MHZ:
+			mcs_nss_size += 4;
+			chwidth = FD_CAP_BSS_CHWIDTH_160_80_80;
+			break;
+		case CHANWIDTH_80MHZ:
+			chwidth = FD_CAP_BSS_CHWIDTH_80;
+			break;
+		case CHANWIDTH_USE_HT:
+			if (hapd->iconf->secondary_channel)
+				chwidth = FD_CAP_BSS_CHWIDTH_40;
+			else
+				chwidth = FD_CAP_BSS_CHWIDTH_20;
+			break;
+		}
+
+#ifdef CONFIG_IEEE80211AX
+		if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax)
+			phy_index = FD_CAP_PHY_INDEX_HE;
+#endif /* CONFIG_IEEE80211AX */
+#ifdef CONFIG_IEEE80211AC
+		if (!phy_index &&
+		    hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac)
+			phy_index = FD_CAP_PHY_INDEX_VHT;
+#endif /* CONFIG_IEEE80211AC */
+		if (!phy_index &&
+		    hapd->iconf->ieee80211n && !hapd->conf->disable_11n)
+			phy_index = FD_CAP_PHY_INDEX_HT;
+	}
+
+	cap_info |= phy_index << FD_CAP_PHY_INDEX_SHIFT;
+	cap_info |= chwidth << FD_CAP_BSS_CHWIDTH_SHIFT;
+
+	if (mode) {
+		u16 *mcs = (u16 *) mode->he_capab[IEEE80211_MODE_AP].mcs;
+		int i;
+		u16 nss = 0;
+
+		for (i = 0; i < HE_NSS_MAX_STREAMS; i++) {
+			u16 nss_mask = 0x3 << (i * 2);
+
+			if (mcs_nss_size == 4 &&
+			    (((mcs[0] & nss_mask) == nss_mask) ||
+			     ((mcs[1] & nss_mask) == nss_mask)))
+				continue;
+
+			if (mcs_nss_size == 8 &&
+			    (((mcs[2] & nss_mask) == nss_mask) ||
+			     ((mcs[3] & nss_mask) == nss_mask)))
+				continue;
+
+			if (mcs_nss_size == 12 &&
+			    (((mcs[4] & nss_mask) == nss_mask) ||
+			     ((mcs[5] & nss_mask) == nss_mask)))
+				continue;
+
+			nss++;
+		}
+
+		if (nss > 4)
+			cap_info |= FD_CAP_NSS_5_8 << FD_CAP_NSS_SHIFT;
+		else if (nss)
+			cap_info |= (nss - 1) << FD_CAP_NSS_SHIFT;
+	}
+
+	return cap_info;
+}
+
+
+static u8 * hostapd_gen_fils_discovery(struct hostapd_data *hapd, size_t *len)
+{
+	struct ieee80211_mgmt *head;
+	const u8 *mobility_domain;
+	u8 *pos, *length_pos, buf[200];
+	u16 ctl = 0;
+	u8 fd_rsn_info[5];
+	size_t total_len, buf_len;
+
+	total_len = 24 + 2 + 12;
+
+	/* FILS Discovery Frame Control */
+	ctl = (sizeof(hapd->conf->ssid.short_ssid) - 1) |
+		FD_FRAME_CTL_SHORT_SSID_PRESENT |
+		FD_FRAME_CTL_LENGTH_PRESENT |
+		FD_FRAME_CTL_CAP_PRESENT;
+	total_len += 4 + 1 + 2;
+
+	/* Check for optional subfields and calculate length */
+	if (wpa_auth_write_fd_rsn_info(hapd->wpa_auth, fd_rsn_info)) {
+		ctl |= FD_FRAME_CTL_RSN_INFO_PRESENT;
+		total_len += sizeof(fd_rsn_info);
+	}
+
+	mobility_domain = hostapd_wpa_ie(hapd, WLAN_EID_MOBILITY_DOMAIN);
+	if (mobility_domain) {
+		ctl |= FD_FRAME_CTL_MD_PRESENT;
+		total_len += 3;
+	}
+
+	total_len += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_ACTION);
+
+	pos = hostapd_eid_fils_indic(hapd, buf, 0);
+	buf_len = pos - buf;
+	total_len += buf_len;
+
+	head = os_zalloc(total_len);
+	if (!head)
+		return NULL;
+
+	head->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
+					   WLAN_FC_STYPE_ACTION);
+	os_memset(head->da, 0xff, ETH_ALEN);
+	os_memcpy(head->sa, hapd->own_addr, ETH_ALEN);
+	os_memcpy(head->bssid, hapd->own_addr, ETH_ALEN);
+
+	head->u.action.category = WLAN_ACTION_PUBLIC;
+	head->u.action.u.public_action.action = WLAN_PA_FILS_DISCOVERY;
+
+	pos = &head->u.action.u.public_action.variable[0];
+
+	/* FILS Discovery Information field */
+
+	/* FILS Discovery Frame Control */
+	WPA_PUT_LE16(pos, ctl);
+	pos += 2;
+
+	/* Hardware or low-level driver will fill in the Timestamp value */
+	pos += 8;
+
+	/* Beacon Interval */
+	WPA_PUT_LE16(pos, hapd->iconf->beacon_int);
+	pos += 2;
+
+	/* Short SSID */
+	WPA_PUT_LE32(pos, hapd->conf->ssid.short_ssid);
+	pos += sizeof(hapd->conf->ssid.short_ssid);
+
+	/* Store position of FILS discovery information element Length field */
+	length_pos = pos++;
+
+	/* FD Capability */
+	WPA_PUT_LE16(pos, hostapd_fils_discovery_cap(hapd));
+	pos += 2;
+
+	/* Operating Class - not present */
+
+	/* Primary Channel - not present */
+
+	/* AP Configuration Sequence Number - not present */
+
+	/* Access Network Options - not present */
+
+	/* FD RSN Information */
+	if (ctl & FD_FRAME_CTL_RSN_INFO_PRESENT) {
+		os_memcpy(pos, fd_rsn_info, sizeof(fd_rsn_info));
+		pos += sizeof(fd_rsn_info);
+	}
+
+	/* Channel Center Frequency Segment 1 - not present */
+
+	/* Mobility Domain */
+	if (ctl & FD_FRAME_CTL_MD_PRESENT) {
+		os_memcpy(pos, &mobility_domain[2], 3);
+		pos += 3;
+	}
+
+	/* Fill in the Length field value */
+	*length_pos = pos - (length_pos + 1);
+
+	pos = hostapd_eid_rnr(hapd, pos, WLAN_FC_STYPE_ACTION);
+
+	/* FILS Indication element */
+	if (buf_len) {
+		os_memcpy(pos, buf, buf_len);
+		pos += buf_len;
+	}
+
+	*len = pos - (u8 *) head;
+	wpa_hexdump(MSG_DEBUG, "FILS Discovery frame template",
+		    head, pos - (u8 *) head);
+	return (u8 *) head;
+}
+
+
+/* Configure FILS Discovery frame transmission parameters */
+static u8 * hostapd_fils_discovery(struct hostapd_data *hapd,
+				   struct wpa_driver_ap_params *params)
+{
+	params->fd_max_int = hapd->conf->fils_discovery_max_int;
+	if (is_6ghz_op_class(hapd->iconf->op_class) &&
+	    params->fd_max_int > FD_MAX_INTERVAL_6GHZ)
+		params->fd_max_int = FD_MAX_INTERVAL_6GHZ;
+
+	params->fd_min_int = hapd->conf->fils_discovery_min_int;
+	if (params->fd_min_int > params->fd_max_int)
+		params->fd_min_int = params->fd_max_int;
+
+	if (params->fd_max_int)
+		return hostapd_gen_fils_discovery(hapd,
+						  &params->fd_frame_tmpl_len);
+
+	return NULL;
+}
+
+#endif /* CONFIG_FILS */
+
+
 int ieee802_11_build_ap_params(struct hostapd_data *hapd,
 			       struct wpa_driver_ap_params *params)
 {
@@ -1163,7 +1460,7 @@
 #endif /* CONFIG_IEEE80211AC */
 
 #ifdef CONFIG_IEEE80211AX
-	if (hapd->iconf->ieee80211ax) {
+	if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
 		tail_len += 3 + sizeof(struct ieee80211_he_capabilities) +
 			3 + sizeof(struct ieee80211_he_operation) +
 			3 + sizeof(struct ieee80211_he_mu_edca_parameter_set) +
@@ -1174,6 +1471,7 @@
 	}
 #endif /* CONFIG_IEEE80211AX */
 
+	tail_len += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_BEACON);
 	tail_len += hostapd_mbo_ie_len(hapd);
 	tail_len += hostapd_eid_owe_trans_len(hapd);
 	tail_len += hostapd_eid_dpp_cc_len(hapd);
@@ -1280,22 +1578,28 @@
 #endif /* CONFIG_FST */
 
 #ifdef CONFIG_IEEE80211AC
-	if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) {
+	if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac &&
+	    !is_6ghz_op_class(hapd->iconf->op_class)) {
 		tailpos = hostapd_eid_vht_capabilities(hapd, tailpos, 0);
 		tailpos = hostapd_eid_vht_operation(hapd, tailpos);
 		tailpos = hostapd_eid_txpower_envelope(hapd, tailpos);
 	}
 #endif /* CONFIG_IEEE80211AC */
 
-	if ((hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) ||
-	     hapd->iconf->ieee80211ax)
-		tailpos = hostapd_eid_wb_chsw_wrapper(hapd, tailpos);
+#ifdef CONFIG_IEEE80211AX
+	if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax &&
+	    is_6ghz_op_class(hapd->iconf->op_class))
+		tailpos = hostapd_eid_txpower_envelope(hapd, tailpos);
+#endif /* CONFIG_IEEE80211AX */
 
+	tailpos = hostapd_eid_wb_chsw_wrapper(hapd, tailpos);
+
+	tailpos = hostapd_eid_rnr(hapd, tailpos, WLAN_FC_STYPE_BEACON);
 	tailpos = hostapd_eid_fils_indic(hapd, tailpos, 0);
 	tailpos = hostapd_get_rsnxe(hapd, tailpos, tailend - tailpos);
 
 #ifdef CONFIG_IEEE80211AX
-	if (hapd->iconf->ieee80211ax) {
+	if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
 		tailpos = hostapd_eid_he_capab(hapd, tailpos,
 					       IEEE80211_MODE_AP);
 		tailpos = hostapd_eid_he_operation(hapd, tailpos);
@@ -1460,29 +1764,6 @@
 		}
 	}
 
-	/* Support for 4-way handshake offload to internal supplicant
-	 * for WPA/WPA2-PSK
-	 */
-	if ((hapd->iface->drv_flags2 &
-	     WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK) &&
-	    (params->key_mgmt_suites &
-	     (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_PSK_SHA256))) {
-		if (hapd->conf->ssid.wpa_passphrase)
-			params->passphrase = hapd->conf->ssid.wpa_passphrase;
-		if (hapd->conf->ssid.wpa_psk->psk[0] != '\0')
-			params->psk = hapd->conf->ssid.wpa_psk->psk;
-	}
-
-#ifdef CONFIG_SAE
-	if ((hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SAE_OFFLOAD_AP) &&
-	    (params->key_mgmt_suites & WPA_KEY_MGMT_SAE)) {
-		params->auth_algs |= WPA_AUTH_ALG_SAE;
-		if (hapd->conf->sae_passwords)
-			params->sae_password = hapd->conf->sae_passwords->password;
-		else if (hapd->conf->ssid.wpa_passphrase)
-			params->passphrase = hapd->conf->ssid.wpa_passphrase;
-	}
-#endif /* CONFIG_SAE */
 
 	return 0;
 }
@@ -1496,6 +1777,14 @@
 	params->head = NULL;
 	os_free(params->proberesp);
 	params->proberesp = NULL;
+#ifdef CONFIG_FILS
+	os_free(params->fd_frame_tmpl);
+	params->fd_frame_tmpl = NULL;
+#endif /* CONFIG_FILS */
+#ifdef CONFIG_IEEE80211AX
+	os_free(params->unsol_bcast_probe_resp_tmpl);
+	params->unsol_bcast_probe_resp_tmpl = NULL;
+#endif /* CONFIG_IEEE80211AX */
 }
 
 #if defined(CONFIG_SAE)
@@ -1532,7 +1821,7 @@
 }
 #endif /* CONFIG_SAE && CONFIG_DRIVER_NL80211_IFX */
 
-int ieee802_11_set_beacon(struct hostapd_data *hapd)
+static int __ieee802_11_set_beacon(struct hostapd_data *hapd)
 {
 	struct wpa_driver_ap_params params;
 	struct hostapd_freq_params freq;
@@ -1542,6 +1831,11 @@
 	struct wpabuf *beacon, *proberesp, *assocresp;
 	int res, ret = -1;
 
+	if (!hapd->drv_priv) {
+		wpa_printf(MSG_ERROR, "Interface is disabled");
+		return -1;
+	}
+
 	if (hapd->csa_in_progress) {
 		wpa_printf(MSG_ERROR, "Cannot set beacons during CSA period");
 		return -1;
@@ -1561,11 +1855,17 @@
 	params.assocresp_ies = assocresp;
 	params.reenable = hapd->reenable_beacon;
 #ifdef CONFIG_IEEE80211AX
-	params.he_spr = !!hapd->iface->conf->spr.sr_control;
+	params.he_spr_ctrl = hapd->iface->conf->spr.sr_control;
+	params.he_spr_non_srg_obss_pd_max_offset =
+		hapd->iface->conf->spr.non_srg_obss_pd_max_offset;
 	params.he_spr_srg_obss_pd_min_offset =
 		hapd->iface->conf->spr.srg_obss_pd_min_offset;
 	params.he_spr_srg_obss_pd_max_offset =
 		hapd->iface->conf->spr.srg_obss_pd_max_offset;
+	os_memcpy(params.he_spr_bss_color_bitmap,
+		  hapd->iface->conf->spr.srg_bss_color_bitmap, 8);
+	os_memcpy(params.he_spr_partial_bssid_bitmap,
+		  hapd->iface->conf->spr.srg_partial_bssid_bitmap, 8);
 	params.he_bss_color_disabled =
 		hapd->iface->conf->he_op.he_bss_color_disabled;
 	params.he_bss_color_partial =
@@ -1573,6 +1873,8 @@
 	params.he_bss_color = hapd->iface->conf->he_op.he_bss_color;
 	params.twt_responder = hostapd_get_he_twt_responder(hapd,
 							    IEEE80211_MODE_AP);
+	params.unsol_bcast_probe_resp_tmpl =
+		hostapd_unsol_bcast_probe_resp(hapd, &params);
 #endif /* CONFIG_IEEE80211AX */
 	hapd->reenable_beacon = 0;
 #ifdef CONFIG_SAE
@@ -1581,6 +1883,10 @@
 		ifx_private_set_sae_pwe(hapd, params.sae_pwe);
 #endif /* CONFIG_SAE */
 
+#ifdef CONFIG_FILS
+	params.fd_frame_tmpl = hostapd_fils_discovery(hapd, &params);
+#endif /* CONFIG_FILS */
+
 	if (cmode &&
 	    hostapd_set_freq_params(&freq, iconf->hw_mode, iface->freq,
 				    iconf->channel, iconf->enable_edmg,
@@ -1606,6 +1912,42 @@
 }
 
 
+int ieee802_11_set_beacon(struct hostapd_data *hapd)
+{
+	struct hostapd_iface *iface = hapd->iface;
+	int ret;
+	size_t i, j;
+	bool is_6g;
+
+	ret = __ieee802_11_set_beacon(hapd);
+	if (ret != 0)
+		return ret;
+
+	if (!iface->interfaces || iface->interfaces->count <= 1)
+		return 0;
+
+	/* Update Beacon frames in case of 6 GHz colocation */
+	is_6g = is_6ghz_op_class(iface->conf->op_class);
+	for (j = 0; j < iface->interfaces->count; j++) {
+		struct hostapd_iface *colocated;
+
+		colocated = iface->interfaces->iface[j];
+		if (colocated == iface || !colocated || !colocated->conf)
+			continue;
+
+		if (is_6g == is_6ghz_op_class(colocated->conf->op_class))
+			continue;
+
+		for (i = 0; i < colocated->num_bss; i++) {
+			if (colocated->bss[i] && colocated->bss[i]->started)
+				__ieee802_11_set_beacon(colocated->bss[i]);
+		}
+	}
+
+	return 0;
+}
+
+
 int ieee802_11_set_beacons(struct hostapd_iface *iface)
 {
 	size_t i;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/beacon.h b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/beacon.h
index a26e308..c320825 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/beacon.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/beacon.h
@@ -30,4 +30,6 @@
 void sta_track_claim_taxonomy_info(struct hostapd_iface *iface, const u8 *addr,
 				   struct wpabuf **probe_ie_taxonomy);
 
+const u8 * hostapd_wpa_ie(struct hostapd_data *hapd, u8 eid);
+
 #endif /* BEACON_H */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ctrl_iface_ap.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ctrl_iface_ap.c
index ef53a82..1d8fb82 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ctrl_iface_ap.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ctrl_iface_ap.c
@@ -50,9 +50,35 @@
 }
 
 
-static int hostapd_get_sta_tx_rx(struct hostapd_data *hapd,
-				 struct sta_info *sta,
-				 char *buf, size_t buflen)
+static int hostapd_get_sta_conn_time(struct sta_info *sta,
+				     struct hostap_sta_driver_data *data,
+				     char *buf, size_t buflen)
+{
+	struct os_reltime age;
+	unsigned long secs;
+	int ret;
+
+	if (sta->connected_time.sec) {
+		/* Locally maintained time in AP mode */
+		os_reltime_age(&sta->connected_time, &age);
+		secs = (unsigned long) age.sec;
+	} else if (data->flags & STA_DRV_DATA_CONN_TIME) {
+		/* Time from the driver in mesh mode */
+		secs = data->connected_sec;
+	} else {
+		return 0;
+	}
+
+	ret = os_snprintf(buf, buflen, "connected_time=%lu\n", secs);
+	if (os_snprintf_error(buflen, ret))
+		return 0;
+	return ret;
+}
+
+
+static int hostapd_get_sta_info(struct hostapd_data *hapd,
+				struct sta_info *sta,
+				char *buf, size_t buflen)
 {
 	struct hostap_sta_driver_data data;
 	int ret;
@@ -160,29 +186,12 @@
 			len += ret;
 	}
 
+	len += hostapd_get_sta_conn_time(sta, &data, buf + len, buflen - len);
+
 	return len;
 }
 
 
-static int hostapd_get_sta_conn_time(struct sta_info *sta,
-				     char *buf, size_t buflen)
-{
-	struct os_reltime age;
-	int ret;
-
-	if (!sta->connected_time.sec)
-		return 0;
-
-	os_reltime_age(&sta->connected_time, &age);
-
-	ret = os_snprintf(buf, buflen, "connected_time=%u\n",
-			  (unsigned int) age.sec);
-	if (os_snprintf_error(buflen, ret))
-		return 0;
-	return ret;
-}
-
-
 static const char * timeout_next_str(int val)
 {
 	switch (val) {
@@ -263,8 +272,7 @@
 	if (res >= 0)
 		len += res;
 
-	len += hostapd_get_sta_tx_rx(hapd, sta, buf + len, buflen - len);
-	len += hostapd_get_sta_conn_time(sta, buf + len, buflen - len);
+	len += hostapd_get_sta_info(hapd, sta, buf + len, buflen - len);
 
 #ifdef CONFIG_SAE
 	if (sta->sae && sta->sae->state == SAE_ACCEPTED) {
@@ -748,7 +756,8 @@
 			  iface->conf->ieee80211n && !hapd->conf->disable_11n,
 			  iface->conf->ieee80211ac &&
 			  !hapd->conf->disable_11ac,
-			  iface->conf->ieee80211ax,
+			  iface->conf->ieee80211ax &&
+			  !hapd->conf->disable_11ax,
 			  iface->conf->beacon_int,
 			  hapd->conf->dtim_period);
 	if (os_snprintf_error(buflen - len, ret))
@@ -756,7 +765,7 @@
 	len += ret;
 
 #ifdef CONFIG_IEEE80211AX
-	if (iface->conf->ieee80211ax) {
+	if (iface->conf->ieee80211ax && !hapd->conf->disable_11ax) {
 		ret = os_snprintf(buf + len, buflen - len,
 				  "he_oper_chwidth=%d\n"
 				  "he_oper_centr_freq_seg0_idx=%d\n"
@@ -908,6 +917,7 @@
 	SET_CSA_SETTING(sec_channel_offset);
 	settings->freq_params.ht_enabled = !!os_strstr(pos, " ht");
 	settings->freq_params.vht_enabled = !!os_strstr(pos, " vht");
+	settings->freq_params.he_enabled = !!os_strstr(pos, " he");
 	settings->block_tx = !!os_strstr(pos, " blocktx");
 #undef SET_CSA_SETTING
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/dfs.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/dfs.c
index f04a00a..5c99ecf 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/dfs.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/dfs.c
@@ -81,17 +81,17 @@
 	 * We will also choose this first channel as the control one.
 	 */
 	int allowed_40[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157,
-			     184, 192 };
+			     165, 173, 184, 192 };
 	/*
 	 * VHT80, valid channels based on center frequency:
-	 * 42, 58, 106, 122, 138, 155
+	 * 42, 58, 106, 122, 138, 155, 171
 	 */
-	int allowed_80[] = { 36, 52, 100, 116, 132, 149 };
+	int allowed_80[] = { 36, 52, 100, 116, 132, 149, 165 };
 	/*
 	 * VHT160 valid channels based on center frequency:
-	 * 50, 114
+	 * 50, 114, 163
 	 */
-	int allowed_160[] = { 36, 100 };
+	int allowed_160[] = { 36, 100, 149 };
 	int *allowed = allowed_40;
 	unsigned int i, allowed_no = 0;
 
@@ -246,6 +246,9 @@
 			continue;
 		}
 
+		if (chan->max_tx_power < iface->conf->min_tx_power)
+			continue;
+
 		if (ret_chan && idx == channel_idx) {
 			wpa_printf(MSG_DEBUG, "Selected channel %d (%d)",
 				   chan->freq, chan->chan);
@@ -1032,6 +1035,7 @@
 	int err = 1;
 	struct hostapd_hw_modes *cmode = iface->current_mode;
 	u8 current_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
+	int ieee80211_mode = IEEE80211_MODE_AP;
 
 	wpa_printf(MSG_DEBUG, "%s called (CAC active: %s, CSA active: %s)",
 		   __func__, iface->cac_started ? "yes" : "no",
@@ -1069,8 +1073,16 @@
 						  &oper_centr_freq_seg0_idx,
 						  &oper_centr_freq_seg1_idx,
 						  &skip_radar);
-		if (!channel)
-			return err;
+		if (!channel) {
+			/*
+			 * Toggle interface state to enter DFS state
+			 * until NOP is finished.
+			 */
+			hostapd_disable_iface(iface);
+			hostapd_enable_iface(iface);
+			return 0;
+		}
+
 		if (!skip_radar) {
 			iface->freq = channel->freq;
 			iface->conf->channel = channel->chan;
@@ -1099,6 +1111,10 @@
 	os_memset(&csa_settings, 0, sizeof(csa_settings));
 	csa_settings.cs_count = 5;
 	csa_settings.block_tx = 1;
+#ifdef CONFIG_MESH
+	if (iface->mconf)
+		ieee80211_mode = IEEE80211_MODE_MESH;
+#endif /* CONFIG_MESH */
 	err = hostapd_set_freq_params(&csa_settings.freq_params,
 				      iface->conf->hw_mode,
 				      channel->freq,
@@ -1113,7 +1129,7 @@
 				      oper_centr_freq_seg0_idx,
 				      oper_centr_freq_seg1_idx,
 				      cmode->vht_capab,
-				      &cmode->he_capab[IEEE80211_MODE_AP]);
+				      &cmode->he_capab[ieee80211_mode]);
 
 	if (err) {
 		wpa_printf(MSG_ERROR, "DFS failed to calculate CSA freq params");
@@ -1215,7 +1231,9 @@
 {
 	int n_chans, n_chans1, start_chan_idx, start_chan_idx1, res;
 
-	if (!iface->conf->ieee80211h || !iface->current_mode ||
+	if ((!(iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) &&
+	     !iface->conf->ieee80211h) ||
+	    !iface->current_mode ||
 	    iface->current_mode->mode != HOSTAPD_MODE_IEEE80211A)
 		return 0;
 
@@ -1266,6 +1284,8 @@
  */
 int hostapd_handle_dfs_offload(struct hostapd_iface *iface)
 {
+	int dfs_res;
+
 	wpa_printf(MSG_DEBUG, "%s: iface->cac_started: %d",
 		   __func__, iface->cac_started);
 
@@ -1281,10 +1301,11 @@
 		return 1;
 	}
 
-	if (ieee80211_is_dfs(iface->freq, iface->hw_features,
-			     iface->num_hw_features)) {
-		wpa_printf(MSG_DEBUG, "%s: freq %d MHz requires DFS",
-			   __func__, iface->freq);
+	dfs_res = hostapd_is_dfs_required(iface);
+	if (dfs_res > 0) {
+		wpa_printf(MSG_DEBUG,
+			   "%s: freq %d MHz requires DFS for %d chans",
+			   __func__, iface->freq, dfs_res);
 		return 0;
 	}
 
@@ -1335,12 +1356,16 @@
 		if (!(chan->flag & HOSTAPD_CHAN_RADAR))
 			continue;
 
+		if ((chan->flag & HOSTAPD_CHAN_DFS_MASK) ==
+		    HOSTAPD_CHAN_DFS_AVAILABLE)
+			continue;
+
 		if (center_freq - chan->freq < half_width &&
 		    chan->freq - center_freq < half_width)
 			res++;
 	}
 
-	wpa_printf(MSG_DEBUG, "DFS: (%d, %d): in range: %s",
+	wpa_printf(MSG_DEBUG, "DFS CAC required: (%d, %d): in range: %s",
 		   center_freq - half_width, center_freq + half_width,
 		   res ? "yes" : "no");
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/dhcp_snoop.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/dhcp_snoop.c
index edc77da..551936b 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/dhcp_snoop.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/dhcp_snoop.c
@@ -88,6 +88,7 @@
 		}
 	}
 
+#ifdef CONFIG_HS20
 	if (hapd->conf->disable_dgaf && is_broadcast_ether_addr(buf)) {
 		for (sta = hapd->sta_list; sta; sta = sta->next) {
 			if (!(sta->flags & WLAN_STA_AUTHORIZED))
@@ -96,6 +97,7 @@
 							    (u8 *) buf, len);
 		}
 	}
+#endif /* CONFIG_HS20 */
 
 	if (msgtype == DHCPACK) {
 		if (b->your_ip == 0)
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/dpp_hostapd.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/dpp_hostapd.c
index 6772a87..13e1fc5 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/dpp_hostapd.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/dpp_hostapd.c
@@ -23,6 +23,8 @@
 
 
 static void hostapd_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx);
+static void hostapd_dpp_auth_conf_wait_timeout(void *eloop_ctx,
+					       void *timeout_ctx);
 static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator);
 static void hostapd_dpp_init_timeout(void *eloop_ctx, void *timeout_ctx);
 static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd);
@@ -246,6 +248,8 @@
 		eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
 		eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
 				     hapd, NULL);
+		eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout,
+				     hapd, NULL);
 		eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
 				     NULL);
 #ifdef CONFIG_DPP2
@@ -277,6 +281,17 @@
 		}
 	}
 
+	if (auth->waiting_auth_conf &&
+	    auth->auth_resp_status == DPP_STATUS_OK) {
+		/* Make sure we do not get stuck waiting for Auth Confirm
+		 * indefinitely after successfully transmitted Auth Response to
+		 * allow new authentication exchanges to be started. */
+		eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd,
+				     NULL);
+		eloop_register_timeout(1, 0, hostapd_dpp_auth_conf_wait_timeout,
+				       hapd, NULL);
+	}
+
 	if (!is_broadcast_ether_addr(dst) && auth->waiting_auth_resp && ok) {
 		/* Allow timeout handling to stop iteration if no response is
 		 * received from a peer that has ACKed a request. */
@@ -377,6 +392,25 @@
 }
 
 
+static void hostapd_dpp_auth_conf_wait_timeout(void *eloop_ctx,
+					       void *timeout_ctx)
+{
+	struct hostapd_data *hapd = eloop_ctx;
+	struct dpp_authentication *auth = hapd->dpp_auth;
+
+	if (!auth || !auth->waiting_auth_conf)
+		return;
+
+	wpa_printf(MSG_DEBUG,
+		   "DPP: Terminate authentication exchange due to Auth Confirm timeout");
+	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_FAIL
+		"No Auth Confirm received");
+	hostapd_drv_send_action_cancel_wait(hapd);
+	dpp_auth_deinit(auth);
+	hapd->dpp_auth = NULL;
+}
+
+
 static void hostapd_dpp_set_testing_options(struct hostapd_data *hapd,
 					    struct dpp_authentication *auth)
 {
@@ -461,7 +495,9 @@
 	freq = auth->freq[auth->freq_idx++];
 	auth->curr_freq = freq;
 
-	if (is_zero_ether_addr(auth->peer_bi->mac_addr))
+	if (!is_zero_ether_addr(auth->peer_mac_addr))
+		dst = auth->peer_mac_addr;
+	else if (is_zero_ether_addr(auth->peer_bi->mac_addr))
 		dst = broadcast;
 	else
 		dst = auth->peer_bi->mac_addr;
@@ -594,6 +630,8 @@
 		eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
 		eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout,
 				     hapd, NULL);
+		eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout,
+				     hapd, NULL);
 		eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd,
 				     NULL);
 #ifdef CONFIG_DPP2
@@ -661,12 +699,14 @@
 		return -1;
 	}
 
+	hostapd_drv_dpp_listen(hapd, true);
 	return 0;
 }
 
 
 void hostapd_dpp_listen_stop(struct hostapd_data *hapd)
 {
+	hostapd_drv_dpp_listen(hapd, false);
 	/* TODO: Stop listen operation on non-operating channel */
 }
 
@@ -717,7 +757,7 @@
 	if (!own_bi) {
 		if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
 					src, hdr, buf, len, freq, i_bootstrap,
-					r_bootstrap) == 0)
+					r_bootstrap, hapd) == 0)
 			return;
 	}
 #endif /* CONFIG_DPP2 */
@@ -875,7 +915,8 @@
 		wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
 		return;
 	}
-	if (!resp || status_code != WLAN_STATUS_SUCCESS) {
+	if (result != GAS_QUERY_AP_SUCCESS ||
+	    !resp || status_code != WLAN_STATUS_SUCCESS) {
 		wpa_printf(MSG_DEBUG, "DPP: GAS query did not succeed");
 		goto fail;
 	}
@@ -1149,6 +1190,7 @@
 		wpa_printf(MSG_DEBUG, "DPP: Wait for Connection Status Result");
 		eloop_cancel_timeout(hostapd_dpp_config_result_wait_timeout,
 				     hapd, NULL);
+		auth->waiting_conn_status_result = 1;
 		eloop_cancel_timeout(
 			hostapd_dpp_conn_status_result_wait_timeout,
 			hapd, NULL);
@@ -1234,7 +1276,7 @@
 	if (!peer_bi) {
 		if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
 					src, hdr, buf, len, freq, NULL,
-					r_bootstrap) == 0)
+					r_bootstrap, hapd) == 0)
 			return;
 		wpa_printf(MSG_DEBUG,
 			   "DPP: No matching bootstrapping information found");
@@ -1261,8 +1303,9 @@
 
 	auth->neg_freq = freq;
 
-	if (!is_zero_ether_addr(peer_bi->mac_addr))
-		os_memcpy(auth->peer_mac_addr, peer_bi->mac_addr, ETH_ALEN);
+	/* The source address of the Presence Announcement frame overrides any
+	 * MAC address information from the bootstrapping information. */
+	os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
 
 	hapd->dpp_auth = auth;
 	if (hostapd_dpp_auth_init_next(hapd) < 0) {
@@ -1323,7 +1366,7 @@
 	if (!conf) {
 		if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
 					src, hdr, buf, len, freq, NULL,
-					NULL) == 0)
+					NULL, hapd) == 0)
 			return;
 		wpa_printf(MSG_DEBUG,
 			   "DPP: No matching Configurator information found");
@@ -1511,17 +1554,38 @@
 
 #ifdef CONFIG_TESTING_OPTIONS
 skip_connector:
+	if (dpp_test == DPP_TEST_NO_PROTOCOL_VERSION_PEER_DISC_RESP) {
+		wpa_printf(MSG_INFO, "DPP: TESTING - no Protocol Version");
+		goto skip_proto_ver;
+	}
 #endif /* CONFIG_TESTING_OPTIONS */
 
 #ifdef CONFIG_DPP2
 	if (DPP_VERSION > 1) {
+		u8 ver = DPP_VERSION;
+#ifdef CONFIG_DPP3
+		int conn_ver;
+
+		conn_ver = dpp_get_connector_version(hapd->conf->dpp_connector);
+		if (conn_ver > 0 && ver != conn_ver) {
+			wpa_printf(MSG_DEBUG,
+				   "DPP: Use Connector version %d instead of current protocol version %d",
+				   conn_ver, ver);
+			ver = conn_ver;
+		}
+#endif /* CONFIG_DPP3 */
+
 		/* Protocol Version */
 		wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
 		wpabuf_put_le16(msg, 1);
-		wpabuf_put_u8(msg, DPP_VERSION);
+		wpabuf_put_u8(msg, ver);
 	}
 #endif /* CONFIG_DPP2 */
 
+#ifdef CONFIG_TESTING_OPTIONS
+skip_proto_ver:
+#endif /* CONFIG_TESTING_OPTIONS */
+
 	wpa_printf(MSG_DEBUG, "DPP: Send Peer Discovery Response to " MACSTR
 		   " status=%d", MAC2STR(src), status);
 	wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
@@ -1605,6 +1669,28 @@
 		return;
 	}
 
+#ifdef CONFIG_DPP3
+	if (intro.peer_version && intro.peer_version >= 2) {
+		const u8 *version;
+		u16 version_len;
+		u8 attr_version = 1;
+
+		version = dpp_get_attr(buf, len, DPP_ATTR_PROTOCOL_VERSION,
+				       &version_len);
+		if (version && version_len >= 1)
+			attr_version = version[0];
+		if (attr_version != intro.peer_version) {
+			wpa_printf(MSG_INFO,
+				   "DPP: Protocol version mismatch (Connector: %d Attribute: %d",
+				   intro.peer_version, attr_version);
+			hostapd_dpp_send_peer_disc_resp(hapd, src, freq,
+							trans_id[0],
+							DPP_STATUS_NO_MATCH);
+			return;
+		}
+	}
+#endif /* CONFIG_DPP3 */
+
 	if (!expire || (os_time_t) hapd->conf->dpp_netaccesskey_expiry < expire)
 		expire = hapd->conf->dpp_netaccesskey_expiry;
 	if (expire)
@@ -1627,7 +1713,7 @@
 static void
 hostapd_dpp_rx_pkex_exchange_req(struct hostapd_data *hapd, const u8 *src,
 				 const u8 *buf, size_t len,
-				 unsigned int freq)
+				 unsigned int freq, bool v2)
 {
 	struct wpabuf *msg;
 
@@ -1655,7 +1741,7 @@
 						  hapd->own_addr, src,
 						  hapd->dpp_pkex_identifier,
 						  hapd->dpp_pkex_code,
-						  buf, len);
+						  buf, len, v2);
 	if (!hapd->dpp_pkex) {
 		wpa_printf(MSG_DEBUG,
 			   "DPP: Failed to process the request - ignore it");
@@ -1849,7 +1935,8 @@
 
 #ifdef CONFIG_DPP2
 	if (dpp_relay_rx_action(hapd->iface->interfaces->dpp,
-				src, hdr, buf, len, freq, NULL, NULL) == 0)
+				src, hdr, buf, len, freq, NULL, NULL,
+				hapd) == 0)
 		return;
 #endif /* CONFIG_DPP2 */
 
@@ -1866,8 +1953,18 @@
 	case DPP_PA_PEER_DISCOVERY_REQ:
 		hostapd_dpp_rx_peer_disc_req(hapd, src, buf, len, freq);
 		break;
+#ifdef CONFIG_DPP3
 	case DPP_PA_PKEX_EXCHANGE_REQ:
-		hostapd_dpp_rx_pkex_exchange_req(hapd, src, buf, len, freq);
+		/* This is for PKEXv2, but for now, process only with
+		 * CONFIG_DPP3 to avoid issues with a capability that has not
+		 * been tested with other implementations. */
+		hostapd_dpp_rx_pkex_exchange_req(hapd, src, buf, len, freq,
+						 true);
+		break;
+#endif /* CONFIG_DPP3 */
+	case DPP_PA_PKEX_V1_EXCHANGE_REQ:
+		hostapd_dpp_rx_pkex_exchange_req(hapd, src, buf, len, freq,
+						 false);
 		break;
 	case DPP_PA_PKEX_EXCHANGE_RESP:
 		hostapd_dpp_rx_pkex_exchange_resp(hapd, src, buf, len, freq);
@@ -1940,6 +2037,19 @@
 		wpa_printf(MSG_DEBUG, "DPP: No matching exchange in progress");
 		return NULL;
 	}
+
+	if (hapd->dpp_auth_ok_on_ack && auth->configurator) {
+		wpa_printf(MSG_DEBUG,
+			   "DPP: Have not received ACK for Auth Confirm yet - assume it was received based on this GAS request");
+		/* hostapd_dpp_auth_success() would normally have been called
+		 * from TX status handler, but since there was no such handler
+		 * call yet, simply send out the event message and proceed with
+		 * exchange. */
+		wpa_msg(hapd->msg_ctx, MSG_INFO,
+			DPP_EVENT_AUTH_SUCCESS "init=1");
+		hapd->dpp_auth_ok_on_ack = 0;
+	}
+
 	wpa_hexdump(MSG_DEBUG,
 		    "DPP: Received Configuration Request (GAS Query Request)",
 		    query, query_len);
@@ -1962,6 +2072,7 @@
 	wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)",
 		   ok);
 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
+	eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd, NULL);
 	eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
 #ifdef CONFIG_DPP2
 		eloop_cancel_timeout(hostapd_dpp_reconfig_reply_wait_timeout,
@@ -2060,15 +2171,16 @@
 	if (!hapd->dpp_pkex_code)
 		return -1;
 
-	if (os_strstr(cmd, " init=1")) {
+	if (os_strstr(cmd, " init=1") || os_strstr(cmd, " init=2")) {
 		struct wpabuf *msg;
+		bool v2 = os_strstr(cmd, " init=2") != NULL;
 
 		wpa_printf(MSG_DEBUG, "DPP: Initiating PKEX");
 		dpp_pkex_free(hapd->dpp_pkex);
 		hapd->dpp_pkex = dpp_pkex_init(hapd->msg_ctx, own_bi,
 					       hapd->own_addr,
 					       hapd->dpp_pkex_identifier,
-					       hapd->dpp_pkex_code);
+					       hapd->dpp_pkex_code, v2);
 		if (!hapd->dpp_pkex)
 			return -1;
 
@@ -2076,7 +2188,8 @@
 		/* TODO: Which channel to use? */
 		wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
 			" freq=%u type=%d", MAC2STR(broadcast), 2437,
-			DPP_PA_PKEX_EXCHANGE_REQ);
+			v2 ? DPP_PA_PKEX_EXCHANGE_REQ :
+			DPP_PA_PKEX_V1_EXCHANGE_REQ);
 		hostapd_drv_send_action(hapd, 2437, 0, broadcast,
 					wpabuf_head(msg), wpabuf_len(msg));
 	}
@@ -2207,6 +2320,7 @@
 	if (!hapd->dpp_init_done)
 		return;
 	eloop_cancel_timeout(hostapd_dpp_reply_wait_timeout, hapd, NULL);
+	eloop_cancel_timeout(hostapd_dpp_auth_conf_wait_timeout, hapd, NULL);
 	eloop_cancel_timeout(hostapd_dpp_init_timeout, hapd, NULL);
 	eloop_cancel_timeout(hostapd_dpp_auth_resp_retry_timeout, hapd, NULL);
 #ifdef CONFIG_DPP2
@@ -2217,6 +2331,8 @@
 	eloop_cancel_timeout(hostapd_dpp_conn_status_result_wait_timeout, hapd,
 			     NULL);
 	hostapd_dpp_chirp_stop(hapd);
+	if (hapd->iface->interfaces)
+		dpp_controller_stop_for_ctx(hapd->iface->interfaces->dpp, hapd);
 #endif /* CONFIG_DPP2 */
 	dpp_auth_deinit(hapd->dpp_auth);
 	hapd->dpp_auth = NULL;
@@ -2328,6 +2444,7 @@
 	unsigned int i;
 	struct hostapd_hw_modes *mode;
 	int c;
+	bool chan6 = hapd->iface->hw_features == NULL;
 
 	if (!bi)
 		return;
@@ -2347,7 +2464,21 @@
 	}
 
 	/* Preferred chirping channels */
-	int_array_add_unique(&hapd->dpp_chirp_freqs, 2437);
+	mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211G);
+	if (mode) {
+		for (c = 0; c < mode->num_channels; c++) {
+			struct hostapd_channel_data *chan = &mode->channels[c];
+
+			if (chan->flag & (HOSTAPD_CHAN_DISABLED |
+					  HOSTAPD_CHAN_RADAR) ||
+			    chan->freq != 2437)
+				continue;
+			chan6 = true;
+			break;
+		}
+	}
+	if (chan6)
+		int_array_add_unique(&hapd->dpp_chirp_freqs, 2437);
 
 	mode = dpp_get_mode(hapd, HOSTAPD_MODE_IEEE80211A);
 	if (mode) {
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/drv_callbacks.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/drv_callbacks.c
index 5ead4e4..c295cf3 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/drv_callbacks.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/drv_callbacks.c
@@ -459,8 +459,8 @@
 		if (hapd->conf->sae_pwe == 2 &&
 		    sta->auth_alg == WLAN_AUTH_SAE &&
 		    sta->sae && !sta->sae->h2e &&
-		    elems.rsnxe && elems.rsnxe_len >= 1 &&
-		    (elems.rsnxe[0] & BIT(WLAN_RSNX_CAPAB_SAE_H2E))) {
+		    ieee802_11_rsnx_capab_len(elems.rsnxe, elems.rsnxe_len,
+					      WLAN_RSNX_CAPAB_SAE_H2E)) {
 			wpa_printf(MSG_INFO, "SAE: " MACSTR
 				   " indicates support for SAE H2E, but did not use it",
 				   MAC2STR(sta->addr));
@@ -870,9 +870,10 @@
 
 	hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
 		       HOSTAPD_LEVEL_INFO,
-		       "driver %s channel switch: freq=%d, ht=%d, vht_ch=0x%x, offset=%d, width=%d (%s), cf1=%d, cf2=%d",
+		       "driver %s channel switch: freq=%d, ht=%d, vht_ch=0x%x, he_ch=0x%x, offset=%d, width=%d (%s), cf1=%d, cf2=%d",
 		       finished ? "had" : "starting",
-		       freq, ht, hapd->iconf->ch_switch_vht_config, offset,
+		       freq, ht, hapd->iconf->ch_switch_vht_config,
+		       hapd->iconf->ch_switch_he_config, offset,
 		       width, channel_width_to_string(width), cf1, cf2);
 
 	if (!hapd->iface->current_mode) {
@@ -971,13 +972,37 @@
 		else if (hapd->iconf->ch_switch_vht_config &
 			 CH_SWITCH_VHT_DISABLED)
 			hapd->iconf->ieee80211ac = 0;
+	} else if (hapd->iconf->ch_switch_he_config) {
+		/* CHAN_SWITCH HE config */
+		if (hapd->iconf->ch_switch_he_config &
+		    CH_SWITCH_HE_ENABLED)
+			hapd->iconf->ieee80211ax = 1;
+		else if (hapd->iconf->ch_switch_he_config &
+			 CH_SWITCH_HE_DISABLED)
+			hapd->iconf->ieee80211ax = 0;
 	}
 	hapd->iconf->ch_switch_vht_config = 0;
+	hapd->iconf->ch_switch_he_config = 0;
+
+	if (width == CHAN_WIDTH_40 || width == CHAN_WIDTH_80 ||
+	    width == CHAN_WIDTH_80P80 || width == CHAN_WIDTH_160)
+		hapd->iconf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
+	else if (width == CHAN_WIDTH_20 || width == CHAN_WIDTH_20_NOHT)
+		hapd->iconf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
 
 	hapd->iconf->secondary_channel = offset;
 	hostapd_set_oper_chwidth(hapd->iconf, chwidth);
 	hostapd_set_oper_centr_freq_seg0_idx(hapd->iconf, seg0_idx);
 	hostapd_set_oper_centr_freq_seg1_idx(hapd->iconf, seg1_idx);
+	if (hapd->iconf->ieee80211ac) {
+		hapd->iconf->vht_capab &= ~VHT_CAP_SUPP_CHAN_WIDTH_MASK;
+		if (chwidth == CHANWIDTH_160MHZ)
+			hapd->iconf->vht_capab |=
+				VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
+		else if (chwidth == CHANWIDTH_80P80MHZ)
+			hapd->iconf->vht_capab |=
+				VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
+	}
 
 	is_dfs = ieee80211_is_dfs(freq, hapd->iface->hw_features,
 				  hapd->iface->num_hw_features);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hostapd.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hostapd.c
index 5eed686..07e975a 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hostapd.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hostapd.c
@@ -1,6 +1,6 @@
 /*
  * hostapd / Initialization and configuration
- * Copyright (c) 2002-2019, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2021, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -107,7 +107,8 @@
 		return;
 
 	if (hapd->conf->wmm_enabled < 0)
-		hapd->conf->wmm_enabled = hapd->iconf->ieee80211n;
+		hapd->conf->wmm_enabled = hapd->iconf->ieee80211n |
+			hapd->iconf->ieee80211ax;
 
 #ifndef CONFIG_NO_RADIUS
 	radius_client_reconfig(hapd->radius, hapd->conf->radius);
@@ -354,7 +355,7 @@
 #endif /* CONFIG_WEP */
 
 
-static void hostapd_free_hapd_data(struct hostapd_data *hapd)
+void hostapd_free_hapd_data(struct hostapd_data *hapd)
 {
 	os_free(hapd->probereq_cb);
 	hapd->probereq_cb = NULL;
@@ -392,6 +393,7 @@
 #ifdef CONFIG_DPP
 	hostapd_dpp_deinit(hapd);
 	gas_query_ap_deinit(hapd->gas);
+	hapd->gas = NULL;
 #endif /* CONFIG_DPP */
 
 	authsrv_deinit(hapd);
@@ -414,6 +416,7 @@
 	}
 
 	wpabuf_free(hapd->time_adv);
+	hapd->time_adv = NULL;
 
 #ifdef CONFIG_INTERWORKING
 	gas_serv_deinit(hapd);
@@ -429,6 +432,7 @@
 		       hapd->tmp_eap_user.identity_len);
 	bin_clear_free(hapd->tmp_eap_user.password,
 		       hapd->tmp_eap_user.password_len);
+	os_memset(&hapd->tmp_eap_user, 0, sizeof(hapd->tmp_eap_user));
 #endif /* CONFIG_SQLITE */
 
 #ifdef CONFIG_BRCM_VENDOR_IE
@@ -442,6 +446,8 @@
 #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);
@@ -504,7 +510,7 @@
 }
 
 
-static void hostapd_cleanup_iface_partial(struct hostapd_iface *iface)
+void hostapd_cleanup_iface_partial(struct hostapd_iface *iface)
 {
 	wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
 #ifdef NEED_AP_MLME
@@ -632,7 +638,7 @@
 }
 
 
-static void hostapd_bss_deinit_no_free(struct hostapd_data *hapd)
+void hostapd_bss_deinit_no_free(struct hostapd_data *hapd)
 {
 	hostapd_free_stas(hapd);
 	hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING);
@@ -1176,7 +1182,8 @@
 	}
 
 	if (conf->wmm_enabled < 0)
-		conf->wmm_enabled = hapd->iconf->ieee80211n;
+		conf->wmm_enabled = hapd->iconf->ieee80211n |
+			hapd->iconf->ieee80211ax;
 
 #ifdef CONFIG_IEEE80211R_AP
 	if (is_zero_ether_addr(conf->r1_key_holder))
@@ -1674,7 +1681,6 @@
 	return -1;
 }
 
-
 #ifndef CONFIG_ACS
 #ifdef CONFIG_BRCM_AUTOMOTIVE
 void bcm_private_acs(struct hostapd_iface *iface)
@@ -1720,6 +1726,27 @@
 }
 #endif
 #endif
+
+static void hostapd_set_6ghz_sec_chan(struct hostapd_iface *iface)
+{
+	int bw, seg0;
+
+	if (!is_6ghz_op_class(iface->conf->op_class))
+		return;
+
+	seg0 = hostapd_get_oper_centr_freq_seg0_idx(iface->conf);
+	bw = center_idx_to_bw_6ghz(seg0);
+	/* Assign the secondary channel if absent in config for
+	 * bandwidths > 20 MHz */
+	if (bw > 20 && !iface->conf->secondary_channel) {
+		if (((iface->conf->channel - 1) / 4) % 2)
+			iface->conf->secondary_channel = -1;
+		else
+			iface->conf->secondary_channel = 1;
+	}
+}
+
+
 static int setup_interface2(struct hostapd_iface *iface)
 {
 	iface->wait_channel_update = 0;
@@ -1745,6 +1772,7 @@
 
 			ch_width = op_class_to_ch_width(iface->conf->op_class);
 			hostapd_set_oper_chwidth(iface->conf, ch_width);
+			hostapd_set_6ghz_sec_chan(iface);
 		}
 
 		ret = hostapd_select_hw_mode(iface);
@@ -1760,6 +1788,9 @@
 		ret = hostapd_check_edmg_capab(iface);
 		if (ret < 0)
 			goto fail;
+		ret = hostapd_check_he_6ghz_capab(iface);
+		if (ret < 0)
+			goto fail;
 		ret = hostapd_check_ht_capab(iface);
 		if (ret < 0)
 			goto fail;
@@ -2185,8 +2216,9 @@
 		 * If freq is DFS, and DFS is offloaded to the driver, then wait
 		 * for CAC to complete.
 		 */
-		wpa_printf(MSG_DEBUG, "%s: Wait for CAC to complete", __func__);
-		return res_dfs_offload;
+		//wpa_printf(MSG_DEBUG, "%s: Wait for CAC to complete", __func__);
+		wpa_printf(MSG_DEBUG, "IFX: don't need wait for CAC to complete");
+		//return res_dfs_offload;
 	}
 
 #ifdef NEED_AP_MLME
@@ -2215,6 +2247,13 @@
 	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)
@@ -2355,10 +2394,12 @@
 {
 	int ret;
 
+	if (!iface->conf)
+		return -1;
 	ret = setup_interface(iface);
 	if (ret) {
 		wpa_printf(MSG_ERROR, "%s: Unable to setup interface.",
-			   iface->bss[0]->conf->iface);
+			   iface->conf->bss[0]->iface);
 		return -1;
 	}
 
@@ -2740,6 +2781,12 @@
 {
 	size_t j;
 
+	if (!hapd_iface)
+		return -1;
+
+	if (hapd_iface->enable_iface_cb)
+		return hapd_iface->enable_iface_cb(hapd_iface);
+
 	if (hapd_iface->bss[0]->drv_priv != NULL) {
 		wpa_printf(MSG_ERROR, "Interface %s already enabled",
 			   hapd_iface->conf->bss[0]->iface);
@@ -2801,6 +2848,9 @@
 	if (hapd_iface == NULL)
 		return -1;
 
+	if (hapd_iface->disable_iface_cb)
+		return hapd_iface->disable_iface_cb(hapd_iface);
+
 	if (hapd_iface->bss[0]->drv_priv == NULL) {
 		wpa_printf(MSG_INFO, "Interface %s already disabled",
 			   hapd_iface->conf->bss[0]->iface);
@@ -3213,10 +3263,6 @@
 void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
 			   int reassoc)
 {
-	/* Support for 4-way handshake offload to internal supplicant
-	 * for WPA/WPA2-PSK
-	 */
-	int key_mgmt = wpa_auth_sta_key_mgmt(sta->wpa_sm);
 
 	if (hapd->tkip_countermeasures) {
 		hostapd_drv_sta_deauth(hapd, sta->addr,
@@ -3251,14 +3297,7 @@
 	/* Start IEEE 802.1X authentication process for new stations */
 	ieee802_1x_new_station(hapd, sta);
 	if (reassoc) {
-		/* Support for 4-way handshake offload to internal supplicant
-		 * for WPA/WPA2-PSK
-		 */
-		if ((hapd->iface->drv_flags2 &
-		     WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK) &&
-		    wpa_key_mgmt_wpa_psk(key_mgmt))
-			wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm);
-		else if (sta->auth_alg != WLAN_AUTH_FT &&
+		if (sta->auth_alg != WLAN_AUTH_FT &&
 		    sta->auth_alg != WLAN_AUTH_FILS_SK &&
 		    sta->auth_alg != WLAN_AUTH_FILS_SK_PFS &&
 		    sta->auth_alg != WLAN_AUTH_FILS_PK &&
@@ -3486,6 +3525,20 @@
 	switch (params->bandwidth) {
 	case 0:
 	case 20:
+		conf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
+		break;
+	case 40:
+	case 80:
+	case 160:
+		conf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
+		break;
+	default:
+		return -1;
+	}
+
+	switch (params->bandwidth) {
+	case 0:
+	case 20:
 	case 40:
 		hostapd_set_oper_chwidth(conf, CHANWIDTH_USE_HT);
 		break;
@@ -3504,6 +3557,7 @@
 
 	conf->channel = channel;
 	conf->ieee80211n = params->ht_enabled;
+	conf->ieee80211ac = params->vht_enabled;
 	conf->secondary_channel = params->sec_channel_offset;
 	ieee80211_freq_to_chan(params->center_freq1,
 			       &seg0);
@@ -3610,15 +3664,23 @@
 }
 
 
-void hostapd_chan_switch_vht_config(struct hostapd_data *hapd, int vht_enabled)
+void hostapd_chan_switch_config(struct hostapd_data *hapd,
+				struct hostapd_freq_params *freq_params)
 {
-	if (vht_enabled)
+	if (freq_params->he_enabled)
+		hapd->iconf->ch_switch_he_config |= CH_SWITCH_HE_ENABLED;
+	else
+		hapd->iconf->ch_switch_he_config |= CH_SWITCH_HE_DISABLED;
+
+	if (freq_params->vht_enabled)
 		hapd->iconf->ch_switch_vht_config |= CH_SWITCH_VHT_ENABLED;
 	else
 		hapd->iconf->ch_switch_vht_config |= CH_SWITCH_VHT_DISABLED;
 
 	hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
-		       HOSTAPD_LEVEL_INFO, "CHAN_SWITCH VHT CONFIG 0x%x",
+		       HOSTAPD_LEVEL_INFO,
+		       "CHAN_SWITCH HE config 0x%x VHT config 0x%x",
+		       hapd->iconf->ch_switch_he_config,
 		       hapd->iconf->ch_switch_vht_config);
 }
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hostapd.c.orig b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hostapd.c.orig
new file mode 100755
index 0000000..bf2874d
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hostapd.c.orig
@@ -0,0 +1,3830 @@
+/*
+ * hostapd / Initialization and configuration
+ * Copyright (c) 2002-2021, Jouni Malinen <j@w1.fi>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "utils/includes.h"
+#ifdef CONFIG_SQLITE
+#include <sqlite3.h>
+#endif /* CONFIG_SQLITE */
+
+#include "utils/common.h"
+#include "utils/eloop.h"
+#include "utils/crc32.h"
+#include "common/ieee802_11_defs.h"
+#include "common/wpa_ctrl.h"
+#include "common/hw_features_common.h"
+#include "radius/radius_client.h"
+#include "radius/radius_das.h"
+#include "eap_server/tncs.h"
+#include "eapol_auth/eapol_auth_sm.h"
+#include "eapol_auth/eapol_auth_sm_i.h"
+#include "fst/fst.h"
+#include "hostapd.h"
+#include "authsrv.h"
+#include "sta_info.h"
+#include "accounting.h"
+#include "ap_list.h"
+#include "beacon.h"
+#include "ieee802_1x.h"
+#include "ieee802_11_auth.h"
+#include "vlan_init.h"
+#include "wpa_auth.h"
+#include "wps_hostapd.h"
+#include "dpp_hostapd.h"
+#include "gas_query_ap.h"
+#include "hw_features.h"
+#include "wpa_auth_glue.h"
+#include "ap_drv_ops.h"
+#include "ap_config.h"
+#include "p2p_hostapd.h"
+#include "gas_serv.h"
+#include "dfs.h"
+#include "ieee802_11.h"
+#include "bss_load.h"
+#include "x_snoop.h"
+#include "dhcp_snoop.h"
+#include "ndisc_snoop.h"
+#include "neighbor_db.h"
+#include "rrm.h"
+#include "fils_hlp.h"
+#include "acs.h"
+#include "hs20.h"
+#include "airtime_policy.h"
+#include "wpa_auth_kay.h"
+
+
+static int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason);
+#ifdef CONFIG_WEP
+static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd);
+static int hostapd_broadcast_wep_clear(struct hostapd_data *hapd);
+#endif /* CONFIG_WEP */
+static int setup_interface2(struct hostapd_iface *iface);
+static void channel_list_update_timeout(void *eloop_ctx, void *timeout_ctx);
+static void hostapd_interface_setup_failure_handler(void *eloop_ctx,
+						    void *timeout_ctx);
+
+
+int hostapd_for_each_interface(struct hapd_interfaces *interfaces,
+			       int (*cb)(struct hostapd_iface *iface,
+					 void *ctx), void *ctx)
+{
+	size_t i;
+	int ret;
+
+	for (i = 0; i < interfaces->count; i++) {
+		if (!interfaces->iface[i])
+			continue;
+		ret = cb(interfaces->iface[i], ctx);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+
+void hostapd_reconfig_encryption(struct hostapd_data *hapd)
+{
+	if (hapd->wpa_auth)
+		return;
+
+	hostapd_set_privacy(hapd, 0);
+#ifdef CONFIG_WEP
+	hostapd_setup_encryption(hapd->conf->iface, hapd);
+#endif /* CONFIG_WEP */
+}
+
+
+static void hostapd_reload_bss(struct hostapd_data *hapd)
+{
+	struct hostapd_ssid *ssid;
+
+	if (!hapd->started)
+		return;
+
+	if (hapd->conf->wmm_enabled < 0)
+		hapd->conf->wmm_enabled = hapd->iconf->ieee80211n |
+			hapd->iconf->ieee80211ax;
+
+#ifndef CONFIG_NO_RADIUS
+	radius_client_reconfig(hapd->radius, hapd->conf->radius);
+#endif /* CONFIG_NO_RADIUS */
+
+	ssid = &hapd->conf->ssid;
+	if (!ssid->wpa_psk_set && ssid->wpa_psk && !ssid->wpa_psk->next &&
+	    ssid->wpa_passphrase_set && ssid->wpa_passphrase) {
+		/*
+		 * Force PSK to be derived again since SSID or passphrase may
+		 * have changed.
+		 */
+		hostapd_config_clear_wpa_psk(&hapd->conf->ssid.wpa_psk);
+	}
+	if (hostapd_setup_wpa_psk(hapd->conf)) {
+		wpa_printf(MSG_ERROR, "Failed to re-configure WPA PSK "
+			   "after reloading configuration");
+	}
+
+	if (hapd->conf->ieee802_1x || hapd->conf->wpa)
+		hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 1);
+	else
+		hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 0);
+
+	if ((hapd->conf->wpa || hapd->conf->osen) && hapd->wpa_auth == NULL) {
+		hostapd_setup_wpa(hapd);
+		if (hapd->wpa_auth)
+			wpa_init_keys(hapd->wpa_auth);
+	} else if (hapd->conf->wpa) {
+		const u8 *wpa_ie;
+		size_t wpa_ie_len;
+		hostapd_reconfig_wpa(hapd);
+		wpa_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &wpa_ie_len);
+		if (hostapd_set_generic_elem(hapd, wpa_ie, wpa_ie_len))
+			wpa_printf(MSG_ERROR, "Failed to configure WPA IE for "
+				   "the kernel driver.");
+	} else if (hapd->wpa_auth) {
+		wpa_deinit(hapd->wpa_auth);
+		hapd->wpa_auth = NULL;
+		hostapd_set_privacy(hapd, 0);
+#ifdef CONFIG_WEP
+		hostapd_setup_encryption(hapd->conf->iface, hapd);
+#endif /* CONFIG_WEP */
+		hostapd_set_generic_elem(hapd, (u8 *) "", 0);
+	}
+
+	ieee802_11_set_beacon(hapd);
+	hostapd_update_wps(hapd);
+
+	if (hapd->conf->ssid.ssid_set &&
+	    hostapd_set_ssid(hapd, hapd->conf->ssid.ssid,
+			     hapd->conf->ssid.ssid_len)) {
+		wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver");
+		/* try to continue */
+	}
+	wpa_printf(MSG_DEBUG, "Reconfigured interface %s", hapd->conf->iface);
+}
+
+
+static void hostapd_clear_old(struct hostapd_iface *iface)
+{
+	size_t j;
+
+	/*
+	 * Deauthenticate all stations since the new configuration may not
+	 * allow them to use the BSS anymore.
+	 */
+	for (j = 0; j < iface->num_bss; j++) {
+		hostapd_flush_old_stations(iface->bss[j],
+					   WLAN_REASON_PREV_AUTH_NOT_VALID);
+#ifdef CONFIG_WEP
+		hostapd_broadcast_wep_clear(iface->bss[j]);
+#endif /* CONFIG_WEP */
+
+#ifndef CONFIG_NO_RADIUS
+		/* TODO: update dynamic data based on changed configuration
+		 * items (e.g., open/close sockets, etc.) */
+		radius_client_flush(iface->bss[j]->radius, 0);
+#endif /* CONFIG_NO_RADIUS */
+	}
+}
+
+
+static int hostapd_iface_conf_changed(struct hostapd_config *newconf,
+				      struct hostapd_config *oldconf)
+{
+	size_t i;
+
+	if (newconf->num_bss != oldconf->num_bss)
+		return 1;
+
+	for (i = 0; i < newconf->num_bss; i++) {
+		if (os_strcmp(newconf->bss[i]->iface,
+			      oldconf->bss[i]->iface) != 0)
+			return 1;
+	}
+
+	return 0;
+}
+
+
+int hostapd_reload_config(struct hostapd_iface *iface)
+{
+	struct hapd_interfaces *interfaces = iface->interfaces;
+	struct hostapd_data *hapd = iface->bss[0];
+	struct hostapd_config *newconf, *oldconf;
+	size_t j;
+
+	if (iface->config_fname == NULL) {
+		/* Only in-memory config in use - assume it has been updated */
+		hostapd_clear_old(iface);
+		for (j = 0; j < iface->num_bss; j++)
+			hostapd_reload_bss(iface->bss[j]);
+		return 0;
+	}
+
+	if (iface->interfaces == NULL ||
+	    iface->interfaces->config_read_cb == NULL)
+		return -1;
+	newconf = iface->interfaces->config_read_cb(iface->config_fname);
+	if (newconf == NULL)
+		return -1;
+
+	hostapd_clear_old(iface);
+
+	oldconf = hapd->iconf;
+	if (hostapd_iface_conf_changed(newconf, oldconf)) {
+		char *fname;
+		int res;
+
+		wpa_printf(MSG_DEBUG,
+			   "Configuration changes include interface/BSS modification - force full disable+enable sequence");
+		fname = os_strdup(iface->config_fname);
+		if (!fname) {
+			hostapd_config_free(newconf);
+			return -1;
+		}
+		hostapd_remove_iface(interfaces, hapd->conf->iface);
+		iface = hostapd_init(interfaces, fname);
+		os_free(fname);
+		hostapd_config_free(newconf);
+		if (!iface) {
+			wpa_printf(MSG_ERROR,
+				   "Failed to initialize interface on config reload");
+			return -1;
+		}
+		iface->interfaces = interfaces;
+		interfaces->iface[interfaces->count] = iface;
+		interfaces->count++;
+		res = hostapd_enable_iface(iface);
+		if (res < 0)
+			wpa_printf(MSG_ERROR,
+				   "Failed to enable interface on config reload");
+		return res;
+	}
+	iface->conf = newconf;
+
+	for (j = 0; j < iface->num_bss; j++) {
+		hapd = iface->bss[j];
+		hapd->iconf = newconf;
+		hapd->iconf->channel = oldconf->channel;
+		hapd->iconf->acs = oldconf->acs;
+		hapd->iconf->secondary_channel = oldconf->secondary_channel;
+		hapd->iconf->ieee80211n = oldconf->ieee80211n;
+		hapd->iconf->ieee80211ac = oldconf->ieee80211ac;
+		hapd->iconf->ht_capab = oldconf->ht_capab;
+		hapd->iconf->vht_capab = oldconf->vht_capab;
+		hostapd_set_oper_chwidth(hapd->iconf,
+					 hostapd_get_oper_chwidth(oldconf));
+		hostapd_set_oper_centr_freq_seg0_idx(
+			hapd->iconf,
+			hostapd_get_oper_centr_freq_seg0_idx(oldconf));
+		hostapd_set_oper_centr_freq_seg1_idx(
+			hapd->iconf,
+			hostapd_get_oper_centr_freq_seg1_idx(oldconf));
+		hapd->conf = newconf->bss[j];
+		hostapd_reload_bss(hapd);
+	}
+
+	hostapd_config_free(oldconf);
+
+
+	return 0;
+}
+
+
+#ifdef CONFIG_WEP
+
+static void hostapd_broadcast_key_clear_iface(struct hostapd_data *hapd,
+					      const char *ifname)
+{
+	int i;
+
+	if (!ifname || !hapd->drv_priv)
+		return;
+	for (i = 0; i < NUM_WEP_KEYS; i++) {
+		if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE, NULL, i, 0,
+					0, NULL, 0, NULL, 0, KEY_FLAG_GROUP)) {
+			wpa_printf(MSG_DEBUG, "Failed to clear default "
+				   "encryption keys (ifname=%s keyidx=%d)",
+				   ifname, i);
+		}
+	}
+	if (hapd->conf->ieee80211w) {
+		for (i = NUM_WEP_KEYS; i < NUM_WEP_KEYS + 2; i++) {
+			if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE,
+						NULL, i, 0, 0, NULL,
+						0, NULL, 0, KEY_FLAG_GROUP)) {
+				wpa_printf(MSG_DEBUG, "Failed to clear "
+					   "default mgmt encryption keys "
+					   "(ifname=%s keyidx=%d)", ifname, i);
+			}
+		}
+	}
+}
+
+
+static int hostapd_broadcast_wep_clear(struct hostapd_data *hapd)
+{
+	hostapd_broadcast_key_clear_iface(hapd, hapd->conf->iface);
+	return 0;
+}
+
+
+static int hostapd_broadcast_wep_set(struct hostapd_data *hapd)
+{
+	int errors = 0, idx;
+	struct hostapd_ssid *ssid = &hapd->conf->ssid;
+
+	idx = ssid->wep.idx;
+	if (ssid->wep.default_len && ssid->wep.key[idx] &&
+	    hostapd_drv_set_key(hapd->conf->iface,
+				hapd, WPA_ALG_WEP, broadcast_ether_addr, idx, 0,
+				1, NULL, 0, ssid->wep.key[idx],
+				ssid->wep.len[idx],
+				KEY_FLAG_GROUP_RX_TX_DEFAULT)) {
+		wpa_printf(MSG_WARNING, "Could not set WEP encryption.");
+		errors++;
+	}
+
+	return errors;
+}
+
+#endif /* CONFIG_WEP */
+
+
+void hostapd_free_hapd_data(struct hostapd_data *hapd)
+{
+	os_free(hapd->probereq_cb);
+	hapd->probereq_cb = NULL;
+	hapd->num_probereq_cb = 0;
+
+#ifdef CONFIG_P2P
+	wpabuf_free(hapd->p2p_beacon_ie);
+	hapd->p2p_beacon_ie = NULL;
+	wpabuf_free(hapd->p2p_probe_resp_ie);
+	hapd->p2p_probe_resp_ie = NULL;
+#endif /* CONFIG_P2P */
+
+	if (!hapd->started) {
+		wpa_printf(MSG_ERROR, "%s: Interface %s wasn't started",
+			   __func__, hapd->conf ? hapd->conf->iface : "N/A");
+		return;
+	}
+	hapd->started = 0;
+	hapd->beacon_set_done = 0;
+
+	wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface);
+	accounting_deinit(hapd);
+	hostapd_deinit_wpa(hapd);
+	vlan_deinit(hapd);
+	hostapd_acl_deinit(hapd);
+#ifndef CONFIG_NO_RADIUS
+	radius_client_deinit(hapd->radius);
+	hapd->radius = NULL;
+	radius_das_deinit(hapd->radius_das);
+	hapd->radius_das = NULL;
+#endif /* CONFIG_NO_RADIUS */
+
+	hostapd_deinit_wps(hapd);
+	ieee802_1x_dealloc_kay_sm_hapd(hapd);
+#ifdef CONFIG_DPP
+	hostapd_dpp_deinit(hapd);
+	gas_query_ap_deinit(hapd->gas);
+	hapd->gas = NULL;
+#endif /* CONFIG_DPP */
+
+	authsrv_deinit(hapd);
+
+	if (hapd->interface_added) {
+		hapd->interface_added = 0;
+		if (hostapd_if_remove(hapd, WPA_IF_AP_BSS, hapd->conf->iface)) {
+			wpa_printf(MSG_WARNING,
+				   "Failed to remove BSS interface %s",
+				   hapd->conf->iface);
+			hapd->interface_added = 1;
+		} else {
+			/*
+			 * Since this was a dynamically added interface, the
+			 * driver wrapper may have removed its internal instance
+			 * and hapd->drv_priv is not valid anymore.
+			 */
+			hapd->drv_priv = NULL;
+		}
+	}
+
+	wpabuf_free(hapd->time_adv);
+	hapd->time_adv = NULL;
+
+#ifdef CONFIG_INTERWORKING
+	gas_serv_deinit(hapd);
+#endif /* CONFIG_INTERWORKING */
+
+	bss_load_update_deinit(hapd);
+	ndisc_snoop_deinit(hapd);
+	dhcp_snoop_deinit(hapd);
+	x_snoop_deinit(hapd);
+
+#ifdef CONFIG_SQLITE
+	bin_clear_free(hapd->tmp_eap_user.identity,
+		       hapd->tmp_eap_user.identity_len);
+	bin_clear_free(hapd->tmp_eap_user.password,
+		       hapd->tmp_eap_user.password_len);
+	os_memset(&hapd->tmp_eap_user, 0, sizeof(hapd->tmp_eap_user));
+#endif /* CONFIG_SQLITE */
+
+#ifdef CONFIG_BRCM_VENDOR_IE
+	for (i = 0; i < MAX_VENDOR_IES; i++ ) {
+		wpabuf_free(hapd->vendor_ie[i]);
+		hapd->vendor_ie[i] = NULL;
+	}
+	wpabuf_free(hapd->vendor_ies);
+	hapd->vendor_ies = NULL;
+#endif /* CONFIG_BRCM_VENDOR_IE */
+#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);
+	fils_hlp_deinit(hapd);
+
+#ifdef CONFIG_OCV
+	eloop_cancel_timeout(hostapd_ocv_check_csa_sa_query, hapd, NULL);
+#endif /* CONFIG_OCV */
+
+#ifdef CONFIG_SAE
+	{
+		struct hostapd_sae_commit_queue *q;
+
+		while ((q = dl_list_first(&hapd->sae_commit_queue,
+					  struct hostapd_sae_commit_queue,
+					  list))) {
+			dl_list_del(&q->list);
+			os_free(q);
+		}
+	}
+	eloop_cancel_timeout(auth_sae_process_commit, hapd, NULL);
+#endif /* CONFIG_SAE */
+}
+
+
+/**
+ * hostapd_cleanup - Per-BSS cleanup (deinitialization)
+ * @hapd: Pointer to BSS data
+ *
+ * This function is used to free all per-BSS data structures and resources.
+ * Most of the modules that are initialized in hostapd_setup_bss() are
+ * deinitialized here.
+ */
+static void hostapd_cleanup(struct hostapd_data *hapd)
+{
+	wpa_printf(MSG_DEBUG, "%s(hapd=%p (%s))", __func__, hapd,
+		   hapd->conf ? hapd->conf->iface : "N/A");
+	if (hapd->iface->interfaces &&
+	    hapd->iface->interfaces->ctrl_iface_deinit) {
+		wpa_msg(hapd->msg_ctx, MSG_INFO, WPA_EVENT_TERMINATING);
+		hapd->iface->interfaces->ctrl_iface_deinit(hapd);
+	}
+	hostapd_free_hapd_data(hapd);
+}
+
+
+static void sta_track_deinit(struct hostapd_iface *iface)
+{
+	struct hostapd_sta_info *info;
+
+	if (!iface->num_sta_seen)
+		return;
+
+	while ((info = dl_list_first(&iface->sta_seen, struct hostapd_sta_info,
+				     list))) {
+		dl_list_del(&info->list);
+		iface->num_sta_seen--;
+		sta_track_del(info);
+	}
+}
+
+
+void hostapd_cleanup_iface_partial(struct hostapd_iface *iface)
+{
+	wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
+#ifdef NEED_AP_MLME
+	hostapd_stop_setup_timers(iface);
+#endif /* NEED_AP_MLME */
+	if (iface->current_mode)
+		acs_cleanup(iface);
+	hostapd_free_hw_features(iface->hw_features, iface->num_hw_features);
+	iface->hw_features = NULL;
+	iface->current_mode = NULL;
+	os_free(iface->current_rates);
+	iface->current_rates = NULL;
+	os_free(iface->basic_rates);
+	iface->basic_rates = NULL;
+	ap_list_deinit(iface);
+	sta_track_deinit(iface);
+	airtime_policy_update_deinit(iface);
+}
+
+
+/**
+ * hostapd_cleanup_iface - Complete per-interface cleanup
+ * @iface: Pointer to interface data
+ *
+ * This function is called after per-BSS data structures are deinitialized
+ * with hostapd_cleanup().
+ */
+static void hostapd_cleanup_iface(struct hostapd_iface *iface)
+{
+	wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
+	eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
+	eloop_cancel_timeout(hostapd_interface_setup_failure_handler, iface,
+			     NULL);
+
+	hostapd_cleanup_iface_partial(iface);
+	hostapd_config_free(iface->conf);
+	iface->conf = NULL;
+
+	os_free(iface->config_fname);
+	os_free(iface->bss);
+	wpa_printf(MSG_DEBUG, "%s: free iface=%p", __func__, iface);
+	os_free(iface);
+}
+
+
+#ifdef CONFIG_WEP
+
+static void hostapd_clear_wep(struct hostapd_data *hapd)
+{
+	if (hapd->drv_priv && !hapd->iface->driver_ap_teardown && hapd->conf) {
+		hostapd_set_privacy(hapd, 0);
+		hostapd_broadcast_wep_clear(hapd);
+	}
+}
+
+
+static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd)
+{
+	int i;
+
+	hostapd_broadcast_wep_set(hapd);
+
+	if (hapd->conf->ssid.wep.default_len) {
+		hostapd_set_privacy(hapd, 1);
+		return 0;
+	}
+
+	/*
+	 * When IEEE 802.1X is not enabled, the driver may need to know how to
+	 * set authentication algorithms for static WEP.
+	 */
+	hostapd_drv_set_authmode(hapd, hapd->conf->auth_algs);
+
+	for (i = 0; i < 4; i++) {
+		if (hapd->conf->ssid.wep.key[i] &&
+		    hostapd_drv_set_key(iface, hapd, WPA_ALG_WEP, NULL, i, 0,
+					i == hapd->conf->ssid.wep.idx, NULL, 0,
+					hapd->conf->ssid.wep.key[i],
+					hapd->conf->ssid.wep.len[i],
+					i == hapd->conf->ssid.wep.idx ?
+					KEY_FLAG_GROUP_RX_TX_DEFAULT :
+					KEY_FLAG_GROUP_RX_TX)) {
+			wpa_printf(MSG_WARNING, "Could not set WEP "
+				   "encryption.");
+			return -1;
+		}
+		if (hapd->conf->ssid.wep.key[i] &&
+		    i == hapd->conf->ssid.wep.idx)
+			hostapd_set_privacy(hapd, 1);
+	}
+
+	return 0;
+}
+
+#endif /* CONFIG_WEP */
+
+
+static int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason)
+{
+	int ret = 0;
+	u8 addr[ETH_ALEN];
+
+	if (hostapd_drv_none(hapd) || hapd->drv_priv == NULL)
+		return 0;
+
+	if (!hapd->iface->driver_ap_teardown) {
+		wpa_dbg(hapd->msg_ctx, MSG_DEBUG,
+			"Flushing old station entries");
+
+		if (hostapd_flush(hapd)) {
+			wpa_msg(hapd->msg_ctx, MSG_WARNING,
+				"Could not connect to kernel driver");
+			ret = -1;
+		}
+	}
+	if (hapd->conf && hapd->conf->broadcast_deauth) {
+		wpa_dbg(hapd->msg_ctx, MSG_DEBUG,
+			"Deauthenticate all stations");
+		os_memset(addr, 0xff, ETH_ALEN);
+		hostapd_drv_sta_deauth(hapd, addr, reason);
+	}
+	hostapd_free_stas(hapd);
+
+	return ret;
+}
+
+
+void hostapd_bss_deinit_no_free(struct hostapd_data *hapd)
+{
+	hostapd_free_stas(hapd);
+	hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING);
+#ifdef CONFIG_WEP
+	hostapd_clear_wep(hapd);
+#endif /* CONFIG_WEP */
+}
+
+
+/**
+ * hostapd_validate_bssid_configuration - Validate BSSID configuration
+ * @iface: Pointer to interface data
+ * Returns: 0 on success, -1 on failure
+ *
+ * This function is used to validate that the configured BSSIDs are valid.
+ */
+static int hostapd_validate_bssid_configuration(struct hostapd_iface *iface)
+{
+	u8 mask[ETH_ALEN] = { 0 };
+	struct hostapd_data *hapd = iface->bss[0];
+	unsigned int i = iface->conf->num_bss, bits = 0, j;
+	int auto_addr = 0;
+
+	if (hostapd_drv_none(hapd))
+		return 0;
+
+	if (iface->conf->use_driver_iface_addr)
+		return 0;
+
+	/* Generate BSSID mask that is large enough to cover the BSSIDs. */
+
+	/* Determine the bits necessary to cover the number of BSSIDs. */
+	for (i--; i; i >>= 1)
+		bits++;
+
+	/* Determine the bits necessary to any configured BSSIDs,
+	   if they are higher than the number of BSSIDs. */
+	for (j = 0; j < iface->conf->num_bss; j++) {
+		if (is_zero_ether_addr(iface->conf->bss[j]->bssid)) {
+			if (j)
+				auto_addr++;
+			continue;
+		}
+
+		for (i = 0; i < ETH_ALEN; i++) {
+			mask[i] |=
+				iface->conf->bss[j]->bssid[i] ^
+				hapd->own_addr[i];
+		}
+	}
+
+	if (!auto_addr)
+		goto skip_mask_ext;
+
+	for (i = 0; i < ETH_ALEN && mask[i] == 0; i++)
+		;
+	j = 0;
+	if (i < ETH_ALEN) {
+		j = (5 - i) * 8;
+
+		while (mask[i] != 0) {
+			mask[i] >>= 1;
+			j++;
+		}
+	}
+
+	if (bits < j)
+		bits = j;
+
+	if (bits > 40) {
+		wpa_printf(MSG_ERROR, "Too many bits in the BSSID mask (%u)",
+			   bits);
+		return -1;
+	}
+
+	os_memset(mask, 0xff, ETH_ALEN);
+	j = bits / 8;
+	for (i = 5; i > 5 - j; i--)
+		mask[i] = 0;
+	j = bits % 8;
+	while (j) {
+		j--;
+		mask[i] <<= 1;
+	}
+
+skip_mask_ext:
+	wpa_printf(MSG_DEBUG, "BSS count %lu, BSSID mask " MACSTR " (%d bits)",
+		   (unsigned long) iface->conf->num_bss, MAC2STR(mask), bits);
+
+	if (!auto_addr)
+		return 0;
+
+	for (i = 0; i < ETH_ALEN; i++) {
+		if ((hapd->own_addr[i] & mask[i]) != hapd->own_addr[i]) {
+			wpa_printf(MSG_ERROR, "Invalid BSSID mask " MACSTR
+				   " for start address " MACSTR ".",
+				   MAC2STR(mask), MAC2STR(hapd->own_addr));
+			wpa_printf(MSG_ERROR, "Start address must be the "
+				   "first address in the block (i.e., addr "
+				   "AND mask == addr).");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+
+static int mac_in_conf(struct hostapd_config *conf, const void *a)
+{
+	size_t i;
+
+	for (i = 0; i < conf->num_bss; i++) {
+		if (hostapd_mac_comp(conf->bss[i]->bssid, a) == 0) {
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+
+#ifndef CONFIG_NO_RADIUS
+
+static int hostapd_das_nas_mismatch(struct hostapd_data *hapd,
+				    struct radius_das_attrs *attr)
+{
+	if (attr->nas_identifier &&
+	    (!hapd->conf->nas_identifier ||
+	     os_strlen(hapd->conf->nas_identifier) !=
+	     attr->nas_identifier_len ||
+	     os_memcmp(hapd->conf->nas_identifier, attr->nas_identifier,
+		       attr->nas_identifier_len) != 0)) {
+		wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-Identifier mismatch");
+		return 1;
+	}
+
+	if (attr->nas_ip_addr &&
+	    (hapd->conf->own_ip_addr.af != AF_INET ||
+	     os_memcmp(&hapd->conf->own_ip_addr.u.v4, attr->nas_ip_addr, 4) !=
+	     0)) {
+		wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-IP-Address mismatch");
+		return 1;
+	}
+
+#ifdef CONFIG_IPV6
+	if (attr->nas_ipv6_addr &&
+	    (hapd->conf->own_ip_addr.af != AF_INET6 ||
+	     os_memcmp(&hapd->conf->own_ip_addr.u.v6, attr->nas_ipv6_addr, 16)
+	     != 0)) {
+		wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-IPv6-Address mismatch");
+		return 1;
+	}
+#endif /* CONFIG_IPV6 */
+
+	return 0;
+}
+
+
+static struct sta_info * hostapd_das_find_sta(struct hostapd_data *hapd,
+					      struct radius_das_attrs *attr,
+					      int *multi)
+{
+	struct sta_info *selected, *sta;
+	char buf[128];
+	int num_attr = 0;
+	int count;
+
+	*multi = 0;
+
+	for (sta = hapd->sta_list; sta; sta = sta->next)
+		sta->radius_das_match = 1;
+
+	if (attr->sta_addr) {
+		num_attr++;
+		sta = ap_get_sta(hapd, attr->sta_addr);
+		if (!sta) {
+			wpa_printf(MSG_DEBUG,
+				   "RADIUS DAS: No Calling-Station-Id match");
+			return NULL;
+		}
+
+		selected = sta;
+		for (sta = hapd->sta_list; sta; sta = sta->next) {
+			if (sta != selected)
+				sta->radius_das_match = 0;
+		}
+		wpa_printf(MSG_DEBUG, "RADIUS DAS: Calling-Station-Id match");
+	}
+
+	if (attr->acct_session_id) {
+		num_attr++;
+		if (attr->acct_session_id_len != 16) {
+			wpa_printf(MSG_DEBUG,
+				   "RADIUS DAS: Acct-Session-Id cannot match");
+			return NULL;
+		}
+		count = 0;
+
+		for (sta = hapd->sta_list; sta; sta = sta->next) {
+			if (!sta->radius_das_match)
+				continue;
+			os_snprintf(buf, sizeof(buf), "%016llX",
+				    (unsigned long long) sta->acct_session_id);
+			if (os_memcmp(attr->acct_session_id, buf, 16) != 0)
+				sta->radius_das_match = 0;
+			else
+				count++;
+		}
+
+		if (count == 0) {
+			wpa_printf(MSG_DEBUG,
+				   "RADIUS DAS: No matches remaining after Acct-Session-Id check");
+			return NULL;
+		}
+		wpa_printf(MSG_DEBUG, "RADIUS DAS: Acct-Session-Id match");
+	}
+
+	if (attr->acct_multi_session_id) {
+		num_attr++;
+		if (attr->acct_multi_session_id_len != 16) {
+			wpa_printf(MSG_DEBUG,
+				   "RADIUS DAS: Acct-Multi-Session-Id cannot match");
+			return NULL;
+		}
+		count = 0;
+
+		for (sta = hapd->sta_list; sta; sta = sta->next) {
+			if (!sta->radius_das_match)
+				continue;
+			if (!sta->eapol_sm ||
+			    !sta->eapol_sm->acct_multi_session_id) {
+				sta->radius_das_match = 0;
+				continue;
+			}
+			os_snprintf(buf, sizeof(buf), "%016llX",
+				    (unsigned long long)
+				    sta->eapol_sm->acct_multi_session_id);
+			if (os_memcmp(attr->acct_multi_session_id, buf, 16) !=
+			    0)
+				sta->radius_das_match = 0;
+			else
+				count++;
+		}
+
+		if (count == 0) {
+			wpa_printf(MSG_DEBUG,
+				   "RADIUS DAS: No matches remaining after Acct-Multi-Session-Id check");
+			return NULL;
+		}
+		wpa_printf(MSG_DEBUG,
+			   "RADIUS DAS: Acct-Multi-Session-Id match");
+	}
+
+	if (attr->cui) {
+		num_attr++;
+		count = 0;
+
+		for (sta = hapd->sta_list; sta; sta = sta->next) {
+			struct wpabuf *cui;
+
+			if (!sta->radius_das_match)
+				continue;
+			cui = ieee802_1x_get_radius_cui(sta->eapol_sm);
+			if (!cui || wpabuf_len(cui) != attr->cui_len ||
+			    os_memcmp(wpabuf_head(cui), attr->cui,
+				      attr->cui_len) != 0)
+				sta->radius_das_match = 0;
+			else
+				count++;
+		}
+
+		if (count == 0) {
+			wpa_printf(MSG_DEBUG,
+				   "RADIUS DAS: No matches remaining after Chargeable-User-Identity check");
+			return NULL;
+		}
+		wpa_printf(MSG_DEBUG,
+			   "RADIUS DAS: Chargeable-User-Identity match");
+	}
+
+	if (attr->user_name) {
+		num_attr++;
+		count = 0;
+
+		for (sta = hapd->sta_list; sta; sta = sta->next) {
+			u8 *identity;
+			size_t identity_len;
+
+			if (!sta->radius_das_match)
+				continue;
+			identity = ieee802_1x_get_identity(sta->eapol_sm,
+							   &identity_len);
+			if (!identity ||
+			    identity_len != attr->user_name_len ||
+			    os_memcmp(identity, attr->user_name, identity_len)
+			    != 0)
+				sta->radius_das_match = 0;
+			else
+				count++;
+		}
+
+		if (count == 0) {
+			wpa_printf(MSG_DEBUG,
+				   "RADIUS DAS: No matches remaining after User-Name check");
+			return NULL;
+		}
+		wpa_printf(MSG_DEBUG,
+			   "RADIUS DAS: User-Name match");
+	}
+
+	if (num_attr == 0) {
+		/*
+		 * In theory, we could match all current associations, but it
+		 * seems safer to just reject requests that do not include any
+		 * session identification attributes.
+		 */
+		wpa_printf(MSG_DEBUG,
+			   "RADIUS DAS: No session identification attributes included");
+		return NULL;
+	}
+
+	selected = NULL;
+	for (sta = hapd->sta_list; sta; sta = sta->next) {
+		if (sta->radius_das_match) {
+			if (selected) {
+				*multi = 1;
+				return NULL;
+			}
+			selected = sta;
+		}
+	}
+
+	return selected;
+}
+
+
+static int hostapd_das_disconnect_pmksa(struct hostapd_data *hapd,
+					struct radius_das_attrs *attr)
+{
+	if (!hapd->wpa_auth)
+		return -1;
+	return wpa_auth_radius_das_disconnect_pmksa(hapd->wpa_auth, attr);
+}
+
+
+static enum radius_das_res
+hostapd_das_disconnect(void *ctx, struct radius_das_attrs *attr)
+{
+	struct hostapd_data *hapd = ctx;
+	struct sta_info *sta;
+	int multi;
+
+	if (hostapd_das_nas_mismatch(hapd, attr))
+		return RADIUS_DAS_NAS_MISMATCH;
+
+	sta = hostapd_das_find_sta(hapd, attr, &multi);
+	if (sta == NULL) {
+		if (multi) {
+			wpa_printf(MSG_DEBUG,
+				   "RADIUS DAS: Multiple sessions match - not supported");
+			return RADIUS_DAS_MULTI_SESSION_MATCH;
+		}
+		if (hostapd_das_disconnect_pmksa(hapd, attr) == 0) {
+			wpa_printf(MSG_DEBUG,
+				   "RADIUS DAS: PMKSA cache entry matched");
+			return RADIUS_DAS_SUCCESS;
+		}
+		wpa_printf(MSG_DEBUG, "RADIUS DAS: No matching session found");
+		return RADIUS_DAS_SESSION_NOT_FOUND;
+	}
+
+	wpa_printf(MSG_DEBUG, "RADIUS DAS: Found a matching session " MACSTR
+		   " - disconnecting", MAC2STR(sta->addr));
+	wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
+
+	hostapd_drv_sta_deauth(hapd, sta->addr,
+			       WLAN_REASON_PREV_AUTH_NOT_VALID);
+	ap_sta_deauthenticate(hapd, sta, WLAN_REASON_PREV_AUTH_NOT_VALID);
+
+	return RADIUS_DAS_SUCCESS;
+}
+
+
+#ifdef CONFIG_HS20
+static enum radius_das_res
+hostapd_das_coa(void *ctx, struct radius_das_attrs *attr)
+{
+	struct hostapd_data *hapd = ctx;
+	struct sta_info *sta;
+	int multi;
+
+	if (hostapd_das_nas_mismatch(hapd, attr))
+		return RADIUS_DAS_NAS_MISMATCH;
+
+	sta = hostapd_das_find_sta(hapd, attr, &multi);
+	if (!sta) {
+		if (multi) {
+			wpa_printf(MSG_DEBUG,
+				   "RADIUS DAS: Multiple sessions match - not supported");
+			return RADIUS_DAS_MULTI_SESSION_MATCH;
+		}
+		wpa_printf(MSG_DEBUG, "RADIUS DAS: No matching session found");
+		return RADIUS_DAS_SESSION_NOT_FOUND;
+	}
+
+	wpa_printf(MSG_DEBUG, "RADIUS DAS: Found a matching session " MACSTR
+		   " - CoA", MAC2STR(sta->addr));
+
+	if (attr->hs20_t_c_filtering) {
+		if (attr->hs20_t_c_filtering[0] & BIT(0)) {
+			wpa_printf(MSG_DEBUG,
+				   "HS 2.0: Unexpected Terms and Conditions filtering required in CoA-Request");
+			return RADIUS_DAS_COA_FAILED;
+		}
+
+		hs20_t_c_filtering(hapd, sta, 0);
+	}
+
+	return RADIUS_DAS_SUCCESS;
+}
+#else /* CONFIG_HS20 */
+#define hostapd_das_coa NULL
+#endif /* CONFIG_HS20 */
+
+
+#ifdef CONFIG_SQLITE
+
+static int db_table_exists(sqlite3 *db, const char *name)
+{
+	char cmd[128];
+
+	os_snprintf(cmd, sizeof(cmd), "SELECT 1 FROM %s;", name);
+	return sqlite3_exec(db, cmd, NULL, NULL, NULL) == SQLITE_OK;
+}
+
+
+static int db_table_create_radius_attributes(sqlite3 *db)
+{
+	char *err = NULL;
+	const char *sql =
+		"CREATE TABLE radius_attributes("
+		" id INTEGER PRIMARY KEY,"
+		" sta TEXT,"
+		" reqtype TEXT,"
+		" attr TEXT"
+		");"
+		"CREATE INDEX idx_sta_reqtype ON radius_attributes(sta,reqtype);";
+
+	wpa_printf(MSG_DEBUG,
+		   "Adding database table for RADIUS attribute information");
+	if (sqlite3_exec(db, sql, NULL, NULL, &err) != SQLITE_OK) {
+		wpa_printf(MSG_ERROR, "SQLite error: %s", err);
+		sqlite3_free(err);
+		return -1;
+	}
+
+	return 0;
+}
+
+#endif /* CONFIG_SQLITE */
+
+#endif /* CONFIG_NO_RADIUS */
+
+
+/**
+ * hostapd_setup_bss - Per-BSS setup (initialization)
+ * @hapd: Pointer to BSS data
+ * @first: Whether this BSS is the first BSS of an interface; -1 = not first,
+ *	but interface may exist
+ *
+ * This function is used to initialize all per-BSS data structures and
+ * resources. This gets called in a loop for each BSS when an interface is
+ * initialized. Most of the modules that are initialized here will be
+ * deinitialized in hostapd_cleanup().
+ */
+static int hostapd_setup_bss(struct hostapd_data *hapd, int first)
+{
+	struct hostapd_bss_config *conf = hapd->conf;
+	u8 ssid[SSID_MAX_LEN + 1];
+	int ssid_len, set_ssid;
+	char force_ifname[IFNAMSIZ];
+	u8 if_addr[ETH_ALEN];
+	int flush_old_stations = 1;
+
+	wpa_printf(MSG_DEBUG, "%s(hapd=%p (%s), first=%d)",
+		   __func__, hapd, conf->iface, first);
+
+#ifdef EAP_SERVER_TNC
+	if (conf->tnc && tncs_global_init() < 0) {
+		wpa_printf(MSG_ERROR, "Failed to initialize TNCS");
+		return -1;
+	}
+#endif /* EAP_SERVER_TNC */
+
+	if (hapd->started) {
+		wpa_printf(MSG_ERROR, "%s: Interface %s was already started",
+			   __func__, conf->iface);
+		return -1;
+	}
+	hapd->started = 1;
+
+	if (!first || first == -1) {
+		u8 *addr = hapd->own_addr;
+
+		if (!is_zero_ether_addr(conf->bssid)) {
+			/* Allocate the configured BSSID. */
+			os_memcpy(hapd->own_addr, conf->bssid, ETH_ALEN);
+
+			if (hostapd_mac_comp(hapd->own_addr,
+					     hapd->iface->bss[0]->own_addr) ==
+			    0) {
+				wpa_printf(MSG_ERROR, "BSS '%s' may not have "
+					   "BSSID set to the MAC address of "
+					   "the radio", conf->iface);
+				return -1;
+			}
+		} else if (hapd->iconf->use_driver_iface_addr) {
+			addr = NULL;
+		} else {
+			/* Allocate the next available BSSID. */
+			do {
+				inc_byte_array(hapd->own_addr, ETH_ALEN);
+			} while (mac_in_conf(hapd->iconf, hapd->own_addr));
+		}
+
+		hapd->interface_added = 1;
+		if (hostapd_if_add(hapd->iface->bss[0], WPA_IF_AP_BSS,
+				   conf->iface, addr, hapd,
+				   &hapd->drv_priv, force_ifname, if_addr,
+				   conf->bridge[0] ? conf->bridge : NULL,
+				   first == -1)) {
+			wpa_printf(MSG_ERROR, "Failed to add BSS (BSSID="
+				   MACSTR ")", MAC2STR(hapd->own_addr));
+			hapd->interface_added = 0;
+			return -1;
+		}
+
+		if (!addr)
+			os_memcpy(hapd->own_addr, if_addr, ETH_ALEN);
+	}
+
+	if (conf->wmm_enabled < 0)
+		conf->wmm_enabled = hapd->iconf->ieee80211n |
+			hapd->iconf->ieee80211ax;
+
+#ifdef CONFIG_IEEE80211R_AP
+	if (is_zero_ether_addr(conf->r1_key_holder))
+		os_memcpy(conf->r1_key_holder, hapd->own_addr, ETH_ALEN);
+#endif /* CONFIG_IEEE80211R_AP */
+
+#ifdef CONFIG_MESH
+	if ((hapd->conf->mesh & MESH_ENABLED) && hapd->iface->mconf == NULL)
+		flush_old_stations = 0;
+#endif /* CONFIG_MESH */
+
+	if (flush_old_stations)
+		hostapd_flush(hapd);
+	hostapd_set_privacy(hapd, 0);
+
+#ifdef CONFIG_WEP
+	if (!hostapd_drv_nl80211(hapd))
+		hostapd_broadcast_wep_clear(hapd);
+	if (hostapd_setup_encryption(conf->iface, hapd))
+		return -1;
+#endif /* CONFIG_WEP */
+
+	/*
+	 * Fetch the SSID from the system and use it or,
+	 * if one was specified in the config file, verify they
+	 * match.
+	 */
+	ssid_len = hostapd_get_ssid(hapd, ssid, sizeof(ssid));
+	if (ssid_len < 0) {
+		wpa_printf(MSG_ERROR, "Could not read SSID from system");
+		return -1;
+	}
+	if (conf->ssid.ssid_set) {
+		/*
+		 * If SSID is specified in the config file and it differs
+		 * from what is being used then force installation of the
+		 * new SSID.
+		 */
+		set_ssid = (conf->ssid.ssid_len != (size_t) ssid_len ||
+			    os_memcmp(conf->ssid.ssid, ssid, ssid_len) != 0);
+	} else {
+		/*
+		 * No SSID in the config file; just use the one we got
+		 * from the system.
+		 */
+		set_ssid = 0;
+		conf->ssid.ssid_len = ssid_len;
+		os_memcpy(conf->ssid.ssid, ssid, conf->ssid.ssid_len);
+	}
+
+	/*
+	 * Short SSID calculation is identical to FCS and it is defined in
+	 * IEEE P802.11-REVmd/D3.0, 9.4.2.170.3 (Calculating the Short-SSID).
+	 */
+	conf->ssid.short_ssid = crc32(conf->ssid.ssid, conf->ssid.ssid_len);
+
+	if (!hostapd_drv_none(hapd)) {
+		wpa_printf(MSG_DEBUG, "Using interface %s with hwaddr " MACSTR
+			   " and ssid \"%s\"",
+			   conf->iface, MAC2STR(hapd->own_addr),
+			   wpa_ssid_txt(conf->ssid.ssid, conf->ssid.ssid_len));
+	}
+
+	if (hostapd_setup_wpa_psk(conf)) {
+		wpa_printf(MSG_ERROR, "WPA-PSK setup failed.");
+		return -1;
+	}
+
+	/* Set SSID for the kernel driver (to be used in beacon and probe
+	 * response frames) */
+	if (set_ssid && hostapd_set_ssid(hapd, conf->ssid.ssid,
+					 conf->ssid.ssid_len)) {
+		wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver");
+		return -1;
+	}
+
+	if (wpa_debug_level <= MSG_MSGDUMP)
+		conf->radius->msg_dumps = 1;
+#ifndef CONFIG_NO_RADIUS
+
+#ifdef CONFIG_SQLITE
+	if (conf->radius_req_attr_sqlite) {
+		if (sqlite3_open(conf->radius_req_attr_sqlite,
+				 &hapd->rad_attr_db)) {
+			wpa_printf(MSG_ERROR, "Could not open SQLite file '%s'",
+				   conf->radius_req_attr_sqlite);
+			return -1;
+		}
+
+		wpa_printf(MSG_DEBUG, "Opening RADIUS attribute database: %s",
+			   conf->radius_req_attr_sqlite);
+		if (!db_table_exists(hapd->rad_attr_db, "radius_attributes") &&
+		    db_table_create_radius_attributes(hapd->rad_attr_db) < 0)
+			return -1;
+	}
+#endif /* CONFIG_SQLITE */
+
+	hapd->radius = radius_client_init(hapd, conf->radius);
+	if (hapd->radius == NULL) {
+		wpa_printf(MSG_ERROR, "RADIUS client initialization failed.");
+		return -1;
+	}
+
+	if (conf->radius_das_port) {
+		struct radius_das_conf das_conf;
+		os_memset(&das_conf, 0, sizeof(das_conf));
+		das_conf.port = conf->radius_das_port;
+		das_conf.shared_secret = conf->radius_das_shared_secret;
+		das_conf.shared_secret_len =
+			conf->radius_das_shared_secret_len;
+		das_conf.client_addr = &conf->radius_das_client_addr;
+		das_conf.time_window = conf->radius_das_time_window;
+		das_conf.require_event_timestamp =
+			conf->radius_das_require_event_timestamp;
+		das_conf.require_message_authenticator =
+			conf->radius_das_require_message_authenticator;
+		das_conf.ctx = hapd;
+		das_conf.disconnect = hostapd_das_disconnect;
+		das_conf.coa = hostapd_das_coa;
+		hapd->radius_das = radius_das_init(&das_conf);
+		if (hapd->radius_das == NULL) {
+			wpa_printf(MSG_ERROR, "RADIUS DAS initialization "
+				   "failed.");
+			return -1;
+		}
+	}
+#endif /* CONFIG_NO_RADIUS */
+
+	if (hostapd_acl_init(hapd)) {
+		wpa_printf(MSG_ERROR, "ACL initialization failed.");
+		return -1;
+	}
+	if (hostapd_init_wps(hapd, conf))
+		return -1;
+
+#ifdef CONFIG_DPP
+	hapd->gas = gas_query_ap_init(hapd, hapd->msg_ctx);
+	if (!hapd->gas)
+		return -1;
+	if (hostapd_dpp_init(hapd))
+		return -1;
+#endif /* CONFIG_DPP */
+
+	if (authsrv_init(hapd) < 0)
+		return -1;
+
+	if (ieee802_1x_init(hapd)) {
+		wpa_printf(MSG_ERROR, "IEEE 802.1X initialization failed.");
+		return -1;
+	}
+
+	if ((conf->wpa || conf->osen) && hostapd_setup_wpa(hapd))
+		return -1;
+
+	if (accounting_init(hapd)) {
+		wpa_printf(MSG_ERROR, "Accounting initialization failed.");
+		return -1;
+	}
+
+#ifdef CONFIG_INTERWORKING
+	if (gas_serv_init(hapd)) {
+		wpa_printf(MSG_ERROR, "GAS server initialization failed");
+		return -1;
+	}
+
+	if (conf->qos_map_set_len &&
+	    hostapd_drv_set_qos_map(hapd, conf->qos_map_set,
+				    conf->qos_map_set_len)) {
+		wpa_printf(MSG_ERROR, "Failed to initialize QoS Map");
+		return -1;
+	}
+#endif /* CONFIG_INTERWORKING */
+
+	if (conf->bss_load_update_period && bss_load_update_init(hapd)) {
+		wpa_printf(MSG_ERROR, "BSS Load initialization failed");
+		return -1;
+	}
+
+	if (conf->proxy_arp) {
+		if (x_snoop_init(hapd)) {
+			wpa_printf(MSG_ERROR,
+				   "Generic snooping infrastructure initialization failed");
+			return -1;
+		}
+
+		if (dhcp_snoop_init(hapd)) {
+			wpa_printf(MSG_ERROR,
+				   "DHCP snooping initialization failed");
+			return -1;
+		}
+
+		if (ndisc_snoop_init(hapd)) {
+			wpa_printf(MSG_ERROR,
+				   "Neighbor Discovery snooping initialization failed");
+			return -1;
+		}
+	}
+
+	if (!hostapd_drv_none(hapd) && vlan_init(hapd)) {
+		wpa_printf(MSG_ERROR, "VLAN initialization failed.");
+		return -1;
+	}
+
+	if (!conf->start_disabled && ieee802_11_set_beacon(hapd) < 0)
+		return -1;
+
+	if (flush_old_stations && !conf->start_disabled &&
+	    conf->broadcast_deauth) {
+		u8 addr[ETH_ALEN];
+
+		/* Should any previously associated STA not have noticed that
+		 * the AP had stopped and restarted, send one more
+		 * deauthentication notification now that the AP is ready to
+		 * operate. */
+		wpa_dbg(hapd->msg_ctx, MSG_DEBUG,
+			"Deauthenticate all stations at BSS start");
+		os_memset(addr, 0xff, ETH_ALEN);
+		hostapd_drv_sta_deauth(hapd, addr,
+				       WLAN_REASON_PREV_AUTH_NOT_VALID);
+	}
+
+	if (hapd->wpa_auth && wpa_init_keys(hapd->wpa_auth) < 0)
+		return -1;
+
+	if (hapd->driver && hapd->driver->set_operstate)
+		hapd->driver->set_operstate(hapd->drv_priv, 1);
+
+	return 0;
+}
+
+
+static void hostapd_tx_queue_params(struct hostapd_iface *iface)
+{
+	struct hostapd_data *hapd = iface->bss[0];
+	int i;
+	struct hostapd_tx_queue_params *p;
+
+#ifdef CONFIG_MESH
+	if ((hapd->conf->mesh & MESH_ENABLED) && iface->mconf == NULL)
+		return;
+#endif /* CONFIG_MESH */
+
+	for (i = 0; i < NUM_TX_QUEUES; i++) {
+		p = &iface->conf->tx_queue[i];
+
+		if (hostapd_set_tx_queue_params(hapd, i, p->aifs, p->cwmin,
+						p->cwmax, p->burst)) {
+			wpa_printf(MSG_DEBUG, "Failed to set TX queue "
+				   "parameters for queue %d.", i);
+			/* Continue anyway */
+		}
+	}
+}
+
+
+static int hostapd_set_acl_list(struct hostapd_data *hapd,
+				struct mac_acl_entry *mac_acl,
+				int n_entries, u8 accept_acl)
+{
+	struct hostapd_acl_params *acl_params;
+	int i, err;
+
+	acl_params = os_zalloc(sizeof(*acl_params) +
+			       (n_entries * sizeof(acl_params->mac_acl[0])));
+	if (!acl_params)
+		return -ENOMEM;
+
+	for (i = 0; i < n_entries; i++)
+		os_memcpy(acl_params->mac_acl[i].addr, mac_acl[i].addr,
+			  ETH_ALEN);
+
+	acl_params->acl_policy = accept_acl;
+	acl_params->num_mac_acl = n_entries;
+
+	err = hostapd_drv_set_acl(hapd, acl_params);
+
+	os_free(acl_params);
+
+	return err;
+}
+
+
+static void hostapd_set_acl(struct hostapd_data *hapd)
+{
+	struct hostapd_config *conf = hapd->iconf;
+	int err;
+	u8 accept_acl;
+
+	if (hapd->iface->drv_max_acl_mac_addrs == 0)
+		return;
+
+	if (conf->bss[0]->macaddr_acl == DENY_UNLESS_ACCEPTED) {
+		accept_acl = 1;
+		err = hostapd_set_acl_list(hapd, conf->bss[0]->accept_mac,
+					   conf->bss[0]->num_accept_mac,
+					   accept_acl);
+		if (err) {
+			wpa_printf(MSG_DEBUG, "Failed to set accept acl");
+			return;
+		}
+	} else if (conf->bss[0]->macaddr_acl == ACCEPT_UNLESS_DENIED) {
+		accept_acl = 0;
+		err = hostapd_set_acl_list(hapd, conf->bss[0]->deny_mac,
+					   conf->bss[0]->num_deny_mac,
+					   accept_acl);
+		if (err) {
+			wpa_printf(MSG_DEBUG, "Failed to set deny acl");
+			return;
+		}
+	}
+}
+
+
+static int start_ctrl_iface_bss(struct hostapd_data *hapd)
+{
+	if (!hapd->iface->interfaces ||
+	    !hapd->iface->interfaces->ctrl_iface_init)
+		return 0;
+
+	if (hapd->iface->interfaces->ctrl_iface_init(hapd)) {
+		wpa_printf(MSG_ERROR,
+			   "Failed to setup control interface for %s",
+			   hapd->conf->iface);
+		return -1;
+	}
+
+	return 0;
+}
+
+
+static int start_ctrl_iface(struct hostapd_iface *iface)
+{
+	size_t i;
+
+	if (!iface->interfaces || !iface->interfaces->ctrl_iface_init)
+		return 0;
+
+	for (i = 0; i < iface->num_bss; i++) {
+		struct hostapd_data *hapd = iface->bss[i];
+		if (iface->interfaces->ctrl_iface_init(hapd)) {
+			wpa_printf(MSG_ERROR,
+				   "Failed to setup control interface for %s",
+				   hapd->conf->iface);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+
+static void channel_list_update_timeout(void *eloop_ctx, void *timeout_ctx)
+{
+	struct hostapd_iface *iface = eloop_ctx;
+
+	if (!iface->wait_channel_update) {
+		wpa_printf(MSG_INFO, "Channel list update timeout, but interface was not waiting for it");
+		return;
+	}
+
+	/*
+	 * It is possible that the existing channel list is acceptable, so try
+	 * to proceed.
+	 */
+	wpa_printf(MSG_DEBUG, "Channel list update timeout - try to continue anyway");
+	setup_interface2(iface);
+}
+
+
+void hostapd_channel_list_updated(struct hostapd_iface *iface, int initiator)
+{
+	if (!iface->wait_channel_update || initiator != REGDOM_SET_BY_USER)
+		return;
+
+	wpa_printf(MSG_DEBUG, "Channel list updated - continue setup");
+	eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
+	setup_interface2(iface);
+}
+
+
+static int setup_interface(struct hostapd_iface *iface)
+{
+	struct hostapd_data *hapd = iface->bss[0];
+	size_t i;
+
+	/*
+	 * It is possible that setup_interface() is called after the interface
+	 * was disabled etc., in which case driver_ap_teardown is possibly set
+	 * to 1. Clear it here so any other key/station deletion, which is not
+	 * part of a teardown flow, would also call the relevant driver
+	 * callbacks.
+	 */
+	iface->driver_ap_teardown = 0;
+
+	if (!iface->phy[0]) {
+		const char *phy = hostapd_drv_get_radio_name(hapd);
+		if (phy) {
+			wpa_printf(MSG_DEBUG, "phy: %s", phy);
+			os_strlcpy(iface->phy, phy, sizeof(iface->phy));
+		}
+	}
+
+	/*
+	 * Make sure that all BSSes get configured with a pointer to the same
+	 * driver interface.
+	 */
+	for (i = 1; i < iface->num_bss; i++) {
+		iface->bss[i]->driver = hapd->driver;
+		iface->bss[i]->drv_priv = hapd->drv_priv;
+	}
+
+	if (hostapd_validate_bssid_configuration(iface))
+		return -1;
+
+	/*
+	 * Initialize control interfaces early to allow external monitoring of
+	 * channel setup operations that may take considerable amount of time
+	 * especially for DFS cases.
+	 */
+	if (start_ctrl_iface(iface))
+		return -1;
+
+	if (hapd->iconf->country[0] && hapd->iconf->country[1]) {
+		char country[4], previous_country[4];
+
+		hostapd_set_state(iface, HAPD_IFACE_COUNTRY_UPDATE);
+		if (hostapd_get_country(hapd, previous_country) < 0)
+			previous_country[0] = '\0';
+
+		os_memcpy(country, hapd->iconf->country, 3);
+		country[3] = '\0';
+		if (hostapd_set_country(hapd, country) < 0) {
+			wpa_printf(MSG_ERROR, "Failed to set country code");
+			return -1;
+		}
+
+		wpa_printf(MSG_DEBUG, "Previous country code %s, new country code %s",
+			   previous_country, country);
+
+		if (os_strncmp(previous_country, country, 2) != 0) {
+			wpa_printf(MSG_DEBUG, "Continue interface setup after channel list update");
+			iface->wait_channel_update = 1;
+			eloop_register_timeout(5, 0,
+					       channel_list_update_timeout,
+					       iface, NULL);
+			return 0;
+		}
+	}
+
+	return setup_interface2(iface);
+}
+
+
+static int configured_fixed_chan_to_freq(struct hostapd_iface *iface)
+{
+	int freq, i, j;
+
+	if (!iface->conf->channel)
+		return 0;
+	if (iface->conf->op_class) {
+		freq = ieee80211_chan_to_freq(NULL, iface->conf->op_class,
+					      iface->conf->channel);
+		if (freq < 0) {
+			wpa_printf(MSG_INFO,
+				   "Could not convert op_class %u channel %u to operating frequency",
+				   iface->conf->op_class, iface->conf->channel);
+			return -1;
+		}
+		iface->freq = freq;
+		return 0;
+	}
+
+	/* Old configurations using only 2.4/5/60 GHz bands may not specify the
+	 * op_class parameter. Select a matching channel from the configured
+	 * mode using the channel parameter for these cases.
+	 */
+	for (j = 0; j < iface->num_hw_features; j++) {
+		struct hostapd_hw_modes *mode = &iface->hw_features[j];
+
+		if (iface->conf->hw_mode != HOSTAPD_MODE_IEEE80211ANY &&
+		    iface->conf->hw_mode != mode->mode)
+			continue;
+		for (i = 0; i < mode->num_channels; i++) {
+			struct hostapd_channel_data *chan = &mode->channels[i];
+
+			if (chan->chan == iface->conf->channel &&
+			    !is_6ghz_freq(chan->freq)) {
+				iface->freq = chan->freq;
+				return 0;
+			}
+		}
+	}
+
+	wpa_printf(MSG_INFO, "Could not determine operating frequency");
+	return -1;
+}
+
+#ifndef CONFIG_ACS
+#ifdef CONFIG_BRCM_AUTOMOTIVE
+void bcm_private_acs(struct hostapd_iface *iface)
+{
+        char cmd[1024];
+        char reply[1024];
+        char *p = cmd;
+        struct hostapd_data *hapd;
+
+        hapd = iface->bss[0];
+        if (hapd == NULL) {
+                wpa_printf(MSG_ERROR, "Failed to get good channel hapd is null");
+                return;
+        }
+
+        memset(cmd, 0, sizeof(cmd));
+        memset(reply, 0, sizeof(reply));
+
+        memcpy(p, "HAPD_AUTO_CHANNEL", 17);
+        p += 17;
+
+        if ((iface->conf->hw_mode == HOSTAPD_MODE_IEEE80211G)
+                        ||  (iface->conf->hw_mode == HOSTAPD_MODE_IEEE80211B)) {
+                memcpy(p, " band=2g", 8);
+        }
+        else {
+                memcpy(p, " band=5g", 8);
+        }
+
+        wpa_printf(MSG_DEBUG, "cmd %s", cmd);
+
+        if (!hapd->driver->driver_cmd)
+                return ;
+
+        if (hapd->driver->driver_cmd(hapd->drv_priv, cmd, reply, sizeof(reply)) <= 0) {
+                wpa_printf(MSG_ERROR, "Failed to get good channel");
+                return;
+        }
+
+        iface->conf->channel = atoi(reply);
+        wpa_printf(MSG_DEBUG, "Channel selected by private ACS = %d", iface->conf->channel);
+        return ;
+}
+#endif
+#endif
+
+static void hostapd_set_6ghz_sec_chan(struct hostapd_iface *iface)
+{
+	int bw, seg0;
+
+	if (!is_6ghz_op_class(iface->conf->op_class))
+		return;
+
+	seg0 = hostapd_get_oper_centr_freq_seg0_idx(iface->conf);
+	bw = center_idx_to_bw_6ghz(seg0);
+	/* Assign the secondary channel if absent in config for
+	 * bandwidths > 20 MHz */
+	if (bw > 20 && !iface->conf->secondary_channel) {
+		if (((iface->conf->channel - 1) / 4) % 2)
+			iface->conf->secondary_channel = -1;
+		else
+			iface->conf->secondary_channel = 1;
+	}
+}
+
+
+static int setup_interface2(struct hostapd_iface *iface)
+{
+	iface->wait_channel_update = 0;
+
+	if (hostapd_get_hw_features(iface)) {
+		/* Not all drivers support this yet, so continue without hw
+		 * feature data. */
+	} else {
+#ifndef CONFIG_ACS
+#ifdef CONFIG_BRCM_AUTOMOTIVE
+                if(!iface->conf->channel)
+                        bcm_private_acs(iface);
+#endif
+#endif
+		int ret;
+
+		ret = configured_fixed_chan_to_freq(iface);
+		if (ret < 0)
+			goto fail;
+
+		if (iface->conf->op_class) {
+			int ch_width;
+
+			ch_width = op_class_to_ch_width(iface->conf->op_class);
+			hostapd_set_oper_chwidth(iface->conf, ch_width);
+			hostapd_set_6ghz_sec_chan(iface);
+		}
+
+		ret = hostapd_select_hw_mode(iface);
+		if (ret < 0) {
+			wpa_printf(MSG_ERROR, "Could not select hw_mode and "
+				   "channel. (%d)", ret);
+			goto fail;
+		}
+		if (ret == 1) {
+			wpa_printf(MSG_DEBUG, "Interface initialization will be completed in a callback (ACS)");
+			return 0;
+		}
+		ret = hostapd_check_edmg_capab(iface);
+		if (ret < 0)
+			goto fail;
+		ret = hostapd_check_he_6ghz_capab(iface);
+		if (ret < 0)
+			goto fail;
+		ret = hostapd_check_ht_capab(iface);
+		if (ret < 0)
+			goto fail;
+		if (ret == 1) {
+			wpa_printf(MSG_DEBUG, "Interface initialization will "
+				   "be completed in a callback");
+			return 0;
+		}
+
+		if (iface->conf->ieee80211h)
+			wpa_printf(MSG_DEBUG, "DFS support is enabled");
+	}
+	return hostapd_setup_interface_complete(iface, 0);
+
+fail:
+	hostapd_set_state(iface, HAPD_IFACE_DISABLED);
+	wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
+	if (iface->interfaces && iface->interfaces->terminate_on_error)
+		eloop_terminate();
+	return -1;
+}
+
+
+#ifdef CONFIG_FST
+
+static const u8 * fst_hostapd_get_bssid_cb(void *ctx)
+{
+	struct hostapd_data *hapd = ctx;
+
+	return hapd->own_addr;
+}
+
+
+static void fst_hostapd_get_channel_info_cb(void *ctx,
+					    enum hostapd_hw_mode *hw_mode,
+					    u8 *channel)
+{
+	struct hostapd_data *hapd = ctx;
+
+	*hw_mode = ieee80211_freq_to_chan(hapd->iface->freq, channel);
+}
+
+
+static void fst_hostapd_set_ies_cb(void *ctx, const struct wpabuf *fst_ies)
+{
+	struct hostapd_data *hapd = ctx;
+
+	if (hapd->iface->fst_ies != fst_ies) {
+		hapd->iface->fst_ies = fst_ies;
+		if (ieee802_11_set_beacon(hapd))
+			wpa_printf(MSG_WARNING, "FST: Cannot set beacon");
+	}
+}
+
+
+static int fst_hostapd_send_action_cb(void *ctx, const u8 *da,
+				      struct wpabuf *buf)
+{
+	struct hostapd_data *hapd = ctx;
+
+	return hostapd_drv_send_action(hapd, hapd->iface->freq, 0, da,
+				       wpabuf_head(buf), wpabuf_len(buf));
+}
+
+
+static const struct wpabuf * fst_hostapd_get_mb_ie_cb(void *ctx, const u8 *addr)
+{
+	struct hostapd_data *hapd = ctx;
+	struct sta_info *sta = ap_get_sta(hapd, addr);
+
+	return sta ? sta->mb_ies : NULL;
+}
+
+
+static void fst_hostapd_update_mb_ie_cb(void *ctx, const u8 *addr,
+					const u8 *buf, size_t size)
+{
+	struct hostapd_data *hapd = ctx;
+	struct sta_info *sta = ap_get_sta(hapd, addr);
+
+	if (sta) {
+		struct mb_ies_info info;
+
+		if (!mb_ies_info_by_ies(&info, buf, size)) {
+			wpabuf_free(sta->mb_ies);
+			sta->mb_ies = mb_ies_by_info(&info);
+		}
+	}
+}
+
+
+static const u8 * fst_hostapd_get_sta(struct fst_get_peer_ctx **get_ctx,
+				      bool mb_only)
+{
+	struct sta_info *s = (struct sta_info *) *get_ctx;
+
+	if (mb_only) {
+		for (; s && !s->mb_ies; s = s->next)
+			;
+	}
+
+	if (s) {
+		*get_ctx = (struct fst_get_peer_ctx *) s->next;
+
+		return s->addr;
+	}
+
+	*get_ctx = NULL;
+	return NULL;
+}
+
+
+static const u8 * fst_hostapd_get_peer_first(void *ctx,
+					     struct fst_get_peer_ctx **get_ctx,
+					     bool mb_only)
+{
+	struct hostapd_data *hapd = ctx;
+
+	*get_ctx = (struct fst_get_peer_ctx *) hapd->sta_list;
+
+	return fst_hostapd_get_sta(get_ctx, mb_only);
+}
+
+
+static const u8 * fst_hostapd_get_peer_next(void *ctx,
+					    struct fst_get_peer_ctx **get_ctx,
+					    bool mb_only)
+{
+	return fst_hostapd_get_sta(get_ctx, mb_only);
+}
+
+
+void fst_hostapd_fill_iface_obj(struct hostapd_data *hapd,
+				struct fst_wpa_obj *iface_obj)
+{
+	iface_obj->ctx = hapd;
+	iface_obj->get_bssid = fst_hostapd_get_bssid_cb;
+	iface_obj->get_channel_info = fst_hostapd_get_channel_info_cb;
+	iface_obj->set_ies = fst_hostapd_set_ies_cb;
+	iface_obj->send_action = fst_hostapd_send_action_cb;
+	iface_obj->get_mb_ie = fst_hostapd_get_mb_ie_cb;
+	iface_obj->update_mb_ie = fst_hostapd_update_mb_ie_cb;
+	iface_obj->get_peer_first = fst_hostapd_get_peer_first;
+	iface_obj->get_peer_next = fst_hostapd_get_peer_next;
+}
+
+#endif /* CONFIG_FST */
+
+#ifdef CONFIG_OWE
+
+static int hostapd_owe_iface_iter(struct hostapd_iface *iface, void *ctx)
+{
+	struct hostapd_data *hapd = ctx;
+	size_t i;
+
+	for (i = 0; i < iface->num_bss; i++) {
+		struct hostapd_data *bss = iface->bss[i];
+
+		if (os_strcmp(hapd->conf->owe_transition_ifname,
+			      bss->conf->iface) != 0)
+			continue;
+
+		wpa_printf(MSG_DEBUG,
+			   "OWE: ifname=%s found transition mode ifname=%s BSSID "
+			   MACSTR " SSID %s",
+			   hapd->conf->iface, bss->conf->iface,
+			   MAC2STR(bss->own_addr),
+			   wpa_ssid_txt(bss->conf->ssid.ssid,
+					bss->conf->ssid.ssid_len));
+		if (!bss->conf->ssid.ssid_set || !bss->conf->ssid.ssid_len ||
+		    is_zero_ether_addr(bss->own_addr))
+			continue;
+
+		os_memcpy(hapd->conf->owe_transition_bssid, bss->own_addr,
+			  ETH_ALEN);
+		os_memcpy(hapd->conf->owe_transition_ssid,
+			  bss->conf->ssid.ssid, bss->conf->ssid.ssid_len);
+		hapd->conf->owe_transition_ssid_len = bss->conf->ssid.ssid_len;
+		wpa_printf(MSG_DEBUG,
+			   "OWE: Copied transition mode information");
+		return 1;
+	}
+
+	return 0;
+}
+
+
+int hostapd_owe_trans_get_info(struct hostapd_data *hapd)
+{
+	if (hapd->conf->owe_transition_ssid_len > 0 &&
+	    !is_zero_ether_addr(hapd->conf->owe_transition_bssid))
+		return 0;
+
+	/* Find transition mode SSID/BSSID information from a BSS operated by
+	 * this hostapd instance. */
+	if (!hapd->iface->interfaces ||
+	    !hapd->iface->interfaces->for_each_interface)
+		return hostapd_owe_iface_iter(hapd->iface, hapd);
+	else
+		return hapd->iface->interfaces->for_each_interface(
+			hapd->iface->interfaces, hostapd_owe_iface_iter, hapd);
+}
+
+
+static int hostapd_owe_iface_iter2(struct hostapd_iface *iface, void *ctx)
+{
+	size_t i;
+
+	for (i = 0; i < iface->num_bss; i++) {
+		struct hostapd_data *bss = iface->bss[i];
+		int res;
+
+		if (!bss->conf->owe_transition_ifname[0])
+			continue;
+		if (bss->iface->state != HAPD_IFACE_ENABLED) {
+			wpa_printf(MSG_DEBUG,
+				   "OWE: Interface %s state %s - defer beacon update",
+				   bss->conf->iface,
+				   hostapd_state_text(bss->iface->state));
+			continue;
+		}
+		res = hostapd_owe_trans_get_info(bss);
+		if (res == 0)
+			continue;
+		wpa_printf(MSG_DEBUG,
+			   "OWE: Matching transition mode interface enabled - update beacon data for %s",
+			   bss->conf->iface);
+		ieee802_11_set_beacon(bss);
+	}
+
+	return 0;
+}
+
+#endif /* CONFIG_OWE */
+
+
+static void hostapd_owe_update_trans(struct hostapd_iface *iface)
+{
+#ifdef CONFIG_OWE
+	/* Check whether the enabled BSS can complete OWE transition mode
+	 * configuration for any pending interface. */
+	if (!iface->interfaces ||
+	    !iface->interfaces->for_each_interface)
+		hostapd_owe_iface_iter2(iface, NULL);
+	else
+		iface->interfaces->for_each_interface(
+			iface->interfaces, hostapd_owe_iface_iter2, NULL);
+#endif /* CONFIG_OWE */
+}
+
+
+static void hostapd_interface_setup_failure_handler(void *eloop_ctx,
+						    void *timeout_ctx)
+{
+	struct hostapd_iface *iface = eloop_ctx;
+	struct hostapd_data *hapd;
+
+	if (iface->num_bss < 1 || !iface->bss || !iface->bss[0])
+		return;
+	hapd = iface->bss[0];
+	if (hapd->setup_complete_cb)
+		hapd->setup_complete_cb(hapd->setup_complete_cb_ctx);
+}
+
+
+static int hostapd_setup_interface_complete_sync(struct hostapd_iface *iface,
+						 int err)
+{
+	struct hostapd_data *hapd = iface->bss[0];
+	size_t j;
+	u8 *prev_addr;
+	int delay_apply_cfg = 0;
+	int res_dfs_offload = 0;
+
+	if (err)
+		goto fail;
+
+	wpa_printf(MSG_DEBUG, "Completing interface initialization");
+	if (iface->freq) {
+#ifdef NEED_AP_MLME
+		int res;
+#endif /* NEED_AP_MLME */
+
+		wpa_printf(MSG_DEBUG, "Mode: %s  Channel: %d  "
+			   "Frequency: %d MHz",
+			   hostapd_hw_mode_txt(iface->conf->hw_mode),
+			   iface->conf->channel, iface->freq);
+
+#ifdef NEED_AP_MLME
+		/* Handle DFS only if it is not offloaded to the driver */
+		if (!(iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)) {
+			/* Check DFS */
+			res = hostapd_handle_dfs(iface);
+			if (res <= 0) {
+				if (res < 0)
+					goto fail;
+				return res;
+			}
+		} else {
+			/* If DFS is offloaded to the driver */
+			res_dfs_offload = hostapd_handle_dfs_offload(iface);
+			if (res_dfs_offload <= 0) {
+				if (res_dfs_offload < 0)
+					goto fail;
+			} else {
+				wpa_printf(MSG_DEBUG,
+					   "Proceed with AP/channel setup");
+				/*
+				 * If this is a DFS channel, move to completing
+				 * AP setup.
+				 */
+				if (res_dfs_offload == 1)
+					goto dfs_offload;
+				/* Otherwise fall through. */
+			}
+		}
+#endif /* NEED_AP_MLME */
+
+#ifdef CONFIG_MESH
+		if (iface->mconf != NULL) {
+			wpa_printf(MSG_DEBUG,
+				   "%s: Mesh configuration will be applied while joining the mesh network",
+				   iface->bss[0]->conf->iface);
+			delay_apply_cfg = 1;
+		}
+#endif /* CONFIG_MESH */
+
+		if (!delay_apply_cfg &&
+		    hostapd_set_freq(hapd, hapd->iconf->hw_mode, iface->freq,
+				     hapd->iconf->channel,
+				     hapd->iconf->enable_edmg,
+				     hapd->iconf->edmg_channel,
+				     hapd->iconf->ieee80211n,
+				     hapd->iconf->ieee80211ac,
+				     hapd->iconf->ieee80211ax,
+				     hapd->iconf->secondary_channel,
+				     hostapd_get_oper_chwidth(hapd->iconf),
+				     hostapd_get_oper_centr_freq_seg0_idx(
+					     hapd->iconf),
+				     hostapd_get_oper_centr_freq_seg1_idx(
+					     hapd->iconf))) {
+			wpa_printf(MSG_ERROR, "Could not set channel for "
+				   "kernel driver");
+			goto fail;
+		}
+	}
+
+	if (iface->current_mode) {
+		if (hostapd_prepare_rates(iface, iface->current_mode)) {
+			wpa_printf(MSG_ERROR, "Failed to prepare rates "
+				   "table.");
+			hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
+				       HOSTAPD_LEVEL_WARNING,
+				       "Failed to prepare rates table.");
+			goto fail;
+		}
+	}
+
+	if (hapd->iconf->rts_threshold >= -1 &&
+	    hostapd_set_rts(hapd, hapd->iconf->rts_threshold) &&
+	    hapd->iconf->rts_threshold >= -1) {
+		wpa_printf(MSG_ERROR, "Could not set RTS threshold for "
+			   "kernel driver");
+		goto fail;
+	}
+
+	if (hapd->iconf->fragm_threshold >= -1 &&
+	    hostapd_set_frag(hapd, hapd->iconf->fragm_threshold) &&
+	    hapd->iconf->fragm_threshold != -1) {
+		wpa_printf(MSG_ERROR, "Could not set fragmentation threshold "
+			   "for kernel driver");
+		goto fail;
+	}
+
+	prev_addr = hapd->own_addr;
+
+	for (j = 0; j < iface->num_bss; j++) {
+		hapd = iface->bss[j];
+		if (j)
+			os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN);
+		if (hostapd_setup_bss(hapd, j == 0)) {
+			for (;;) {
+				hapd = iface->bss[j];
+				hostapd_bss_deinit_no_free(hapd);
+				hostapd_free_hapd_data(hapd);
+				if (j == 0)
+					break;
+				j--;
+			}
+			goto fail;
+		}
+		if (is_zero_ether_addr(hapd->conf->bssid))
+			prev_addr = hapd->own_addr;
+	}
+	hapd = iface->bss[0];
+
+	hostapd_tx_queue_params(iface);
+
+	ap_list_init(iface);
+
+	hostapd_set_acl(hapd);
+
+	if (hostapd_driver_commit(hapd) < 0) {
+		wpa_printf(MSG_ERROR, "%s: Failed to commit driver "
+			   "configuration", __func__);
+		goto fail;
+	}
+
+	/*
+	 * WPS UPnP module can be initialized only when the "upnp_iface" is up.
+	 * If "interface" and "upnp_iface" are the same (e.g., non-bridge
+	 * mode), the interface is up only after driver_commit, so initialize
+	 * WPS after driver_commit.
+	 */
+	for (j = 0; j < iface->num_bss; j++) {
+		if (hostapd_init_wps_complete(iface->bss[j]))
+			goto fail;
+	}
+
+	if ((iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) &&
+	    !res_dfs_offload) {
+		/*
+		 * If freq is DFS, and DFS is offloaded to the driver, then wait
+		 * for CAC to complete.
+		 */
+		wpa_printf(MSG_DEBUG, "%s: Wait for CAC to complete", __func__);
+		return res_dfs_offload;
+	}
+
+#ifdef NEED_AP_MLME
+dfs_offload:
+#endif /* NEED_AP_MLME */
+
+#ifdef CONFIG_FST
+	if (hapd->iconf->fst_cfg.group_id[0]) {
+		struct fst_wpa_obj iface_obj;
+
+		fst_hostapd_fill_iface_obj(hapd, &iface_obj);
+		iface->fst = fst_attach(hapd->conf->iface, hapd->own_addr,
+					&iface_obj, &hapd->iconf->fst_cfg);
+		if (!iface->fst) {
+			wpa_printf(MSG_ERROR, "Could not attach to FST %s",
+				   hapd->iconf->fst_cfg.group_id);
+			goto fail;
+		}
+	}
+#endif /* CONFIG_FST */
+
+	hostapd_set_state(iface, HAPD_IFACE_ENABLED);
+	hostapd_owe_update_trans(iface);
+	airtime_policy_update_init(iface);
+	wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_ENABLED);
+	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)
+		iface->interfaces->terminate_on_error--;
+
+	for (j = 0; j < iface->num_bss; j++)
+		hostapd_neighbor_set_own_report(iface->bss[j]);
+
+	return 0;
+
+fail:
+	wpa_printf(MSG_ERROR, "Interface initialization failed");
+	hostapd_set_state(iface, HAPD_IFACE_DISABLED);
+	wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
+#ifdef CONFIG_FST
+	if (iface->fst) {
+		fst_detach(iface->fst);
+		iface->fst = NULL;
+	}
+#endif /* CONFIG_FST */
+
+	if (iface->interfaces && iface->interfaces->terminate_on_error) {
+		eloop_terminate();
+	} else if (hapd->setup_complete_cb) {
+		/*
+		 * Calling hapd->setup_complete_cb directly may cause iface
+		 * deinitialization which may be accessed later by the caller.
+		 */
+		eloop_register_timeout(0, 0,
+				       hostapd_interface_setup_failure_handler,
+				       iface, NULL);
+	}
+
+	return -1;
+}
+
+
+/**
+ * hostapd_setup_interface_complete - Complete interface setup
+ *
+ * This function is called when previous steps in the interface setup has been
+ * completed. This can also start operations, e.g., DFS, that will require
+ * additional processing before interface is ready to be enabled. Such
+ * operations will call this function from eloop callbacks when finished.
+ */
+int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err)
+{
+	struct hapd_interfaces *interfaces = iface->interfaces;
+	struct hostapd_data *hapd = iface->bss[0];
+	unsigned int i;
+	int not_ready_in_sync_ifaces = 0;
+
+	if (!iface->need_to_start_in_sync)
+		return hostapd_setup_interface_complete_sync(iface, err);
+
+	if (err) {
+		wpa_printf(MSG_ERROR, "Interface initialization failed");
+		hostapd_set_state(iface, HAPD_IFACE_DISABLED);
+		iface->need_to_start_in_sync = 0;
+		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
+		if (interfaces && interfaces->terminate_on_error)
+			eloop_terminate();
+		return -1;
+	}
+
+	if (iface->ready_to_start_in_sync) {
+		/* Already in ready and waiting. should never happpen */
+		return 0;
+	}
+
+	for (i = 0; i < interfaces->count; i++) {
+		if (interfaces->iface[i]->need_to_start_in_sync &&
+		    !interfaces->iface[i]->ready_to_start_in_sync)
+			not_ready_in_sync_ifaces++;
+	}
+
+	/*
+	 * Check if this is the last interface, if yes then start all the other
+	 * waiting interfaces. If not, add this interface to the waiting list.
+	 */
+	if (not_ready_in_sync_ifaces > 1 && iface->state == HAPD_IFACE_DFS) {
+		/*
+		 * If this interface went through CAC, do not synchronize, just
+		 * start immediately.
+		 */
+		iface->need_to_start_in_sync = 0;
+		wpa_printf(MSG_INFO,
+			   "%s: Finished CAC - bypass sync and start interface",
+			   iface->bss[0]->conf->iface);
+		return hostapd_setup_interface_complete_sync(iface, err);
+	}
+
+	if (not_ready_in_sync_ifaces > 1) {
+		/* need to wait as there are other interfaces still coming up */
+		iface->ready_to_start_in_sync = 1;
+		wpa_printf(MSG_INFO,
+			   "%s: Interface waiting to sync with other interfaces",
+			   iface->bss[0]->conf->iface);
+		return 0;
+	}
+
+	wpa_printf(MSG_INFO,
+		   "%s: Last interface to sync - starting all interfaces",
+		   iface->bss[0]->conf->iface);
+	iface->need_to_start_in_sync = 0;
+	hostapd_setup_interface_complete_sync(iface, err);
+	for (i = 0; i < interfaces->count; i++) {
+		if (interfaces->iface[i]->need_to_start_in_sync &&
+		    interfaces->iface[i]->ready_to_start_in_sync) {
+			hostapd_setup_interface_complete_sync(
+				interfaces->iface[i], 0);
+			/* Only once the interfaces are sync started */
+			interfaces->iface[i]->need_to_start_in_sync = 0;
+		}
+	}
+
+	return 0;
+}
+
+
+/**
+ * hostapd_setup_interface - Setup of an interface
+ * @iface: Pointer to interface data.
+ * Returns: 0 on success, -1 on failure
+ *
+ * Initializes the driver interface, validates the configuration,
+ * and sets driver parameters based on the configuration.
+ * Flushes old stations, sets the channel, encryption,
+ * beacons, and WDS links based on the configuration.
+ *
+ * If interface setup requires more time, e.g., to perform HT co-ex scans, ACS,
+ * or DFS operations, this function returns 0 before such operations have been
+ * completed. The pending operations are registered into eloop and will be
+ * completed from eloop callbacks. Those callbacks end up calling
+ * hostapd_setup_interface_complete() once setup has been completed.
+ */
+int hostapd_setup_interface(struct hostapd_iface *iface)
+{
+	int ret;
+
+	if (!iface->conf)
+		return -1;
+	ret = setup_interface(iface);
+	if (ret) {
+		wpa_printf(MSG_ERROR, "%s: Unable to setup interface.",
+			   iface->conf->bss[0]->iface);
+		return -1;
+	}
+
+	return 0;
+}
+
+
+/**
+ * hostapd_alloc_bss_data - Allocate and initialize per-BSS data
+ * @hapd_iface: Pointer to interface data
+ * @conf: Pointer to per-interface configuration
+ * @bss: Pointer to per-BSS configuration for this BSS
+ * Returns: Pointer to allocated BSS data
+ *
+ * This function is used to allocate per-BSS data structure. This data will be
+ * freed after hostapd_cleanup() is called for it during interface
+ * deinitialization.
+ */
+struct hostapd_data *
+hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface,
+		       struct hostapd_config *conf,
+		       struct hostapd_bss_config *bss)
+{
+	struct hostapd_data *hapd;
+
+	hapd = os_zalloc(sizeof(*hapd));
+	if (hapd == NULL)
+		return NULL;
+
+	hapd->new_assoc_sta_cb = hostapd_new_assoc_sta;
+	hapd->iconf = conf;
+	hapd->conf = bss;
+	hapd->iface = hapd_iface;
+	if (conf)
+		hapd->driver = conf->driver;
+	hapd->ctrl_sock = -1;
+	dl_list_init(&hapd->ctrl_dst);
+	dl_list_init(&hapd->nr_db);
+	hapd->dhcp_sock = -1;
+#ifdef CONFIG_IEEE80211R_AP
+	dl_list_init(&hapd->l2_queue);
+	dl_list_init(&hapd->l2_oui_queue);
+#endif /* CONFIG_IEEE80211R_AP */
+#ifdef CONFIG_SAE
+	dl_list_init(&hapd->sae_commit_queue);
+#endif /* CONFIG_SAE */
+
+	return hapd;
+}
+
+
+static void hostapd_bss_deinit(struct hostapd_data *hapd)
+{
+	if (!hapd)
+		return;
+	wpa_printf(MSG_DEBUG, "%s: deinit bss %s", __func__,
+		   hapd->conf ? hapd->conf->iface : "N/A");
+	hostapd_bss_deinit_no_free(hapd);
+	wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
+#ifdef CONFIG_SQLITE
+	if (hapd->rad_attr_db) {
+		sqlite3_close(hapd->rad_attr_db);
+		hapd->rad_attr_db = NULL;
+	}
+#endif /* CONFIG_SQLITE */
+	hostapd_cleanup(hapd);
+}
+
+
+void hostapd_interface_deinit(struct hostapd_iface *iface)
+{
+	int j;
+
+	wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
+	if (iface == NULL)
+		return;
+
+	hostapd_set_state(iface, HAPD_IFACE_DISABLED);
+
+	eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
+	iface->wait_channel_update = 0;
+
+#ifdef CONFIG_FST
+	if (iface->fst) {
+		fst_detach(iface->fst);
+		iface->fst = NULL;
+	}
+#endif /* CONFIG_FST */
+
+	for (j = (int) iface->num_bss - 1; j >= 0; j--) {
+		if (!iface->bss)
+			break;
+		hostapd_bss_deinit(iface->bss[j]);
+	}
+
+#ifdef NEED_AP_MLME
+	hostapd_stop_setup_timers(iface);
+	eloop_cancel_timeout(ap_ht2040_timeout, iface, NULL);
+#endif /* NEED_AP_MLME */
+}
+
+
+void hostapd_interface_free(struct hostapd_iface *iface)
+{
+	size_t j;
+	wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
+	for (j = 0; j < iface->num_bss; j++) {
+		if (!iface->bss)
+			break;
+		wpa_printf(MSG_DEBUG, "%s: free hapd %p",
+			   __func__, iface->bss[j]);
+		os_free(iface->bss[j]);
+	}
+	hostapd_cleanup_iface(iface);
+}
+
+
+struct hostapd_iface * hostapd_alloc_iface(void)
+{
+	struct hostapd_iface *hapd_iface;
+
+	hapd_iface = os_zalloc(sizeof(*hapd_iface));
+	if (!hapd_iface)
+		return NULL;
+
+	dl_list_init(&hapd_iface->sta_seen);
+
+	return hapd_iface;
+}
+
+
+/**
+ * hostapd_init - Allocate and initialize per-interface data
+ * @config_file: Path to the configuration file
+ * Returns: Pointer to the allocated interface data or %NULL on failure
+ *
+ * This function is used to allocate main data structures for per-interface
+ * data. The allocated data buffer will be freed by calling
+ * hostapd_cleanup_iface().
+ */
+struct hostapd_iface * hostapd_init(struct hapd_interfaces *interfaces,
+				    const char *config_file)
+{
+	struct hostapd_iface *hapd_iface = NULL;
+	struct hostapd_config *conf = NULL;
+	struct hostapd_data *hapd;
+	size_t i;
+
+	hapd_iface = hostapd_alloc_iface();
+	if (hapd_iface == NULL)
+		goto fail;
+
+	hapd_iface->config_fname = os_strdup(config_file);
+	if (hapd_iface->config_fname == NULL)
+		goto fail;
+
+	conf = interfaces->config_read_cb(hapd_iface->config_fname);
+	if (conf == NULL)
+		goto fail;
+	hapd_iface->conf = conf;
+
+	hapd_iface->num_bss = conf->num_bss;
+	hapd_iface->bss = os_calloc(conf->num_bss,
+				    sizeof(struct hostapd_data *));
+	if (hapd_iface->bss == NULL)
+		goto fail;
+
+	for (i = 0; i < conf->num_bss; i++) {
+		hapd = hapd_iface->bss[i] =
+			hostapd_alloc_bss_data(hapd_iface, conf,
+					       conf->bss[i]);
+		if (hapd == NULL)
+			goto fail;
+		hapd->msg_ctx = hapd;
+	}
+
+	return hapd_iface;
+
+fail:
+	wpa_printf(MSG_ERROR, "Failed to set up interface with %s",
+		   config_file);
+	if (conf)
+		hostapd_config_free(conf);
+	if (hapd_iface) {
+		os_free(hapd_iface->config_fname);
+		os_free(hapd_iface->bss);
+		wpa_printf(MSG_DEBUG, "%s: free iface %p",
+			   __func__, hapd_iface);
+		os_free(hapd_iface);
+	}
+	return NULL;
+}
+
+
+static int ifname_in_use(struct hapd_interfaces *interfaces, const char *ifname)
+{
+	size_t i, j;
+
+	for (i = 0; i < interfaces->count; i++) {
+		struct hostapd_iface *iface = interfaces->iface[i];
+		for (j = 0; j < iface->num_bss; j++) {
+			struct hostapd_data *hapd = iface->bss[j];
+			if (os_strcmp(ifname, hapd->conf->iface) == 0)
+				return 1;
+		}
+	}
+
+	return 0;
+}
+
+
+/**
+ * hostapd_interface_init_bss - Read configuration file and init BSS data
+ *
+ * This function is used to parse configuration file for a BSS. This BSS is
+ * added to an existing interface sharing the same radio (if any) or a new
+ * interface is created if this is the first interface on a radio. This
+ * allocate memory for the BSS. No actual driver operations are started.
+ *
+ * This is similar to hostapd_interface_init(), but for a case where the
+ * configuration is used to add a single BSS instead of all BSSes for a radio.
+ */
+struct hostapd_iface *
+hostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy,
+			   const char *config_fname, int debug)
+{
+	struct hostapd_iface *new_iface = NULL, *iface = NULL;
+	struct hostapd_data *hapd;
+	int k;
+	size_t i, bss_idx;
+
+	if (!phy || !*phy)
+		return NULL;
+
+	for (i = 0; i < interfaces->count; i++) {
+		if (os_strcmp(interfaces->iface[i]->phy, phy) == 0) {
+			iface = interfaces->iface[i];
+			break;
+		}
+	}
+
+	wpa_printf(MSG_INFO, "Configuration file: %s (phy %s)%s",
+		   config_fname, phy, iface ? "" : " --> new PHY");
+	if (iface) {
+		struct hostapd_config *conf;
+		struct hostapd_bss_config **tmp_conf;
+		struct hostapd_data **tmp_bss;
+		struct hostapd_bss_config *bss;
+		const char *ifname;
+
+		/* Add new BSS to existing iface */
+		conf = interfaces->config_read_cb(config_fname);
+		if (conf == NULL)
+			return NULL;
+		if (conf->num_bss > 1) {
+			wpa_printf(MSG_ERROR, "Multiple BSSes specified in BSS-config");
+			hostapd_config_free(conf);
+			return NULL;
+		}
+
+		ifname = conf->bss[0]->iface;
+		if (ifname[0] != '\0' && ifname_in_use(interfaces, ifname)) {
+			wpa_printf(MSG_ERROR,
+				   "Interface name %s already in use", ifname);
+			hostapd_config_free(conf);
+			return NULL;
+		}
+
+		tmp_conf = os_realloc_array(
+			iface->conf->bss, iface->conf->num_bss + 1,
+			sizeof(struct hostapd_bss_config *));
+		tmp_bss = os_realloc_array(iface->bss, iface->num_bss + 1,
+					   sizeof(struct hostapd_data *));
+		if (tmp_bss)
+			iface->bss = tmp_bss;
+		if (tmp_conf) {
+			iface->conf->bss = tmp_conf;
+			iface->conf->last_bss = tmp_conf[0];
+		}
+		if (tmp_bss == NULL || tmp_conf == NULL) {
+			hostapd_config_free(conf);
+			return NULL;
+		}
+		bss = iface->conf->bss[iface->conf->num_bss] = conf->bss[0];
+		iface->conf->num_bss++;
+
+		hapd = hostapd_alloc_bss_data(iface, iface->conf, bss);
+		if (hapd == NULL) {
+			iface->conf->num_bss--;
+			hostapd_config_free(conf);
+			return NULL;
+		}
+		iface->conf->last_bss = bss;
+		iface->bss[iface->num_bss] = hapd;
+		hapd->msg_ctx = hapd;
+
+		bss_idx = iface->num_bss++;
+		conf->num_bss--;
+		conf->bss[0] = NULL;
+		hostapd_config_free(conf);
+	} else {
+		/* Add a new iface with the first BSS */
+		new_iface = iface = hostapd_init(interfaces, config_fname);
+		if (!iface)
+			return NULL;
+		os_strlcpy(iface->phy, phy, sizeof(iface->phy));
+		iface->interfaces = interfaces;
+		bss_idx = 0;
+	}
+
+	for (k = 0; k < debug; k++) {
+		if (iface->bss[bss_idx]->conf->logger_stdout_level > 0)
+			iface->bss[bss_idx]->conf->logger_stdout_level--;
+	}
+
+	if (iface->conf->bss[bss_idx]->iface[0] == '\0' &&
+	    !hostapd_drv_none(iface->bss[bss_idx])) {
+		wpa_printf(MSG_ERROR, "Interface name not specified in %s",
+			   config_fname);
+		if (new_iface)
+			hostapd_interface_deinit_free(new_iface);
+		return NULL;
+	}
+
+	return iface;
+}
+
+
+void hostapd_interface_deinit_free(struct hostapd_iface *iface)
+{
+	const struct wpa_driver_ops *driver;
+	void *drv_priv;
+
+	wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
+	if (iface == NULL)
+		return;
+	wpa_printf(MSG_DEBUG, "%s: num_bss=%u conf->num_bss=%u",
+		   __func__, (unsigned int) iface->num_bss,
+		   (unsigned int) iface->conf->num_bss);
+	driver = iface->bss[0]->driver;
+	drv_priv = iface->bss[0]->drv_priv;
+	hostapd_interface_deinit(iface);
+	wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit",
+		   __func__, driver, drv_priv);
+	if (driver && driver->hapd_deinit && drv_priv) {
+		driver->hapd_deinit(drv_priv);
+		iface->bss[0]->drv_priv = NULL;
+	}
+	hostapd_interface_free(iface);
+}
+
+
+static void hostapd_deinit_driver(const struct wpa_driver_ops *driver,
+				  void *drv_priv,
+				  struct hostapd_iface *hapd_iface)
+{
+	size_t j;
+
+	wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit",
+		   __func__, driver, drv_priv);
+	if (driver && driver->hapd_deinit && drv_priv) {
+		driver->hapd_deinit(drv_priv);
+		for (j = 0; j < hapd_iface->num_bss; j++) {
+			wpa_printf(MSG_DEBUG, "%s:bss[%d]->drv_priv=%p",
+				   __func__, (int) j,
+				   hapd_iface->bss[j]->drv_priv);
+			if (hapd_iface->bss[j]->drv_priv == drv_priv) {
+				hapd_iface->bss[j]->drv_priv = NULL;
+				hapd_iface->extended_capa = NULL;
+				hapd_iface->extended_capa_mask = NULL;
+				hapd_iface->extended_capa_len = 0;
+			}
+		}
+	}
+}
+
+
+int hostapd_enable_iface(struct hostapd_iface *hapd_iface)
+{
+	size_t j;
+
+	if (!hapd_iface)
+		return -1;
+
+	if (hapd_iface->enable_iface_cb)
+		return hapd_iface->enable_iface_cb(hapd_iface);
+
+	if (hapd_iface->bss[0]->drv_priv != NULL) {
+		wpa_printf(MSG_ERROR, "Interface %s already enabled",
+			   hapd_iface->conf->bss[0]->iface);
+		return -1;
+	}
+
+	wpa_printf(MSG_DEBUG, "Enable interface %s",
+		   hapd_iface->conf->bss[0]->iface);
+
+	for (j = 0; j < hapd_iface->num_bss; j++)
+		hostapd_set_security_params(hapd_iface->conf->bss[j], 1);
+	if (hostapd_config_check(hapd_iface->conf, 1) < 0) {
+		wpa_printf(MSG_INFO, "Invalid configuration - cannot enable");
+		return -1;
+	}
+
+	if (hapd_iface->interfaces == NULL ||
+	    hapd_iface->interfaces->driver_init == NULL ||
+	    hapd_iface->interfaces->driver_init(hapd_iface))
+		return -1;
+
+	if (hostapd_setup_interface(hapd_iface)) {
+		hostapd_deinit_driver(hapd_iface->bss[0]->driver,
+				      hapd_iface->bss[0]->drv_priv,
+				      hapd_iface);
+		return -1;
+	}
+
+	return 0;
+}
+
+
+int hostapd_reload_iface(struct hostapd_iface *hapd_iface)
+{
+	size_t j;
+
+	wpa_printf(MSG_DEBUG, "Reload interface %s",
+		   hapd_iface->conf->bss[0]->iface);
+	for (j = 0; j < hapd_iface->num_bss; j++)
+		hostapd_set_security_params(hapd_iface->conf->bss[j], 1);
+	if (hostapd_config_check(hapd_iface->conf, 1) < 0) {
+		wpa_printf(MSG_ERROR, "Updated configuration is invalid");
+		return -1;
+	}
+	hostapd_clear_old(hapd_iface);
+	for (j = 0; j < hapd_iface->num_bss; j++)
+		hostapd_reload_bss(hapd_iface->bss[j]);
+
+	return 0;
+}
+
+
+int hostapd_disable_iface(struct hostapd_iface *hapd_iface)
+{
+	size_t j;
+	const struct wpa_driver_ops *driver;
+	void *drv_priv;
+
+	if (hapd_iface == NULL)
+		return -1;
+
+	if (hapd_iface->disable_iface_cb)
+		return hapd_iface->disable_iface_cb(hapd_iface);
+
+	if (hapd_iface->bss[0]->drv_priv == NULL) {
+		wpa_printf(MSG_INFO, "Interface %s already disabled",
+			   hapd_iface->conf->bss[0]->iface);
+		return -1;
+	}
+
+	wpa_msg(hapd_iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
+	driver = hapd_iface->bss[0]->driver;
+	drv_priv = hapd_iface->bss[0]->drv_priv;
+
+	hapd_iface->driver_ap_teardown =
+		!!(hapd_iface->drv_flags &
+		   WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
+
+#ifdef NEED_AP_MLME
+	for (j = 0; j < hapd_iface->num_bss; j++)
+		hostapd_cleanup_cs_params(hapd_iface->bss[j]);
+#endif /* NEED_AP_MLME */
+
+	/* same as hostapd_interface_deinit without deinitializing ctrl-iface */
+	for (j = 0; j < hapd_iface->num_bss; j++) {
+		struct hostapd_data *hapd = hapd_iface->bss[j];
+		hostapd_bss_deinit_no_free(hapd);
+		hostapd_free_hapd_data(hapd);
+	}
+
+	hostapd_deinit_driver(driver, drv_priv, hapd_iface);
+
+	/* From hostapd_cleanup_iface: These were initialized in
+	 * hostapd_setup_interface and hostapd_setup_interface_complete
+	 */
+	hostapd_cleanup_iface_partial(hapd_iface);
+
+	wpa_printf(MSG_DEBUG, "Interface %s disabled",
+		   hapd_iface->bss[0]->conf->iface);
+	hostapd_set_state(hapd_iface, HAPD_IFACE_DISABLED);
+	return 0;
+}
+
+
+static struct hostapd_iface *
+hostapd_iface_alloc(struct hapd_interfaces *interfaces)
+{
+	struct hostapd_iface **iface, *hapd_iface;
+
+	iface = os_realloc_array(interfaces->iface, interfaces->count + 1,
+				 sizeof(struct hostapd_iface *));
+	if (iface == NULL)
+		return NULL;
+	interfaces->iface = iface;
+	hapd_iface = interfaces->iface[interfaces->count] =
+		hostapd_alloc_iface();
+	if (hapd_iface == NULL) {
+		wpa_printf(MSG_ERROR, "%s: Failed to allocate memory for "
+			   "the interface", __func__);
+		return NULL;
+	}
+	interfaces->count++;
+	hapd_iface->interfaces = interfaces;
+
+	return hapd_iface;
+}
+
+
+static struct hostapd_config *
+hostapd_config_alloc(struct hapd_interfaces *interfaces, const char *ifname,
+		     const char *ctrl_iface, const char *driver)
+{
+	struct hostapd_bss_config *bss;
+	struct hostapd_config *conf;
+
+	/* Allocates memory for bss and conf */
+	conf = hostapd_config_defaults();
+	if (conf == NULL) {
+		 wpa_printf(MSG_ERROR, "%s: Failed to allocate memory for "
+				"configuration", __func__);
+		 return NULL;
+	}
+
+	if (driver) {
+		int j;
+
+		for (j = 0; wpa_drivers[j]; j++) {
+			if (os_strcmp(driver, wpa_drivers[j]->name) == 0) {
+				conf->driver = wpa_drivers[j];
+				goto skip;
+			}
+		}
+
+		wpa_printf(MSG_ERROR,
+			   "Invalid/unknown driver '%s' - registering the default driver",
+			   driver);
+	}
+
+	conf->driver = wpa_drivers[0];
+	if (conf->driver == NULL) {
+		wpa_printf(MSG_ERROR, "No driver wrappers registered!");
+		hostapd_config_free(conf);
+		return NULL;
+	}
+
+skip:
+	bss = conf->last_bss = conf->bss[0];
+
+	os_strlcpy(bss->iface, ifname, sizeof(bss->iface));
+	bss->ctrl_interface = os_strdup(ctrl_iface);
+	if (bss->ctrl_interface == NULL) {
+		hostapd_config_free(conf);
+		return NULL;
+	}
+
+	/* Reading configuration file skipped, will be done in SET!
+	 * From reading the configuration till the end has to be done in
+	 * SET
+	 */
+	return conf;
+}
+
+
+static int hostapd_data_alloc(struct hostapd_iface *hapd_iface,
+			      struct hostapd_config *conf)
+{
+	size_t i;
+	struct hostapd_data *hapd;
+
+	hapd_iface->bss = os_calloc(conf->num_bss,
+				    sizeof(struct hostapd_data *));
+	if (hapd_iface->bss == NULL)
+		return -1;
+
+	for (i = 0; i < conf->num_bss; i++) {
+		hapd = hapd_iface->bss[i] =
+			hostapd_alloc_bss_data(hapd_iface, conf, conf->bss[i]);
+		if (hapd == NULL) {
+			while (i > 0) {
+				i--;
+				os_free(hapd_iface->bss[i]);
+				hapd_iface->bss[i] = NULL;
+			}
+			os_free(hapd_iface->bss);
+			hapd_iface->bss = NULL;
+			return -1;
+		}
+		hapd->msg_ctx = hapd;
+	}
+
+	hapd_iface->conf = conf;
+	hapd_iface->num_bss = conf->num_bss;
+
+	return 0;
+}
+
+
+int hostapd_add_iface(struct hapd_interfaces *interfaces, char *buf)
+{
+	struct hostapd_config *conf = NULL;
+	struct hostapd_iface *hapd_iface = NULL, *new_iface = NULL;
+	struct hostapd_data *hapd;
+	char *ptr;
+	size_t i, j;
+	const char *conf_file = NULL, *phy_name = NULL;
+
+	if (os_strncmp(buf, "bss_config=", 11) == 0) {
+		char *pos;
+		phy_name = buf + 11;
+		pos = os_strchr(phy_name, ':');
+		if (!pos)
+			return -1;
+		*pos++ = '\0';
+		conf_file = pos;
+		if (!os_strlen(conf_file))
+			return -1;
+
+		hapd_iface = hostapd_interface_init_bss(interfaces, phy_name,
+							conf_file, 0);
+		if (!hapd_iface)
+			return -1;
+		for (j = 0; j < interfaces->count; j++) {
+			if (interfaces->iface[j] == hapd_iface)
+				break;
+		}
+		if (j == interfaces->count) {
+			struct hostapd_iface **tmp;
+			tmp = os_realloc_array(interfaces->iface,
+					       interfaces->count + 1,
+					       sizeof(struct hostapd_iface *));
+			if (!tmp) {
+				hostapd_interface_deinit_free(hapd_iface);
+				return -1;
+			}
+			interfaces->iface = tmp;
+			interfaces->iface[interfaces->count++] = hapd_iface;
+			new_iface = hapd_iface;
+		}
+
+		if (new_iface) {
+			if (interfaces->driver_init(hapd_iface))
+				goto fail;
+
+			if (hostapd_setup_interface(hapd_iface)) {
+				hostapd_deinit_driver(
+					hapd_iface->bss[0]->driver,
+					hapd_iface->bss[0]->drv_priv,
+					hapd_iface);
+				goto fail;
+			}
+		} else {
+			/* Assign new BSS with bss[0]'s driver info */
+			hapd = hapd_iface->bss[hapd_iface->num_bss - 1];
+			hapd->driver = hapd_iface->bss[0]->driver;
+			hapd->drv_priv = hapd_iface->bss[0]->drv_priv;
+			os_memcpy(hapd->own_addr, hapd_iface->bss[0]->own_addr,
+				  ETH_ALEN);
+
+			if (start_ctrl_iface_bss(hapd) < 0 ||
+			    (hapd_iface->state == HAPD_IFACE_ENABLED &&
+			     hostapd_setup_bss(hapd, -1))) {
+				hostapd_cleanup(hapd);
+				hapd_iface->bss[hapd_iface->num_bss - 1] = NULL;
+				hapd_iface->conf->num_bss--;
+				hapd_iface->num_bss--;
+				wpa_printf(MSG_DEBUG, "%s: free hapd %p %s",
+					   __func__, hapd, hapd->conf->iface);
+				hostapd_config_free_bss(hapd->conf);
+				hapd->conf = NULL;
+				os_free(hapd);
+				return -1;
+			}
+		}
+		hostapd_owe_update_trans(hapd_iface);
+		return 0;
+	}
+
+	ptr = os_strchr(buf, ' ');
+	if (ptr == NULL)
+		return -1;
+	*ptr++ = '\0';
+
+	if (os_strncmp(ptr, "config=", 7) == 0)
+		conf_file = ptr + 7;
+
+	for (i = 0; i < interfaces->count; i++) {
+		if (!os_strcmp(interfaces->iface[i]->conf->bss[0]->iface,
+			       buf)) {
+			wpa_printf(MSG_INFO, "Cannot add interface - it "
+				   "already exists");
+			return -1;
+		}
+	}
+
+	hapd_iface = hostapd_iface_alloc(interfaces);
+	if (hapd_iface == NULL) {
+		wpa_printf(MSG_ERROR, "%s: Failed to allocate memory "
+			   "for interface", __func__);
+		goto fail;
+	}
+	new_iface = hapd_iface;
+
+	if (conf_file && interfaces->config_read_cb) {
+		conf = interfaces->config_read_cb(conf_file);
+		if (conf && conf->bss)
+			os_strlcpy(conf->bss[0]->iface, buf,
+				   sizeof(conf->bss[0]->iface));
+	} else {
+		char *driver = os_strchr(ptr, ' ');
+
+		if (driver)
+			*driver++ = '\0';
+		conf = hostapd_config_alloc(interfaces, buf, ptr, driver);
+	}
+
+	if (conf == NULL || conf->bss == NULL) {
+		wpa_printf(MSG_ERROR, "%s: Failed to allocate memory "
+			   "for configuration", __func__);
+		goto fail;
+	}
+
+	if (hostapd_data_alloc(hapd_iface, conf) < 0) {
+		wpa_printf(MSG_ERROR, "%s: Failed to allocate memory "
+			   "for hostapd", __func__);
+		goto fail;
+	}
+	conf = NULL;
+
+	if (start_ctrl_iface(hapd_iface) < 0)
+		goto fail;
+
+	wpa_printf(MSG_INFO, "Add interface '%s'",
+		   hapd_iface->conf->bss[0]->iface);
+
+	return 0;
+
+fail:
+	if (conf)
+		hostapd_config_free(conf);
+	if (hapd_iface) {
+		if (hapd_iface->bss) {
+			for (i = 0; i < hapd_iface->num_bss; i++) {
+				hapd = hapd_iface->bss[i];
+				if (!hapd)
+					continue;
+				if (hapd_iface->interfaces &&
+				    hapd_iface->interfaces->ctrl_iface_deinit)
+					hapd_iface->interfaces->
+						ctrl_iface_deinit(hapd);
+				wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)",
+					   __func__, hapd_iface->bss[i],
+					   hapd->conf->iface);
+				hostapd_cleanup(hapd);
+				os_free(hapd);
+				hapd_iface->bss[i] = NULL;
+			}
+			os_free(hapd_iface->bss);
+			hapd_iface->bss = NULL;
+		}
+		if (new_iface) {
+			interfaces->count--;
+			interfaces->iface[interfaces->count] = NULL;
+		}
+		hostapd_cleanup_iface(hapd_iface);
+	}
+	return -1;
+}
+
+
+static int hostapd_remove_bss(struct hostapd_iface *iface, unsigned int idx)
+{
+	size_t i;
+
+	wpa_printf(MSG_INFO, "Remove BSS '%s'", iface->conf->bss[idx]->iface);
+
+	/* Remove hostapd_data only if it has already been initialized */
+	if (idx < iface->num_bss) {
+		struct hostapd_data *hapd = iface->bss[idx];
+
+		hostapd_bss_deinit(hapd);
+		wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)",
+			   __func__, hapd, hapd->conf->iface);
+		hostapd_config_free_bss(hapd->conf);
+		hapd->conf = NULL;
+		os_free(hapd);
+
+		iface->num_bss--;
+
+		for (i = idx; i < iface->num_bss; i++)
+			iface->bss[i] = iface->bss[i + 1];
+	} else {
+		hostapd_config_free_bss(iface->conf->bss[idx]);
+		iface->conf->bss[idx] = NULL;
+	}
+
+	iface->conf->num_bss--;
+	for (i = idx; i < iface->conf->num_bss; i++)
+		iface->conf->bss[i] = iface->conf->bss[i + 1];
+
+	return 0;
+}
+
+
+int hostapd_remove_iface(struct hapd_interfaces *interfaces, char *buf)
+{
+	struct hostapd_iface *hapd_iface;
+	size_t i, j, k = 0;
+
+	for (i = 0; i < interfaces->count; i++) {
+		hapd_iface = interfaces->iface[i];
+		if (hapd_iface == NULL)
+			return -1;
+		if (!os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) {
+			wpa_printf(MSG_INFO, "Remove interface '%s'", buf);
+			hapd_iface->driver_ap_teardown =
+				!!(hapd_iface->drv_flags &
+				   WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
+
+			hostapd_interface_deinit_free(hapd_iface);
+			k = i;
+			while (k < (interfaces->count - 1)) {
+				interfaces->iface[k] =
+					interfaces->iface[k + 1];
+				k++;
+			}
+			interfaces->count--;
+			return 0;
+		}
+
+		for (j = 0; j < hapd_iface->conf->num_bss; j++) {
+			if (!os_strcmp(hapd_iface->conf->bss[j]->iface, buf)) {
+				hapd_iface->driver_ap_teardown =
+					!(hapd_iface->drv_flags &
+					  WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
+				return hostapd_remove_bss(hapd_iface, j);
+			}
+		}
+	}
+	return -1;
+}
+
+
+/**
+ * hostapd_new_assoc_sta - Notify that a new station associated with the AP
+ * @hapd: Pointer to BSS data
+ * @sta: Pointer to the associated STA data
+ * @reassoc: 1 to indicate this was a re-association; 0 = first association
+ *
+ * This function will be called whenever a station associates with the AP. It
+ * can be called from ieee802_11.c for drivers that export MLME to hostapd and
+ * from drv_callbacks.c based on driver events for drivers that take care of
+ * management frames (IEEE 802.11 authentication and association) internally.
+ */
+void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
+			   int reassoc)
+{
+
+	if (hapd->tkip_countermeasures) {
+		hostapd_drv_sta_deauth(hapd, sta->addr,
+				       WLAN_REASON_MICHAEL_MIC_FAILURE);
+		return;
+	}
+
+	hostapd_prune_associations(hapd, sta->addr);
+	ap_sta_clear_disconnect_timeouts(hapd, sta);
+	sta->post_csa_sa_query = 0;
+
+#ifdef CONFIG_P2P
+	if (sta->p2p_ie == NULL && !sta->no_p2p_set) {
+		sta->no_p2p_set = 1;
+		hapd->num_sta_no_p2p++;
+		if (hapd->num_sta_no_p2p == 1)
+			hostapd_p2p_non_p2p_sta_connected(hapd);
+	}
+#endif /* CONFIG_P2P */
+
+	airtime_policy_new_sta(hapd, sta);
+
+	/* Start accounting here, if IEEE 802.1X and WPA are not used.
+	 * IEEE 802.1X/WPA code will start accounting after the station has
+	 * been authorized. */
+	if (!hapd->conf->ieee802_1x && !hapd->conf->wpa && !hapd->conf->osen) {
+		ap_sta_set_authorized(hapd, sta, 1);
+		os_get_reltime(&sta->connected_time);
+		accounting_sta_start(hapd, sta);
+	}
+
+	/* Start IEEE 802.1X authentication process for new stations */
+	ieee802_1x_new_station(hapd, sta);
+	if (reassoc) {
+		if (sta->auth_alg != WLAN_AUTH_FT &&
+		    sta->auth_alg != WLAN_AUTH_FILS_SK &&
+		    sta->auth_alg != WLAN_AUTH_FILS_SK_PFS &&
+		    sta->auth_alg != WLAN_AUTH_FILS_PK &&
+		    !(sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)))
+			wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH);
+	} else
+		wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm);
+
+	if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_WIRED) {
+		if (eloop_cancel_timeout(ap_handle_timer, hapd, sta) > 0) {
+			wpa_printf(MSG_DEBUG,
+				   "%s: %s: canceled wired ap_handle_timer timeout for "
+				   MACSTR,
+				   hapd->conf->iface, __func__,
+				   MAC2STR(sta->addr));
+		}
+	} else if (!(hapd->iface->drv_flags &
+		     WPA_DRIVER_FLAGS_INACTIVITY_TIMER)) {
+		wpa_printf(MSG_DEBUG,
+			   "%s: %s: reschedule ap_handle_timer timeout for "
+			   MACSTR " (%d seconds - ap_max_inactivity)",
+			   hapd->conf->iface, __func__, MAC2STR(sta->addr),
+			   hapd->conf->ap_max_inactivity);
+		eloop_cancel_timeout(ap_handle_timer, hapd, sta);
+		eloop_register_timeout(hapd->conf->ap_max_inactivity, 0,
+				       ap_handle_timer, hapd, sta);
+	}
+
+#ifdef CONFIG_MACSEC
+	if (hapd->conf->wpa_key_mgmt == WPA_KEY_MGMT_NONE &&
+	    hapd->conf->mka_psk_set)
+		ieee802_1x_create_preshared_mka_hapd(hapd, sta);
+	else
+		ieee802_1x_alloc_kay_sm_hapd(hapd, sta);
+#endif /* CONFIG_MACSEC */
+}
+
+
+const char * hostapd_state_text(enum hostapd_iface_state s)
+{
+	switch (s) {
+	case HAPD_IFACE_UNINITIALIZED:
+		return "UNINITIALIZED";
+	case HAPD_IFACE_DISABLED:
+		return "DISABLED";
+	case HAPD_IFACE_COUNTRY_UPDATE:
+		return "COUNTRY_UPDATE";
+	case HAPD_IFACE_ACS:
+		return "ACS";
+	case HAPD_IFACE_HT_SCAN:
+		return "HT_SCAN";
+	case HAPD_IFACE_DFS:
+		return "DFS";
+	case HAPD_IFACE_ENABLED:
+		return "ENABLED";
+	}
+
+	return "UNKNOWN";
+}
+
+
+void hostapd_set_state(struct hostapd_iface *iface, enum hostapd_iface_state s)
+{
+	wpa_printf(MSG_INFO, "%s: interface state %s->%s",
+		   iface->conf ? iface->conf->bss[0]->iface : "N/A",
+		   hostapd_state_text(iface->state), hostapd_state_text(s));
+	iface->state = s;
+}
+
+
+int hostapd_csa_in_progress(struct hostapd_iface *iface)
+{
+	unsigned int i;
+
+	for (i = 0; i < iface->num_bss; i++)
+		if (iface->bss[i]->csa_in_progress)
+			return 1;
+	return 0;
+}
+
+
+#ifdef NEED_AP_MLME
+
+static void free_beacon_data(struct beacon_data *beacon)
+{
+	os_free(beacon->head);
+	beacon->head = NULL;
+	os_free(beacon->tail);
+	beacon->tail = NULL;
+	os_free(beacon->probe_resp);
+	beacon->probe_resp = NULL;
+	os_free(beacon->beacon_ies);
+	beacon->beacon_ies = NULL;
+	os_free(beacon->proberesp_ies);
+	beacon->proberesp_ies = NULL;
+	os_free(beacon->assocresp_ies);
+	beacon->assocresp_ies = NULL;
+}
+
+
+static int hostapd_build_beacon_data(struct hostapd_data *hapd,
+				     struct beacon_data *beacon)
+{
+	struct wpabuf *beacon_extra, *proberesp_extra, *assocresp_extra;
+	struct wpa_driver_ap_params params;
+	int ret;
+
+	os_memset(beacon, 0, sizeof(*beacon));
+	ret = ieee802_11_build_ap_params(hapd, &params);
+	if (ret < 0)
+		return ret;
+
+	ret = hostapd_build_ap_extra_ies(hapd, &beacon_extra,
+					 &proberesp_extra,
+					 &assocresp_extra);
+	if (ret)
+		goto free_ap_params;
+
+	ret = -1;
+	beacon->head = os_memdup(params.head, params.head_len);
+	if (!beacon->head)
+		goto free_ap_extra_ies;
+
+	beacon->head_len = params.head_len;
+
+	beacon->tail = os_memdup(params.tail, params.tail_len);
+	if (!beacon->tail)
+		goto free_beacon;
+
+	beacon->tail_len = params.tail_len;
+
+	if (params.proberesp != NULL) {
+		beacon->probe_resp = os_memdup(params.proberesp,
+					       params.proberesp_len);
+		if (!beacon->probe_resp)
+			goto free_beacon;
+
+		beacon->probe_resp_len = params.proberesp_len;
+	}
+
+	/* copy the extra ies */
+	if (beacon_extra) {
+		beacon->beacon_ies = os_memdup(beacon_extra->buf,
+					       wpabuf_len(beacon_extra));
+		if (!beacon->beacon_ies)
+			goto free_beacon;
+
+		beacon->beacon_ies_len = wpabuf_len(beacon_extra);
+	}
+
+	if (proberesp_extra) {
+		beacon->proberesp_ies = os_memdup(proberesp_extra->buf,
+						  wpabuf_len(proberesp_extra));
+		if (!beacon->proberesp_ies)
+			goto free_beacon;
+
+		beacon->proberesp_ies_len = wpabuf_len(proberesp_extra);
+	}
+
+	if (assocresp_extra) {
+		beacon->assocresp_ies = os_memdup(assocresp_extra->buf,
+						  wpabuf_len(assocresp_extra));
+		if (!beacon->assocresp_ies)
+			goto free_beacon;
+
+		beacon->assocresp_ies_len = wpabuf_len(assocresp_extra);
+	}
+
+	ret = 0;
+free_beacon:
+	/* if the function fails, the caller should not free beacon data */
+	if (ret)
+		free_beacon_data(beacon);
+
+free_ap_extra_ies:
+	hostapd_free_ap_extra_ies(hapd, beacon_extra, proberesp_extra,
+				  assocresp_extra);
+free_ap_params:
+	ieee802_11_free_ap_params(&params);
+	return ret;
+}
+
+
+/*
+ * TODO: This flow currently supports only changing channel and width within
+ * the same hw_mode. Any other changes to MAC parameters or provided settings
+ * are not supported.
+ */
+static int hostapd_change_config_freq(struct hostapd_data *hapd,
+				      struct hostapd_config *conf,
+				      struct hostapd_freq_params *params,
+				      struct hostapd_freq_params *old_params)
+{
+	int channel;
+	u8 seg0, seg1;
+	struct hostapd_hw_modes *mode;
+
+	if (!params->channel) {
+		/* check if the new channel is supported by hw */
+		params->channel = hostapd_hw_get_channel(hapd, params->freq);
+	}
+
+	channel = params->channel;
+	if (!channel)
+		return -1;
+
+	mode = hapd->iface->current_mode;
+
+	/* if a pointer to old_params is provided we save previous state */
+	if (old_params &&
+	    hostapd_set_freq_params(old_params, conf->hw_mode,
+				    hostapd_hw_get_freq(hapd, conf->channel),
+				    conf->channel, conf->enable_edmg,
+				    conf->edmg_channel, conf->ieee80211n,
+				    conf->ieee80211ac, conf->ieee80211ax,
+				    conf->secondary_channel,
+				    hostapd_get_oper_chwidth(conf),
+				    hostapd_get_oper_centr_freq_seg0_idx(conf),
+				    hostapd_get_oper_centr_freq_seg1_idx(conf),
+				    conf->vht_capab,
+				    mode ? &mode->he_capab[IEEE80211_MODE_AP] :
+				    NULL))
+		return -1;
+
+	switch (params->bandwidth) {
+	case 0:
+	case 20:
+		conf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
+		break;
+	case 40:
+	case 80:
+	case 160:
+		conf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
+		break;
+	default:
+		return -1;
+	}
+
+	switch (params->bandwidth) {
+	case 0:
+	case 20:
+	case 40:
+		hostapd_set_oper_chwidth(conf, CHANWIDTH_USE_HT);
+		break;
+	case 80:
+		if (params->center_freq2)
+			hostapd_set_oper_chwidth(conf, CHANWIDTH_80P80MHZ);
+		else
+			hostapd_set_oper_chwidth(conf, CHANWIDTH_80MHZ);
+		break;
+	case 160:
+		hostapd_set_oper_chwidth(conf, CHANWIDTH_160MHZ);
+		break;
+	default:
+		return -1;
+	}
+
+	conf->channel = channel;
+	conf->ieee80211n = params->ht_enabled;
+	conf->ieee80211ac = params->vht_enabled;
+	conf->secondary_channel = params->sec_channel_offset;
+	ieee80211_freq_to_chan(params->center_freq1,
+			       &seg0);
+	ieee80211_freq_to_chan(params->center_freq2,
+			       &seg1);
+	hostapd_set_oper_centr_freq_seg0_idx(conf, seg0);
+	hostapd_set_oper_centr_freq_seg1_idx(conf, seg1);
+
+	/* TODO: maybe call here hostapd_config_check here? */
+
+	return 0;
+}
+
+
+static int hostapd_fill_csa_settings(struct hostapd_data *hapd,
+				     struct csa_settings *settings)
+{
+	struct hostapd_iface *iface = hapd->iface;
+	struct hostapd_freq_params old_freq;
+	int ret;
+	u8 chan, bandwidth;
+
+	os_memset(&old_freq, 0, sizeof(old_freq));
+	if (!iface || !iface->freq || hapd->csa_in_progress)
+		return -1;
+
+	switch (settings->freq_params.bandwidth) {
+	case 80:
+		if (settings->freq_params.center_freq2)
+			bandwidth = CHANWIDTH_80P80MHZ;
+		else
+			bandwidth = CHANWIDTH_80MHZ;
+		break;
+	case 160:
+		bandwidth = CHANWIDTH_160MHZ;
+		break;
+	default:
+		bandwidth = CHANWIDTH_USE_HT;
+		break;
+	}
+
+	if (ieee80211_freq_to_channel_ext(
+		    settings->freq_params.freq,
+		    settings->freq_params.sec_channel_offset,
+		    bandwidth,
+		    &hapd->iface->cs_oper_class,
+		    &chan) == NUM_HOSTAPD_MODES) {
+		wpa_printf(MSG_DEBUG,
+			   "invalid frequency for channel switch (freq=%d, sec_channel_offset=%d, vht_enabled=%d, he_enabled=%d)",
+			   settings->freq_params.freq,
+			   settings->freq_params.sec_channel_offset,
+			   settings->freq_params.vht_enabled,
+			   settings->freq_params.he_enabled);
+		return -1;
+	}
+
+	settings->freq_params.channel = chan;
+
+	ret = hostapd_change_config_freq(iface->bss[0], iface->conf,
+					 &settings->freq_params,
+					 &old_freq);
+	if (ret)
+		return ret;
+
+	ret = hostapd_build_beacon_data(hapd, &settings->beacon_after);
+
+	/* change back the configuration */
+	hostapd_change_config_freq(iface->bss[0], iface->conf,
+				   &old_freq, NULL);
+
+	if (ret)
+		return ret;
+
+	/* set channel switch parameters for csa ie */
+	hapd->cs_freq_params = settings->freq_params;
+	hapd->cs_count = settings->cs_count;
+	hapd->cs_block_tx = settings->block_tx;
+
+	ret = hostapd_build_beacon_data(hapd, &settings->beacon_csa);
+	if (ret) {
+		free_beacon_data(&settings->beacon_after);
+		return ret;
+	}
+
+	settings->counter_offset_beacon[0] = hapd->cs_c_off_beacon;
+	settings->counter_offset_presp[0] = hapd->cs_c_off_proberesp;
+	settings->counter_offset_beacon[1] = hapd->cs_c_off_ecsa_beacon;
+	settings->counter_offset_presp[1] = hapd->cs_c_off_ecsa_proberesp;
+
+	return 0;
+}
+
+
+void hostapd_cleanup_cs_params(struct hostapd_data *hapd)
+{
+	os_memset(&hapd->cs_freq_params, 0, sizeof(hapd->cs_freq_params));
+	hapd->cs_count = 0;
+	hapd->cs_block_tx = 0;
+	hapd->cs_c_off_beacon = 0;
+	hapd->cs_c_off_proberesp = 0;
+	hapd->csa_in_progress = 0;
+	hapd->cs_c_off_ecsa_beacon = 0;
+	hapd->cs_c_off_ecsa_proberesp = 0;
+}
+
+
+void hostapd_chan_switch_config(struct hostapd_data *hapd,
+				struct hostapd_freq_params *freq_params)
+{
+	if (freq_params->he_enabled)
+		hapd->iconf->ch_switch_he_config |= CH_SWITCH_HE_ENABLED;
+	else
+		hapd->iconf->ch_switch_he_config |= CH_SWITCH_HE_DISABLED;
+
+	if (freq_params->vht_enabled)
+		hapd->iconf->ch_switch_vht_config |= CH_SWITCH_VHT_ENABLED;
+	else
+		hapd->iconf->ch_switch_vht_config |= CH_SWITCH_VHT_DISABLED;
+
+	hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
+		       HOSTAPD_LEVEL_INFO,
+		       "CHAN_SWITCH HE config 0x%x VHT config 0x%x",
+		       hapd->iconf->ch_switch_he_config,
+		       hapd->iconf->ch_switch_vht_config);
+}
+
+
+int hostapd_switch_channel(struct hostapd_data *hapd,
+			   struct csa_settings *settings)
+{
+	int ret;
+
+	if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA)) {
+		wpa_printf(MSG_INFO, "CSA is not supported");
+		return -1;
+	}
+
+	ret = hostapd_fill_csa_settings(hapd, settings);
+	if (ret)
+		return ret;
+
+	ret = hostapd_drv_switch_channel(hapd, settings);
+	free_beacon_data(&settings->beacon_csa);
+	free_beacon_data(&settings->beacon_after);
+
+	if (ret) {
+		/* if we failed, clean cs parameters */
+		hostapd_cleanup_cs_params(hapd);
+		return ret;
+	}
+
+	hapd->csa_in_progress = 1;
+	return 0;
+}
+
+
+void
+hostapd_switch_channel_fallback(struct hostapd_iface *iface,
+				const struct hostapd_freq_params *freq_params)
+{
+	int seg0_idx = 0, seg1_idx = 0, bw = CHANWIDTH_USE_HT;
+
+	wpa_printf(MSG_DEBUG, "Restarting all CSA-related BSSes");
+
+	if (freq_params->center_freq1)
+		seg0_idx = 36 + (freq_params->center_freq1 - 5180) / 5;
+	if (freq_params->center_freq2)
+		seg1_idx = 36 + (freq_params->center_freq2 - 5180) / 5;
+
+	switch (freq_params->bandwidth) {
+	case 0:
+	case 20:
+	case 40:
+		bw = CHANWIDTH_USE_HT;
+		break;
+	case 80:
+		if (freq_params->center_freq2)
+			bw = CHANWIDTH_80P80MHZ;
+		else
+			bw = CHANWIDTH_80MHZ;
+		break;
+	case 160:
+		bw = CHANWIDTH_160MHZ;
+		break;
+	default:
+		wpa_printf(MSG_WARNING, "Unknown CSA bandwidth: %d",
+			   freq_params->bandwidth);
+		break;
+	}
+
+	iface->freq = freq_params->freq;
+	iface->conf->channel = freq_params->channel;
+	iface->conf->secondary_channel = freq_params->sec_channel_offset;
+	hostapd_set_oper_centr_freq_seg0_idx(iface->conf, seg0_idx);
+	hostapd_set_oper_centr_freq_seg1_idx(iface->conf, seg1_idx);
+	hostapd_set_oper_chwidth(iface->conf, bw);
+	iface->conf->ieee80211n = freq_params->ht_enabled;
+	iface->conf->ieee80211ac = freq_params->vht_enabled;
+	iface->conf->ieee80211ax = freq_params->he_enabled;
+
+	/*
+	 * cs_params must not be cleared earlier because the freq_params
+	 * argument may actually point to one of these.
+	 * These params will be cleared during interface disable below.
+	 */
+	hostapd_disable_iface(iface);
+	hostapd_enable_iface(iface);
+}
+
+#endif /* NEED_AP_MLME */
+
+
+struct hostapd_data * hostapd_get_iface(struct hapd_interfaces *interfaces,
+					const char *ifname)
+{
+	size_t i, j;
+
+	for (i = 0; i < interfaces->count; i++) {
+		struct hostapd_iface *iface = interfaces->iface[i];
+
+		for (j = 0; j < iface->num_bss; j++) {
+			struct hostapd_data *hapd = iface->bss[j];
+
+			if (os_strcmp(ifname, hapd->conf->iface) == 0)
+				return hapd;
+		}
+	}
+
+	return NULL;
+}
+
+
+void hostapd_periodic_iface(struct hostapd_iface *iface)
+{
+	size_t i;
+
+	ap_list_timer(iface);
+
+	for (i = 0; i < iface->num_bss; i++) {
+		struct hostapd_data *hapd = iface->bss[i];
+
+		if (!hapd->started)
+			continue;
+
+#ifndef CONFIG_NO_RADIUS
+		hostapd_acl_expire(hapd);
+#endif /* CONFIG_NO_RADIUS */
+	}
+}
+
+
+#ifdef CONFIG_OCV
+void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx)
+{
+	struct hostapd_data *hapd = eloop_ctx;
+	struct sta_info *sta;
+
+	wpa_printf(MSG_DEBUG, "OCV: Post-CSA SA Query initiation check");
+
+	for (sta = hapd->sta_list; sta; sta = sta->next) {
+		if (!sta->post_csa_sa_query)
+			continue;
+
+		wpa_printf(MSG_DEBUG, "OCV: OCVC STA " MACSTR
+			   " did not start SA Query after CSA - disconnect",
+			   MAC2STR(sta->addr));
+		ap_sta_disconnect(hapd, sta, sta->addr,
+				  WLAN_REASON_PREV_AUTH_NOT_VALID);
+	}
+}
+#endif /* CONFIG_OCV */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hostapd.h b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hostapd.h
index 109b9af..c60903f 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hostapd.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hostapd.h
@@ -138,6 +138,8 @@
 	/* LCI update time */
 	struct os_time lci_date;
 	int stationary;
+	u32 short_ssid;
+	u8 bss_parameters;
 };
 
 struct hostapd_sae_commit_queue {
@@ -326,10 +328,10 @@
 
 #ifdef CONFIG_SAE
 	/** Key used for generating SAE anti-clogging tokens */
-	u8 sae_token_key[8];
-	struct os_reltime last_sae_token_key_update;
-	u16 sae_token_idx;
-	u16 sae_pending_token_idx[256];
+	u8 comeback_key[8];
+	struct os_reltime last_comeback_key_update;
+	u16 comeback_idx;
+	u16 comeback_pending_idx[256];
 	int dot11RSNASAERetransPeriod; /* msec */
 	struct dl_list sae_commit_queue; /* struct hostapd_sae_commit_queue */
 #endif /* CONFIG_SAE */
@@ -354,6 +356,8 @@
 	int last_bigtk_key_idx;
 	u8 last_bigtk[WPA_BIGTK_MAX_LEN];
 	size_t last_bigtk_len;
+
+	bool force_backlog_bytes;
 #endif /* CONFIG_TESTING_OPTIONS */
 
 #ifdef CONFIG_MBO
@@ -370,6 +374,8 @@
 
 	int dhcp_sock; /* UDP socket used with the DHCP server */
 
+	struct ptksa_cache *ptksa;
+
 #ifdef CONFIG_DPP
 	int dpp_init_done;
 	struct dpp_authentication *dpp_auth;
@@ -599,6 +605,9 @@
 
 	/* Previous WMM element information */
 	struct hostapd_wmm_ac_params prev_wmm[WMM_AC_NUM];
+
+	int (*enable_iface_cb)(struct hostapd_iface *iface);
+	int (*disable_iface_cb)(struct hostapd_iface *iface);
 };
 
 /* hostapd.c */
@@ -627,13 +636,17 @@
 int hostapd_enable_iface(struct hostapd_iface *hapd_iface);
 int hostapd_reload_iface(struct hostapd_iface *hapd_iface);
 int hostapd_disable_iface(struct hostapd_iface *hapd_iface);
+void hostapd_bss_deinit_no_free(struct hostapd_data *hapd);
+void hostapd_free_hapd_data(struct hostapd_data *hapd);
+void hostapd_cleanup_iface_partial(struct hostapd_iface *iface);
 int hostapd_add_iface(struct hapd_interfaces *ifaces, char *buf);
 int hostapd_remove_iface(struct hapd_interfaces *ifaces, char *buf);
 void hostapd_channel_list_updated(struct hostapd_iface *iface, int initiator);
 void hostapd_set_state(struct hostapd_iface *iface, enum hostapd_iface_state s);
 const char * hostapd_state_text(enum hostapd_iface_state s);
 int hostapd_csa_in_progress(struct hostapd_iface *iface);
-void hostapd_chan_switch_vht_config(struct hostapd_data *hapd, int vht_enabled);
+void hostapd_chan_switch_config(struct hostapd_data *hapd,
+				struct hostapd_freq_params *freq_params);
 int hostapd_switch_channel(struct hostapd_data *hapd,
 			   struct csa_settings *settings);
 void
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hostapd_patch_20230316.diff b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hostapd_patch_20230316.diff
new file mode 100755
index 0000000..96a7d2c
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hostapd_patch_20230316.diff
@@ -0,0 +1,14 @@
+--- b/hostapd.c	2023-03-16 16:56:03.313755143 +0800
++++ a/hostapd.c	2023-03-16 16:57:59.997750241 +0800
+@@ -2294,8 +2294,9 @@
+ 		 * If freq is DFS, and DFS is offloaded to the driver, then wait
+ 		 * for CAC to complete.
+ 		 */
+-		wpa_printf(MSG_DEBUG, "%s: Wait for CAC to complete", __func__);
+-		return res_dfs_offload;
++		//wpa_printf(MSG_DEBUG, "%s: Wait for CAC to complete", __func__);
++		wpa_printf(MSG_DEBUG, "IFX: don't need wait for CAC to complete");
++		//return res_dfs_offload;
+ 	}
+ 
+ #ifdef NEED_AP_MLME
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hs20.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hs20.c
index 543fa33..05e9b9d 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hs20.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hs20.c
@@ -86,7 +86,9 @@
 			capab |= WPA_CAPABILITY_MFPR;
 	}
 #ifdef CONFIG_OCV
-	if (hapd->conf->ocv)
+	if (hapd->conf->ocv &&
+	    (hapd->iface->drv_flags2 &
+	     (WPA_DRIVER_FLAGS2_AP_SME | WPA_DRIVER_FLAGS2_OCV)))
 		capab |= WPA_CAPABILITY_OCVC;
 #endif /* CONFIG_OCV */
 	WPA_PUT_LE16(eid, capab);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hw_features.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hw_features.c
index bfaded2..307e2fb 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hw_features.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hw_features.c
@@ -313,7 +313,7 @@
 {
 	struct wpa_scan_results *scan_res;
 	int oper40;
-	int res;
+	int res = 0;
 
 	/* Check list of neighboring BSSes (from scan) to see whether 40 MHz is
 	 * allowed per IEEE Std 802.11-2012, 10.15.3.2 */
@@ -349,7 +349,24 @@
 		}
 	}
 
-	res = ieee80211n_allowed_ht40_channel_pair(iface);
+#ifdef CONFIG_IEEE80211AX
+	if (iface->conf->secondary_channel &&
+	    iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G &&
+	    iface->conf->ieee80211ax) {
+		struct he_capabilities *he_cap;
+
+		he_cap = &iface->current_mode->he_capab[IEEE80211_MODE_AP];
+		if (!(he_cap->phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
+		      HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_IN_2G)) {
+			wpa_printf(MSG_DEBUG,
+				   "HE: 40 MHz channel width is not supported in 2.4 GHz; clear secondary channel configuration");
+			iface->conf->secondary_channel = 0;
+		}
+	}
+#endif /* CONFIG_IEEE80211AX */
+
+	if (iface->conf->secondary_channel)
+		res = ieee80211n_allowed_ht40_channel_pair(iface);
 	if (!res) {
 		iface->conf->secondary_channel = 0;
 		hostapd_set_oper_centr_freq_seg0_idx(iface->conf, 0);
@@ -732,6 +749,51 @@
 }
 
 
+int hostapd_check_he_6ghz_capab(struct hostapd_iface *iface)
+{
+#ifdef CONFIG_IEEE80211AX
+	struct he_capabilities *he_cap;
+	u16 hw;
+
+	if (!iface->current_mode || !is_6ghz_freq(iface->freq))
+		return 0;
+
+	he_cap = &iface->current_mode->he_capab[IEEE80211_MODE_AP];
+	hw = he_cap->he_6ghz_capa;
+	if (iface->conf->he_6ghz_max_mpdu >
+	    ((hw & HE_6GHZ_BAND_CAP_MAX_MPDU_LEN_MASK) >>
+	     HE_6GHZ_BAND_CAP_MAX_MPDU_LEN_SHIFT)) {
+		wpa_printf(MSG_ERROR,
+			   "The driver does not support the configured HE 6 GHz Max MPDU length");
+		return -1;
+	}
+
+	if (iface->conf->he_6ghz_max_ampdu_len_exp >
+	    ((hw & HE_6GHZ_BAND_CAP_MAX_AMPDU_LEN_EXP_MASK) >>
+	     HE_6GHZ_BAND_CAP_MAX_AMPDU_LEN_EXP_SHIFT)) {
+		wpa_printf(MSG_ERROR,
+			   "The driver does not support the configured HE 6 GHz Max AMPDU Length Exponent");
+		return -1;
+	}
+
+	if (iface->conf->he_6ghz_rx_ant_pat &&
+	    !(hw & HE_6GHZ_BAND_CAP_RX_ANTPAT_CONS)) {
+		wpa_printf(MSG_ERROR,
+			   "The driver does not support the configured HE 6 GHz Rx Antenna Pattern");
+		return -1;
+	}
+
+	if (iface->conf->he_6ghz_tx_ant_pat &&
+	    !(hw & HE_6GHZ_BAND_CAP_TX_ANTPAT_CONS)) {
+		wpa_printf(MSG_ERROR,
+			   "The driver does not support the configured HE 6 GHz Tx Antenna Pattern");
+		return -1;
+	}
+#endif /* CONFIG_IEEE80211AX */
+	return 0;
+}
+
+
 static int hostapd_is_usable_chan(struct hostapd_iface *iface,
 				  int frequency, int primary)
 {
@@ -776,6 +838,8 @@
 				       iface->freq, NULL,
 				       iface->hw_features,
 				       iface->num_hw_features);
+	if (!pri_chan)
+		return 0;
 	hostapd_encode_edmg_chan(iface->conf->enable_edmg,
 				 iface->conf->edmg_channel,
 				 pri_chan->chan,
@@ -855,8 +919,14 @@
 		return 1;
 
 	if (hostapd_is_usable_chan(iface, iface->freq +
-				   iface->conf->secondary_channel * 20, 0))
-		return 1;
+				   iface->conf->secondary_channel * 20, 0)) {
+		if (iface->conf->secondary_channel == 1 &&
+		    (pri_chan->allowed_bw & HOSTAPD_CHAN_WIDTH_40P))
+			return 1;
+		if (iface->conf->secondary_channel == -1 &&
+		    (pri_chan->allowed_bw & HOSTAPD_CHAN_WIDTH_40M))
+			return 1;
+	}
 	if (!iface->conf->ht40_plus_minus_allowed)
 		return 0;
 
@@ -949,9 +1019,9 @@
 	hostapd_logger(iface->bss[0], NULL,
 		       HOSTAPD_MODULE_IEEE80211,
 		       HOSTAPD_LEVEL_WARNING,
-		       "Configured channel (%d) or frequency (%d) not found from the channel list of the current mode (%d) %s",
+		       "Configured channel (%d) or frequency (%d) (secondary_channel=%d) not found from the channel list of the current mode (%d) %s",
 		       iface->conf->channel,
-		       iface->freq,
+		       iface->freq, iface->conf->secondary_channel,
 		       iface->current_mode->mode,
 		       hostapd_hw_mode_txt(iface->current_mode->mode));
 	hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,
@@ -1029,12 +1099,13 @@
 	iface->current_mode = NULL;
 	for (i = 0; i < iface->num_hw_features; i++) {
 		struct hostapd_hw_modes *mode = &iface->hw_features[i];
+		int chan;
+
 		if (mode->mode == iface->conf->hw_mode) {
 			if (iface->freq > 0 &&
-			    !hw_get_chan(mode->mode, iface->freq,
-					 iface->hw_features,
-					 iface->num_hw_features))
+			    !hw_mode_get_channel(mode, iface->freq, &chan))
 				continue;
+
 			iface->current_mode = mode;
 			break;
 		}
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hw_features.h b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hw_features.h
index a250875..f816d81 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hw_features.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/hw_features.h
@@ -26,6 +26,7 @@
 #endif /* #ifdef BRCM_SUPP */
 int hostapd_check_ht_capab(struct hostapd_iface *iface);
 int hostapd_check_edmg_capab(struct hostapd_iface *iface);
+int hostapd_check_he_6ghz_capab(struct hostapd_iface *iface);
 int hostapd_prepare_rates(struct hostapd_iface *iface,
 			  struct hostapd_hw_modes *mode);
 void hostapd_stop_setup_timers(struct hostapd_iface *iface);
@@ -89,6 +90,11 @@
 	return 0;
 }
 
+static inline int hostapd_check_he_6ghz_capab(struct hostapd_iface *iface)
+{
+	return 0;
+}
+
 #endif /* NEED_AP_MLME */
 
 #endif /* HW_FEATURES_H */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ieee802_11.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ieee802_11.c
index 57c6903..8cd5a49 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ieee802_11.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ieee802_11.c
@@ -25,6 +25,7 @@
 #include "common/ocv.h"
 #include "common/wpa_common.h"
 #include "common/wpa_ctrl.h"
+#include "common/ptksa_cache.h"
 #include "radius/radius.h"
 #include "radius/radius_client.h"
 #include "p2p/p2p.h"
@@ -65,11 +66,31 @@
 		       const u8 *msk, size_t msk_len,
 		       int *is_pub);
 #endif /* CONFIG_FILS */
+
+#ifdef CONFIG_PASN
+
+static int handle_auth_pasn_resp(struct hostapd_data *hapd,
+				 struct sta_info *sta,
+				 struct rsn_pmksa_cache_entry *pmksa,
+				 u16 status);
+#ifdef CONFIG_FILS
+
+static void pasn_fils_auth_resp(struct hostapd_data *hapd,
+				struct sta_info *sta, u16 status,
+				struct wpabuf *erp_resp,
+				const u8 *msk, size_t msk_len);
+
+#endif /* CONFIG_FILS */
+#endif /* CONFIG_PASN */
+
 static void handle_auth(struct hostapd_data *hapd,
 			const struct ieee80211_mgmt *mgmt, size_t len,
 			int rssi, int from_queue);
 
-
+/* Refer commit 7d2b7730d5: Add CONFIG_WPA3_SAE_AUTH_EARLY_SET flags 
+ * and codes. Enable this flags allow the AP to set authorization to
+ * firmware earlier as the SAE confirm from is ok.
+ */
 #ifdef CONFIG_WPA3_SAE_AUTH_EARLY_SET
 static void sae_sme_send_external_auth_status(struct hostapd_data *hapd,
                                               struct sta_info *sta, u16 status);
@@ -473,6 +494,49 @@
 }
 
 
+static const char * sae_get_password(struct hostapd_data *hapd,
+				     struct sta_info *sta,
+				     const char *rx_id,
+				     struct sae_password_entry **pw_entry,
+				     struct sae_pt **s_pt,
+				     const struct sae_pk **s_pk)
+{
+	const char *password = NULL;
+	struct sae_password_entry *pw;
+	struct sae_pt *pt = NULL;
+	const struct sae_pk *pk = NULL;
+
+	for (pw = hapd->conf->sae_passwords; pw; pw = pw->next) {
+		if (!is_broadcast_ether_addr(pw->peer_addr) &&
+		    os_memcmp(pw->peer_addr, sta->addr, ETH_ALEN) != 0)
+			continue;
+		if ((rx_id && !pw->identifier) || (!rx_id && pw->identifier))
+			continue;
+		if (rx_id && pw->identifier &&
+		    os_strcmp(rx_id, pw->identifier) != 0)
+			continue;
+		password = pw->password;
+		pt = pw->pt;
+		if (!(hapd->conf->mesh & MESH_ENABLED))
+			pk = pw->pk;
+		break;
+	}
+	if (!password) {
+		password = hapd->conf->ssid.wpa_passphrase;
+		pt = hapd->conf->ssid.pt;
+	}
+
+	if (pw_entry)
+		*pw_entry = pw;
+	if (s_pt)
+		*s_pt = pt;
+	if (s_pk)
+		*s_pk = pk;
+
+	return password;
+}
+
+
 static struct wpabuf * auth_build_sae_commit(struct hostapd_data *hapd,
 					     struct sta_info *sta, int update,
 					     int status_code)
@@ -502,25 +566,7 @@
 		 status_code == WLAN_STATUS_SAE_PK)
 		use_pt = 1;
 
-	for (pw = hapd->conf->sae_passwords; pw; pw = pw->next) {
-		if (!is_broadcast_ether_addr(pw->peer_addr) &&
-		    os_memcmp(pw->peer_addr, sta->addr, ETH_ALEN) != 0)
-			continue;
-		if ((rx_id && !pw->identifier) || (!rx_id && pw->identifier))
-			continue;
-		if (rx_id && pw->identifier &&
-		    os_strcmp(rx_id, pw->identifier) != 0)
-			continue;
-		password = pw->password;
-		pt = pw->pt;
-		if (!(hapd->conf->mesh & MESH_ENABLED))
-			pk = pw->pk;
-		break;
-	}
-	if (!password) {
-		password = hapd->conf->ssid.wpa_passphrase;
-		pt = hapd->conf->ssid.pt;
-	}
+	password = sae_get_password(hapd, sta, rx_id, &pw, &pt, &pk);
 	if (!password || (use_pt && !pt)) {
 		wpa_printf(MSG_DEBUG, "SAE: No password available");
 		return NULL;
@@ -533,7 +579,7 @@
 
 	if (update && !use_pt &&
 	    sae_prepare_commit(hapd->own_addr, sta->addr,
-			       (u8 *) password, os_strlen(password), rx_id,
+			       (u8 *) password, os_strlen(password),
 			       sta->sae) < 0) {
 		wpa_printf(MSG_DEBUG, "SAE: Could not pick PWE");
 		return NULL;
@@ -638,6 +684,10 @@
 	if (data == NULL)
 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
 
+/* Refer commit 7d2b7730d5: Add CONFIG_WPA3_SAE_AUTH_EARLY_SET flags 
+ * and codes. Enable this flags allow the AP to set authorization to
+ * firmware earlier as the SAE confirm from is ok.
+ */
 #ifdef CONFIG_WPA3_SAE_AUTH_EARLY_SET
 	wpa_printf(MSG_DEBUG, "\nCalling sae_sme_send_external_auth_status\n");
 	sae_sme_send_external_auth_status(hapd, sta, WLAN_STATUS_SUCCESS);
@@ -652,42 +702,53 @@
 	return reply_res;
 }
 
+#endif /* CONFIG_SAE */
 
-static int use_sae_anti_clogging(struct hostapd_data *hapd)
+
+#if defined(CONFIG_SAE) || defined(CONFIG_PASN)
+
+static int use_anti_clogging(struct hostapd_data *hapd)
 {
 	struct sta_info *sta;
 	unsigned int open = 0;
 
-	if (hapd->conf->sae_anti_clogging_threshold == 0)
+	if (hapd->conf->anti_clogging_threshold == 0)
 		return 1;
 
 	for (sta = hapd->sta_list; sta; sta = sta->next) {
-		if (!sta->sae)
-			continue;
-		if (sta->sae->state != SAE_COMMITTED &&
-		    sta->sae->state != SAE_CONFIRMED)
-			continue;
-		open++;
-		if (open >= hapd->conf->sae_anti_clogging_threshold)
+#ifdef CONFIG_SAE
+		if (sta->sae &&
+		    (sta->sae->state == SAE_COMMITTED ||
+		     sta->sae->state == SAE_CONFIRMED))
+			open++;
+#endif /* CONFIG_SAE */
+#ifdef CONFIG_PASN
+		if (sta->pasn && sta->pasn->ecdh)
+			open++;
+#endif /* CONFIG_PASN */
+		if (open >= hapd->conf->anti_clogging_threshold)
 			return 1;
 	}
 
+#ifdef CONFIG_SAE
 	/* In addition to already existing open SAE sessions, check whether
 	 * there are enough pending commit messages in the processing queue to
 	 * potentially result in too many open sessions. */
 	if (open + dl_list_len(&hapd->sae_commit_queue) >=
-	    hapd->conf->sae_anti_clogging_threshold)
+	    hapd->conf->anti_clogging_threshold)
 		return 1;
+#endif /* CONFIG_SAE */
 
 	return 0;
 }
 
 
-static int sae_token_hash(struct hostapd_data *hapd, const u8 *addr, u8 *idx)
+static int comeback_token_hash(struct hostapd_data *hapd, const u8 *addr,
+			       u8 *idx)
 {
 	u8 hash[SHA256_MAC_LEN];
 
-	if (hmac_sha256(hapd->sae_token_key, sizeof(hapd->sae_token_key),
+	if (hmac_sha256(hapd->comeback_key, sizeof(hapd->comeback_key),
 			addr, ETH_ALEN, hash) < 0)
 		return -1;
 	*idx = hash[0];
@@ -695,8 +756,8 @@
 }
 
 
-static int check_sae_token(struct hostapd_data *hapd, const u8 *addr,
-			   const u8 *token, size_t token_len)
+static int check_comeback_token(struct hostapd_data *hapd, const u8 *addr,
+				const u8 *token, size_t token_len)
 {
 	u8 mac[SHA256_MAC_LEN];
 	const u8 *addrs[2];
@@ -704,11 +765,13 @@
 	u16 token_idx;
 	u8 idx;
 
-	if (token_len != SHA256_MAC_LEN || sae_token_hash(hapd, addr, &idx) < 0)
+	if (token_len != SHA256_MAC_LEN ||
+	    comeback_token_hash(hapd, addr, &idx) < 0)
 		return -1;
-	token_idx = hapd->sae_pending_token_idx[idx];
+	token_idx = hapd->comeback_pending_idx[idx];
 	if (token_idx == 0 || token_idx != WPA_GET_BE16(token)) {
-		wpa_printf(MSG_DEBUG, "SAE: Invalid anti-clogging token from "
+		wpa_printf(MSG_DEBUG,
+			   "Comeback: Invalid anti-clogging token from "
 			   MACSTR " - token_idx 0x%04x, expected 0x%04x",
 			   MAC2STR(addr), WPA_GET_BE16(token), token_idx);
 		return -1;
@@ -718,12 +781,12 @@
 	len[0] = ETH_ALEN;
 	addrs[1] = token;
 	len[1] = 2;
-	if (hmac_sha256_vector(hapd->sae_token_key, sizeof(hapd->sae_token_key),
+	if (hmac_sha256_vector(hapd->comeback_key, sizeof(hapd->comeback_key),
 			       2, addrs, len, mac) < 0 ||
 	    os_memcmp_const(token + 2, &mac[2], SHA256_MAC_LEN - 2) != 0)
 		return -1;
 
-	hapd->sae_pending_token_idx[idx] = 0; /* invalidate used token */
+	hapd->comeback_pending_idx[idx] = 0; /* invalidate used token */
 
 	return 0;
 }
@@ -742,25 +805,26 @@
 	u16 token_idx;
 
 	os_get_reltime(&now);
-	if (!os_reltime_initialized(&hapd->last_sae_token_key_update) ||
-	    os_reltime_expired(&now, &hapd->last_sae_token_key_update, 60) ||
-	    hapd->sae_token_idx == 0xffff) {
-		if (random_get_bytes(hapd->sae_token_key,
-				     sizeof(hapd->sae_token_key)) < 0)
+	if (!os_reltime_initialized(&hapd->last_comeback_key_update) ||
+	    os_reltime_expired(&now, &hapd->last_comeback_key_update, 60) ||
+	    hapd->comeback_idx == 0xffff) {
+		if (random_get_bytes(hapd->comeback_key,
+				     sizeof(hapd->comeback_key)) < 0)
 			return NULL;
-		wpa_hexdump(MSG_DEBUG, "SAE: Updated token key",
-			    hapd->sae_token_key, sizeof(hapd->sae_token_key));
-		hapd->last_sae_token_key_update = now;
-		hapd->sae_token_idx = 0;
-		os_memset(hapd->sae_pending_token_idx, 0,
-			  sizeof(hapd->sae_pending_token_idx));
+		wpa_hexdump(MSG_DEBUG, "Comeback: Updated token key",
+			    hapd->comeback_key, sizeof(hapd->comeback_key));
+		hapd->last_comeback_key_update = now;
+		hapd->comeback_idx = 0;
+		os_memset(hapd->comeback_pending_idx, 0,
+			  sizeof(hapd->comeback_pending_idx));
 	}
 
 	buf = wpabuf_alloc(sizeof(le16) + 3 + SHA256_MAC_LEN);
 	if (buf == NULL)
 		return NULL;
 
-	wpabuf_put_le16(buf, group); /* Finite Cyclic Group */
+	if (group)
+		wpabuf_put_le16(buf, group); /* Finite Cyclic Group */
 
 	if (h2e) {
 		/* Encapsulate Anti-clogging Token field in a container IE */
@@ -769,15 +833,16 @@
 		wpabuf_put_u8(buf, WLAN_EID_EXT_ANTI_CLOGGING_TOKEN);
 	}
 
-	if (sae_token_hash(hapd, addr, &p_idx) < 0) {
+	if (comeback_token_hash(hapd, addr, &p_idx) < 0) {
 		wpabuf_free(buf);
 		return NULL;
 	}
-	token_idx = hapd->sae_pending_token_idx[p_idx];
+
+	token_idx = hapd->comeback_pending_idx[p_idx];
 	if (!token_idx) {
-		hapd->sae_token_idx++;
-		token_idx = hapd->sae_token_idx;
-		hapd->sae_pending_token_idx[p_idx] = token_idx;
+		hapd->comeback_idx++;
+		token_idx = hapd->comeback_idx;
+		hapd->comeback_pending_idx[p_idx] = token_idx;
 	}
 	WPA_PUT_BE16(idx, token_idx);
 	token = wpabuf_put(buf, SHA256_MAC_LEN);
@@ -785,7 +850,7 @@
 	len[0] = ETH_ALEN;
 	addrs[1] = idx;
 	len[1] = sizeof(idx);
-	if (hmac_sha256_vector(hapd->sae_token_key, sizeof(hapd->sae_token_key),
+	if (hmac_sha256_vector(hapd->comeback_key, sizeof(hapd->comeback_key),
 			       2, addrs, len, token) < 0) {
 		wpabuf_free(buf);
 		return NULL;
@@ -795,6 +860,10 @@
 	return buf;
 }
 
+#endif /* defined(CONFIG_SAE) || defined(CONFIG_PASN) */
+
+
+#ifdef CONFIG_SAE
 
 static int sae_check_big_sync(struct hostapd_data *hapd, struct sta_info *sta)
 {
@@ -917,9 +986,18 @@
 	crypto_bignum_deinit(sta->sae->peer_commit_scalar_accepted, 0);
 	sta->sae->peer_commit_scalar_accepted = sta->sae->peer_commit_scalar;
 	sta->sae->peer_commit_scalar = NULL;
+
+	/* Refer commit 587411dd62: Fix for PMK expiration issue through
+	 * supplicant
+	 */
 	wpa_auth_set_pmk_life_time(hapd->wpa_auth,hapd->conf->dot11RSNAConfigPMKLifetime);
 	wpa_auth_pmksa_add_sae(hapd->wpa_auth, sta->addr,
 			       sta->sae->pmk, sta->sae->pmkid);
+
+/* Refer commit 7d2b7730d5: Add CONFIG_WPA3_SAE_AUTH_EARLY_SET flags 
+ * and codes. Enable this flags allow the AP to set authorization to
+ * firmware earlier as the SAE confirm from is ok.
+ */
 #ifndef CONFIG_WPA3_SAE_AUTH_EARLY_SET
 	sae_sme_send_external_auth_status(hapd, sta, WLAN_STATUS_SUCCESS);
 #endif /* CONFIG_WPA3_SAE_AUTH_EARLY_SET */
@@ -1245,6 +1323,7 @@
 	int default_groups[] = { 19, 0 };
 	const u8 *pos, *end;
 	int sta_removed = 0;
+	bool success_status;
 
 	if (!groups)
 		groups = default_groups;
@@ -1419,7 +1498,8 @@
 			goto remove_sta;
 		}
 
-		if (token && check_sae_token(hapd, sta->addr, token, token_len)
+		if (token &&
+		    check_comeback_token(hapd, sta->addr, token, token_len)
 		    < 0) {
 			wpa_printf(MSG_DEBUG, "SAE: Drop commit message with "
 				   "incorrect token from " MACSTR,
@@ -1436,7 +1516,7 @@
 			goto reply;
 		}
 
-		if (!token && use_sae_anti_clogging(hapd) && !allow_reuse) {
+		if (!token && use_anti_clogging(hapd) && !allow_reuse) {
 			int h2e = 0;
 
 			wpa_printf(MSG_DEBUG,
@@ -1530,6 +1610,8 @@
 	}
 
 remove_sta:
+
+	/* Refer commit dd235b6200: WPA3AP remove incorrect password STA */
 	if (!sta_removed && (resp != WLAN_STATUS_SUCCESS ||
 			     status_code != WLAN_STATUS_SUCCESS)) {
 		sta->timeout_next = STA_DEAUTH;
@@ -1537,9 +1619,14 @@
 		eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer,
 				       hapd, sta);
 	}
+
+	if (auth_transaction == 1)
+		success_status = sae_status_success(hapd, status_code);
+	else
+		success_status = status_code == WLAN_STATUS_SUCCESS;
+
 	if (!sta_removed && sta->added_unassoc &&
-	    (resp != WLAN_STATUS_SUCCESS ||
-	     status_code != WLAN_STATUS_SUCCESS)) {
+	    (resp != WLAN_STATUS_SUCCESS || !success_status)) {
 		hostapd_drv_sta_remove(hapd, sta->addr);
 		sta->added_unassoc = 0;
 	}
@@ -2203,23 +2290,35 @@
 				 struct wpabuf *erp_resp,
 				 const u8 *msk, size_t msk_len)
 {
-	struct wpabuf *data;
-	int pub = 0;
 	u16 resp;
+	u32 flags = sta->flags;
 
-	sta->flags &= ~WLAN_STA_PENDING_FILS_ERP;
+	sta->flags &= ~(WLAN_STA_PENDING_FILS_ERP |
+			WLAN_STA_PENDING_PASN_FILS_ERP);
 
-	if (!sta->fils_pending_cb)
-		return;
 	resp = success ? WLAN_STATUS_SUCCESS : WLAN_STATUS_UNSPECIFIED_FAILURE;
-	data = prepare_auth_resp_fils(hapd, sta, &resp, NULL, erp_resp,
-				      msk, msk_len, &pub);
-	if (!data) {
-		wpa_printf(MSG_DEBUG,
-			   "%s: prepare_auth_resp_fils() returned failure",
-			   __func__);
+
+	if (flags & WLAN_STA_PENDING_FILS_ERP) {
+		struct wpabuf *data;
+		int pub = 0;
+
+		if (!sta->fils_pending_cb)
+			return;
+
+		data = prepare_auth_resp_fils(hapd, sta, &resp, NULL, erp_resp,
+					      msk, msk_len, &pub);
+		if (!data) {
+			wpa_printf(MSG_DEBUG,
+				   "%s: prepare_auth_resp_fils() failure",
+				   __func__);
+		}
+		sta->fils_pending_cb(hapd, sta, resp, data, pub);
+#ifdef CONFIG_PASN
+	} else if (flags & WLAN_STA_PENDING_PASN_FILS_ERP) {
+		pasn_fils_auth_resp(hapd, sta, resp, erp_resp,
+				    msk, msk_len);
+#endif /* CONFIG_PASN */
 	}
-	sta->fils_pending_cb(hapd, sta, resp, data, pub);
 }
 
 #endif /* CONFIG_FILS */
@@ -2314,6 +2413,1177 @@
 }
 
 
+#ifdef CONFIG_PASN
+#ifdef CONFIG_SAE
+
+static int pasn_wd_handle_sae_commit(struct hostapd_data *hapd,
+				     struct sta_info *sta,
+				     struct wpabuf *wd)
+{
+	struct pasn_data *pasn = sta->pasn;
+	const char *password;
+	const u8 *data;
+	size_t buf_len;
+	u16 res, alg, seq, status;
+	int groups[] = { pasn->group, 0 };
+	struct sae_pt *pt = NULL;
+	int ret;
+
+	if (!wd)
+		return -1;
+
+	data = wpabuf_head_u8(wd);
+	buf_len = wpabuf_len(wd);
+
+	if (buf_len < 6) {
+		wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short. len=%zu",
+			   buf_len);
+		return -1;
+	}
+
+	alg = WPA_GET_LE16(data);
+	seq = WPA_GET_LE16(data + 2);
+	status = WPA_GET_LE16(data + 4);
+
+	wpa_printf(MSG_DEBUG, "PASN: SAE commit: alg=%u, seq=%u, status=%u",
+		   alg, seq, status);
+
+	if (alg != WLAN_AUTH_SAE || seq != 1 ||
+	    status != WLAN_STATUS_SAE_HASH_TO_ELEMENT) {
+		wpa_printf(MSG_DEBUG, "PASN: Dropping peer SAE commit");
+		return -1;
+	}
+
+	sae_clear_data(&pasn->sae);
+	pasn->sae.state = SAE_NOTHING;
+
+	ret = sae_set_group(&pasn->sae, pasn->group);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed to set SAE group");
+		return -1;
+	}
+
+	password = sae_get_password(hapd, sta, NULL, NULL, &pt, NULL);
+	if (!password || !pt) {
+		wpa_printf(MSG_DEBUG, "PASN: No SAE PT found");
+		return -1;
+	}
+
+	ret = sae_prepare_commit_pt(&pasn->sae, pt, hapd->own_addr, sta->addr,
+				    NULL, NULL);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed to prepare SAE commit");
+		return -1;
+	}
+
+	res = sae_parse_commit(&pasn->sae, data + 6, buf_len - 6, NULL, 0,
+			       groups, 0);
+	if (res != WLAN_STATUS_SUCCESS) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed parsing SAE commit");
+		return -1;
+	}
+
+	/* Process the commit message and derive the PMK */
+	ret = sae_process_commit(&pasn->sae);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "SAE: Failed to process peer commit");
+		return -1;
+	}
+
+	pasn->sae.state = SAE_COMMITTED;
+
+	return 0;
+}
+
+
+static int pasn_wd_handle_sae_confirm(struct hostapd_data *hapd,
+				      struct sta_info *sta,
+				      struct wpabuf *wd)
+{
+	struct pasn_data *pasn = sta->pasn;
+	const u8 *data;
+	size_t buf_len;
+	u16 res, alg, seq, status;
+
+	if (!wd)
+		return -1;
+
+	data = wpabuf_head_u8(wd);
+	buf_len = wpabuf_len(wd);
+
+	if (buf_len < 6) {
+		wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short. len=%zu",
+			   buf_len);
+		return -1;
+	}
+
+	alg = WPA_GET_LE16(data);
+	seq = WPA_GET_LE16(data + 2);
+	status = WPA_GET_LE16(data + 4);
+
+	wpa_printf(MSG_DEBUG, "PASN: SAE confirm: alg=%u, seq=%u, status=%u",
+		   alg, seq, status);
+
+	if (alg != WLAN_AUTH_SAE || seq != 2 || status != WLAN_STATUS_SUCCESS) {
+		wpa_printf(MSG_DEBUG, "PASN: Dropping peer SAE confirm");
+		return -1;
+	}
+
+	res = sae_check_confirm(&pasn->sae, data + 6, buf_len - 6);
+	if (res != WLAN_STATUS_SUCCESS) {
+		wpa_printf(MSG_DEBUG, "PASN: SAE failed checking confirm");
+		return -1;
+	}
+
+	pasn->sae.state = SAE_ACCEPTED;
+
+	/*
+	 * TODO: Based on on IEEE P802.11az/D2.6, the PMKSA derived with
+	 * PASN/SAE should only be allowed with future PASN only. For now do not
+	 * restrict this only for PASN.
+	 */
+	wpa_auth_pmksa_add_sae(hapd->wpa_auth, sta->addr,
+			       pasn->sae.pmk, pasn->sae.pmkid);
+	return 0;
+}
+
+
+static struct wpabuf * pasn_get_sae_wd(struct hostapd_data *hapd,
+				       struct sta_info *sta)
+{
+	struct pasn_data *pasn = sta->pasn;
+	struct wpabuf *buf = NULL;
+	u8 *len_ptr;
+	size_t len;
+
+	/* Need to add the entire Authentication frame body */
+	buf = wpabuf_alloc(8 + SAE_COMMIT_MAX_LEN + 8 + SAE_CONFIRM_MAX_LEN);
+	if (!buf) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed to allocate SAE buffer");
+		return NULL;
+	}
+
+	/* Need to add the entire authentication frame body for the commit */
+	len_ptr = wpabuf_put(buf, 2);
+	wpabuf_put_le16(buf, WLAN_AUTH_SAE);
+	wpabuf_put_le16(buf, 1);
+	wpabuf_put_le16(buf, WLAN_STATUS_SAE_HASH_TO_ELEMENT);
+
+	/* Write the actual commit and update the length accordingly */
+	sae_write_commit(&pasn->sae, buf, NULL, 0);
+	len = wpabuf_len(buf);
+	WPA_PUT_LE16(len_ptr, len - 2);
+
+	/* Need to add the entire Authentication frame body for the confirm */
+	len_ptr = wpabuf_put(buf, 2);
+	wpabuf_put_le16(buf, WLAN_AUTH_SAE);
+	wpabuf_put_le16(buf, 2);
+	wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
+
+	sae_write_confirm(&pasn->sae, buf);
+	WPA_PUT_LE16(len_ptr, wpabuf_len(buf) - len - 2);
+
+	pasn->sae.state = SAE_CONFIRMED;
+
+	return buf;
+}
+
+#endif /* CONFIG_SAE */
+
+
+#ifdef CONFIG_FILS
+
+static struct wpabuf * pasn_get_fils_wd(struct hostapd_data *hapd,
+					struct sta_info *sta)
+{
+	struct pasn_data *pasn = sta->pasn;
+	struct pasn_fils_data *fils = &pasn->fils;
+	struct wpabuf *buf = NULL;
+
+	if (!fils->erp_resp) {
+		wpa_printf(MSG_DEBUG, "PASN: FILS: Missing erp_resp");
+		return NULL;
+	}
+
+	buf = wpabuf_alloc(1500);
+	if (!buf)
+		return NULL;
+
+	/* Add the authentication algorithm */
+	wpabuf_put_le16(buf, WLAN_AUTH_FILS_SK);
+
+	/* Authentication Transaction seq# */
+	wpabuf_put_le16(buf, 2);
+
+	/* Status Code */
+	wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
+
+	/* Own RSNE */
+	wpa_pasn_add_rsne(buf, NULL, pasn->akmp, pasn->cipher);
+
+	/* FILS Nonce */
+	wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
+	wpabuf_put_u8(buf, 1 + FILS_NONCE_LEN);
+	wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_NONCE);
+	wpabuf_put_data(buf, fils->anonce, FILS_NONCE_LEN);
+
+	/* FILS Session */
+	wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
+	wpabuf_put_u8(buf, 1 + FILS_SESSION_LEN);
+	wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_SESSION);
+	wpabuf_put_data(buf, fils->session, FILS_SESSION_LEN);
+
+	/* Wrapped Data */
+	wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
+	wpabuf_put_u8(buf, 1 + wpabuf_len(fils->erp_resp));
+	wpabuf_put_u8(buf, WLAN_EID_EXT_WRAPPED_DATA);
+	wpabuf_put_buf(buf, fils->erp_resp);
+
+	return buf;
+}
+
+
+static void pasn_fils_auth_resp(struct hostapd_data *hapd,
+				struct sta_info *sta, u16 status,
+				struct wpabuf *erp_resp,
+				const u8 *msk, size_t msk_len)
+{
+	struct pasn_data *pasn = sta->pasn;
+	struct pasn_fils_data *fils = &pasn->fils;
+	u8 pmk[PMK_LEN_MAX];
+	size_t pmk_len;
+	int ret;
+
+	wpa_printf(MSG_DEBUG, "PASN: FILS: Handle AS response - status=%u",
+		   status);
+
+	if (status != WLAN_STATUS_SUCCESS)
+		goto fail;
+
+	if (!pasn->secret) {
+		wpa_printf(MSG_DEBUG, "PASN: FILS: Missing secret");
+		goto fail;
+	}
+
+	if (random_get_bytes(fils->anonce, FILS_NONCE_LEN) < 0) {
+		wpa_printf(MSG_DEBUG, "PASN: FILS: Failed to get ANonce");
+		goto fail;
+	}
+
+	wpa_hexdump(MSG_DEBUG, "RSN: Generated FILS ANonce",
+		    fils->anonce, FILS_NONCE_LEN);
+
+	ret = fils_rmsk_to_pmk(pasn->akmp, msk, msk_len, fils->nonce,
+			       fils->anonce, NULL, 0, pmk, &pmk_len);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "FILS: Failed to derive PMK");
+		goto fail;
+	}
+
+	ret = pasn_pmk_to_ptk(pmk, pmk_len, sta->addr, hapd->own_addr,
+			      wpabuf_head(pasn->secret),
+			      wpabuf_len(pasn->secret),
+			      &sta->pasn->ptk, sta->pasn->akmp,
+			      sta->pasn->cipher, sta->pasn->kdk_len);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: FILS: Failed to derive PTK");
+		goto fail;
+	}
+
+	wpa_printf(MSG_DEBUG, "PASN: PTK successfully derived");
+
+	wpabuf_free(pasn->secret);
+	pasn->secret = NULL;
+
+	fils->erp_resp = erp_resp;
+	ret = handle_auth_pasn_resp(hapd, sta, NULL, WLAN_STATUS_SUCCESS);
+	fils->erp_resp = NULL;
+
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: FILS: Failed to send response");
+		goto fail;
+	}
+
+	fils->state = PASN_FILS_STATE_COMPLETE;
+	return;
+fail:
+	ap_free_sta(hapd, sta);
+}
+
+
+static int pasn_wd_handle_fils(struct hostapd_data *hapd, struct sta_info *sta,
+			       struct wpabuf *wd)
+{
+#ifdef CONFIG_NO_RADIUS
+	wpa_printf(MSG_DEBUG, "PASN: FILS: RADIUS is not configured. Fail");
+	return -1;
+#else /* CONFIG_NO_RADIUS */
+	struct pasn_data *pasn = sta->pasn;
+	struct pasn_fils_data *fils = &pasn->fils;
+	struct ieee802_11_elems elems;
+	struct wpa_ie_data rsne_data;
+	struct wpabuf *fils_wd;
+	const u8 *data;
+	size_t buf_len;
+	u16 alg, seq, status;
+	int ret;
+
+	if (fils->state != PASN_FILS_STATE_NONE) {
+		wpa_printf(MSG_DEBUG, "PASN: FILS: Not expecting wrapped data");
+		return -1;
+	}
+
+	if (!wd) {
+		wpa_printf(MSG_DEBUG, "PASN: FILS: No wrapped data");
+		return -1;
+	}
+
+	data = wpabuf_head_u8(wd);
+	buf_len = wpabuf_len(wd);
+
+	if (buf_len < 6) {
+		wpa_printf(MSG_DEBUG, "PASN: FILS: Buffer too short. len=%zu",
+			   buf_len);
+		return -1;
+	}
+
+	alg = WPA_GET_LE16(data);
+	seq = WPA_GET_LE16(data + 2);
+	status = WPA_GET_LE16(data + 4);
+
+	wpa_printf(MSG_DEBUG, "PASN: FILS: alg=%u, seq=%u, status=%u",
+		   alg, seq, status);
+
+	if (alg != WLAN_AUTH_FILS_SK || seq != 1 ||
+	    status != WLAN_STATUS_SUCCESS) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: FILS: Dropping peer authentication");
+		return -1;
+	}
+
+	data += 6;
+	buf_len -= 6;
+
+	if (ieee802_11_parse_elems(data, buf_len, &elems, 1) == ParseFailed) {
+		wpa_printf(MSG_DEBUG, "PASN: FILS: Could not parse elements");
+		return -1;
+	}
+
+	if (!elems.rsn_ie || !elems.fils_nonce || !elems.fils_nonce ||
+	    !elems.wrapped_data) {
+		wpa_printf(MSG_DEBUG, "PASN: FILS: Missing IEs");
+		return -1;
+	}
+
+	ret = wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
+				   &rsne_data);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: FILS: Failed parsing RNSE");
+		return -1;
+	}
+
+	ret = wpa_pasn_validate_rsne(&rsne_data);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: FILS: Failed validating RSNE");
+		return -1;
+	}
+
+	if (rsne_data.num_pmkid) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: FILS: Not expecting PMKID in RSNE");
+		return -1;
+	}
+
+	wpa_hexdump(MSG_DEBUG, "PASN: FILS: Nonce", elems.fils_nonce,
+		    FILS_NONCE_LEN);
+	os_memcpy(fils->nonce, elems.fils_nonce, FILS_NONCE_LEN);
+
+	wpa_hexdump(MSG_DEBUG, "PASN: FILS: Session", elems.fils_session,
+		    FILS_SESSION_LEN);
+	os_memcpy(fils->session, elems.fils_session, FILS_SESSION_LEN);
+
+	fils_wd = ieee802_11_defrag(&elems, WLAN_EID_EXTENSION,
+				    WLAN_EID_EXT_WRAPPED_DATA);
+
+	if (!fils_wd) {
+		wpa_printf(MSG_DEBUG, "PASN: FILS: Missing wrapped data");
+		return -1;
+	}
+
+	if (!sta->eapol_sm)
+		sta->eapol_sm = ieee802_1x_alloc_eapol_sm(hapd, sta);
+
+	wpa_printf(MSG_DEBUG,
+		   "PASN: FILS: Forward EAP-Initiate/Re-auth to AS");
+
+	ieee802_1x_encapsulate_radius(hapd, sta, wpabuf_head(fils_wd),
+				      wpabuf_len(fils_wd));
+
+	sta->flags |= WLAN_STA_PENDING_PASN_FILS_ERP;
+
+	fils->state = PASN_FILS_STATE_PENDING_AS;
+
+	/*
+	 * Calculate pending PMKID here so that we do not need to maintain a
+	 * copy of the EAP-Initiate/Reautt message.
+	 */
+	fils_pmkid_erp(pasn->akmp, wpabuf_head(fils_wd), wpabuf_len(fils_wd),
+		       fils->erp_pmkid);
+
+	wpabuf_free(fils_wd);
+	return 0;
+#endif /* CONFIG_NO_RADIUS */
+}
+
+#endif /* CONFIG_FILS */
+
+
+static struct wpabuf * pasn_get_wrapped_data(struct hostapd_data *hapd,
+					     struct sta_info *sta)
+{
+	switch (sta->pasn->akmp) {
+	case WPA_KEY_MGMT_PASN:
+		/* no wrapped data */
+		return NULL;
+	case WPA_KEY_MGMT_SAE:
+#ifdef CONFIG_SAE
+		return pasn_get_sae_wd(hapd, sta);
+#else /* CONFIG_SAE */
+		wpa_printf(MSG_ERROR,
+			   "PASN: SAE: Cannot derive wrapped data");
+		return NULL;
+#endif /* CONFIG_SAE */
+	case WPA_KEY_MGMT_FILS_SHA256:
+	case WPA_KEY_MGMT_FILS_SHA384:
+#ifdef CONFIG_FILS
+		return pasn_get_fils_wd(hapd, sta);
+#endif /* CONFIG_FILS */
+		/* fall through */
+	case WPA_KEY_MGMT_FT_PSK:
+	case WPA_KEY_MGMT_FT_IEEE8021X:
+	case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
+	default:
+		wpa_printf(MSG_ERROR,
+			   "PASN: TODO: Wrapped data for akmp=0x%x",
+			   sta->pasn->akmp);
+		return NULL;
+	}
+}
+
+
+static int
+pasn_derive_keys(struct hostapd_data *hapd, struct sta_info *sta,
+		 const u8 *cached_pmk, size_t cached_pmk_len,
+		 struct wpa_pasn_params_data *pasn_data,
+		 struct wpabuf *wrapped_data,
+		 struct wpabuf *secret)
+{
+	static const u8 pasn_default_pmk[] = {'P', 'M', 'K', 'z'};
+	u8 pmk[PMK_LEN_MAX];
+	u8 pmk_len;
+	int ret;
+
+	os_memset(pmk, 0, sizeof(pmk));
+	pmk_len = 0;
+
+	if (!cached_pmk || !cached_pmk_len)
+		wpa_printf(MSG_DEBUG, "PASN: No valid PMKSA entry");
+
+	if (sta->pasn->akmp == WPA_KEY_MGMT_PASN) {
+		wpa_printf(MSG_DEBUG, "PASN: Using default PMK");
+
+		pmk_len = WPA_PASN_PMK_LEN;
+		os_memcpy(pmk, pasn_default_pmk, sizeof(pasn_default_pmk));
+	} else if (cached_pmk && cached_pmk_len) {
+		wpa_printf(MSG_DEBUG, "PASN: Using PMKSA entry");
+
+		pmk_len = cached_pmk_len;
+		os_memcpy(pmk, cached_pmk, cached_pmk_len);
+	} else {
+		switch (sta->pasn->akmp) {
+#ifdef CONFIG_SAE
+		case WPA_KEY_MGMT_SAE:
+			if (sta->pasn->sae.state == SAE_COMMITTED) {
+				pmk_len = PMK_LEN;
+				os_memcpy(pmk, sta->pasn->sae.pmk, PMK_LEN);
+				break;
+			}
+#endif /* CONFIG_SAE */
+			/* fall through */
+		default:
+			/* TODO: Derive PMK based on wrapped data */
+			wpa_printf(MSG_DEBUG,
+				   "PASN: Missing PMK derivation");
+			return -1;
+		}
+	}
+
+	ret = pasn_pmk_to_ptk(pmk, pmk_len, sta->addr, hapd->own_addr,
+			      wpabuf_head(secret), wpabuf_len(secret),
+			      &sta->pasn->ptk, sta->pasn->akmp,
+			      sta->pasn->cipher, sta->pasn->kdk_len);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed to derive PTK");
+		return -1;
+	}
+
+	wpa_printf(MSG_DEBUG, "PASN: PTK successfully derived");
+	return 0;
+}
+
+
+static void handle_auth_pasn_comeback(struct hostapd_data *hapd,
+				      struct sta_info *sta, u16 group)
+{
+	struct wpabuf *buf, *comeback;
+	int ret;
+
+	wpa_printf(MSG_DEBUG,
+		   "PASN: Building comeback frame 2. Comeback after=%u",
+		   hapd->conf->pasn_comeback_after);
+
+	buf = wpabuf_alloc(1500);
+	if (!buf)
+		return;
+
+	wpa_pasn_build_auth_header(buf, hapd->own_addr, hapd->own_addr,
+				   sta->addr, 2,
+				   WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY);
+
+	/*
+	 * Do not include the group as a part of the token since it is not going
+	 * to be used.
+	 */
+	comeback = auth_build_token_req(hapd, 0, sta->addr, 0);
+	if (!comeback) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: Failed sending auth with comeback");
+		wpabuf_free(buf);
+		return;
+	}
+
+	wpa_pasn_add_parameter_ie(buf, group,
+				  WPA_PASN_WRAPPED_DATA_NO,
+				  NULL, 0, comeback,
+				  hapd->conf->pasn_comeback_after);
+	wpabuf_free(comeback);
+
+	wpa_printf(MSG_DEBUG,
+		   "PASN: comeback: STA=" MACSTR, MAC2STR(sta->addr));
+
+	ret = hostapd_drv_send_mlme(hapd, wpabuf_head(buf), wpabuf_len(buf), 0,
+				    NULL, 0, 0);
+	if (ret)
+		wpa_printf(MSG_INFO, "PASN: Failed to send comeback frame 2");
+
+	wpabuf_free(buf);
+}
+
+
+static int handle_auth_pasn_resp(struct hostapd_data *hapd,
+				 struct sta_info *sta,
+				 struct rsn_pmksa_cache_entry *pmksa,
+				 u16 status)
+{
+	struct wpabuf *buf, *pubkey = NULL, *wrapped_data_buf = NULL;
+	u8 mic[WPA_PASN_MAX_MIC_LEN];
+	u8 mic_len;
+	u8 *ptr;
+	const u8 *frame, *data, *rsn_ie, *rsnxe_ie;
+	u8 *data_buf = NULL;
+	size_t rsn_ie_len, frame_len, data_len;
+	int ret;
+	const u8 *pmkid = NULL;
+
+	wpa_printf(MSG_DEBUG, "PASN: Building frame 2: status=%u", status);
+
+	buf = wpabuf_alloc(1500);
+	if (!buf)
+		goto fail;
+
+	wpa_pasn_build_auth_header(buf, hapd->own_addr, hapd->own_addr,
+				   sta->addr, 2, status);
+
+	if (status != WLAN_STATUS_SUCCESS)
+		goto done;
+
+	if (pmksa) {
+		pmkid = pmksa->pmkid;
+#ifdef CONFIG_SAE
+	} else if (sta->pasn->akmp == WPA_KEY_MGMT_SAE) {
+		wpa_printf(MSG_DEBUG, "PASN: Use SAE PMKID");
+		pmkid = sta->pasn->sae.pmkid;
+#endif /* CONFIG_SAE */
+#ifdef CONFIG_FILS
+	} else if (sta->pasn->akmp == WPA_KEY_MGMT_FILS_SHA256 ||
+		   sta->pasn->akmp == WPA_KEY_MGMT_FILS_SHA384) {
+		wpa_printf(MSG_DEBUG, "PASN: Use FILS ERP PMKID");
+		pmkid = sta->pasn->fils.erp_pmkid;
+#endif /* CONFIG_FILS */
+	}
+
+	if (wpa_pasn_add_rsne(buf, pmkid,
+			      sta->pasn->akmp, sta->pasn->cipher) < 0)
+		goto fail;
+
+	/* No need to derive PMK if PMKSA is given */
+	if (!pmksa)
+		wrapped_data_buf = pasn_get_wrapped_data(hapd, sta);
+	else
+		sta->pasn->wrapped_data_format = WPA_PASN_WRAPPED_DATA_NO;
+
+	/* Get public key */
+	pubkey = crypto_ecdh_get_pubkey(sta->pasn->ecdh, 0);
+	pubkey = wpabuf_zeropad(pubkey,
+				crypto_ecdh_prime_len(sta->pasn->ecdh));
+	if (!pubkey) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed to get pubkey");
+		goto fail;
+	}
+
+	wpa_pasn_add_parameter_ie(buf, sta->pasn->group,
+				  sta->pasn->wrapped_data_format,
+				  pubkey, true, NULL, 0);
+
+	if (wpa_pasn_add_wrapped_data(buf, wrapped_data_buf) < 0)
+		goto fail;
+
+	wpabuf_free(wrapped_data_buf);
+	wrapped_data_buf = NULL;
+	wpabuf_free(pubkey);
+	pubkey = NULL;
+
+	/* Add RSNXE if needed */
+	rsnxe_ie = hostapd_wpa_ie(hapd, WLAN_EID_RSNX);
+	if (rsnxe_ie)
+		wpabuf_put_data(buf, rsnxe_ie, 2 + rsnxe_ie[1]);
+
+	/* Add the mic */
+	mic_len = pasn_mic_len(sta->pasn->akmp, sta->pasn->cipher);
+	wpabuf_put_u8(buf, WLAN_EID_MIC);
+	wpabuf_put_u8(buf, mic_len);
+	ptr = wpabuf_put(buf, mic_len);
+
+	os_memset(ptr, 0, mic_len);
+
+	frame = wpabuf_head_u8(buf) + IEEE80211_HDRLEN;
+	frame_len = wpabuf_len(buf) - IEEE80211_HDRLEN;
+
+	rsn_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &rsn_ie_len);
+	if (!rsn_ie || !rsn_ie_len)
+		goto fail;
+
+	/*
+	 * Note: wpa_auth_get_wpa_ie() might return not only the RSNE but also
+	 * MDE, etc. Thus, do not use the returned length but instead use the
+	 * length specified in the IE header.
+	 */
+	data_len = rsn_ie[1] + 2;
+	if (rsnxe_ie) {
+		data_buf = os_zalloc(rsn_ie[1] + 2 + rsnxe_ie[1] + 2);
+		if (!data_buf)
+			goto fail;
+
+		os_memcpy(data_buf, rsn_ie, rsn_ie[1] + 2);
+		os_memcpy(data_buf + rsn_ie[1] + 2, rsnxe_ie, rsnxe_ie[1] + 2);
+		data_len += rsnxe_ie[1] + 2;
+		data = data_buf;
+	} else {
+		data = rsn_ie;
+	}
+
+	ret = pasn_mic(sta->pasn->ptk.kck, sta->pasn->akmp, sta->pasn->cipher,
+		       hapd->own_addr, sta->addr, data, data_len,
+		       frame, frame_len, mic);
+	os_free(data_buf);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: Frame 3: Failed MIC calculation");
+		goto fail;
+	}
+
+#ifdef CONFIG_TESTING_OPTIONS
+	if (hapd->conf->pasn_corrupt_mic) {
+		wpa_printf(MSG_DEBUG, "PASN: frame 2: Corrupt MIC");
+		mic[0] = ~mic[0];
+	}
+#endif /* CONFIG_TESTING_OPTIONS */
+
+	os_memcpy(ptr, mic, mic_len);
+
+done:
+	wpa_printf(MSG_DEBUG,
+		   "PASN: Building frame 2: success; resp STA=" MACSTR,
+		   MAC2STR(sta->addr));
+
+	ret = hostapd_drv_send_mlme(hapd, wpabuf_head(buf), wpabuf_len(buf), 0,
+				    NULL, 0, 0);
+	if (ret)
+		wpa_printf(MSG_INFO, "send_auth_reply: Send failed");
+
+	wpabuf_free(buf);
+	return ret;
+fail:
+	wpabuf_free(wrapped_data_buf);
+	wpabuf_free(pubkey);
+	wpabuf_free(buf);
+	return -1;
+}
+
+
+static void handle_auth_pasn_1(struct hostapd_data *hapd, struct sta_info *sta,
+			       const struct ieee80211_mgmt *mgmt, size_t len)
+{
+	struct ieee802_11_elems elems;
+	struct wpa_ie_data rsn_data;
+	struct wpa_pasn_params_data pasn_params;
+	struct rsn_pmksa_cache_entry *pmksa = NULL;
+	const u8 *cached_pmk = NULL;
+	size_t cached_pmk_len = 0;
+#ifdef CONFIG_IEEE80211R_AP
+	u8 pmk_r1[PMK_LEN_MAX];
+	size_t pmk_r1_len;
+#endif /* CONFIG_IEEE80211R_AP */
+	struct wpabuf *wrapped_data = NULL, *secret = NULL;
+	const int *groups = hapd->conf->pasn_groups;
+	static const int default_groups[] = { 19, 0 };
+	u16 status = WLAN_STATUS_SUCCESS;
+	int ret, inc_y;
+	bool derive_keys;
+	u32 i;
+
+	if (!groups)
+		groups = default_groups;
+
+	if (ieee802_11_parse_elems(mgmt->u.auth.variable,
+				   len - offsetof(struct ieee80211_mgmt,
+						  u.auth.variable),
+				   &elems, 0) == ParseFailed) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: Failed parsing Authentication frame");
+		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+		goto send_resp;
+	}
+
+	ret = wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
+				   &rsn_data);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed parsing RNSE");
+		status = WLAN_STATUS_INVALID_RSNIE;
+		goto send_resp;
+	}
+
+	ret = wpa_pasn_validate_rsne(&rsn_data);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed validating RSNE");
+		status = WLAN_STATUS_INVALID_RSNIE;
+		goto send_resp;
+	}
+
+	if (!(rsn_data.key_mgmt & hapd->conf->wpa_key_mgmt) ||
+	    !(rsn_data.pairwise_cipher & hapd->conf->rsn_pairwise)) {
+		wpa_printf(MSG_DEBUG, "PASN: Mismatch in AKMP/cipher");
+		status = WLAN_STATUS_INVALID_RSNIE;
+		goto send_resp;
+	}
+
+	sta->pasn->akmp = rsn_data.key_mgmt;
+	sta->pasn->cipher = rsn_data.pairwise_cipher;
+
+	if (hapd->conf->force_kdk_derivation ||
+	    ((hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF) &&
+	     ieee802_11_rsnx_capab_len(elems.rsnxe, elems.rsnxe_len,
+				       WLAN_RSNX_CAPAB_SECURE_LTF)))
+		sta->pasn->kdk_len = WPA_KDK_MAX_LEN;
+	else
+		sta->pasn->kdk_len = 0;
+	wpa_printf(MSG_DEBUG, "PASN: kdk_len=%zu", sta->pasn->kdk_len);
+
+	if (!elems.pasn_params || !elems.pasn_params_len) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: No PASN Parameters element found");
+		status = WLAN_STATUS_INVALID_PARAMETERS;
+		goto send_resp;
+	}
+
+	ret = wpa_pasn_parse_parameter_ie(elems.pasn_params - 3,
+					  elems.pasn_params_len + 3,
+					  false, &pasn_params);
+	if (ret) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: Failed validation of PASN Parameters IE");
+		status = WLAN_STATUS_INVALID_PARAMETERS;
+		goto send_resp;
+	}
+
+	for (i = 0; groups[i] > 0 && groups[i] != pasn_params.group; i++)
+		;
+
+	if (!pasn_params.group || groups[i] != pasn_params.group) {
+		wpa_printf(MSG_DEBUG, "PASN: Requested group=%hu not allowed",
+			   pasn_params.group);
+		status = WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
+		goto send_resp;
+	}
+
+	if (!pasn_params.pubkey || !pasn_params.pubkey_len) {
+		wpa_printf(MSG_DEBUG, "PASN: Invalid public key");
+		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+		goto send_resp;
+	}
+
+	if (pasn_params.comeback) {
+		wpa_printf(MSG_DEBUG, "PASN: Checking peer comeback token");
+
+		ret = check_comeback_token(hapd, sta->addr,
+					   pasn_params.comeback,
+					   pasn_params.comeback_len);
+
+		if (ret) {
+			wpa_printf(MSG_DEBUG, "PASN: Invalid comeback token");
+			status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+			goto send_resp;
+		}
+	} else if (use_anti_clogging(hapd)) {
+		wpa_printf(MSG_DEBUG, "PASN: Respond with comeback");
+		handle_auth_pasn_comeback(hapd, sta, pasn_params.group);
+		ap_free_sta(hapd, sta);
+		return;
+	}
+
+	sta->pasn->ecdh = crypto_ecdh_init(pasn_params.group);
+	if (!sta->pasn->ecdh) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed to init ECDH");
+		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+		goto send_resp;
+	}
+
+	sta->pasn->group = pasn_params.group;
+
+	if (pasn_params.pubkey[0] == WPA_PASN_PUBKEY_UNCOMPRESSED) {
+		inc_y = 1;
+	} else if (pasn_params.pubkey[0] == WPA_PASN_PUBKEY_COMPRESSED_0 ||
+		   pasn_params.pubkey[0] == WPA_PASN_PUBKEY_COMPRESSED_1) {
+		inc_y = 0;
+	} else {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: Invalid first octet in pubkey=0x%x",
+			   pasn_params.pubkey[0]);
+		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+		goto send_resp;
+	}
+
+	secret = crypto_ecdh_set_peerkey(sta->pasn->ecdh, inc_y,
+					 pasn_params.pubkey + 1,
+					 pasn_params.pubkey_len - 1);
+	if (!secret) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed to derive shared secret");
+		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+		goto send_resp;
+	}
+
+	derive_keys = true;
+	if (pasn_params.wrapped_data_format != WPA_PASN_WRAPPED_DATA_NO) {
+		wrapped_data = ieee802_11_defrag(&elems,
+						 WLAN_EID_EXTENSION,
+						 WLAN_EID_EXT_WRAPPED_DATA);
+		if (!wrapped_data) {
+			wpa_printf(MSG_DEBUG, "PASN: Missing wrapped data");
+			status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+			goto send_resp;
+		}
+
+#ifdef CONFIG_SAE
+		if (sta->pasn->akmp == WPA_KEY_MGMT_SAE) {
+			ret = pasn_wd_handle_sae_commit(hapd, sta,
+							wrapped_data);
+			if (ret) {
+				wpa_printf(MSG_DEBUG,
+					   "PASN: Failed processing SAE commit");
+				status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+				goto send_resp;
+			}
+		}
+#endif /* CONFIG_SAE */
+#ifdef CONFIG_FILS
+		if (sta->pasn->akmp == WPA_KEY_MGMT_FILS_SHA256 ||
+		    sta->pasn->akmp == WPA_KEY_MGMT_FILS_SHA384) {
+			ret = pasn_wd_handle_fils(hapd, sta, wrapped_data);
+			if (ret) {
+				wpa_printf(MSG_DEBUG,
+					   "PASN: Failed processing FILS wrapped data");
+				status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+				goto send_resp;
+			}
+
+			wpa_printf(MSG_DEBUG,
+				   "PASN: FILS: Pending AS response");
+
+			/*
+			 * With PASN/FILS, keys can be derived only after a
+			 * response from the AS is processed.
+			 */
+			derive_keys = false;
+		}
+#endif /* CONFIG_FILS */
+	}
+
+	sta->pasn->wrapped_data_format = pasn_params.wrapped_data_format;
+
+	ret = pasn_auth_frame_hash(sta->pasn->akmp, sta->pasn->cipher,
+				   ((const u8 *) mgmt) + IEEE80211_HDRLEN,
+				   len - IEEE80211_HDRLEN, sta->pasn->hash);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed to compute hash");
+		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+		goto send_resp;
+	}
+
+	if (!derive_keys) {
+		wpa_printf(MSG_DEBUG, "PASN: Storing secret");
+		sta->pasn->secret = secret;
+		wpabuf_free(wrapped_data);
+		return;
+	}
+
+	if (rsn_data.num_pmkid) {
+		if (wpa_key_mgmt_ft(sta->pasn->akmp)) {
+#ifdef CONFIG_IEEE80211R_AP
+			wpa_printf(MSG_DEBUG, "PASN: FT: Fetch PMK-R1");
+
+			ret = wpa_ft_fetch_pmk_r1(hapd->wpa_auth, sta->addr,
+						  rsn_data.pmkid,
+						  pmk_r1, &pmk_r1_len, NULL,
+						  NULL, NULL, NULL,
+						  NULL, NULL, NULL);
+			if (ret) {
+				wpa_printf(MSG_DEBUG,
+					   "PASN: FT: Failed getting PMK-R1");
+				status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+				goto send_resp;
+			}
+			cached_pmk = pmk_r1;
+			cached_pmk_len = pmk_r1_len;
+#else /* CONFIG_IEEE80211R_AP */
+			wpa_printf(MSG_DEBUG, "PASN: FT: Not supported");
+			status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+			goto send_resp;
+#endif /* CONFIG_IEEE80211R_AP */
+		} else {
+			wpa_printf(MSG_DEBUG, "PASN: Try to find PMKSA entry");
+
+			pmksa = wpa_auth_pmksa_get(hapd->wpa_auth, sta->addr,
+						   rsn_data.pmkid);
+			if (pmksa) {
+				cached_pmk = pmksa->pmk;
+				cached_pmk_len = pmksa->pmk_len;
+			}
+		}
+	} else {
+		wpa_printf(MSG_DEBUG, "PASN: No PMKID specified");
+	}
+
+	ret = pasn_derive_keys(hapd, sta, cached_pmk, cached_pmk_len,
+			       &pasn_params, wrapped_data, secret);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed to derive keys");
+		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+		goto send_resp;
+	}
+
+	ret = pasn_auth_frame_hash(sta->pasn->akmp, sta->pasn->cipher,
+				   ((const u8 *) mgmt) + IEEE80211_HDRLEN,
+				   len - IEEE80211_HDRLEN, sta->pasn->hash);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed to compute hash");
+		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+	}
+
+send_resp:
+	ret = handle_auth_pasn_resp(hapd, sta, pmksa, status);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed to send response");
+		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+	} else {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: Success handling transaction == 1");
+	}
+
+	wpabuf_free(secret);
+	wpabuf_free(wrapped_data);
+
+	if (status != WLAN_STATUS_SUCCESS)
+		ap_free_sta(hapd, sta);
+}
+
+
+static void handle_auth_pasn_3(struct hostapd_data *hapd, struct sta_info *sta,
+			       const struct ieee80211_mgmt *mgmt, size_t len)
+{
+	struct ieee802_11_elems elems;
+	struct wpa_pasn_params_data pasn_params;
+	struct wpabuf *wrapped_data = NULL;
+	u8 mic[WPA_PASN_MAX_MIC_LEN], out_mic[WPA_PASN_MAX_MIC_LEN];
+	u8 mic_len;
+	int ret;
+
+	if (ieee802_11_parse_elems(mgmt->u.auth.variable,
+				   len - offsetof(struct ieee80211_mgmt,
+						  u.auth.variable),
+				   &elems, 0) == ParseFailed) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: Failed parsing Authentication frame");
+		goto fail;
+	}
+
+	/* Check that the MIC IE exists. Save it and zero out the memory. */
+	mic_len = pasn_mic_len(sta->pasn->akmp, sta->pasn->cipher);
+	if (!elems.mic || elems.mic_len != mic_len) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: Invalid MIC. Expecting len=%u", mic_len);
+		goto fail;
+	} else {
+		os_memcpy(mic, elems.mic, mic_len);
+		/* TODO: Clean this up.. Should not modify received frame
+		 * buffer. */
+		os_memset((u8 *) elems.mic, 0, mic_len);
+	}
+
+	if (!elems.pasn_params || !elems.pasn_params_len) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: No PASN Parameters element found");
+		goto fail;
+	}
+
+	ret = wpa_pasn_parse_parameter_ie(elems.pasn_params - 3,
+					  elems.pasn_params_len + 3,
+					  false, &pasn_params);
+	if (ret) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: Failed validation of PASN Parameters IE");
+		goto fail;
+	}
+
+	if (pasn_params.pubkey || pasn_params.pubkey_len) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: Public key should not be included");
+		goto fail;
+	}
+
+	/* Verify the MIC */
+	ret = pasn_mic(sta->pasn->ptk.kck, sta->pasn->akmp, sta->pasn->cipher,
+		       sta->addr, hapd->own_addr,
+		       sta->pasn->hash, mic_len * 2,
+		       (u8 *) &mgmt->u.auth,
+		       len - offsetof(struct ieee80211_mgmt, u.auth),
+		       out_mic);
+
+	wpa_hexdump_key(MSG_DEBUG, "PASN: Frame MIC", mic, mic_len);
+	if (ret || os_memcmp(mic, out_mic, mic_len) != 0) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed MIC verification");
+		goto fail;
+	}
+
+	if (pasn_params.wrapped_data_format != WPA_PASN_WRAPPED_DATA_NO) {
+		wrapped_data = ieee802_11_defrag(&elems,
+						 WLAN_EID_EXTENSION,
+						 WLAN_EID_EXT_WRAPPED_DATA);
+
+		if (!wrapped_data) {
+			wpa_printf(MSG_DEBUG, "PASN: Missing wrapped data");
+			goto fail;
+		}
+
+#ifdef CONFIG_SAE
+		if (sta->pasn->akmp == WPA_KEY_MGMT_SAE) {
+			ret = pasn_wd_handle_sae_confirm(hapd, sta,
+							 wrapped_data);
+			if (ret) {
+				wpa_printf(MSG_DEBUG,
+					   "PASN: Failed processing SAE confirm");
+				wpabuf_free(wrapped_data);
+				goto fail;
+			}
+		}
+#endif /* CONFIG_SAE */
+#ifdef CONFIG_FILS
+		if (sta->pasn->akmp == WPA_KEY_MGMT_FILS_SHA256 ||
+		    sta->pasn->akmp == WPA_KEY_MGMT_FILS_SHA384) {
+			if (wrapped_data) {
+				wpa_printf(MSG_DEBUG,
+					   "PASN: FILS: Ignore wrapped data");
+			}
+		}
+#endif /* CONFIG_FILS */
+		wpabuf_free(wrapped_data);
+	}
+
+	wpa_printf(MSG_INFO,
+		   "PASN: Success handling transaction == 3. Store PTK");
+
+	ptksa_cache_add(hapd->ptksa, sta->addr, sta->pasn->cipher, 43200,
+			&sta->pasn->ptk);
+fail:
+	ap_free_sta(hapd, sta);
+}
+
+
+static void handle_auth_pasn(struct hostapd_data *hapd, struct sta_info *sta,
+			     const struct ieee80211_mgmt *mgmt, size_t len,
+			     u16 trans_seq, u16 status)
+{
+	if (hapd->conf->wpa != WPA_PROTO_RSN) {
+		wpa_printf(MSG_INFO, "PASN: RSN is not configured");
+		return;
+	}
+
+	wpa_printf(MSG_INFO, "PASN authentication: sta=" MACSTR,
+		   MAC2STR(sta->addr));
+
+	if (trans_seq == 1) {
+		if (sta->pasn) {
+			wpa_printf(MSG_DEBUG,
+				   "PASN: Not expecting transaction == 1");
+			return;
+		}
+
+		if (status != WLAN_STATUS_SUCCESS) {
+			wpa_printf(MSG_DEBUG,
+				   "PASN: Failure status in transaction == 1");
+			return;
+		}
+
+		sta->pasn = os_zalloc(sizeof(*sta->pasn));
+		if (!sta->pasn) {
+			wpa_printf(MSG_DEBUG,
+				   "PASN: Failed to allocate PASN context");
+			return;
+		}
+
+		handle_auth_pasn_1(hapd, sta, mgmt, len);
+	} else if (trans_seq == 3) {
+		if (!sta->pasn) {
+			wpa_printf(MSG_DEBUG,
+				   "PASN: Not expecting transaction == 3");
+			return;
+		}
+
+		if (status != WLAN_STATUS_SUCCESS) {
+			wpa_printf(MSG_DEBUG,
+				   "PASN: Failure status in transaction == 3");
+			ap_free_sta_pasn(hapd, sta);
+			return;
+		}
+
+		handle_auth_pasn_3(hapd, sta, mgmt, len);
+	} else {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: Invalid transaction %u - ignore", trans_seq);
+	}
+}
+
+#endif /* CONFIG_PASN */
+
+
 static void handle_auth(struct hostapd_data *hapd,
 			const struct ieee80211_mgmt *mgmt, size_t len,
 			int rssi, int from_queue)
@@ -2400,6 +3670,11 @@
 	       hapd->conf->fils_dh_group &&
 	       auth_alg == WLAN_AUTH_FILS_SK_PFS) ||
 #endif /* CONFIG_FILS */
+#ifdef CONFIG_PASN
+	      (hapd->conf->wpa &&
+	       (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_PASN) &&
+	       auth_alg == WLAN_AUTH_PASN) ||
+#endif /* CONFIG_PASN */
 	      ((hapd->conf->auth_algs & WPA_AUTH_ALG_SHARED) &&
 	       auth_alg == WLAN_AUTH_SHARED_KEY))) {
 		wpa_printf(MSG_INFO, "Unsupported authentication algorithm (%d)",
@@ -2409,6 +3684,9 @@
 	}
 
 	if (!(auth_transaction == 1 || auth_alg == WLAN_AUTH_SAE ||
+#ifdef CONFIG_PASN
+	      (auth_alg == WLAN_AUTH_PASN && auth_transaction == 3) ||
+#endif /* CONFIG_PASN */
 	      (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 3))) {
 		wpa_printf(MSG_INFO, "Unknown authentication transaction number (%d)",
 			   auth_transaction);
@@ -2530,6 +3808,15 @@
 			return;
 		}
 #endif /* CONFIG_MESH */
+#ifdef CONFIG_PASN
+		if (auth_alg == WLAN_AUTH_PASN &&
+		    (sta->flags & WLAN_STA_ASSOC)) {
+			wpa_printf(MSG_DEBUG,
+				   "PASN: auth: Existing station: " MACSTR,
+				   MAC2STR(sta->addr));
+			return;
+		}
+#endif /* CONFIG_PASN */
 	} else {
 #ifdef CONFIG_MESH
 		if (hapd->conf->mesh & MESH_ENABLED) {
@@ -2590,11 +3877,14 @@
 	 * to allow the original connection work until the attempt can complete
 	 * (re)association, so that unprotected Authentication frame cannot be
 	 * used to bypass PMF protection.
+	 *
+	 * PASN authentication does not require adding/removing station to the
+	 * driver so skip this flow in case of PASN authentication.
 	 */
 	if (FULL_AP_CLIENT_STATE_SUPP(hapd->iface->drv_flags) &&
 	    (!(sta->flags & WLAN_STA_MFP) || !ap_sta_is_authorized(sta)) &&
 	    !(hapd->conf->mesh & MESH_ENABLED) &&
-	    !(sta->added_unassoc)) {
+	    !(sta->added_unassoc) && auth_alg != WLAN_AUTH_PASN) {
 		if (ap_sta_re_add(hapd, sta) < 0) {
 			resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
 			goto fail;
@@ -2681,12 +3971,20 @@
 				 handle_auth_fils_finish);
 		return;
 #endif /* CONFIG_FILS */
+#ifdef CONFIG_PASN
+	case WLAN_AUTH_PASN:
+		handle_auth_pasn(hapd, sta, mgmt, len, auth_transaction,
+				 status_code);
+		return;
+#endif /* CONFIG_PASN */
 	}
 
  fail:
 	reply_res = send_auth_reply(hapd, sta, mgmt->sa, mgmt->bssid, auth_alg,
-				    auth_transaction + 1, resp, resp_ies,
-				    resp_ies_len, "handle-auth");
+				    auth_alg == WLAN_AUTH_SAE ?
+				    auth_transaction : auth_transaction + 1,
+				    resp, resp_ies, resp_ies_len,
+				    "handle-auth");
 
 	if (sta && sta->added_unassoc && (resp != WLAN_STATUS_SUCCESS ||
 					  reply_res != WLAN_STATUS_SUCCESS)) {
@@ -3272,7 +4570,7 @@
 	}
 #endif /* CONFIG_IEEE80211AC */
 #ifdef CONFIG_IEEE80211AX
-	if (hapd->iconf->ieee80211ax) {
+	if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
 		resp = copy_sta_he_capab(hapd, sta, IEEE80211_MODE_AP,
 					 elems.he_capabilities,
 					 elems.he_capabilities_len);
@@ -3435,8 +4733,8 @@
 		if (hapd->conf->sae_pwe == 2 &&
 		    sta->auth_alg == WLAN_AUTH_SAE &&
 		    sta->sae && !sta->sae->h2e &&
-		    elems.rsnxe && elems.rsnxe_len >= 1 &&
-		    (elems.rsnxe[0] & BIT(WLAN_RSNX_CAPAB_SAE_H2E))) {
+		    ieee802_11_rsnx_capab_len(elems.rsnxe, elems.rsnxe_len,
+					      WLAN_RSNX_CAPAB_SAE_H2E)) {
 			wpa_printf(MSG_INFO, "SAE: " MACSTR
 				   " indicates support for SAE H2E, but did not use it",
 				   MAC2STR(sta->addr));
@@ -3887,7 +5185,7 @@
 #endif /* CONFIG_IEEE80211AC */
 
 #ifdef CONFIG_IEEE80211AX
-	if (hapd->iconf->ieee80211ax) {
+	if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
 		p = hostapd_eid_he_capab(hapd, p, IEEE80211_MODE_AP);
 		p = hostapd_eid_he_operation(hapd, p);
 		p = hostapd_eid_spatial_reuse(hapd, p);
@@ -4660,6 +5958,9 @@
 		" reason_code=%d",
 		MAC2STR(mgmt->sa), le_to_host16(mgmt->u.deauth.reason_code));
 
+	/* Clear the PTKSA cache entries for PASN */
+	ptksa_cache_flush(hapd->ptksa, mgmt->sa, WPA_CIPHER_NONE);
+
 	sta = ap_get_sta(hapd, mgmt->sa);
 	if (sta == NULL) {
 		wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " trying "
@@ -4904,6 +6205,31 @@
 
 
 /**
+ * notify_mgmt_frame - Notify of Management frames on the control interface
+ * @hapd: hostapd BSS data structure (the BSS to which the Management frame was
+ * sent to)
+ * @buf: Management frame data (starting from the IEEE 802.11 header)
+ * @len: Length of frame data in octets
+ *
+ * Notify the control interface of any received Management frame.
+ */
+static void notify_mgmt_frame(struct hostapd_data *hapd, const u8 *buf,
+			      size_t len)
+{
+
+	int hex_len = len * 2 + 1;
+	char *hex = os_malloc(hex_len);
+
+	if (hex) {
+		wpa_snprintf_hex(hex, hex_len, buf, len);
+		wpa_msg_ctrl(hapd->msg_ctx, MSG_INFO,
+			     AP_MGMT_FRAME_RECEIVED "buf=%s", hex);
+		os_free(hex);
+	}
+}
+
+
+/**
  * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
  * @hapd: hostapd BSS data structure (the BSS to which the management frame was
  * sent to)
@@ -4993,6 +6319,9 @@
 	if (hapd->iconf->track_sta_max_num)
 		sta_track_add(hapd->iface, mgmt->sa, ssi_signal);
 
+	if (hapd->conf->notify_mgmt_frames)
+		notify_mgmt_frame(hapd, buf, len);
+
 	switch (stype) {
 	case WLAN_FC_STYPE_AUTH:
 		wpa_printf(MSG_DEBUG, "mgmt::auth");
@@ -5040,6 +6369,7 @@
 {
 	u16 auth_alg, auth_transaction, status_code;
 	struct sta_info *sta;
+	bool success_status;
 
 	sta = ap_get_sta(hapd, mgmt->da);
 	if (!sta) {
@@ -5049,6 +6379,15 @@
 		return;
 	}
 
+	if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
+		wpa_printf(MSG_INFO, "handle_auth_cb - too short payload (len=%lu)",
+			   (unsigned long) len);
+		auth_alg = 0;
+		auth_transaction = 0;
+		status_code = WLAN_STATUS_UNSPECIFIED_FAILURE;
+		goto fail;
+	}
+
 	auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
 	auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
 	status_code = le_to_host16(mgmt->u.auth.status_code);
@@ -5060,12 +6399,6 @@
 		goto fail;
 	}
 
-	if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
-		wpa_printf(MSG_INFO, "handle_auth_cb - too short payload (len=%lu)",
-			   (unsigned long) len);
-		goto fail;
-	}
-
 	if (status_code == WLAN_STATUS_SUCCESS &&
 	    ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 2) ||
 	     (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 4))) {
@@ -5078,7 +6411,12 @@
 	}
 
 fail:
-	if (status_code != WLAN_STATUS_SUCCESS && sta->added_unassoc) {
+	success_status = status_code == WLAN_STATUS_SUCCESS;
+#ifdef CONFIG_SAE
+	if (auth_alg == WLAN_AUTH_SAE && auth_transaction == 1)
+		success_status = sae_status_success(hapd, status_code);
+#endif /* CONFIG_SAE */
+	if (!success_status && sta->added_unassoc) {
 		hostapd_drv_sta_remove(hapd, sta->addr);
 		sta->added_unassoc = 0;
 	}
@@ -5608,6 +6946,118 @@
 }
 
 
+u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid)
+{
+	struct hostapd_iface *iface = hapd->iface;
+	struct hostapd_config *iconf = iface->conf;
+	struct hostapd_hw_modes *mode = iface->current_mode;
+	struct hostapd_channel_data *chan;
+	int dfs, i;
+	u8 channel, tx_pwr_count, local_pwr_constraint;
+	int max_tx_power;
+	u8 tx_pwr;
+
+	if (!mode)
+		return eid;
+
+	if (ieee80211_freq_to_chan(iface->freq, &channel) == NUM_HOSTAPD_MODES)
+		return eid;
+
+	for (i = 0; i < mode->num_channels; i++) {
+		if (mode->channels[i].freq == iface->freq)
+			break;
+	}
+	if (i == mode->num_channels)
+		return eid;
+
+	switch (hostapd_get_oper_chwidth(iconf)) {
+	case CHANWIDTH_USE_HT:
+		if (iconf->secondary_channel == 0) {
+			/* Max Transmit Power count = 0 (20 MHz) */
+			tx_pwr_count = 0;
+		} else {
+			/* Max Transmit Power count = 1 (20, 40 MHz) */
+			tx_pwr_count = 1;
+		}
+		break;
+	case CHANWIDTH_80MHZ:
+		/* Max Transmit Power count = 2 (20, 40, and 80 MHz) */
+		tx_pwr_count = 2;
+		break;
+	case CHANWIDTH_80P80MHZ:
+	case CHANWIDTH_160MHZ:
+		/* Max Transmit Power count = 3 (20, 40, 80, 160/80+80 MHz) */
+		tx_pwr_count = 3;
+		break;
+	default:
+		return eid;
+	}
+
+	/*
+	 * Below local_pwr_constraint logic is referred from
+	 * hostapd_eid_pwr_constraint.
+	 *
+	 * Check if DFS is required by regulatory.
+	 */
+	dfs = hostapd_is_dfs_required(hapd->iface);
+	if (dfs < 0)
+		dfs = 0;
+
+	/*
+	 * In order to meet regulations when TPC is not implemented using
+	 * a transmit power that is below the legal maximum (including any
+	 * mitigation factor) should help. In this case, indicate 3 dB below
+	 * maximum allowed transmit power.
+	 */
+	if (hapd->iconf->local_pwr_constraint == -1)
+		local_pwr_constraint = (dfs == 0) ? 0 : 3;
+	else
+		local_pwr_constraint = hapd->iconf->local_pwr_constraint;
+
+	/*
+	 * A STA that is not an AP shall use a transmit power less than or
+	 * equal to the local maximum transmit power level for the channel.
+	 * The local maximum transmit power can be calculated from the formula:
+	 * local max TX pwr = max TX pwr - local pwr constraint
+	 * Where max TX pwr is maximum transmit power level specified for
+	 * channel in Country element and local pwr constraint is specified
+	 * for channel in this Power Constraint element.
+	 */
+	chan = &mode->channels[i];
+	max_tx_power = chan->max_tx_power - local_pwr_constraint;
+
+	/*
+	 * Local Maximum Transmit power is encoded as two's complement
+	 * with a 0.5 dB step.
+	 */
+	max_tx_power *= 2; /* in 0.5 dB steps */
+	if (max_tx_power > 127) {
+		/* 63.5 has special meaning of 63.5 dBm or higher */
+		max_tx_power = 127;
+	}
+	if (max_tx_power < -128)
+		max_tx_power = -128;
+	if (max_tx_power < 0)
+		tx_pwr = 0x80 + max_tx_power + 128;
+	else
+		tx_pwr = max_tx_power;
+
+	*eid++ = WLAN_EID_TRANSMIT_POWER_ENVELOPE;
+	*eid++ = 2 + tx_pwr_count;
+
+	/*
+	 * Max Transmit Power count and
+	 * Max Transmit Power units = 0 (EIRP)
+	 */
+	*eid++ = tx_pwr_count;
+
+	for (i = 0; i <= tx_pwr_count; i++)
+		*eid++ = tx_pwr;
+
+	return eid;
+}
+
+
 u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid)
 {
 	u8 bw, chan1, chan2 = 0;
@@ -5661,4 +7111,386 @@
 	return eid;
 }
 
+
+static size_t hostapd_eid_nr_db_len(struct hostapd_data *hapd,
+				    size_t *current_len)
+{
+	struct hostapd_neighbor_entry *nr;
+	size_t total_len = 0, len = *current_len;
+
+	dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
+			 list) {
+		if (!nr->nr || wpabuf_len(nr->nr) < 12)
+			continue;
+
+		if (nr->short_ssid == hapd->conf->ssid.short_ssid)
+			continue;
+
+		/* Start a new element */
+		if (!len ||
+		    len + RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN > 255) {
+			len = RNR_HEADER_LEN;
+			total_len += RNR_HEADER_LEN;
+		}
+
+		len += RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN;
+		total_len += RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN;
+	}
+
+	*current_len = len;
+	return total_len;
+}
+
+
+static size_t hostapd_eid_rnr_iface_len(struct hostapd_data *hapd,
+					struct hostapd_data *reporting_hapd,
+					size_t *current_len)
+{
+	size_t total_len = 0, len = *current_len;
+	int tbtt_count = 0;
+	size_t i, start = 0;
+
+	while (start < hapd->iface->num_bss) {
+		if (!len ||
+		    len + RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN > 255) {
+			len = RNR_HEADER_LEN;
+			total_len += RNR_HEADER_LEN;
+		}
+
+		len += RNR_TBTT_HEADER_LEN;
+		total_len += RNR_TBTT_HEADER_LEN;
+
+		for (i = start; i < hapd->iface->num_bss; i++) {
+			struct hostapd_data *bss = hapd->iface->bss[i];
+
+			if (!bss || !bss->conf || !bss->started)
+				continue;
+
+			if (bss == reporting_hapd ||
+			    bss->conf->ignore_broadcast_ssid)
+				continue;
+
+			if (len + RNR_TBTT_INFO_LEN > 255 ||
+			    tbtt_count >= RNR_TBTT_INFO_COUNT_MAX)
+				break;
+
+			len += RNR_TBTT_INFO_LEN;
+			total_len += RNR_TBTT_INFO_LEN;
+			tbtt_count++;
+		}
+		start = i;
+	}
+
+	if (!tbtt_count)
+		total_len = 0;
+	else
+		*current_len = len;
+
+	return total_len;
+}
+
+
+enum colocation_mode {
+	NO_COLOCATED_6GHZ,
+	STANDALONE_6GHZ,
+	COLOCATED_6GHZ,
+	COLOCATED_LOWER_BAND,
+};
+
+static enum colocation_mode get_colocation_mode(struct hostapd_data *hapd)
+{
+	u8 i;
+	bool is_6ghz = is_6ghz_op_class(hapd->iconf->op_class);
+
+	if (!hapd->iface || !hapd->iface->interfaces)
+		return NO_COLOCATED_6GHZ;
+
+	if (is_6ghz && hapd->iface->interfaces->count == 1)
+		return STANDALONE_6GHZ;
+
+	for (i = 0; i < hapd->iface->interfaces->count; i++) {
+		struct hostapd_iface *iface;
+		bool is_colocated_6ghz;
+
+		iface = hapd->iface->interfaces->iface[i];
+		if (iface == hapd->iface || !iface || !iface->conf)
+			continue;
+
+		is_colocated_6ghz = is_6ghz_op_class(iface->conf->op_class);
+		if (!is_6ghz && is_colocated_6ghz)
+			return COLOCATED_LOWER_BAND;
+		if (is_6ghz && !is_colocated_6ghz)
+			return COLOCATED_6GHZ;
+	}
+
+	if (is_6ghz)
+		return STANDALONE_6GHZ;
+
+	return NO_COLOCATED_6GHZ;
+}
+
+
+static size_t hostapd_eid_rnr_colocation_len(struct hostapd_data *hapd,
+					     size_t *current_len)
+{
+	struct hostapd_iface *iface;
+	size_t len = 0;
+	size_t i;
+
+	if (!hapd->iface || !hapd->iface->interfaces)
+		return 0;
+
+	for (i = 0; i < hapd->iface->interfaces->count; i++) {
+		iface = hapd->iface->interfaces->iface[i];
+
+		if (iface == hapd->iface ||
+		    !is_6ghz_op_class(iface->conf->op_class))
+			continue;
+
+		len += hostapd_eid_rnr_iface_len(iface->bss[0], hapd,
+						 current_len);
+	}
+
+	return len;
+}
+
+
+size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type)
+{
+	size_t total_len = 0, current_len = 0;
+	enum colocation_mode mode = get_colocation_mode(hapd);
+
+	switch (type) {
+	case WLAN_FC_STYPE_BEACON:
+		if (hapd->conf->rnr)
+			total_len += hostapd_eid_nr_db_len(hapd, &current_len);
+		/* fallthrough */
+
+	case WLAN_FC_STYPE_PROBE_RESP:
+		if (mode == COLOCATED_LOWER_BAND)
+			total_len += hostapd_eid_rnr_colocation_len(
+				hapd, &current_len);
+
+		if (hapd->conf->rnr && hapd->iface->num_bss > 1)
+			total_len += hostapd_eid_rnr_iface_len(hapd, hapd,
+							       &current_len);
+		break;
+
+	case WLAN_FC_STYPE_ACTION:
+		if (hapd->iface->num_bss > 1 && mode == STANDALONE_6GHZ)
+			total_len += hostapd_eid_rnr_iface_len(hapd, hapd,
+							       &current_len);
+		break;
+
+	default:
+		break;
+	}
+
+	return total_len;
+}
+
+
+static u8 * hostapd_eid_nr_db(struct hostapd_data *hapd, u8 *eid,
+			      size_t *current_len)
+{
+	struct hostapd_neighbor_entry *nr;
+	size_t len = *current_len;
+	u8 *size_offset = (eid - len) + 1;
+
+	dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
+			 list) {
+		if (!nr->nr || wpabuf_len(nr->nr) < 12)
+			continue;
+
+		if (nr->short_ssid == hapd->conf->ssid.short_ssid)
+			continue;
+
+		/* Start a new element */
+		if (!len ||
+		    len + RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN > 255) {
+			*eid++ = WLAN_EID_REDUCED_NEIGHBOR_REPORT;
+			size_offset = eid++;
+			len = RNR_HEADER_LEN;
+		}
+
+		/* TBTT Information Header subfield (2 octets) */
+		*eid++ = 0;
+		/* TBTT Information Length */
+		*eid++ = RNR_TBTT_INFO_LEN;
+		/* Operating Class */
+		*eid++ = wpabuf_head_u8(nr->nr)[10];
+		/* Channel Number */
+		*eid++ = wpabuf_head_u8(nr->nr)[11];
+		len += RNR_TBTT_HEADER_LEN;
+		/* TBTT Information Set */
+		/* TBTT Information field */
+		/* Neighbor AP TBTT Offset */
+		*eid++ = RNR_NEIGHBOR_AP_OFFSET_UNKNOWN;
+		/* BSSID */
+		os_memcpy(eid, nr->bssid, ETH_ALEN);
+		eid += ETH_ALEN;
+		/* Short SSID */
+		os_memcpy(eid, &nr->short_ssid, 4);
+		eid += 4;
+		/* BSS parameters */
+		*eid++ = nr->bss_parameters;
+		/* 20 MHz PSD */
+		*eid++ = RNR_20_MHZ_PSD_MAX_TXPOWER - 1;
+		len += RNR_TBTT_INFO_LEN;
+		*size_offset = (eid - size_offset) - 1;
+	}
+
+	*current_len = len;
+	return eid;
+}
+
+
+static u8 * hostapd_eid_rnr_iface(struct hostapd_data *hapd,
+				  struct hostapd_data *reporting_hapd,
+				  u8 *eid, size_t *current_len)
+{
+	struct hostapd_data *bss;
+	struct hostapd_iface *iface = hapd->iface;
+	size_t i, start = 0;
+	size_t len = *current_len;
+	u8 *tbtt_count_pos, *eid_start = eid, *size_offset = (eid - len) + 1;
+	u8 tbtt_count = 0, op_class, channel, bss_param;
+
+	if (!(iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA) || !iface->freq)
+		return eid;
+
+	if (ieee80211_freq_to_channel_ext(iface->freq,
+					  hapd->iconf->secondary_channel,
+					  hostapd_get_oper_chwidth(hapd->iconf),
+					  &op_class, &channel) ==
+	    NUM_HOSTAPD_MODES)
+		return eid;
+
+	while (start < iface->num_bss) {
+		if (!len ||
+		    len + RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN > 255) {
+			eid_start = eid;
+			*eid++ = WLAN_EID_REDUCED_NEIGHBOR_REPORT;
+			size_offset = eid++;
+			len = RNR_HEADER_LEN;
+			tbtt_count = 0;
+		}
+
+		tbtt_count_pos = eid++;
+		*eid++ = RNR_TBTT_INFO_LEN;
+		*eid++ = op_class;
+		*eid++ = hapd->iconf->channel;
+		len += RNR_TBTT_HEADER_LEN;
+
+		for (i = start; i < iface->num_bss; i++) {
+			bss_param = 0;
+			bss = iface->bss[i];
+			if (!bss || !bss->conf || !bss->started)
+				continue;
+
+			if (bss == reporting_hapd ||
+			    bss->conf->ignore_broadcast_ssid)
+				continue;
+
+			if (len + RNR_TBTT_INFO_LEN > 255 ||
+			    tbtt_count >= RNR_TBTT_INFO_COUNT_MAX)
+				break;
+
+			*eid++ = RNR_NEIGHBOR_AP_OFFSET_UNKNOWN;
+			os_memcpy(eid, bss->conf->bssid, ETH_ALEN);
+			eid += ETH_ALEN;
+			os_memcpy(eid, &bss->conf->ssid.short_ssid, 4);
+			eid += 4;
+			if (bss->conf->ssid.short_ssid ==
+			    reporting_hapd->conf->ssid.short_ssid)
+				bss_param |= RNR_BSS_PARAM_SAME_SSID;
+
+			if (is_6ghz_op_class(hapd->iconf->op_class) &&
+			    bss->conf->unsol_bcast_probe_resp_interval)
+				bss_param |=
+					RNR_BSS_PARAM_UNSOLIC_PROBE_RESP_ACTIVE;
+
+			bss_param |= RNR_BSS_PARAM_CO_LOCATED;
+
+			*eid++ = bss_param;
+			*eid++ = RNR_20_MHZ_PSD_MAX_TXPOWER - 1;
+			len += RNR_TBTT_INFO_LEN;
+			tbtt_count += 1;
+		}
+
+		start = i;
+		*tbtt_count_pos = RNR_TBTT_INFO_COUNT(tbtt_count - 1);
+		*size_offset = (eid - size_offset) - 1;
+	}
+
+	if (tbtt_count == 0)
+		return eid_start;
+
+	*current_len = len;
+	return eid;
+}
+
+
+static u8 * hostapd_eid_rnr_colocation(struct hostapd_data *hapd, u8 *eid,
+				       size_t *current_len)
+{
+	struct hostapd_iface *iface;
+	size_t i;
+
+	if (!hapd->iface || !hapd->iface->interfaces)
+		return eid;
+
+	for (i = 0; i < hapd->iface->interfaces->count; i++) {
+		iface = hapd->iface->interfaces->iface[i];
+
+		if (iface == hapd->iface ||
+		    !is_6ghz_op_class(iface->conf->op_class))
+			continue;
+
+		eid = hostapd_eid_rnr_iface(iface->bss[0], hapd, eid,
+					    current_len);
+	}
+
+	return eid;
+}
+
+
+u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type)
+{
+	u8 *eid_start = eid;
+	size_t current_len = 0;
+	enum colocation_mode mode = get_colocation_mode(hapd);
+
+	switch (type) {
+	case WLAN_FC_STYPE_BEACON:
+		if (hapd->conf->rnr)
+			eid = hostapd_eid_nr_db(hapd, eid, &current_len);
+		/* fallthrough */
+
+	case WLAN_FC_STYPE_PROBE_RESP:
+		if (mode == COLOCATED_LOWER_BAND)
+			eid = hostapd_eid_rnr_colocation(hapd, eid,
+							 &current_len);
+
+		if (hapd->conf->rnr && hapd->iface->num_bss > 1)
+			eid = hostapd_eid_rnr_iface(hapd, hapd, eid,
+						    &current_len);
+		break;
+
+	case WLAN_FC_STYPE_ACTION:
+		if (hapd->iface->num_bss > 1 && mode == STANDALONE_6GHZ)
+			eid = hostapd_eid_rnr_iface(hapd, hapd,	eid,
+						    &current_len);
+		break;
+
+	default:
+		return eid_start;
+	}
+
+	if (eid == eid_start + 2)
+		return eid_start;
+
+	return eid;
+}
+
 #endif /* CONFIG_NATIVE_WINDOWS */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ieee802_11.h b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ieee802_11.h
index ea8c608..c59ad5e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ieee802_11.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ieee802_11.h
@@ -194,5 +194,7 @@
 
 void auth_sae_process_commit(void *eloop_ctx, void *user_ctx);
 u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len);
+size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type);
+u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type);
 
 #endif /* IEEE802_11_H */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ieee802_11_he.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ieee802_11_he.c
index 85b7140..6cd6c90 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ieee802_11_he.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ieee802_11_he.c
@@ -192,6 +192,9 @@
 		params |= (hapd->iface->conf->he_op.he_rts_threshold <<
 			   HE_OPERATION_RTS_THRESHOLD_OFFSET);
 
+	if (hapd->iface->conf->he_op.he_er_su_disable)
+		params |= HE_OPERATION_ER_SU_DISABLE;
+
 	if (hapd->iface->conf->he_op.he_bss_color_disabled)
 		params |= HE_OPERATION_BSS_COLOR_DISABLED;
 	if (hapd->iface->conf->he_op.he_bss_color_partial)
@@ -216,7 +219,10 @@
 
 		params |= HE_OPERATION_6GHZ_OPER_INFO;
 
-		/* 6 GHz Operation Information field */
+		/* 6 GHz Operation Information field
+		 * IEEE P802.11ax/D8.0, 9.4.2.249 HE Operation element,
+		 * Figure 9-788k
+		 */
 		*pos++ = hapd->iconf->channel; /* Primary Channel */
 
 		/* Control: Channel Width */
@@ -226,6 +232,18 @@
 			*pos++ = center_idx_to_bw_6ghz(seg0);
 
 		/* Channel Center Freq Seg0/Seg1 */
+		if (hapd->iconf->he_oper_chwidth == 2) {
+			/*
+			 * Seg 0 indicates the channel center frequency index of
+			 * the 160 MHz channel.
+			 */
+			seg1 = seg0;
+			if (hapd->iconf->channel < seg0)
+				seg0 -= 8;
+			else
+				seg0 += 8;
+		}
+
 		*pos++ = seg0;
 		*pos++ = seg1;
 		/* Minimum Rate */
@@ -304,6 +322,11 @@
 	if (spr->sr_ctrl & SPATIAL_REUSE_SRG_INFORMATION_PRESENT) {
 		*spr_param++ = hapd->iface->conf->spr.srg_obss_pd_min_offset;
 		*spr_param++ = hapd->iface->conf->spr.srg_obss_pd_max_offset;
+		os_memcpy(spr_param,
+			  hapd->iface->conf->spr.srg_bss_color_bitmap, 8);
+		spr_param += 8;
+		os_memcpy(spr_param,
+			  hapd->iface->conf->spr.srg_partial_bssid_bitmap, 8);
 		pos += 18;
 	}
 
@@ -313,6 +336,7 @@
 
 u8 * hostapd_eid_he_6ghz_band_cap(struct hostapd_data *hapd, u8 *eid)
 {
+	struct hostapd_config *conf = hapd->iface->conf;
 	struct hostapd_hw_modes *mode = hapd->iface->current_mode;
 	struct he_capabilities *he_cap;
 	struct ieee80211_he_6ghz_band_cap *cap;
@@ -324,8 +348,18 @@
 		return eid;
 
 	he_cap = &mode->he_capab[IEEE80211_MODE_AP];
-	capab = he_cap->he_6ghz_capa;
+	capab = he_cap->he_6ghz_capa & HE_6GHZ_BAND_CAP_MIN_MPDU_START;
+	capab |= (conf->he_6ghz_max_ampdu_len_exp <<
+		  HE_6GHZ_BAND_CAP_MAX_AMPDU_LEN_EXP_SHIFT) &
+		HE_6GHZ_BAND_CAP_MAX_AMPDU_LEN_EXP_MASK;
+	capab |= (conf->he_6ghz_max_mpdu <<
+		  HE_6GHZ_BAND_CAP_MAX_MPDU_LEN_SHIFT) &
+		HE_6GHZ_BAND_CAP_MAX_MPDU_LEN_MASK;
 	capab |= HE_6GHZ_BAND_CAP_SMPS_DISABLED;
+	if (conf->he_6ghz_rx_ant_pat)
+		capab |= HE_6GHZ_BAND_CAP_RX_ANTPAT_CONS;
+	if (conf->he_6ghz_tx_ant_pat)
+		capab |= HE_6GHZ_BAND_CAP_TX_ANTPAT_CONS;
 
 	pos = eid;
 	*pos++ = WLAN_EID_EXTENSION;
@@ -418,7 +452,8 @@
 		      enum ieee80211_op_mode opmode, const u8 *he_capab,
 		      size_t he_capab_len)
 {
-	if (!he_capab || !hapd->iconf->ieee80211ax ||
+	if (!he_capab || !(sta->flags & WLAN_STA_WMM) ||
+	    !hapd->iconf->ieee80211ax || hapd->conf->disable_11ax ||
 	    !check_valid_he_mcs(hapd, he_capab, opmode) ||
 	    ieee80211_invalid_he_cap_size(he_capab, he_capab_len) ||
 	    he_capab_len > sizeof(struct ieee80211_he_capabilities)) {
@@ -448,6 +483,7 @@
 			   const u8 *he_6ghz_capab)
 {
 	if (!he_6ghz_capab || !hapd->iconf->ieee80211ax ||
+	    hapd->conf->disable_11ax ||
 	    !is_6ghz_op_class(hapd->iconf->op_class)) {
 		sta->flags &= ~WLAN_STA_6GHZ;
 		os_free(sta->he_6ghz_capab);
@@ -481,5 +517,6 @@
 
 	mac_cap = hapd->iface->current_mode->he_capab[mode].mac_cap;
 
-	return !!(mac_cap[HE_MAC_CAPAB_0] & HE_MACCAP_TWT_RESPONDER);
+	return !!(mac_cap[HE_MAC_CAPAB_0] & HE_MACCAP_TWT_RESPONDER) &&
+		hapd->iface->conf->he_op.he_twt_responder;
 }
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ieee802_11_shared.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ieee802_11_shared.c
index 5110270..66da424 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ieee802_11_shared.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ieee802_11_shared.c
@@ -244,6 +244,12 @@
 			   (unsigned long) len);
 		return;
 	}
+	if (is_multicast_ether_addr(mgmt->da)) {
+		wpa_printf(MSG_DEBUG,
+			   "IEEE 802.11: Ignore group-addressed SA Query frame (A1=" MACSTR " A2=" MACSTR ")",
+			   MAC2STR(mgmt->da), MAC2STR(mgmt->sa));
+		return;
+	}
 
 	sta = ap_get_sta(hapd, sa);
 
@@ -428,7 +434,9 @@
 					       * Identifiers Used Exclusively */
 		}
 #endif /* CONFIG_SAE */
-		if (hapd->conf->beacon_prot)
+		if (hapd->conf->beacon_prot &&
+		    (hapd->iface->drv_flags &
+		     WPA_DRIVER_FLAGS_BEACON_PROTECTION))
 			*pos |= 0x10; /* Bit 84 - Beacon Protection Enabled */
 		break;
 	case 11: /* Bits 88-95 */
@@ -446,69 +454,10 @@
 u8 * hostapd_eid_ext_capab(struct hostapd_data *hapd, u8 *eid)
 {
 	u8 *pos = eid;
-	u8 len = 0, i;
+	u8 len = EXT_CAPA_MAX_LEN, i;
 
-	if (hapd->conf->qos_map_set_len ||
-	    (hapd->conf->tdls & (TDLS_PROHIBIT | TDLS_PROHIBIT_CHAN_SWITCH)))
-		len = 5;
-	if (len < 4 &&
-	    (hapd->conf->time_advertisement == 2 || hapd->conf->interworking))
-		len = 4;
-	if (len < 3 &&
-	    (hapd->conf->wnm_sleep_mode || hapd->conf->bss_transition))
-		len = 3;
-	if (len < 1 &&
-	    (hapd->iconf->obss_interval ||
-	     (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA)))
-		len = 1;
-	if (len < 2 &&
-	    (hapd->conf->proxy_arp || hapd->conf->coloc_intf_reporting))
-		len = 2;
-	if (len < 7 && hapd->conf->ssid.utf8_ssid)
-		len = 7;
-	if (len < 9 &&
-	    (hapd->conf->ftm_initiator || hapd->conf->ftm_responder))
-		len = 9;
-#ifdef CONFIG_WNM_AP
-	if (len < 4)
-		len = 4;
-#endif /* CONFIG_WNM_AP */
-#ifdef CONFIG_HS20
-	if (hapd->conf->hs20 && len < 6)
-		len = 6;
-#endif /* CONFIG_HS20 */
-#ifdef CONFIG_MBO
-	if (hapd->conf->mbo_enabled && len < 6)
-		len = 6;
-#endif /* CONFIG_MBO */
-#ifdef CONFIG_FILS
-	if ((!(hapd->conf->wpa & WPA_PROTO_RSN) ||
-	     !wpa_key_mgmt_fils(hapd->conf->wpa_key_mgmt)) && len < 10)
-		len = 10;
-#endif /* CONFIG_FILS */
-#ifdef CONFIG_IEEE80211AX
-	if (len < 10 && hapd->iconf->ieee80211ax &&
-	    hostapd_get_he_twt_responder(hapd, IEEE80211_MODE_AP))
-		len = 10;
-#endif /* CONFIG_IEEE80211AX */
-#ifdef CONFIG_SAE
-	if (len < 11 && hapd->conf->wpa &&
-	    wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) &&
-	    hostapd_sae_pw_id_in_use(hapd->conf))
-		len = 11;
-#endif /* CONFIG_SAE */
-	if (len < 11 && hapd->conf->beacon_prot)
-		len = 11;
-#ifdef CONFIG_SAE_PK
-	if (len < 12 && hapd->conf->wpa &&
-	    wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) &&
-	    hostapd_sae_pk_exclusively(hapd->conf))
-		len = 12;
-#endif /* CONFIG_SAE_PK */
 	if (len < hapd->iface->extended_capa_len)
 		len = hapd->iface->extended_capa_len;
-	if (len == 0)
-		return eid;
 
 	*pos++ = WLAN_EID_EXT_CAPAB;
 	*pos++ = len;
@@ -519,6 +468,11 @@
 			*pos &= ~hapd->iface->extended_capa_mask[i];
 			*pos |= hapd->iface->extended_capa[i];
 		}
+
+		if (i < EXT_CAPA_MAX_LEN) {
+			*pos &= ~hapd->conf->ext_capa_mask[i];
+			*pos |= hapd->conf->ext_capa[i];
+		}
 	}
 
 	while (len > 0 && eid[1 + len] == 0) {
@@ -1137,29 +1091,45 @@
 {
 	u8 *pos = eid;
 	bool sae_pk = false;
+	u16 capab = 0;
+	size_t flen;
+
+	if (!(hapd->conf->wpa & WPA_PROTO_RSN))
+		return eid;
 
 #ifdef CONFIG_SAE_PK
 	sae_pk = hostapd_sae_pk_in_use(hapd->conf);
 #endif /* CONFIG_SAE_PK */
 
-	if (!(hapd->conf->wpa & WPA_PROTO_RSN) ||
-	    !wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) ||
-	    (hapd->conf->sae_pwe != 1 && hapd->conf->sae_pwe != 2 &&
-	     !hostapd_sae_pw_id_in_use(hapd->conf) && !sae_pk) ||
-	    hapd->conf->sae_pwe == 3 ||
-	    len < 3)
-		return pos;
+	if (wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) &&
+	    (hapd->conf->sae_pwe == 1 || hapd->conf->sae_pwe == 2 ||
+	     hostapd_sae_pw_id_in_use(hapd->conf) || sae_pk) &&
+	    hapd->conf->sae_pwe != 3) {
+		capab |= BIT(WLAN_RSNX_CAPAB_SAE_H2E);
+#ifdef CONFIG_SAE_PK
+		if (sae_pk)
+			capab |= BIT(WLAN_RSNX_CAPAB_SAE_PK);
+#endif /* CONFIG_SAE_PK */
+	}
+
+	if (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF)
+		capab |= BIT(WLAN_RSNX_CAPAB_SECURE_LTF);
+	if (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_RTT)
+		capab |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT);
+	if (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_PROT_RANGE_NEG)
+		capab |= BIT(WLAN_RSNX_CAPAB_PROT_RANGE_NEG);
+
+	flen = (capab & 0xff00) ? 2 : 1;
+	if (len < 2 + flen || !capab)
+		return eid; /* no supported extended RSN capabilities */
+	capab |= flen - 1; /* bit 0-3 = Field length (n - 1) */
 
 	*pos++ = WLAN_EID_RSNX;
-	*pos++ = 1;
-	/* bits 0-3 = 0 since only one octet of Extended RSN Capabilities is
-	 * used for now */
-	*pos = BIT(WLAN_RSNX_CAPAB_SAE_H2E);
-#ifdef CONFIG_SAE_PK
-	if (sae_pk)
-		*pos |= BIT(WLAN_RSNX_CAPAB_SAE_PK);
-#endif /* CONFIG_SAE_PK */
-	pos++;
+	*pos++ = flen;
+	*pos++ = capab & 0x00ff;
+	capab >>= 8;
+	if (capab)
+		*pos++ = capab;
 
 	return pos;
 }
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ieee802_11_vht.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ieee802_11_vht.c
index 8a70eb4..579cc52 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ieee802_11_vht.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ieee802_11_vht.c
@@ -159,123 +159,11 @@
 }
 
 
-u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid)
-{
-	struct hostapd_iface *iface = hapd->iface;
-	struct hostapd_config *iconf = iface->conf;
-	struct hostapd_hw_modes *mode = iface->current_mode;
-	struct hostapd_channel_data *chan;
-	int dfs, i;
-	u8 channel, tx_pwr_count, local_pwr_constraint;
-	int max_tx_power;
-	u8 tx_pwr;
-
-	if (!mode)
-		return eid;
-
-	if (ieee80211_freq_to_chan(iface->freq, &channel) == NUM_HOSTAPD_MODES)
-		return eid;
-
-	for (i = 0; i < mode->num_channels; i++) {
-		if (mode->channels[i].freq == iface->freq)
-			break;
-	}
-	if (i == mode->num_channels)
-		return eid;
-
-	switch (iface->conf->vht_oper_chwidth) {
-	case CHANWIDTH_USE_HT:
-		if (iconf->secondary_channel == 0) {
-			/* Max Transmit Power count = 0 (20 MHz) */
-			tx_pwr_count = 0;
-		} else {
-			/* Max Transmit Power count = 1 (20, 40 MHz) */
-			tx_pwr_count = 1;
-		}
-		break;
-	case CHANWIDTH_80MHZ:
-		/* Max Transmit Power count = 2 (20, 40, and 80 MHz) */
-		tx_pwr_count = 2;
-		break;
-	case CHANWIDTH_80P80MHZ:
-	case CHANWIDTH_160MHZ:
-		/* Max Transmit Power count = 3 (20, 40, 80, 160/80+80 MHz) */
-		tx_pwr_count = 3;
-		break;
-	default:
-		return eid;
-	}
-
-	/*
-	 * Below local_pwr_constraint logic is referred from
-	 * hostapd_eid_pwr_constraint.
-	 *
-	 * Check if DFS is required by regulatory.
-	 */
-	dfs = hostapd_is_dfs_required(hapd->iface);
-	if (dfs < 0)
-		dfs = 0;
-
-	/*
-	 * In order to meet regulations when TPC is not implemented using
-	 * a transmit power that is below the legal maximum (including any
-	 * mitigation factor) should help. In this case, indicate 3 dB below
-	 * maximum allowed transmit power.
-	 */
-	if (hapd->iconf->local_pwr_constraint == -1)
-		local_pwr_constraint = (dfs == 0) ? 0 : 3;
-	else
-		local_pwr_constraint = hapd->iconf->local_pwr_constraint;
-
-	/*
-	 * A STA that is not an AP shall use a transmit power less than or
-	 * equal to the local maximum transmit power level for the channel.
-	 * The local maximum transmit power can be calculated from the formula:
-	 * local max TX pwr = max TX pwr - local pwr constraint
-	 * Where max TX pwr is maximum transmit power level specified for
-	 * channel in Country element and local pwr constraint is specified
-	 * for channel in this Power Constraint element.
-	 */
-	chan = &mode->channels[i];
-	max_tx_power = chan->max_tx_power - local_pwr_constraint;
-
-	/*
-	 * Local Maximum Transmit power is encoded as two's complement
-	 * with a 0.5 dB step.
-	 */
-	max_tx_power *= 2; /* in 0.5 dB steps */
-	if (max_tx_power > 127) {
-		/* 63.5 has special meaning of 63.5 dBm or higher */
-		max_tx_power = 127;
-	}
-	if (max_tx_power < -128)
-		max_tx_power = -128;
-	if (max_tx_power < 0)
-		tx_pwr = 0x80 + max_tx_power + 128;
-	else
-		tx_pwr = max_tx_power;
-
-	*eid++ = WLAN_EID_VHT_TRANSMIT_POWER_ENVELOPE;
-	*eid++ = 2 + tx_pwr_count;
-
-	/*
-	 * Max Transmit Power count and
-	 * Max Transmit Power units = 0 (EIRP)
-	 */
-	*eid++ = tx_pwr_count;
-
-	for (i = 0; i <= tx_pwr_count; i++)
-		*eid++ = tx_pwr;
-
-	return eid;
-}
-
-
 u16 copy_sta_vht_capab(struct hostapd_data *hapd, struct sta_info *sta,
 		       const u8 *vht_capab)
 {
 	/* Disable VHT caps for STAs associated to no-VHT BSSes. */
-	if (!vht_capab ||
+	if (!vht_capab || !(sta->flags & WLAN_STA_WMM) ||
 	    !hapd->iconf->ieee80211ac || hapd->conf->disable_11ac ||
 	    !check_valid_vht_mcs(hapd->iface->current_mode, vht_capab)) {
 		sta->flags &= ~WLAN_STA_VHT;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ieee802_1x.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ieee802_1x.c
index 1bc19b3..88b4e22 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ieee802_1x.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ieee802_1x.c
@@ -39,11 +39,6 @@
 #include "ieee802_1x.h"
 #include "wpa_auth_kay.h"
 
-#if !defined(HOSTAPD)
-#include <wpa_supplicant_i.h>
-#include <config_ssid.h>
-#include <config.h>
-#endif /* !HOSTAPD && CONFIG_DRIVER_NL80211_IFX */
 
 #ifdef CONFIG_HS20
 static void ieee802_1x_wnm_notif_send(void *eloop_ctx, void *timeout_ctx);
@@ -113,12 +108,7 @@
 				   struct sta_info *sta, int authorized)
 {
 	int res;
-#if !defined(HOSTAPD)
-	int i;
-	struct wpa_supplicant *wpa_s, *wpa_last;
-	struct wpa_global *global;
-	struct wpa_ssid *ssid;
-#endif /* !HOSTAPD && CONFIG_DRIVER_NL80211_IFX */
+
 	if (sta->flags & WLAN_STA_PREAUTH)
 		return;
 
@@ -143,29 +133,6 @@
 	if (authorized) {
 		os_get_reltime(&sta->connected_time);
 		accounting_sta_start(hapd, sta);
-#if !defined(HOSTAPD)
-		for(i=0;i < hapd->iface->num_bss;i++)
-			wpa_s = (struct wpa_supplicant *)hapd->iface->bss[i]->msg_ctx;
-
-		if (!wpa_s->global->rsdb_flag) {
-			global = wpa_s->global;
-
-			for (wpa_last = global->ifaces; wpa_last; wpa_last = wpa_last->next) {
-				if(os_strcmp(hapd->conf->iface, wpa_last->ifname) == 0 ||
-					os_strcmp(wpa_last->ifname, "wlan0") == 0 ||
-					os_strcmp(wpa_last->ifname, "p2p-dev-wlan0") ==	0)
-					continue;
-				else {
-					ssid = wpa_config_get_network(wpa_last->conf, 0);
-					if (ssid == NULL)
-						return;
-					if (ssid->disabled == 2)
-						return;
-					wpa_supplicant_disable_network(wpa_last, ssid);
-				}
-			}
-		}	
-#endif /* !HOSTAPD && CONFIG_DRIVER_NL80211_IFX */
 	}
 }
 
@@ -2096,7 +2063,8 @@
 
 #ifdef CONFIG_FILS
 #ifdef NEED_AP_MLME
-	if (sta->flags & WLAN_STA_PENDING_FILS_ERP) {
+	if (sta->flags &
+	    (WLAN_STA_PENDING_FILS_ERP | WLAN_STA_PENDING_PASN_FILS_ERP)) {
 		/* TODO: Add a PMKSA entry on success? */
 		ieee802_11_finish_fils_auth(
 			hapd, sta, hdr->code == RADIUS_CODE_ACCESS_ACCEPT,
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ndisc_snoop.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ndisc_snoop.c
index 4d6a92e..788c12f 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ndisc_snoop.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/ndisc_snoop.c
@@ -150,10 +150,12 @@
 				return;
 		}
 		break;
+#ifdef CONFIG_HS20
 	case ROUTER_ADVERTISEMENT:
 		if (hapd->conf->disable_dgaf)
 			ucast_to_stas(hapd, buf, len);
 		break;
+#endif /* CONFIG_HS20 */
 	case NEIGHBOR_ADVERTISEMENT:
 		if (hapd->conf->na_mcast_to_ucast)
 			ucast_to_stas(hapd, buf, len);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/neighbor_db.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/neighbor_db.c
index 01bf886..229edd2 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/neighbor_db.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/neighbor_db.c
@@ -10,6 +10,7 @@
 #include "utils/includes.h"
 
 #include "utils/common.h"
+#include "utils/crc32.h"
 #include "hostapd.h"
 #include "ieee802_11.h"
 #include "neighbor_db.h"
@@ -120,7 +121,8 @@
 int hostapd_neighbor_set(struct hostapd_data *hapd, const u8 *bssid,
 			 const struct wpa_ssid_value *ssid,
 			 const struct wpabuf *nr, const struct wpabuf *lci,
-			 const struct wpabuf *civic, int stationary)
+			 const struct wpabuf *civic, int stationary,
+			 u8 bss_parameters)
 {
 	struct hostapd_neighbor_entry *entry;
 
@@ -134,6 +136,7 @@
 
 	os_memcpy(entry->bssid, bssid, ETH_ALEN);
 	os_memcpy(&entry->ssid, ssid, sizeof(entry->ssid));
+	entry->short_ssid = crc32(ssid->ssid, ssid->ssid_len);
 
 	entry->nr = wpabuf_dup(nr);
 	if (!entry->nr)
@@ -152,6 +155,7 @@
 	}
 
 	entry->stationary = stationary;
+	entry->bss_parameters = bss_parameters;
 
 	return 0;
 
@@ -220,7 +224,7 @@
 	u16 capab = hostapd_own_capab_info(hapd);
 	int ht = hapd->iconf->ieee80211n && !hapd->conf->disable_11n;
 	int vht = hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac;
-	int he = hapd->iconf->ieee80211ax;
+	int he = hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax;
 	struct wpa_ssid_value ssid;
 	u8 channel, op_class;
 	u8 center_freq1_idx = 0, center_freq2_idx = 0;
@@ -311,7 +315,7 @@
 	wpabuf_put_u8(nr, center_freq2_idx);
 
 	hostapd_neighbor_set(hapd, hapd->own_addr, &ssid, nr, hapd->iconf->lci,
-			     hapd->iconf->civic, hapd->iconf->stationary_ap);
+			     hapd->iconf->civic, hapd->iconf->stationary_ap, 0);
 
 	wpabuf_free(nr);
 #endif /* NEED_AP_MLME */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/neighbor_db.h b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/neighbor_db.h
index bed0a2f..992671b 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/neighbor_db.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/neighbor_db.h
@@ -17,7 +17,8 @@
 int hostapd_neighbor_set(struct hostapd_data *hapd, const u8 *bssid,
 			 const struct wpa_ssid_value *ssid,
 			 const struct wpabuf *nr, const struct wpabuf *lci,
-			 const struct wpabuf *civic, int stationary);
+			 const struct wpabuf *civic, int stationary,
+			 u8 bss_parameters);
 void hostapd_neighbor_set_own_report(struct hostapd_data *hapd);
 int hostapd_neighbor_remove(struct hostapd_data *hapd, const u8 *bssid,
 			    const struct wpa_ssid_value *ssid);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/pmksa_cache_auth.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/pmksa_cache_auth.c
index 8222aa4..1a4f558 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/pmksa_cache_auth.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/pmksa_cache_auth.c
@@ -16,10 +16,12 @@
 #include "sta_info.h"
 #include "ap_config.h"
 #include "pmksa_cache_auth.h"
+#include "wpa_auth.h"
 
 
 static const int pmksa_cache_max_entries = 1024;
 static const int dot11RSNAConfigPMKLifetime = 43200;
+static const int dot11RSNAConfigPMKReauthThreshold = 70;
 
 struct rsn_pmksa_cache {
 #define PMKID_HASH_SIZE 128
@@ -56,6 +58,7 @@
 	struct rsn_pmksa_cache_entry *pos, *prev;
 	unsigned int hash;
 
+	wpa_auth_remove_pmkid(pmksa->ctx, entry->spa, entry->pmkid);
 	pmksa->pmksa_count--;
 	pmksa->free_cb(entry, pmksa->ctx, reason);
 
@@ -252,6 +255,10 @@
 	pmksa->pmksa_count++;
 	if (prev == NULL)
 		pmksa_cache_set_expiration(pmksa);
+
+	wpa_auth_add_pmkid(pmksa->ctx, entry->spa, entry->pmkid, entry->pmk,
+			   entry->pmk_len, dot11RSNAConfigPMKLifetime,
+			   dot11RSNAConfigPMKReauthThreshold, entry->akmp);
 	wpa_printf(MSG_DEBUG, "RSN: added PMKSA cache entry for " MACSTR,
 		   MAC2STR(entry->spa));
 	wpa_hexdump(MSG_DEBUG, "RSN: added PMKID", entry->pmkid, PMKID_LEN);
@@ -519,7 +526,8 @@
 	for (entry = pmksa->pmksa; entry; entry = entry->next) {
 		if (os_memcmp(entry->spa, spa, ETH_ALEN) != 0)
 			continue;
-		if (wpa_key_mgmt_sae(entry->akmp)) {
+		if (wpa_key_mgmt_sae(entry->akmp) ||
+		    wpa_key_mgmt_fils(entry->akmp)) {
 			if (os_memcmp(entry->pmkid, pmkid, PMKID_LEN) == 0)
 				return entry;
 			continue;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/sta_info.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/sta_info.c
index 64fa276..9b94fa0 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/sta_info.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/sta_info.c
@@ -39,11 +39,7 @@
 #include "sta_info.h"
 #include "vlan.h"
 #include "wps_hostapd.h"
-#if !defined(HOSTAPD)
-#include <wpa_supplicant_i.h>
-#include <config_ssid.h>
-#include <config.h>
-#endif /* !HOSTAPD && CONFIG_DRIVER_NL80211_IFX */
+
 static void ap_sta_remove_in_other_bss(struct hostapd_data *hapd,
 				       struct sta_info *sta);
 static void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx);
@@ -160,15 +156,41 @@
 }
 
 
+#ifdef CONFIG_PASN
+
+void ap_free_sta_pasn(struct hostapd_data *hapd, struct sta_info *sta)
+{
+	if (sta->pasn) {
+		wpa_printf(MSG_DEBUG, "PASN: Free PASN context: " MACSTR,
+			   MAC2STR(sta->addr));
+
+		if (sta->pasn->ecdh)
+			crypto_ecdh_deinit(sta->pasn->ecdh);
+
+		wpabuf_free(sta->pasn->secret);
+		sta->pasn->secret = NULL;
+
+#ifdef CONFIG_SAE
+		sae_clear_data(&sta->pasn->sae);
+#endif /* CONFIG_SAE */
+
+#ifdef CONFIG_FILS
+		/* In practice this pointer should be NULL */
+		wpabuf_free(sta->pasn->fils.erp_resp);
+		sta->pasn->fils.erp_resp = NULL;
+#endif /* CONFIG_FILS */
+
+		bin_clear_free(sta->pasn, sizeof(*sta->pasn));
+		sta->pasn = NULL;
+	}
+}
+
+#endif /* CONFIG_PASN */
+
 void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
 {
 	int set_beacon = 0;
-#if !defined(HOSTAPD)
-	int i;
-	struct wpa_supplicant *wpa_s,*wpa_last;
-	struct wpa_global *global;
-	struct wpa_ssid *ssid;
-#endif /* !HOSTAPD && CONFIG_DRIVER_NL80211_IFX */
+
 	accounting_sta_stop(hapd, sta);
 
 	/* just in case */
@@ -196,31 +218,6 @@
 			~BIT((sta->aid - 1) % 32);
 
 	hapd->num_sta--;
-#if !defined(HOSTAPD)
-	if (hapd->num_sta == 0) {
-		for (i=0;i < hapd->iface->num_bss;i++)
-			wpa_s = (struct wpa_supplicant *)hapd->iface->bss[i]->msg_ctx;
-
-		if (!wpa_s->global->rsdb_flag) {
-			global = wpa_s->global;
-
-			for (wpa_last = global->ifaces; wpa_last; wpa_last = wpa_last->next) {
-				if(os_strcmp(hapd->conf->iface, wpa_last->ifname) == 0 ||
-					os_strcmp(wpa_last->ifname, "wlan0") == 0 ||
-					os_strcmp(wpa_last->ifname, "p2p-dev-wlan0") == 0)
-					continue;
-				else {
-					ssid = wpa_config_get_network(wpa_last->conf, 0);
-					if (ssid == NULL)
-						return;
-					if (ssid->disabled == 2)
-						return;
-					wpa_supplicant_enable_network(wpa_last, ssid);
-				}
-			}
-		}
-	}
-#endif /* !HOSTAPD && CONFIG_DRIVER_NL80211_IFX */
 	if (sta->nonerp_set) {
 		sta->nonerp_set = 0;
 		hapd->iface->num_sta_non_erp--;
@@ -405,6 +402,10 @@
 	eloop_cancel_timeout(ap_sta_reset_steer_flag_timer, hapd, sta);
 #endif /* CONFIG_WNM_AP */
 
+#ifdef CONFIG_PASN
+	ap_free_sta_pasn(hapd, sta);
+#endif /* CONFIG_PASN */
+
 	os_free(sta->ifname_wds);
 
 #ifdef CONFIG_TESTING_OPTIONS
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/sta_info.h b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/sta_info.h
index ef48561..27e72f9 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/sta_info.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/sta_info.h
@@ -14,6 +14,8 @@
 #include "vlan.h"
 #include "common/wpa_common.h"
 #include "common/ieee802_11_defs.h"
+#include "common/sae.h"
+#include "crypto/sha384.h"
 
 /* STA flags */
 #define WLAN_STA_AUTH BIT(0)
@@ -39,6 +41,7 @@
 #define WLAN_STA_MULTI_AP BIT(23)
 #define WLAN_STA_HE BIT(24)
 #define WLAN_STA_6GHZ BIT(25)
+#define WLAN_STA_PENDING_PASN_FILS_ERP BIT(26)
 #define WLAN_STA_PENDING_DISASSOC_CB BIT(29)
 #define WLAN_STA_PENDING_DEAUTH_CB BIT(30)
 #define WLAN_STA_NONERP BIT(31)
@@ -63,6 +66,43 @@
 	struct os_reltime rx_time;
 };
 
+enum pasn_fils_state {
+	PASN_FILS_STATE_NONE = 0,
+	PASN_FILS_STATE_PENDING_AS,
+	PASN_FILS_STATE_COMPLETE
+};
+
+struct pasn_fils_data {
+	u8 state;
+	u8 nonce[FILS_NONCE_LEN];
+	u8 anonce[FILS_NONCE_LEN];
+	u8 session[FILS_SESSION_LEN];
+	u8 erp_pmkid[PMKID_LEN];
+
+	struct wpabuf *erp_resp;
+};
+
+struct pasn_data {
+	int akmp;
+	int cipher;
+	u16 group;
+	u8 trans_seq;
+	u8 wrapped_data_format;
+	size_t kdk_len;
+
+	u8 hash[SHA384_MAC_LEN];
+	struct wpa_ptk ptk;
+	struct crypto_ecdh *ecdh;
+
+	struct wpabuf *secret;
+#ifdef CONFIG_SAE
+	struct sae_data sae;
+#endif /* CONFIG_SAE */
+#ifdef CONFIG_FILS
+	struct pasn_fils_data fils;
+#endif /* CONFIG_FILS */
+};
+
 struct sta_info {
 	struct sta_info *next; /* next entry in sta list */
 	struct sta_info *hnext; /* next entry in hash table list */
@@ -286,6 +326,10 @@
 	unsigned int airtime_weight;
 	struct os_reltime backlogged_until;
 #endif /* CONFIG_AIRTIME_POLICY */
+
+#ifdef CONFIG_PASN
+	struct pasn_data *pasn;
+#endif /* CONFIG_PASN */
 };
 
 
@@ -363,4 +407,6 @@
 						   struct sta_info *sta);
 int ap_sta_re_add(struct hostapd_data *hapd, struct sta_info *sta);
 
+void ap_free_sta_pasn(struct hostapd_data *hapd, struct sta_info *sta);
+
 #endif /* STA_INFO_H */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wapiap_interface.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wapiap_interface.c
index ac4ab13..39a6da5 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wapiap_interface.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wapiap_interface.c
@@ -35,7 +35,7 @@
 
 	wpa_printf(MSG_INFO, "%s :Entered\n", __FUNCTION__);
 
-	ret = wapiap_lib_disassoc(sta_mac, ie, ielen, ifname);
+	ret = wapiap_lib_disassoc(sta_mac, ifname);
 
 	if (ret != 0)
 		wpa_printf(MSG_ERROR, "%s: Failed\n", __FUNCTION__);
@@ -86,7 +86,7 @@
                 key_flag = KEY_FLAG_GROUP_RX_TX_DEFAULT;
 
 	return hostapd_drv_set_key(ifname, hostapd, WAPI_ALG_SMS4,
-		addr, key_idx, set_tx, seq, seq_len, key, key_len, key_flag);
+		addr, key_idx, 0, set_tx, seq, seq_len, key, key_len, key_flag);
 }
 
 void brcm_wapiap_set_port_authorized(void *hapd_ctx, const u8 *addr, int authorized)
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wnm_ap.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wnm_ap.c
index be81797..0042ed6 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wnm_ap.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wnm_ap.c
@@ -169,7 +169,9 @@
 		pos += igtk_elem_len;
 		wpa_printf(MSG_DEBUG, "Pass 4 igtk_len = %d",
 			   (int) igtk_elem_len);
-		if (hapd->conf->beacon_prot) {
+		if (hapd->conf->beacon_prot &&
+		    (hapd->iface->drv_flags &
+		     WPA_DRIVER_FLAGS_BEACON_PROTECTION)) {
 			res = wpa_wnmsleep_bigtk_subelem(sta->wpa_sm, pos);
 			if (res < 0)
 				goto fail;
@@ -537,7 +539,8 @@
 {
 	struct sta_info *sta;
 
-	if (!hapd->conf->beacon_prot)
+	if (!hapd->conf->beacon_prot ||
+	    !(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_BEACON_PROTECTION))
 		return;
 
 	sta = ap_get_sta(hapd, addr);
@@ -785,8 +788,8 @@
 
 int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta,
 			u8 req_mode, int disassoc_timer, u8 valid_int,
-			const u8 *bss_term_dur, const char *url,
-			const u8 *nei_rep, size_t nei_rep_len,
+			const u8 *bss_term_dur, u8 dialog_token,
+			const char *url, const u8 *nei_rep, size_t nei_rep_len,
 			const u8 *mbo_attrs, size_t mbo_len)
 {
 	u8 *buf, *pos;
@@ -794,8 +797,10 @@
 	size_t url_len;
 
 	wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request to "
-		   MACSTR " req_mode=0x%x disassoc_timer=%d valid_int=0x%x",
-		   MAC2STR(sta->addr), req_mode, disassoc_timer, valid_int);
+		   MACSTR
+		   " req_mode=0x%x disassoc_timer=%d valid_int=0x%x dialog_token=%u",
+		   MAC2STR(sta->addr), req_mode, disassoc_timer, valid_int,
+		   dialog_token);
 	buf = os_zalloc(1000 + nei_rep_len + mbo_len);
 	if (buf == NULL)
 		return -1;
@@ -807,7 +812,7 @@
 	os_memcpy(mgmt->bssid, hapd->own_addr, ETH_ALEN);
 	mgmt->u.action.category = WLAN_ACTION_WNM;
 	mgmt->u.action.u.bss_tm_req.action = WNM_BSS_TRANS_MGMT_REQ;
-	mgmt->u.action.u.bss_tm_req.dialog_token = 1;
+	mgmt->u.action.u.bss_tm_req.dialog_token = dialog_token;
 	mgmt->u.action.u.bss_tm_req.req_mode = req_mode;
 	mgmt->u.action.u.bss_tm_req.disassoc_timer =
 		host_to_le16(disassoc_timer);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wnm_ap.h b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wnm_ap.h
index 1806ba0..f86c6b2 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wnm_ap.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wnm_ap.h
@@ -20,8 +20,8 @@
 				   int disassoc_timer);
 int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta,
 			u8 req_mode, int disassoc_timer, u8 valid_int,
-			const u8 *bss_term_dur, const char *url,
-			const u8 *nei_rep, size_t nei_rep_len,
+			const u8 *bss_term_dur, u8 dialog_token,
+			const char *url, const u8 *nei_rep, size_t nei_rep_len,
 			const u8 *mbo_attrs, size_t mbo_len);
 void ap_sta_reset_steer_flag_timer(void *eloop_ctx, void *timeout_ctx);
 int wnm_send_coloc_intf_req(struct hostapd_data *hapd, struct sta_info *sta,
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wpa_auth.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wpa_auth.c
index 1b084b4..04db88c 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wpa_auth.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wpa_auth.c
@@ -224,6 +224,47 @@
 }
 
 
+int wpa_auth_add_pmkid(struct wpa_authenticator *wpa_auth,
+			const u8 *bssid, const u8 *pmkid,
+			const u8 *pmk, size_t pmk_len, u32 pmk_lifetime,
+			u8 pmk_reauth_threshold, int akmp)
+{
+	if (!wpa_auth->cb->add_pmkid)
+		return 0;
+
+	return wpa_auth->cb->add_pmkid(wpa_auth->cb_ctx, bssid, pmkid,
+					pmk, pmk_len, pmk_lifetime,
+					pmk_reauth_threshold, akmp);
+}
+
+
+int wpa_auth_remove_pmkid(struct wpa_authenticator *wpa_auth,
+			const u8 *bssid, const u8 *pmkid)
+{
+	if (!wpa_auth->cb->remove_pmkid)
+		return 0;
+
+	return wpa_auth->cb->remove_pmkid(wpa_auth->cb_ctx, bssid, pmkid);
+}
+
+
+void wpa_auth_store_ptksa(struct wpa_authenticator *wpa_auth,
+			  const u8 *addr, int cipher,
+			  u32 life_time, const struct wpa_ptk *ptk)
+{
+	if (wpa_auth->cb->store_ptksa)
+		wpa_auth->cb->store_ptksa(wpa_auth->cb_ctx, addr, cipher,
+					  life_time, ptk);
+}
+
+
+void wpa_auth_remove_ptksa(struct wpa_authenticator *wpa_auth,
+			   const u8 *addr, int cipher)
+{
+	if (wpa_auth->cb->clear_ptksa)
+		wpa_auth->cb->clear_ptksa(wpa_auth->cb_ctx, addr, cipher);
+}
+
 void wpa_auth_logger(struct wpa_authenticator *wpa_auth, const u8 *addr,
 		     logger_level level, const char *txt)
 {
@@ -374,6 +415,10 @@
 {
 	struct wpa_authenticator *wpa_auth = ctx;
 
+	/*
+	 * Refer commit 99c91c01c5: Avoid deauthenticating STA if the reason for
+	 * freeing PMK entry isn't expiry
+	 */
 	if (reason == PMKSA_EXPIRE) {
 		/*
 		 * Once when the PMK cache entry for a STA expires in the SoftAP,
@@ -689,24 +734,6 @@
 	}
 #endif /* CONFIG_FILS */
 
-	/* Support for 4-way handshake offload to internal supplicant
-	 * for WPA/WPA2-PSK
-	 */
-	if (wpa_auth->conf.psk_4way_hs_offload) {
-		wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG,
-				"4-way handshake offloading for WPA/WPA2-PSK");
-		sm->wpa_ptk_state = WPA_PTK_PTKINITDONE;
-		sm->Pair = true;
-		wpa_auth_set_eapol(sm->wpa_auth, sm->addr,
-				   WPA_EAPOL_authorized, 1);
-		wpa_auth_set_eapol(sm->wpa_auth, sm->addr,
-				   WPA_EAPOL_portValid, 1);
-		wpa_auth_set_eapol(sm->wpa_auth, sm->addr,
-				   WPA_EAPOL_keyAvailable, 0);
-		wpa_auth_set_eapol(sm->wpa_auth, sm->addr,
-				   WPA_EAPOL_keyDone, 1);
-		return 0;
-	}
 
 	if (sm->started) {
 		os_memset(&sm->key_replay, 0, sizeof(sm->key_replay));
@@ -1013,6 +1040,18 @@
 }
 
 
+static bool wpa_auth_gtk_rekey_in_process(struct wpa_authenticator *wpa_auth)
+{
+	struct wpa_group *group;
+
+	for (group = wpa_auth->group; group; group = group->next) {
+		if (group->GKeyDoneStations)
+			return true;
+	}
+	return false;
+}
+
+
 void wpa_receive(struct wpa_authenticator *wpa_auth,
 		 struct wpa_state_machine *sm,
 		 u8 *data, size_t data_len)
@@ -1373,7 +1412,11 @@
 			wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
 					"received EAPOL-Key Request for GTK rekeying");
 			eloop_cancel_timeout(wpa_rekey_gtk, wpa_auth, NULL);
-			wpa_rekey_gtk(wpa_auth, NULL);
+			if (wpa_auth_gtk_rekey_in_process(wpa_auth))
+				wpa_auth_logger(wpa_auth, NULL, LOGGER_DEBUG,
+						"skip new GTK rekey - already in process");
+			else
+				wpa_rekey_gtk(wpa_auth, NULL);
 		}
 	} else {
 		/* Do not allow the same key replay counter to be reused. */
@@ -1754,6 +1797,9 @@
 {
 	sm->PTK_valid = false;
 	os_memset(&sm->PTK, 0, sizeof(sm->PTK));
+
+	wpa_auth_remove_ptksa(sm->wpa_auth, sm->addr, sm->pairwise);
+
 	if (wpa_auth_set_key(sm->wpa_auth, 0, WPA_ALG_NONE, sm->addr, 0, NULL,
 			     0, KEY_FLAG_PAIRWISE))
 		wpa_printf(MSG_DEBUG,
@@ -2265,9 +2311,16 @@
 			  struct wpa_ptk *ptk, int force_sha256)
 {
 	const u8 *z = NULL;
-	size_t z_len = 0;
+	size_t z_len = 0, kdk_len;
 	int akmp;
 
+	if (sm->wpa_auth->conf.force_kdk_derivation ||
+	    (sm->wpa_auth->conf.secure_ltf &&
+	     ieee802_11_rsnx_capab(sm->rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
+		kdk_len = WPA_KDK_MAX_LEN;
+	else
+		kdk_len = 0;
+
 #ifdef CONFIG_IEEE80211R_AP
 	if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) {
 		if (sm->ft_completed) {
@@ -2279,7 +2332,8 @@
 						 sm->pmk_r1_name,
 						 ptk, ptk_name,
 						 sm->wpa_key_mgmt,
-						 sm->pairwise);
+						 sm->pairwise,
+						 kdk_len);
 		}
 		return wpa_auth_derive_ptk_ft(sm, ptk);
 	}
@@ -2297,7 +2351,7 @@
 		akmp |= WPA_KEY_MGMT_PSK_SHA256;
 	return wpa_pmk_to_ptk(pmk, pmk_len, "Pairwise key expansion",
 			      sm->wpa_auth->addr, sm->addr, sm->ANonce, snonce,
-			      ptk, akmp, sm->pairwise, z, z_len);
+			      ptk, akmp, sm->pairwise, z, z_len, kdk_len);
 }
 
 
@@ -2312,13 +2366,20 @@
 	size_t ick_len;
 	int res;
 	u8 fils_ft[FILS_FT_MAX_LEN];
-	size_t fils_ft_len = 0;
+	size_t fils_ft_len = 0, kdk_len;
+
+	if (sm->wpa_auth->conf.force_kdk_derivation ||
+	    (sm->wpa_auth->conf.secure_ltf &&
+	     ieee802_11_rsnx_capab(sm->rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
+		kdk_len = WPA_KDK_MAX_LEN;
+	else
+		kdk_len = 0;
 
 	res = fils_pmk_to_ptk(pmk, pmk_len, sm->addr, sm->wpa_auth->addr,
 			      snonce, anonce, dhss, dhss_len,
 			      &sm->PTK, ick, &ick_len,
 			      sm->wpa_key_mgmt, sm->pairwise,
-			      fils_ft, &fils_ft_len);
+			      fils_ft, &fils_ft_len, kdk_len);
 	if (res < 0)
 		return res;
 	sm->PTK_valid = true;
@@ -2698,7 +2759,7 @@
 	struct wpabuf *plain;
 	u8 *len, *tmp, *tmp2;
 	u8 hdr[2];
-	u8 *gtk, dummy_gtk[32];
+	u8 *gtk, stub_gtk[32];
 	size_t gtk_len;
 	struct wpa_group *gsm;
 	size_t plain_len;
@@ -2741,11 +2802,11 @@
 		 * Provide unique random GTK to each STA to prevent use
 		 * of GTK in the BSS.
 		 */
-		if (random_get_bytes(dummy_gtk, gtk_len) < 0) {
+		if (random_get_bytes(stub_gtk, gtk_len) < 0) {
 			wpabuf_clear_free(plain);
 			return NULL;
 		}
-		gtk = dummy_gtk;
+		gtk = stub_gtk;
 	}
 	hdr[0] = gsm->GN & 0x03;
 	hdr[1] = 0;
@@ -2826,6 +2887,9 @@
 	}
 	sm->tk_already_set = true;
 
+	wpa_auth_store_ptksa(sm->wpa_auth, sm->addr, sm->pairwise,
+			     dot11RSNAConfigPMKLifetime, &sm->PTK);
+
 	return 0;
 }
 
@@ -3324,7 +3388,7 @@
 
 SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
 {
-	u8 rsc[WPA_KEY_RSC_LEN], *_rsc, *gtk, *kde = NULL, *pos, dummy_gtk[32];
+	u8 rsc[WPA_KEY_RSC_LEN], *_rsc, *gtk, *kde = NULL, *pos, stub_gtk[32];
 	size_t gtk_len, kde_len, wpa_ie_len;
 	struct wpa_group *gsm = sm->group;
 	u8 *wpa_ie;
@@ -3359,6 +3423,8 @@
 	    wpa_ie_len > wpa_ie[1] + 2U && wpa_ie[0] == WLAN_EID_RSN) {
 		/* WPA-only STA, remove RSN IE and possible MDIE */
 		wpa_ie = wpa_ie + wpa_ie[1] + 2;
+		if (wpa_ie[0] == WLAN_EID_RSNX)
+			wpa_ie = wpa_ie + wpa_ie[1] + 2;
 		if (wpa_ie[0] == WLAN_EID_MOBILITY_DOMAIN)
 			wpa_ie = wpa_ie + wpa_ie[1] + 2;
 		wpa_ie_len = wpa_ie[1] + 2;
@@ -3408,9 +3474,9 @@
 			 * Provide unique random GTK to each STA to prevent use
 			 * of GTK in the BSS.
 			 */
-			if (random_get_bytes(dummy_gtk, gtk_len) < 0)
+			if (random_get_bytes(stub_gtk, gtk_len) < 0)
 				goto done;
-			gtk = dummy_gtk;
+			gtk = stub_gtk;
 		}
 		gtkidx = gsm->GN;
 		_rsc = rsc;
@@ -3605,6 +3671,8 @@
 		sm->pairwise_set = true;
 
 		wpa_auth_set_ptk_rekey_timer(sm);
+		wpa_auth_store_ptksa(sm->wpa_auth, sm->addr, sm->pairwise,
+				     dot11RSNAConfigPMKLifetime, &sm->PTK);
 
 		if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) ||
 		    sm->wpa_key_mgmt == WPA_KEY_MGMT_DPP ||
@@ -3634,6 +3702,8 @@
 	wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_INFO,
 			 "pairwise key handshake completed (%s)",
 			 sm->wpa == WPA_VERSION_WPA ? "WPA" : "RSN");
+	wpa_msg(sm->wpa_auth->conf.msg_ctx, MSG_INFO, "EAPOL-4WAY-HS-COMPLETED "
+		MACSTR, MAC2STR(sm->addr));
 
 #ifdef CONFIG_IEEE80211R_AP
 	wpa_ft_push_pmk_r1(sm->wpa_auth, sm->addr);
@@ -3791,7 +3861,7 @@
 	const u8 *kde;
 	u8 *kde_buf = NULL, *pos, hdr[2];
 	size_t kde_len;
-	u8 *gtk, dummy_gtk[32];
+	u8 *gtk, stub_gtk[32];
 	struct wpa_auth_config *conf = &sm->wpa_auth->conf;
 
 	SM_ENTRY_MA(WPA_PTK_GROUP, REKEYNEGOTIATING, wpa_ptk_group);
@@ -3823,9 +3893,9 @@
 		 * Provide unique random GTK to each STA to prevent use
 		 * of GTK in the BSS.
 		 */
-		if (random_get_bytes(dummy_gtk, gsm->GTK_len) < 0)
+		if (random_get_bytes(stub_gtk, gsm->GTK_len) < 0)
 			return;
-		gtk = dummy_gtk;
+		gtk = stub_gtk;
 	}
 	if (sm->wpa == WPA_VERSION_WPA2) {
 		kde_len = 2 + RSN_SELECTOR_LEN + 2 + gsm->GTK_len +
@@ -4221,7 +4291,7 @@
 	wpa_printf(MSG_DEBUG, "WNM: BIGTK Key ID %u in WNM-Sleep Mode exit",
 		   gsm->GN_bigtk);
 	wpa_hexdump_key(MSG_DEBUG, "WNM: BIGTK in WNM-Sleep Mode exit",
-			gsm->IGTK[gsm->GN_bigtk - 6], len);
+			gsm->BIGTK[gsm->GN_bigtk - 6], len);
 
 	return pos - start;
 }
@@ -4756,6 +4826,9 @@
 	return -1;
 }
 
+/* Refer commit 587411dd62: Fix for PMK expiration issue through
+ * supplicant
+ */
 void wpa_auth_set_pmk_life_time(struct wpa_authenticator *wpa_auth, unsigned int pmk_life_time)
 {
         wpa_auth->pmk_life_time = pmk_life_time;
@@ -4769,6 +4842,10 @@
 		return -1;
 
 	wpa_hexdump_key(MSG_DEBUG, "RSN: Cache PMK from SAE", pmk, PMK_LEN);
+
+	/* Refer commit 587411dd62: Fix for PMK expiration issue through
+	 * supplicant
+	 */
 	if (pmksa_cache_auth_add(wpa_auth->pmksa, pmk, PMK_LEN, pmkid,
 				 NULL, 0,
 				 wpa_auth->addr, addr, wpa_auth->pmk_life_time, NULL,
@@ -4790,7 +4867,7 @@
 			const u8 *pmk, size_t pmk_len, const u8 *pmkid,
 			int session_timeout, int akmp)
 {
-	if (wpa_auth->conf.disable_pmksa_caching)
+	if (!wpa_auth || wpa_auth->conf.disable_pmksa_caching)
 		return -1;
 
 	wpa_hexdump_key(MSG_DEBUG, "RSN: Cache PMK (2)", pmk, PMK_LEN);
@@ -5358,6 +5435,8 @@
 	    wpa_ie_len > wpa_ie[1] + 2 && wpa_ie[0] == WLAN_EID_RSN) {
 		/* WPA-only STA, remove RSN IE and possible MDIE */
 		wpa_ie = wpa_ie + wpa_ie[1] + 2;
+		if (wpa_ie[0] == WLAN_EID_RSNX)
+			wpa_ie = wpa_ie + wpa_ie[1] + 2;
 		if (wpa_ie[0] == WLAN_EID_MOBILITY_DOMAIN)
 			wpa_ie = wpa_ie + wpa_ie[1] + 2;
 		wpa_ie_len = wpa_ie[1] + 2;
@@ -5578,6 +5657,18 @@
 }
 
 
+int wpa_auth_rekey_ptk(struct wpa_authenticator *wpa_auth,
+		       struct wpa_state_machine *sm)
+{
+	if (!wpa_auth || !sm)
+		return -1;
+	wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, "rekeying PTK");
+	wpa_request_new_ptk(sm);
+	wpa_sm_step(sm);
+	return 0;
+}
+
+
 void wpa_auth_set_ft_rsnxe_used(struct wpa_authenticator *wpa_auth, int val)
 {
 	if (wpa_auth)
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wpa_auth.h b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wpa_auth.h
index 48970a8..e89dd18 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wpa_auth.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wpa_auth.h
@@ -263,18 +263,22 @@
 #endif /* CONFIG_FILS */
 	int sae_pwe;
 	bool sae_pk;
+
+	unsigned int secure_ltf:1;
+	unsigned int secure_rtt:1;
+	unsigned int prot_range_neg:1;
+
 	int owe_ptk_workaround;
 	u8 transition_disable;
 #ifdef CONFIG_DPP2
 	int dpp_pfs;
 #endif /* CONFIG_DPP2 */
-	/* Support for 4-way handshake offload to internal supplicant
-	 * for WPA/WPA2-PSK
+
+	/*
+	 * If set Key Derivation Key should be derived as part of PMK to
+	 * PTK derivation regardless of advertised capabilities.
 	 */
-	int psk_4way_hs_offload;
-#ifdef CONFIG_SAE
-	int sae_offload;
-#endif /* CONFIG_SAE */
+	bool force_kdk_derivation;
 };
 
 typedef enum {
@@ -319,6 +323,9 @@
 	int (*get_sta_tx_params)(void *ctx, const u8 *addr,
 				 int ap_max_chanwidth, int ap_seg1_idx,
 				 int *bandwidth, int *seg1_idx);
+	void (*store_ptksa)(void *ctx, const u8 *addr, int cipher,
+			    u32 life_time, const struct wpa_ptk *ptk);
+	void (*clear_ptksa)(void *ctx, const u8 *addr, int cipher);
 #ifdef CONFIG_IEEE80211R_AP
 	struct wpa_state_machine * (*add_sta)(void *ctx, const u8 *sta_addr);
 	int (*add_sta_ft)(void *ctx, const u8 *sta_addr);
@@ -344,6 +351,10 @@
 #ifdef CONFIG_MESH
 	int (*start_ampe)(void *ctx, const u8 *sta_addr);
 #endif /* CONFIG_MESH */
+	int (*add_pmkid)(void *ctx, const u8 *bssid, const u8 *pmkid,
+			 const u8 *pmk, size_t pmk_len, u32 pmk_lifetime,
+			 u8 pmk_reauth_threshold, int akmp);
+	int (*remove_pmkid)(void *ctx, const u8 *bssid, const u8 *pmkid);
 };
 
 struct wpa_authenticator * wpa_init(const u8 *addr,
@@ -420,6 +431,10 @@
 			       struct eapol_state_machine *eapol);
 int wpa_auth_pmksa_add_sae(struct wpa_authenticator *wpa_auth, const u8 *addr,
 			   const u8 *pmk, const u8 *pmkid);
+
+/* Refer commit 587411dd62: Fix for PMK expiration issue through
+ * supplicant
+ */
 void wpa_auth_set_pmk_life_time(struct wpa_authenticator *wpa_auth, unsigned int pmk_life_time);
 
 void wpa_auth_add_sae_pmkid(struct wpa_state_machine *sm, const u8 *pmkid);
@@ -448,6 +463,12 @@
 			      struct wpa_state_machine *sm,
 			      struct wpa_authenticator *wpa_auth,
 			      u8 *pmkid, u8 *pmk);
+int wpa_auth_add_pmkid(struct wpa_authenticator *wpa_auth,
+			const u8 *bssid, const u8 *pmkid,
+			const u8 *pmk, size_t pmk_len, u32 pmk_lifetime,
+			u8 pmk_reauth_threshold, int akmp);
+int wpa_auth_remove_pmkid(struct wpa_authenticator *wpa_auth,
+			const u8 *bssid, const u8 *pmkid);
 int wpa_auth_sta_set_vlan(struct wpa_state_machine *sm, int vlan_id);
 void wpa_auth_eapol_key_tx_status(struct wpa_authenticator *wpa_auth,
 				  struct wpa_state_machine *sm, int ack);
@@ -474,6 +495,14 @@
 void wpa_ft_push_pmk_r1(struct wpa_authenticator *wpa_auth, const u8 *addr);
 void wpa_ft_deinit(struct wpa_authenticator *wpa_auth);
 void wpa_ft_sta_deinit(struct wpa_state_machine *sm);
+int wpa_ft_fetch_pmk_r1(struct wpa_authenticator *wpa_auth,
+			const u8 *spa, const u8 *pmk_r1_name,
+			u8 *pmk_r1, size_t *pmk_r1_len, int *pairwise,
+			struct vlan_description *vlan,
+			const u8 **identity, size_t *identity_len,
+			const u8 **radius_cui, size_t *radius_cui_len,
+			int *session_timeout);
+
 #endif /* CONFIG_IEEE80211R_AP */
 
 void wpa_wnmsleep_rekey_gtk(struct wpa_state_machine *sm);
@@ -530,6 +559,8 @@
 u8 * wpa_auth_write_assoc_resp_fils(struct wpa_state_machine *sm,
 				    u8 *pos, size_t max_len,
 				    const u8 *req_ies, size_t req_ies_len);
+bool wpa_auth_write_fd_rsn_info(struct wpa_authenticator *wpa_auth,
+				u8 *fd_rsn_info);
 void wpa_auth_set_auth_alg(struct wpa_state_machine *sm, u16 auth_alg);
 void wpa_auth_set_dpp_z(struct wpa_state_machine *sm, const struct wpabuf *z);
 void wpa_auth_set_transition_disable(struct wpa_authenticator *wpa_auth,
@@ -544,7 +575,12 @@
 int wpa_auth_resend_group_m1(struct wpa_state_machine *sm,
 			     void (*cb)(void *ctx1, void *ctx2),
 			     void *ctx1, void *ctx2);
+int wpa_auth_rekey_ptk(struct wpa_authenticator *wpa_auth,
+		       struct wpa_state_machine *sm);
 int wpa_auth_rekey_gtk(struct wpa_authenticator *wpa_auth);
+int hostapd_wpa_auth_send_eapol(void *ctx, const u8 *addr,
+				const u8 *data, size_t data_len,
+				int encrypt);
 void wpa_auth_set_ptk_rekey_timer(struct wpa_state_machine *sm);
 void wpa_auth_set_ft_rsnxe_used(struct wpa_authenticator *wpa_auth, int val);
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wpa_auth_ft.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wpa_auth_ft.c
index ab00db6..09b19b0 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wpa_auth_ft.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wpa_auth_ft.c
@@ -452,7 +452,7 @@
 	pos += wpa_ft_tlv_lin(tlvs2, pos, endpos);
 	pos += wpa_ft_vlan_lin(vlan, pos, endpos);
 
-	/* sanity check */
+	/* validity check */
 	if (pos != endpos) {
 		wpa_printf(MSG_ERROR, "FT: Length error building RRB");
 		goto err;
@@ -1470,13 +1470,13 @@
 }
 
 
-static int wpa_ft_fetch_pmk_r1(struct wpa_authenticator *wpa_auth,
-			       const u8 *spa, const u8 *pmk_r1_name,
-			       u8 *pmk_r1, size_t *pmk_r1_len, int *pairwise,
-			       struct vlan_description *vlan,
-			       const u8 **identity, size_t *identity_len,
-			       const u8 **radius_cui, size_t *radius_cui_len,
-			       int *session_timeout)
+int wpa_ft_fetch_pmk_r1(struct wpa_authenticator *wpa_auth,
+			const u8 *spa, const u8 *pmk_r1_name,
+			u8 *pmk_r1, size_t *pmk_r1_len, int *pairwise,
+			struct vlan_description *vlan,
+			const u8 **identity, size_t *identity_len,
+			const u8 **radius_cui, size_t *radius_cui_len,
+			int *session_timeout)
 {
 	struct wpa_ft_pmk_cache *cache = wpa_auth->ft_pmk_cache;
 	struct wpa_ft_pmk_r1_sa *r1;
@@ -2144,7 +2144,8 @@
 
 	return wpa_pmk_r1_to_ptk(pmk_r1, pmk_r1_len, sm->SNonce, sm->ANonce,
 				 sm->addr, sm->wpa_auth->addr, sm->pmk_r1_name,
-				 ptk, ptk_name, sm->wpa_key_mgmt, sm->pairwise);
+				 ptk, ptk_name, sm->wpa_key_mgmt, sm->pairwise,
+				 0);
 }
 
 
@@ -2255,7 +2256,7 @@
 	const u8 *kek, *igtk;
 	size_t kek_len;
 	size_t igtk_len;
-	u8 dummy_igtk[WPA_IGTK_MAX_LEN];
+	u8 stub_igtk[WPA_IGTK_MAX_LEN];
 
 	if (wpa_key_mgmt_fils(sm->wpa_key_mgmt)) {
 		kek = sm->PTK.kek2;
@@ -2288,11 +2289,11 @@
 		 * Provide unique random IGTK to each STA to prevent use of
 		 * IGTK in the BSS.
 		 */
-		if (random_get_bytes(dummy_igtk, igtk_len / 8) < 0) {
+		if (random_get_bytes(stub_igtk, igtk_len / 8) < 0) {
 			os_free(subelem);
 			return NULL;
 		}
-		igtk = dummy_igtk;
+		igtk = stub_igtk;
 	}
 	if (aes_wrap(kek, kek_len, igtk_len / 8, igtk, pos)) {
 		wpa_printf(MSG_DEBUG,
@@ -2315,7 +2316,7 @@
 	const u8 *kek, *bigtk;
 	size_t kek_len;
 	size_t bigtk_len;
-	u8 dummy_bigtk[WPA_IGTK_MAX_LEN];
+	u8 stub_bigtk[WPA_IGTK_MAX_LEN];
 
 	if (wpa_key_mgmt_fils(sm->wpa_key_mgmt)) {
 		kek = sm->PTK.kek2;
@@ -2348,11 +2349,11 @@
 		 * Provide unique random BIGTK to each OSEN STA to prevent use
 		 * of BIGTK in the BSS.
 		 */
-		if (random_get_bytes(dummy_bigtk, bigtk_len / 8) < 0) {
+		if (random_get_bytes(stub_bigtk, bigtk_len / 8) < 0) {
 			os_free(subelem);
 			return NULL;
 		}
-		bigtk = dummy_bigtk;
+		bigtk = stub_bigtk;
 	}
 	if (aes_wrap(kek, kek_len, bigtk_len / 8, bigtk, pos)) {
 		wpa_printf(MSG_DEBUG,
@@ -3062,7 +3063,7 @@
 	const u8 *identity, *radius_cui;
 	size_t identity_len = 0, radius_cui_len = 0;
 	int use_sha384;
-	size_t pmk_r1_len;
+	size_t pmk_r1_len, kdk_len;
 
 	*resp_ies = NULL;
 	*resp_ies_len = 0;
@@ -3192,10 +3193,17 @@
 	wpa_hexdump(MSG_DEBUG, "FT: Generated ANonce",
 		    sm->ANonce, WPA_NONCE_LEN);
 
+	if (sm->wpa_auth->conf.force_kdk_derivation ||
+	    (sm->wpa_auth->conf.secure_ltf &&
+	     ieee802_11_rsnx_capab(sm->rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
+		kdk_len = WPA_KDK_MAX_LEN;
+	else
+		kdk_len = 0;
+
 	if (wpa_pmk_r1_to_ptk(pmk_r1, pmk_r1_len, sm->SNonce, sm->ANonce,
 			      sm->addr, sm->wpa_auth->addr, pmk_r1_name,
 			      &sm->PTK, ptk_name, sm->wpa_key_mgmt,
-			      pairwise) < 0)
+			      pairwise, kdk_len) < 0)
 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
 
 	sm->pairwise = pairwise;
@@ -3578,7 +3586,7 @@
 	}
 
 	/*
-	 * Do some sanity checking on the target AP address (not own and not
+	 * Do some validity checking on the target AP address (not own and not
 	 * broadcast. This could be extended to filter based on a list of known
 	 * APs in the MD (if such a list were configured).
 	 */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wpa_auth_glue.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wpa_auth_glue.c
index bb67087..2cf98be 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wpa_auth_glue.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wpa_auth_glue.c
@@ -14,6 +14,7 @@
 #include "common/ieee802_11_defs.h"
 #include "common/sae.h"
 #include "common/wpa_ctrl.h"
+#include "common/ptksa_cache.h"
 #include "crypto/sha1.h"
 #include "eapol_auth/eapol_auth_sm.h"
 #include "eapol_auth/eapol_auth_sm_i.h"
@@ -211,6 +212,11 @@
 #ifdef CONFIG_DPP2
 	wconf->dpp_pfs = conf->dpp_pfs;
 #endif /* CONFIG_DPP2 */
+#ifdef CONFIG_PASN
+#ifdef CONFIG_TESTING_OPTIONS
+	wconf->force_kdk_derivation = conf->force_kdk_derivation;
+#endif /* CONFIG_TESTING_OPTIONS */
+#endif /* CONFIG_PASN */
 }
 
 
@@ -502,9 +508,9 @@
 }
 
 
-static int hostapd_wpa_auth_send_eapol(void *ctx, const u8 *addr,
-				       const u8 *data, size_t data_len,
-				       int encrypt)
+int hostapd_wpa_auth_send_eapol(void *ctx, const u8 *addr,
+				const u8 *data, size_t data_len,
+				int encrypt)
 {
 	struct hostapd_data *hapd = ctx;
 	struct sta_info *sta;
@@ -915,6 +921,61 @@
 }
 
 
+static int hostapd_wpa_auth_set_pmkid(void *ctx, const u8 *bssid,
+					const u8 *pmkid, const u8 *pmk,
+					size_t pmk_len, u32 pmk_lifetime,
+					u8 pmk_reauth_threshold, int akmp)
+{
+	struct hostapd_data *hapd = ctx;
+	struct wpa_pmkid_params params;
+
+	os_memset(&params, 0, sizeof(params));
+	params.bssid = bssid;
+	params.pmkid = pmkid;
+	params.pmk = pmk;
+	params.pmk_len = pmk_len;
+	params.pmk_lifetime = pmk_lifetime;
+	params.pmk_reauth_threshold = pmk_reauth_threshold;
+
+	return hostapd_drv_add_pmkid(hapd, &params);
+}
+
+
+static int hostapd_wpa_auth_remove_pmkid(void *ctx, const u8 *bssid,
+					 const u8 *pmkid)
+{
+	struct hostapd_data *hapd = ctx;
+	struct wpa_pmkid_params params;
+
+	os_memset(&params, 0, sizeof(params));
+	params.bssid = bssid;
+	params.pmkid = pmkid;
+
+	return hostapd_drv_remove_pmkid(hapd, &params);
+}
+
+
+#ifdef CONFIG_PASN
+
+static void hostapd_store_ptksa(void *ctx, const u8 *addr,int cipher,
+				u32 life_time, const struct wpa_ptk *ptk)
+{
+	struct hostapd_data *hapd = ctx;
+
+	ptksa_cache_add(hapd->ptksa, addr, cipher, life_time, ptk);
+}
+
+
+static void hostapd_clear_ptksa(void *ctx, const u8 *addr, int cipher)
+{
+	struct hostapd_data *hapd = ctx;
+
+	ptksa_cache_flush(hapd->ptksa, addr, cipher);
+}
+
+#endif /* CONFIG_PASN */
+
+
 static int hostapd_wpa_auth_update_vlan(void *ctx, const u8 *addr, int vlan_id)
 {
 #ifndef CONFIG_NO_VLAN
@@ -1440,6 +1501,11 @@
 		.send_oui = hostapd_wpa_auth_send_oui,
 		.channel_info = hostapd_channel_info,
 		.update_vlan = hostapd_wpa_auth_update_vlan,
+#ifdef CONFIG_PASN
+		.store_ptksa = hostapd_store_ptksa,
+		.clear_ptksa = hostapd_clear_ptksa,
+#endif /* CONFIG_PASN */
+
 #ifdef CONFIG_OCV
 		.get_sta_tx_params = hostapd_get_sta_tx_params,
 #endif /* CONFIG_OCV */
@@ -1457,6 +1523,8 @@
 		.set_session_timeout = hostapd_wpa_auth_set_session_timeout,
 		.get_session_timeout = hostapd_wpa_auth_get_session_timeout,
 #endif /* CONFIG_IEEE80211R_AP */
+		.add_pmkid = hostapd_wpa_auth_set_pmkid,
+		.remove_pmkid = hostapd_wpa_auth_remove_pmkid,
 	};
 	const u8 *wpa_ie;
 	size_t wpa_ie_len;
@@ -1483,17 +1551,22 @@
 	else
 		_conf.extended_key_id = 0;
 
-	/* Support for 4-way handshake offload to internal supplicant
-	 * for WPA/WPA2-PSK
-	 */
-	if (!hapd->conf->p2p &&
-	    (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK))
-		_conf.psk_4way_hs_offload = 1;
+	if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_BEACON_PROTECTION))
+		_conf.beacon_prot = 0;
 
-#ifdef CONFIG_SAE
-	if (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SAE_OFFLOAD_AP)
-		_conf.sae_offload = 1;
-#endif /* CONFIG_SAE */
+#ifdef CONFIG_OCV
+	if (!(hapd->iface->drv_flags2 &
+	      (WPA_DRIVER_FLAGS2_AP_SME | WPA_DRIVER_FLAGS2_OCV)))
+		_conf.ocv = 0;
+#endif /* CONFIG_OCV */
+
+	_conf.secure_ltf =
+		!!(hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF);
+	_conf.secure_rtt =
+		!!(hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_RTT);
+	_conf.prot_range_neg =
+		!!(hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_PROT_RANGE_NEG);
+
 
 	hapd->wpa_auth = wpa_init(hapd->own_addr, &_conf, &cb, hapd);
 	if (hapd->wpa_auth == NULL) {
@@ -1520,6 +1593,13 @@
 		return -1;
 	}
 
+	if (!hapd->ptksa)
+		hapd->ptksa = ptksa_cache_init();
+	if (!hapd->ptksa) {
+		wpa_printf(MSG_ERROR, "Failed to allocate PTKSA cache");
+		return -1;
+	}
+
 #ifdef CONFIG_IEEE80211R_AP
 	if (!hostapd_drv_none(hapd) &&
 	    wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt)) {
@@ -1559,6 +1639,9 @@
 void hostapd_deinit_wpa(struct hostapd_data *hapd)
 {
 	ieee80211_tkip_countermeasures_deinit(hapd);
+	ptksa_cache_deinit(hapd->ptksa);
+	hapd->ptksa = NULL;
+
 	rsn_preauth_iface_deinit(hapd);
 	if (hapd->wpa_auth) {
 		wpa_deinit(hapd->wpa_auth);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wpa_auth_i.h b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wpa_auth_i.h
index f46bdab..05a623d 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wpa_auth_i.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wpa_auth_i.h
@@ -237,6 +237,10 @@
 #ifdef CONFIG_P2P
 	struct bitfield *ip_pool;
 #endif /* CONFIG_P2P */
+
+	/* Refer commit 587411dd62: Fix for PMK expiration issue through
+	 * supplicant
+	 */
 	unsigned int pmk_life_time;
 };
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wpa_auth_ie.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wpa_auth_ie.c
index 0b57158..ef757a3 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wpa_auth_ie.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wpa_auth_ie.c
@@ -88,13 +88,54 @@
 }
 
 
+static u16 wpa_own_rsn_capab(struct wpa_auth_config *conf)
+{
+	u16 capab = 0;
+
+	if (conf->rsn_preauth)
+		capab |= WPA_CAPABILITY_PREAUTH;
+#ifdef CONFIG_BRCM_MERGES
+	if (conf->peerkey)
+		capab |= WPA_CAPABILITY_PEERKEY_ENABLED;
+#endif /* CONFIG_BRCM_MERGES */
+	if (conf->wmm_enabled) {
+#if defined(CONFIG_BRCM_RSN_CNTRS)
+		if (conf->replay_cntrs) {
+			capab |= (conf->replay_cntrs << 2);
+		} else {
+			capab |= (RSN_NUM_REPLAY_COUNTERS_16 << 2);
+		}
+#else
+		/* 4 PTKSA replay counters when using WMM */
+		capab |= (RSN_NUM_REPLAY_COUNTERS_16 << 2);
+#endif /* CONFIG_DRIVER_NL80211_IFX && CONFIG_BRCM_RSN_CNTRS */
+	}
+	if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
+		capab |= WPA_CAPABILITY_MFPC;
+		if (conf->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED)
+			capab |= WPA_CAPABILITY_MFPR;
+	}
+#ifdef CONFIG_OCV
+	if (conf->ocv)
+		capab |= WPA_CAPABILITY_OCVC;
+#endif /* CONFIG_OCV */
+#ifdef CONFIG_RSN_TESTING
+	if (rsn_testing)
+		capab |= BIT(8) | BIT(15);
+#endif /* CONFIG_RSN_TESTING */
+	if (conf->extended_key_id)
+		capab |= WPA_CAPABILITY_EXT_KEY_ID_FOR_UNICAST;
+
+	return capab;
+}
+
+
 int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len,
 		     const u8 *pmkid)
 {
 	struct rsn_ie_hdr *hdr;
 	int num_suites, res;
 	u8 *pos, *count;
-	u16 capab;
 	u32 suite;
 
 	hdr = (struct rsn_ie_hdr *) buf;
@@ -260,6 +301,13 @@
 		num_suites++;
 	}
 #endif /* CONFIG_HS20 */
+#ifdef CONFIG_PASN
+	if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PASN) {
+		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PASN);
+		pos += RSN_SELECTOR_LEN;
+		num_suites++;
+	}
+#endif /* CONFIG_PASN */
 
 #ifdef CONFIG_RSN_TESTING
 	if (rsn_testing) {
@@ -277,41 +325,7 @@
 	WPA_PUT_LE16(count, num_suites);
 
 	/* RSN Capabilities */
-	capab = 0;
-	if (conf->rsn_preauth)
-		capab |= WPA_CAPABILITY_PREAUTH;
-#ifdef CONFIG_BRCM_MERGES
-        if (conf->peerkey)
-                capab |= WPA_CAPABILITY_PEERKEY_ENABLED;
-#endif /* CONFIG_BRCM_MERGES */
-	if (conf->wmm_enabled) {
-		/* 4 PTKSA replay counters when using WMM */
-#if defined(CONFIG_BRCM_RSN_CNTRS)
-                if (conf->replay_cntrs) {
-                        capab |= (conf->replay_cntrs << 2);
-                } else {
-                        capab |= (RSN_NUM_REPLAY_COUNTERS_16 << 2);
-                }
-#else
-		capab |= (RSN_NUM_REPLAY_COUNTERS_16 << 2);
-#endif /* CONFIG_DRIVER_NL80211_IFX && CONFIG_BRCM_RSN_CNTRS */
-	}
-	if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
-		capab |= WPA_CAPABILITY_MFPC;
-		if (conf->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED)
-			capab |= WPA_CAPABILITY_MFPR;
-	}
-#ifdef CONFIG_OCV
-	if (conf->ocv)
-		capab |= WPA_CAPABILITY_OCVC;
-#endif /* CONFIG_OCV */
-#ifdef CONFIG_RSN_TESTING
-	if (rsn_testing)
-		capab |= BIT(8) | BIT(15);
-#endif /* CONFIG_RSN_TESTING */
-	if (conf->extended_key_id)
-		capab |= WPA_CAPABILITY_EXT_KEY_ID_FOR_UNICAST;
-	WPA_PUT_LE16(pos, capab);
+	WPA_PUT_LE16(pos, wpa_own_rsn_capab(conf));
 	pos += 2;
 
 	if (pmkid) {
@@ -389,27 +403,45 @@
 int wpa_write_rsnxe(struct wpa_auth_config *conf, u8 *buf, size_t len)
 {
 	u8 *pos = buf;
+	u16 capab = 0;
+	size_t flen;
 
 	/* Refer commit 7ce7b05cda: WPA3 R3 client fails to associate AP
-	* * configured in Mixed mode (WPA2+WPA3) security
-	* */
+	 * configured in Mixed mode (WPA2+WPA3) security
+	 */
 	if ((conf->wpa_key_mgmt & WPA_KEY_MGMT_SAE) != WPA_KEY_MGMT_SAE &&
 		(conf->sae_pwe != 1 || conf->sae_pwe != 2) && !conf->sae_pk)
 		return 0; /* no supported extended RSN capabilities */
 
-	if (len < 3)
+	if (wpa_key_mgmt_sae(conf->wpa_key_mgmt) &&
+	    (conf->sae_pwe == 1 || conf->sae_pwe == 2 || conf->sae_pk)) {
+		capab |= BIT(WLAN_RSNX_CAPAB_SAE_H2E);
+#ifdef CONFIG_SAE_PK
+		if (conf->sae_pk)
+			capab |= BIT(WLAN_RSNX_CAPAB_SAE_PK);
+#endif /* CONFIG_SAE_PK */
+	}
+
+	if (conf->secure_ltf)
+		capab |= BIT(WLAN_RSNX_CAPAB_SECURE_LTF);
+	if (conf->secure_rtt)
+		capab |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT);
+	if (conf->prot_range_neg)
+		capab |= BIT(WLAN_RSNX_CAPAB_PROT_RANGE_NEG);
+
+	flen = (capab & 0xff00) ? 2 : 1;
+	if (!capab)
+		return 0; /* no supported extended RSN capabilities */
+	if (len < 2 + flen)
 		return -1;
+	capab |= flen - 1; /* bit 0-3 = Field length (n - 1) */
 
 	*pos++ = WLAN_EID_RSNX;
-	*pos++ = 1;
-	/* bits 0-3 = 0 since only one octet of Extended RSN Capabilities is
-	 * used for now */
-	*pos = BIT(WLAN_RSNX_CAPAB_SAE_H2E);
-#ifdef CONFIG_SAE_PK
-	if (conf->sae_pk)
-		*pos |= BIT(WLAN_RSNX_CAPAB_SAE_PK);
-#endif /* CONFIG_SAE_PK */
-	pos++;
+	*pos++ = flen;
+	*pos++ = capab & 0x00ff;
+	capab >>= 8;
+	if (capab)
+		*pos++ = capab;
 
 	return pos - buf;
 }
@@ -971,12 +1003,7 @@
 	}
 
 #ifdef CONFIG_SAE
-	/* Support for 4-way handshake offload to internal supplicant
-	 * for WPA/WPA2-PSK
-	 */
-	if (!wpa_auth->conf.psk_4way_hs_offload &&
-	    !wpa_auth->conf.sae_offload &&
-	    sm->wpa_key_mgmt == WPA_KEY_MGMT_SAE && data.num_pmkid &&
+	if (sm->wpa_key_mgmt == WPA_KEY_MGMT_SAE && data.num_pmkid &&
 	    !sm->pmksa) {
 		wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
 				 "No PMKSA cache entry found for SAE");
@@ -1124,6 +1151,7 @@
 
 
 #ifdef CONFIG_FILS
+
 u8 * wpa_auth_write_assoc_resp_fils(struct wpa_state_machine *sm,
 				    u8 *pos, size_t max_len,
 				    const u8 *req_ies, size_t req_ies_len)
@@ -1140,4 +1168,91 @@
 		return pos;
 	return pos + res;
 }
+
+
+bool wpa_auth_write_fd_rsn_info(struct wpa_authenticator *wpa_auth,
+				u8 *fd_rsn_info)
+{
+	struct wpa_auth_config *conf;
+	u32 selectors = 0;
+	u8 *pos = fd_rsn_info;
+	int i, res;
+	u32 cipher, suite, selector, mask;
+	u8 tmp[10 * RSN_SELECTOR_LEN];
+
+	if (!wpa_auth)
+		return false;
+	conf = &wpa_auth->conf;
+
+	if (!(conf->wpa & WPA_PROTO_RSN))
+		return false;
+
+	/* RSN Capability (B0..B15) */
+	WPA_PUT_LE16(pos, wpa_own_rsn_capab(conf));
+	pos += 2;
+
+	/* Group Data Cipher Suite Selector (B16..B21) */
+	suite = wpa_cipher_to_suite(WPA_PROTO_RSN, conf->wpa_group);
+	if (suite == RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED)
+		cipher = 63; /* No cipher suite selected */
+	else if ((suite >> 8) == 0x000fac && ((suite & 0xff) <= 13))
+		cipher = suite & 0xff;
+	else
+		cipher = 62; /* vendor specific */
+	selectors |= cipher;
+
+	/* Group Management Cipher Suite Selector (B22..B27) */
+	cipher = 63; /* Default to no cipher suite selected */
+	if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
+		switch (conf->group_mgmt_cipher) {
+		case WPA_CIPHER_AES_128_CMAC:
+			cipher = RSN_CIPHER_SUITE_AES_128_CMAC & 0xff;
+			break;
+		case WPA_CIPHER_BIP_GMAC_128:
+			cipher = RSN_CIPHER_SUITE_BIP_GMAC_128 & 0xff;
+			break;
+		case WPA_CIPHER_BIP_GMAC_256:
+			cipher = RSN_CIPHER_SUITE_BIP_GMAC_256 & 0xff;
+			break;
+		case WPA_CIPHER_BIP_CMAC_256:
+			cipher = RSN_CIPHER_SUITE_BIP_CMAC_256 & 0xff;
+			break;
+		}
+	}
+	selectors |= cipher << 6;
+
+	/* Pairwise Cipher Suite Selector (B28..B33) */
+	cipher = 63; /* Default to no cipher suite selected */
+	res = rsn_cipher_put_suites(tmp, conf->rsn_pairwise);
+	if (res == 1 && tmp[0] == 0x00 && tmp[1] == 0x0f && tmp[2] == 0xac &&
+	    tmp[3] <= 13)
+		cipher = tmp[3];
+	selectors |= cipher << 12;
+
+	/* AKM Suite Selector (B34..B39) */
+	selector = 0; /* default to AKM from RSNE in Beacon/Probe Response */
+	mask = WPA_KEY_MGMT_FILS_SHA256 | WPA_KEY_MGMT_FILS_SHA384 |
+		WPA_KEY_MGMT_FT_FILS_SHA384;
+	if ((conf->wpa_key_mgmt & mask) && (conf->wpa_key_mgmt & ~mask) == 0) {
+		suite = conf->wpa_key_mgmt & mask;
+		if (suite == WPA_KEY_MGMT_FILS_SHA256)
+			selector = 1; /* 00-0f-ac:14 */
+		else if (suite == WPA_KEY_MGMT_FILS_SHA384)
+			selector = 2; /* 00-0f-ac:15 */
+		else if (suite == (WPA_KEY_MGMT_FILS_SHA256 |
+				   WPA_KEY_MGMT_FILS_SHA384))
+			selector = 3; /* 00-0f-ac:14 or 00-0f-ac:15 */
+		else if (suite == WPA_KEY_MGMT_FT_FILS_SHA384)
+			selector = 4; /* 00-0f-ac:17 */
+	}
+	selectors |= selector << 18;
+
+	for (i = 0; i < 3; i++) {
+		*pos++ = selectors & 0xff;
+		selectors >>= 8;
+	}
+
+	return true;
+}
+
 #endif /* CONFIG_FILS */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wps_hostapd.c b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wps_hostapd.c
index a4fd208..2958618 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wps_hostapd.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/ap/wps_hostapd.c
@@ -1172,6 +1172,8 @@
 			wps->auth_types |= WPS_AUTH_WPA2PSK;
 		if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X)
 			wps->auth_types |= WPS_AUTH_WPA2;
+		if (conf->wpa_key_mgmt & WPA_KEY_MGMT_SAE)
+			wps->auth_types |= WPS_AUTH_WPA2PSK;
 
 		if (conf->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP |
 					  WPA_CIPHER_CCMP_256 |
@@ -1328,6 +1330,11 @@
 
 	hostapd_register_probereq_cb(hapd, hostapd_wps_probe_req_rx, hapd);
 
+#ifdef CONFIG_P2P
+	if ((hapd->conf->p2p & P2P_ENABLED) &&
+	    is_6ghz_op_class(hapd->iconf->op_class))
+		wps->use_passphrase = true;
+#endif /* CONFIG_P2P */
 	hapd->wps = wps;
 	bin_clear_free(multi_ap_netw_key, 2 * PMK_LEN);
 
@@ -1376,6 +1383,48 @@
 }
 
 
+static int hostapd_wps_update_multi_ap(struct hostapd_data *hapd,
+				       struct wps_registrar *reg)
+{
+	struct hostapd_bss_config *conf = hapd->conf;
+	u8 *multi_ap_backhaul_network_key = NULL;
+	size_t multi_ap_backhaul_network_key_len = 0;
+	int ret;
+
+	if (!(conf->multi_ap & FRONTHAUL_BSS) ||
+	    !conf->multi_ap_backhaul_ssid.ssid_len)
+		return 0;
+
+	if (conf->multi_ap_backhaul_ssid.wpa_passphrase) {
+		multi_ap_backhaul_network_key =
+			(u8 *) os_strdup(
+				conf->multi_ap_backhaul_ssid.wpa_passphrase);
+		if (!multi_ap_backhaul_network_key)
+			return -1;
+		multi_ap_backhaul_network_key_len =
+			os_strlen(conf->multi_ap_backhaul_ssid.wpa_passphrase);
+	} else if (conf->multi_ap_backhaul_ssid.wpa_psk) {
+		multi_ap_backhaul_network_key = os_malloc(2 * PMK_LEN + 1);
+		if (!multi_ap_backhaul_network_key)
+			return -1;
+		wpa_snprintf_hex((char *) multi_ap_backhaul_network_key,
+				 2 * PMK_LEN + 1,
+				 conf->multi_ap_backhaul_ssid.wpa_psk->psk,
+				 PMK_LEN);
+		multi_ap_backhaul_network_key_len = 2 * PMK_LEN;
+	}
+
+	ret = wps_registrar_update_multi_ap(
+		reg, conf->multi_ap_backhaul_ssid.ssid,
+		conf->multi_ap_backhaul_ssid.ssid_len,
+		multi_ap_backhaul_network_key,
+		multi_ap_backhaul_network_key_len);
+	os_free(multi_ap_backhaul_network_key);
+
+	return ret;
+}
+
+
 void hostapd_deinit_wps(struct hostapd_data *hapd)
 {
 	eloop_cancel_timeout(hostapd_wps_reenable_ap_pin, hapd, NULL);
@@ -1398,22 +1447,65 @@
 
 void hostapd_update_wps(struct hostapd_data *hapd)
 {
-	if (hapd->wps == NULL)
+	struct wps_context *wps = hapd->wps;
+	struct hostapd_bss_config *conf = hapd->conf;
+
+	if (!wps)
 		return;
 
 #ifdef CONFIG_WPS_UPNP
-	hapd->wps->friendly_name = hapd->conf->friendly_name;
-	hapd->wps->manufacturer_url = hapd->conf->manufacturer_url;
-	hapd->wps->model_description = hapd->conf->model_description;
-	hapd->wps->model_url = hapd->conf->model_url;
-	hapd->wps->upc = hapd->conf->upc;
+	wps->friendly_name = conf->friendly_name;
+	wps->manufacturer_url = conf->manufacturer_url;
+	wps->model_description = conf->model_description;
+	wps->model_url = conf->model_url;
+	wps->upc = conf->upc;
 #endif /* CONFIG_WPS_UPNP */
 
-	hostapd_wps_set_vendor_ext(hapd, hapd->wps);
-	hostapd_wps_set_application_ext(hapd, hapd->wps);
+	os_memcpy(wps->ssid, conf->ssid.ssid, conf->ssid.ssid_len);
+	wps->ssid_len = conf->ssid.ssid_len;
 
-	if (hapd->conf->wps_state)
-		wps_registrar_update_ie(hapd->wps->registrar);
+	/* Clear WPS settings, then fill them again */
+	os_free(wps->network_key);
+	wps->network_key = NULL;
+	wps->network_key_len = 0;
+	wps->psk_set = 0;
+	if (conf->ssid.wpa_psk_file) {
+		/* Use per-device PSKs */
+	} else if (conf->ssid.wpa_passphrase) {
+		wps->network_key = (u8 *) os_strdup(conf->ssid.wpa_passphrase);
+		if (!wps->network_key)
+			return;
+		wps->network_key_len = os_strlen(conf->ssid.wpa_passphrase);
+	} else if (conf->ssid.wpa_psk) {
+		wps->network_key = os_malloc(2 * PMK_LEN + 1);
+		if (!wps->network_key)
+			return;
+		wpa_snprintf_hex((char *) wps->network_key, 2 * PMK_LEN + 1,
+				 conf->ssid.wpa_psk->psk, PMK_LEN);
+		wps->network_key_len = 2 * PMK_LEN;
+#ifdef CONFIG_WEP
+	} else if (conf->ssid.wep.keys_set && conf->ssid.wep.key[0]) {
+		wps->network_key = os_malloc(conf->ssid.wep.len[0]);
+		if (!wps->network_key)
+			return;
+		os_memcpy(wps->network_key, conf->ssid.wep.key[0],
+			  conf->ssid.wep.len[0]);
+		wps->network_key_len = conf->ssid.wep.len[0];
+#endif /* CONFIG_WEP */
+	}
+
+	if (conf->ssid.wpa_psk) {
+		os_memcpy(wps->psk, conf->ssid.wpa_psk->psk, PMK_LEN);
+		wps->psk_set = 1;
+	}
+
+	hostapd_wps_update_multi_ap(hapd, wps->registrar);
+
+	hostapd_wps_set_vendor_ext(hapd, wps);
+	hostapd_wps_set_application_ext(hapd, wps);
+
+	if (conf->wps_state)
+		wps_registrar_update_ie(wps->registrar);
 	else
 		hostapd_deinit_wps(hapd);
 }
@@ -1867,6 +1959,11 @@
 		cred.key_len = len / 2;
 	}
 
+	if (!hapd->wps) {
+		wpa_printf(MSG_ERROR, "WPS: WPS config does not exist");
+		return -1;
+	}
+
 	return wps_registrar_config_ap(hapd->wps->registrar, &cred);
 }
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/Makefile b/src/lynq/packages/thirdpart/lynq-wg870/src/common/Makefile
index 59ba6c5..e2c5f03 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/Makefile
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/Makefile
@@ -3,12 +3,14 @@
 CFLAGS += -DCONFIG_SAE
 CFLAGS += -DCONFIG_SUITE
 CFLAGS += -DCONFIG_SUITEB
+CFLAGS += -DCONFIG_PTKSA_CACHE
 
 LIB_OBJS= \
 	gas.o \
 	hw_features_common.o \
 	ieee802_11_common.o \
 	sae.o \
+	ptksa_cache.o \
 	wpa_common.o
 
 include ../lib.rules
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/brcm_vendor.h b/src/lynq/packages/thirdpart/lynq-wg870/src/common/brcm_vendor.h
index a7cde17..a8725f2 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/brcm_vendor.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/brcm_vendor.h
@@ -1,6 +1,6 @@
 /*
  * Broadcom Corporation OUI and vendor specific assignments
- * Copyright (c) 2015, Broadcom Corporation.
+ * Copyright (c) 2020, Broadcom Corporation.
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -16,21 +16,54 @@
  * hostap.git repository.
  */
 
-#define OUI_BRCM  0x001018
+#define OUI_BRCM    0x001018
 
 /**
  * enum brcm_nl80211_vendor_subcmds - BRCM nl80211 vendor command identifiers
  *
- * @BRCM_VENDOR_SUBCMD_UNSPEC: Reserved value 0
+ * @BRCM_VENDOR_SCMD_UNSPEC: Reserved value 0
  *
- * @BRCM_VENDOR_SUBCMD_PRIV_STR: String command/event
+ * @BRCM_VENDOR_SCMD_PRIV_STR: Provide vendor private cmds to send to FW.
+ *
+ * @BRCM_VENDOR_SCMD_BCM_STR:  Provide vendor cmds to BCMDHD driver.
+ *
+ * @BRCM_VENDOR_SCMD_BCM_PSK: Used to set SAE password.
+ *
+ * @BRCM_VENDOR_SCMD_SET_PMK: Command to check driver support
+ *	for DFS offloading.
+ *
+ * @BRCM_VENDOR_SCMD_GET_FEATURES: Command to get the features
+ *      supported by the driver.
+ *
+ * @BRCM_VENDOR_SCMD_SET_MAC: Set random mac address for P2P interface.
+ *
+ * @BRCM_VENDOR_SCMD_SET_CONNECT_PARAMS: Set some connect parameters.
+ *      Used for the case that FW handle SAE.
+ *
+ * @BRCM_VENDOR_SCMD_SET_START_AP_PARAMS: Set SoftAP paramters.
+ *      Used for the case that FW handle SAE.
+ *
+ * @BRCM_VENDOR_SCMD_ACS: ACS command/event which is used to
+ *	invoke the ACS function in device and pass selected channels to
+ *	hostapd. Uses enum qca_wlan_vendor_attr_acs_offload attributes.
+ *
+ * @BRCM_VENDOR_SCMD_MAX: This acts as a the tail of cmds list.
+ *      Make sure it located at the end of the list.
+ *
  */
 enum brcm_nl80211_vendor_subcmds {
-        BRCM_VENDOR_SUBCMD_UNSPEC,
-        BRCM_VENDOR_SUBCMD_PRIV_STR,
-        BRCM_VENDOR_SUBCMD_BCM_STR,
-	BRCM_VENDOR_SUBCMD_SET_PSK,
-	BRCM_VENDOR_SUBCMD_EXTERNAL_AUTH
+	BRCM_VENDOR_SCMD_UNSPEC			= 0,
+	BRCM_VENDOR_SCMD_PRIV_STR		= 1,
+	BRCM_VENDOR_SCMD_BCM_STR		= 2,
+	BRCM_VENDOR_SCMD_BCM_PSK		= 3,
+	BRCM_VENDOR_SCMD_SET_PMK		= 4,
+	BRCM_VENDOR_SCMD_GET_FEATURES		= 5,
+	BRCM_VENDOR_SCMD_SET_MAC		= 6,
+	BRCM_VENDOR_SCMD_SET_CONNECT_PARAMS	= 7,
+	BRCM_VENDOR_SCMD_SET_START_AP_PARAMS	= 8,
+	BRCM_VENDOR_SCMD_ACS			= 9,
+	BRCM_VENDOR_SUBCMD_EXTERNAL_AUTH	= 10,
+	BRCM_VENDOR_SCMD_MAX			= 11
 };
 
 /**
@@ -41,20 +74,64 @@
  * @BRCM_VENDOR_EVENT_PRIV_STR: String command/event
  */
 enum brcm_nl80211_vendor_events {
-        BRCM_VENDOR_EVENT_UNSPEC,
-        BRCM_VENDOR_EVENT_PRIV_STR,
-	BRCM_VENDOR_EVENT_EXTERNAL_AUTH,
-        BRCM_VENDOR_EVENT_HANGED	= 33,
-	BRCM_VENDOR_EVENT_SAE_KEY	= 34,
-	BRCM_VENDOR_EVENT_BEACON_RECV   = 35,
-	BRCM_VENDOR_EVENT_OVERTEMP	= 43
+	BRCM_VENDOR_EVENT_UNSPEC		= 0,
+	BRCM_VENDOR_EVENT_PRIV_STR		= 1,
+	GOOGLE_GSCAN_SIGNIFICANT_EVENT		= 2,
+	GOOGLE_GSCAN_GEOFENCE_FOUND_EVENT	= 3,
+	GOOGLE_GSCAN_BATCH_SCAN_EVENT		= 4,
+	GOOGLE_SCAN_FULL_RESULTS_EVENT		= 5,
+	GOOGLE_RTT_COMPLETE_EVENT		= 6,
+	GOOGLE_SCAN_COMPLETE_EVENT		= 7,
+	GOOGLE_GSCAN_GEOFENCE_LOST_EVENT	= 8,
+	GOOGLE_SCAN_EPNO_EVENT			= 9,
+	GOOGLE_DEBUG_RING_EVENT			= 10,
+	GOOGLE_FW_DUMP_EVENT			= 11,
+	GOOGLE_PNO_HOTSPOT_FOUND_EVENT		= 12,
+	GOOGLE_RSSI_MONITOR_EVENT		= 13,
+	GOOGLE_MKEEP_ALIVE_EVENT		= 14,
+
+	/*
+	 * BRCM specific events should be placed after
+	 * the Generic events so that enums don't mismatch
+	 * between the DHD and HAL
+	 */
+	GOOGLE_NAN_EVENT_ENABLED		= 15,
+	GOOGLE_NAN_EVENT_DISABLED		= 16,
+	GOOGLE_NAN_EVENT_SUBSCRIBE_MATCH	= 17,
+	GOOGLE_NAN_EVENT_REPLIED		= 18,
+	GOOGLE_NAN_EVENT_PUBLISH_TERMINATED	= 19,
+	GOOGLE_NAN_EVENT_SUBSCRIBE_TERMINATED	= 20,
+	GOOGLE_NAN_EVENT_DE_EVENT		= 21,
+	GOOGLE_NAN_EVENT_FOLLOWUP		= 22,
+	GOOGLE_NAN_EVENT_TRANSMIT_FOLLOWUP_IND	= 23,
+	GOOGLE_NAN_EVENT_DATA_REQUEST		= 24,
+	GOOGLE_NAN_EVENT_DATA_CONFIRMATION	= 25,
+	GOOGLE_NAN_EVENT_DATA_END		= 26,
+	GOOGLE_NAN_EVENT_BEACON			= 27,
+	GOOGLE_NAN_EVENT_SDF			= 28,
+	GOOGLE_NAN_EVENT_TCA			= 29,
+	GOOGLE_NAN_EVENT_SUBSCRIBE_UNMATCH	= 30,
+	GOOGLE_NAN_EVENT_UNKNOWN		= 31,
+	GOOGLE_ROAM_EVENT_START			= 32,
+	BRCM_VENDOR_EVENT_HANGED                = 33,
+	BRCM_VENDOR_EVENT_SAE_KEY               = 34,
+	BRCM_VENDOR_EVENT_BEACON_RECV           = 35,
+	BRCM_VENDOR_EVENT_PORT_AUTHORIZED       = 36,
+	GOOGLE_FILE_DUMP_EVENT			= 37,
+	BRCM_VENDOR_EVENT_CU			= 38,
+	BRCM_VENDOR_EVENT_WIPS			= 39,
+	NAN_ASYNC_RESPONSE_DISABLED		= 40,
+	BRCM_VENDOR_EVENT_RCC_INFO		= 41,
+	BRCM_VENDOR_EVENT_ACS			= 42,
+	BRCM_VENDOR_EVENT_OVERTEMP		= 43,
+	BRCM_VENDOR_EVENT_LAST
 };
 
 #ifdef CONFIG_BRCM_SAE
 enum wifi_sae_key_attr {
-        BRCM_SAE_KEY_ATTR_PEER_MAC,
-        BRCM_SAE_KEY_ATTR_PMK,
-        BRCM_SAE_KEY_ATTR_PMKID
+	BRCM_SAE_KEY_ATTR_PEER_MAC,
+	BRCM_SAE_KEY_ATTR_PMK,
+	BRCM_SAE_KEY_ATTR_PMKID
 };
 #endif /* CONFIG_BRCM_SAE */
 
@@ -64,4 +141,24 @@
 	BRCM_BCNRECV_ATTR_BCNINFO,
 	BRCM_BCNRECV_ATTR_MAX
 };
+
+enum wl_vendor_attr_acs_offload {
+	BRCM_VENDOR_ATTR_ACS_CHANNEL_INVALID = 0,
+	BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ,
+	BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ,
+	BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL,
+	BRCM_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL,
+
+	BRCM_VENDOR_ATTR_ACS_HW_MODE,
+	BRCM_VENDOR_ATTR_ACS_HT_ENABLED,
+	BRCM_VENDOR_ATTR_ACS_HT40_ENABLED,
+	BRCM_VENDOR_ATTR_ACS_VHT_ENABLED,
+	BRCM_VENDOR_ATTR_ACS_CHWIDTH,
+	BRCM_VENDOR_ATTR_ACS_CH_LIST,
+	BRCM_VENDOR_ATTR_ACS_FREQ_LIST,
+
+	BRCM_VENDOR_ATTR_ACS_LAST
+};
+
+
 #endif /* BRCM_VENDOR_H */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/common_module_tests.c b/src/lynq/packages/thirdpart/lynq-wg870/src/common/common_module_tests.c
index 00308d4..8aba713 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/common_module_tests.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/common_module_tests.c
@@ -256,87 +256,69 @@
 #ifdef CONFIG_SAE
 	struct sae_data sae;
 	int ret = -1;
-	/* IEEE P802.11-REVmd/D2.1, Annex J.10 */
-	const u8 addr1[ETH_ALEN] = { 0x82, 0x7b, 0x91, 0x9d, 0xd4, 0xb9 };
-	const u8 addr2[ETH_ALEN] = { 0x1e, 0xec, 0x49, 0xea, 0x64, 0x88 };
+	/* IEEE Std 802.11-2020, Annex J.10 */
+	const u8 addr1[ETH_ALEN] = { 0x4d, 0x3f, 0x2f, 0xff, 0xe3, 0x87 };
+	const u8 addr2[ETH_ALEN] = { 0xa5, 0xd8, 0xaa, 0x95, 0x8e, 0x3c };
 	const char *ssid = "byteme";
 	const char *pw = "mekmitasdigoat";
 	const char *pwid = "psk4internet";
 	const u8 local_rand[] = {
-		0xa9, 0x06, 0xf6, 0x1e, 0x4d, 0x3a, 0x5d, 0x4e,
-		0xb2, 0x96, 0x5f, 0xf3, 0x4c, 0xf9, 0x17, 0xdd,
-		0x04, 0x44, 0x45, 0xc8, 0x78, 0xc1, 0x7c, 0xa5,
-		0xd5, 0xb9, 0x37, 0x86, 0xda, 0x9f, 0x83, 0xcf
+		0x99, 0x24, 0x65, 0xfd, 0x3d, 0xaa, 0x3c, 0x60,
+		0xaa, 0x65, 0x65, 0xb7, 0xf6, 0x2a, 0x2a, 0x7f,
+		0x2e, 0x12, 0xdd, 0x12, 0xf1, 0x98, 0xfa, 0xf4,
+		0xfb, 0xed, 0x89, 0xd7, 0xff, 0x1a, 0xce, 0x94
 	};
 	const u8 local_mask[] = {
-		0x42, 0x34, 0xb4, 0xfb, 0x17, 0xaa, 0x43, 0x5c,
-		0x52, 0xfb, 0xfd, 0xeb, 0xe6, 0x40, 0x39, 0xb4,
-		0x34, 0x78, 0x20, 0x0e, 0x54, 0xff, 0x7b, 0x6e,
-		0x07, 0xb6, 0x9c, 0xad, 0x74, 0x15, 0x3c, 0x15
+		0x95, 0x07, 0xa9, 0x0f, 0x77, 0x7a, 0x04, 0x4d,
+		0x6a, 0x08, 0x30, 0xb9, 0x1e, 0xa3, 0xd5, 0xdd,
+		0x70, 0xbe, 0xce, 0x44, 0xe1, 0xac, 0xff, 0xb8,
+		0x69, 0x83, 0xb5, 0xe1, 0xbf, 0x9f, 0xb3, 0x22
 	};
 	const u8 local_commit[] = {
-		0x13, 0x00, 0xeb, 0x3b, 0xab, 0x19, 0x64, 0xe4,
-		0xa0, 0xab, 0x05, 0x92, 0x5d, 0xdf, 0x33, 0x39,
-		0x51, 0x91, 0x38, 0xbc, 0x65, 0xd6, 0xcd, 0xc0,
-		0xf8, 0x13, 0xdd, 0x6f, 0xd4, 0x34, 0x4e, 0xb4,
-		0xbf, 0xe4, 0x4b, 0x5c, 0x21, 0x59, 0x76, 0x58,
-		0xf4, 0xe3, 0xed, 0xdf, 0xb4, 0xb9, 0x9f, 0x25,
-		0xb4, 0xd6, 0x54, 0x0f, 0x32, 0xff, 0x1f, 0xd5,
-		0xc5, 0x30, 0xc6, 0x0a, 0x79, 0x44, 0x48, 0x61,
-		0x0b, 0xc6, 0xde, 0x3d, 0x92, 0xbd, 0xbb, 0xd4,
-		0x7d, 0x93, 0x59, 0x80, 0xca, 0x6c, 0xf8, 0x98,
-		0x8a, 0xb6, 0x63, 0x0b, 0xe6, 0x76, 0x4c, 0x88,
-		0x5c, 0xeb, 0x97, 0x93, 0x97, 0x0f, 0x69, 0x52,
-		0x17, 0xee, 0xff, 0x0d, 0x21, 0x70, 0x73, 0x6b,
-		0x34, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
-		0x74
+		0x13, 0x00, 0x2e, 0x2c, 0x0f, 0x0d, 0xb5, 0x24,
+		0x40, 0xad, 0x14, 0x6d, 0x96, 0x71, 0x14, 0xce,
+		0x00, 0x5c, 0xe1, 0xea, 0xb0, 0xaa, 0x2c, 0x2e,
+		0x5c, 0x28, 0x71, 0xb7, 0x74, 0xf6, 0xc2, 0x57,
+		0x5c, 0x65, 0xd5, 0xad, 0x9e, 0x00, 0x82, 0x97,
+		0x07, 0xaa, 0x36, 0xba, 0x8b, 0x85, 0x97, 0x38,
+		0xfc, 0x96, 0x1d, 0x08, 0x24, 0x35, 0x05, 0xf4,
+		0x7c, 0x03, 0x53, 0x76, 0xd7, 0xac, 0x4b, 0xc8,
+		0xd7, 0xb9, 0x50, 0x83, 0xbf, 0x43, 0x82, 0x7d,
+		0x0f, 0xc3, 0x1e, 0xd7, 0x78, 0xdd, 0x36, 0x71,
+		0xfd, 0x21, 0xa4, 0x6d, 0x10, 0x91, 0xd6, 0x4b,
+		0x6f, 0x9a, 0x1e, 0x12, 0x72, 0x62, 0x13, 0x25,
+		0xdb, 0xe1
 	};
 	const u8 peer_commit[] = {
-		0x13, 0x00, 0x55, 0x64, 0xf0, 0x45, 0xb2, 0xea,
-		0x1e, 0x56, 0x6c, 0xf1, 0xdd, 0x74, 0x1f, 0x70,
-		0xd9, 0xbe, 0x35, 0xd2, 0xdf, 0x5b, 0x9a, 0x55,
-		0x02, 0x94, 0x6e, 0xe0, 0x3c, 0xf8, 0xda, 0xe2,
-		0x7e, 0x1e, 0x05, 0xb8, 0x43, 0x0e, 0xb7, 0xa9,
-		0x9e, 0x24, 0x87, 0x7c, 0xe6, 0x9b, 0xaf, 0x3d,
-		0xc5, 0x80, 0xe3, 0x09, 0x63, 0x3d, 0x6b, 0x38,
-		0x5f, 0x83, 0xee, 0x1c, 0x3e, 0xc3, 0x59, 0x1f,
-		0x1a, 0x53, 0x93, 0xc0, 0x6e, 0x80, 0x5d, 0xdc,
-		0xeb, 0x2f, 0xde, 0x50, 0x93, 0x0d, 0xd7, 0xcf,
-		0xeb, 0xb9, 0x87, 0xc6, 0xff, 0x96, 0x66, 0xaf,
-		0x16, 0x4e, 0xb5, 0x18, 0x4d, 0x8e, 0x66, 0x62,
-		0xed, 0x6a, 0xff, 0x0d, 0x21, 0x70, 0x73, 0x6b,
-		0x34, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
-		0x74
+		0x13, 0x00, 0x59, 0x1b, 0x96, 0xf3, 0x39, 0x7f,
+		0xb9, 0x45, 0x10, 0x08, 0x48, 0xe7, 0xb5, 0x50,
+		0x54, 0x3b, 0x67, 0x20, 0xd8, 0x83, 0x37, 0xee,
+		0x93, 0xfc, 0x49, 0xfd, 0x6d, 0xf7, 0xe0, 0x8b,
+		0x52, 0x23, 0xe7, 0x1b, 0x9b, 0xb0, 0x48, 0xd3,
+		0x87, 0x3f, 0x20, 0x55, 0x69, 0x53, 0xa9, 0x6c,
+		0x91, 0x53, 0x6f, 0xd8, 0xee, 0x6c, 0xa9, 0xb4,
+		0xa6, 0x8a, 0x14, 0x8b, 0x05, 0x6a, 0x90, 0x9b,
+		0xe0, 0x3e, 0x83, 0xae, 0x20, 0x8f, 0x60, 0xf8,
+		0xef, 0x55, 0x37, 0x85, 0x80, 0x74, 0xdb, 0x06,
+		0x68, 0x70, 0x32, 0x39, 0x98, 0x62, 0x99, 0x9b,
+		0x51, 0x1e, 0x0a, 0x15, 0x52, 0xa5, 0xfe, 0xa3,
+		0x17, 0xc2
 	};
 	const u8 kck[] = {
-		0x59, 0x9d, 0x6f, 0x1e, 0x27, 0x54, 0x8b, 0xe8,
-		0x49, 0x9d, 0xce, 0xed, 0x2f, 0xec, 0xcf, 0x94,
-		0x81, 0x8c, 0xe1, 0xc7, 0x9f, 0x1b, 0x4e, 0xb3,
-		0xd6, 0xa5, 0x32, 0x28, 0xa0, 0x9b, 0xf3, 0xed
+		0x1e, 0x73, 0x3f, 0x6d, 0x9b, 0xd5, 0x32, 0x56,
+		0x28, 0x73, 0x04, 0x33, 0x88, 0x31, 0xb0, 0x9a,
+		0x39, 0x40, 0x6d, 0x12, 0x10, 0x17, 0x07, 0x3a,
+		0x5c, 0x30, 0xdb, 0x36, 0xf3, 0x6c, 0xb8, 0x1a
 	};
 	const u8 pmk[] = {
-		0x7a, 0xea, 0xd8, 0x6f, 0xba, 0x4c, 0x32, 0x21,
-		0xfc, 0x43, 0x7f, 0x5f, 0x14, 0xd7, 0x0d, 0x85,
-		0x4e, 0xa5, 0xd5, 0xaa, 0xc1, 0x69, 0x01, 0x16,
-		0x79, 0x30, 0x81, 0xed, 0xa4, 0xd5, 0x57, 0xc5
+		0x4e, 0x4d, 0xfa, 0xb1, 0xa2, 0xdd, 0x8a, 0xc1,
+		0xa9, 0x17, 0x90, 0xf9, 0x53, 0xfa, 0xaa, 0x45,
+		0x2a, 0xe5, 0xc6, 0x87, 0x3a, 0xb7, 0x5b, 0x63,
+		0x60, 0x5b, 0xa6, 0x63, 0xf8, 0xa7, 0xfe, 0x59
 	};
 	const u8 pmkid[] = {
-		0x40, 0xa0, 0x9b, 0x60, 0x17, 0xce, 0xbf, 0x00,
-		0x72, 0x84, 0x3b, 0x53, 0x52, 0xaa, 0x2b, 0x4f
-	};
-	const u8 local_confirm[] = {
-		0x01, 0x00, 0x12, 0xd9, 0xd5, 0xc7, 0x8c, 0x50,
-		0x05, 0x26, 0xd3, 0x6c, 0x41, 0xdb, 0xc5, 0x6a,
-		0xed, 0xf2, 0x91, 0x4c, 0xed, 0xdd, 0xd7, 0xca,
-		0xd4, 0xa5, 0x8c, 0x48, 0xf8, 0x3d, 0xbd, 0xe9,
-		0xfc, 0x77
-	};
-	const u8 peer_confirm[] = {
-		0x01, 0x00, 0x02, 0x87, 0x1c, 0xf9, 0x06, 0x89,
-		0x8b, 0x80, 0x60, 0xec, 0x18, 0x41, 0x43, 0xbe,
-		0x77, 0xb8, 0xc0, 0x8a, 0x80, 0x19, 0xb1, 0x3e,
-		0xb6, 0xd0, 0xae, 0xf0, 0xd8, 0x38, 0x3d, 0xfa,
-		0xc2, 0xfd
+		0x87, 0x47, 0xa6, 0x00, 0xee, 0xa3, 0xf9, 0xf2,
+		0x24, 0x75, 0xdf, 0x58, 0xca, 0x1e, 0x54, 0x98
 	};
 	struct wpabuf *buf = NULL;
 	struct crypto_bignum *mask = NULL;
@@ -412,7 +394,7 @@
 	if (!buf ||
 	    sae_set_group(&sae, 19) < 0 ||
 	    sae_prepare_commit(addr1, addr2, (const u8 *) pw, os_strlen(pw),
-			       pwid, &sae) < 0)
+			       &sae) < 0)
 		goto fail;
 
 	/* Override local values based on SAE test vector */
@@ -434,7 +416,7 @@
 		goto fail;
 
 	/* Check that output matches the test vector */
-	if (sae_write_commit(&sae, buf, NULL, pwid) < 0)
+	if (sae_write_commit(&sae, buf, NULL, NULL) < 0)
 		goto fail;
 	wpa_hexdump_buf(MSG_DEBUG, "SAE: Commit message", buf);
 
@@ -465,21 +447,6 @@
 		goto fail;
 	}
 
-	buf->used = 0;
-	sae.send_confirm = 1;
-	sae_write_confirm(&sae, buf);
-	wpa_hexdump_buf(MSG_DEBUG, "SAE: Confirm message", buf);
-
-	if (wpabuf_len(buf) != sizeof(local_confirm) ||
-	    os_memcmp(wpabuf_head(buf), local_confirm,
-		      sizeof(local_confirm)) != 0) {
-		wpa_printf(MSG_ERROR, "SAE: Mismatch in local confirm");
-		goto fail;
-	}
-
-	if (sae_check_confirm(&sae, peer_confirm, sizeof(peer_confirm)) < 0)
-		goto fail;
-
 	pt_info = sae_derive_pt(pt_groups,
 				(const u8 *) ssid, os_strlen(ssid),
 				(const u8 *) pw, os_strlen(pw), pwid);
@@ -637,6 +604,178 @@
 }
 
 
+#ifdef CONFIG_PASN
+
+static int pasn_test_pasn_auth(void)
+{
+	/* Test vector taken from IEEE P802.11az/D2.6, J.12 */
+	const u8 pmk[] = {
+		0xde, 0xf4, 0x3e, 0x55, 0x67, 0xe0, 0x1c, 0xa6,
+		0x64, 0x92, 0x65, 0xf1, 0x9a, 0x29, 0x0e, 0xef,
+		0xf8, 0xbd, 0x88, 0x8f, 0x6c, 0x1d, 0x9c, 0xc9,
+		0xd1, 0x0f, 0x04, 0xbd, 0x37, 0x8f, 0x3c, 0xad
+	};
+
+	const u8 spa_addr[] = {
+		0x00, 0x90, 0x4c, 0x01, 0xc1, 0x07
+	};
+	const u8 bssid[] = {
+		0xc0, 0xff, 0xd4, 0xa8, 0xdb, 0xc1
+	};
+	const u8 dhss[] = {
+		0xf8, 0x7b, 0x20, 0x8e, 0x7e, 0xd2, 0xb7, 0x37,
+		0xaf, 0xdb, 0xc2, 0xe1, 0x3e, 0xae, 0x78, 0xda,
+		0x30, 0x01, 0x23, 0xd4, 0xd8, 0x4b, 0xa8, 0xb0,
+		0xea, 0xfe, 0x90, 0xc4, 0x8c, 0xdf, 0x1f, 0x93
+	};
+	const u8 kck[] = {
+		0x7b, 0xb8, 0x21, 0xac, 0x0a, 0xa5, 0x90, 0x9d,
+		0xd6, 0x54, 0xa5, 0x60, 0x65, 0xad, 0x7c, 0x77,
+		0xeb, 0x88, 0x9c, 0xbe, 0x29, 0x05, 0xbb, 0xf0,
+		0x5a, 0xbb, 0x1e, 0xea, 0xc8, 0x8b, 0xa3, 0x06
+	};
+	const u8 tk[] = {
+		0x67, 0x3e, 0xab, 0x46, 0xb8, 0x32, 0xd5, 0xa8,
+		0x0c, 0xbc, 0x02, 0x43, 0x01, 0x6e, 0x20, 0x7e
+	};
+	const u8 kdk[] = {
+		0x2d, 0x0f, 0x0e, 0x82, 0xc7, 0x0d, 0xd2, 0x6b,
+		0x79, 0x06, 0x1a, 0x46, 0x81, 0xe8, 0xdb, 0xb2,
+		0xea, 0x83, 0xbe, 0xa3, 0x99, 0x84, 0x4b, 0xd5,
+		0x89, 0x4e, 0xb3, 0x20, 0xf6, 0x9d, 0x7d, 0xd6
+	};
+	struct wpa_ptk ptk;
+	int ret;
+
+	ret = pasn_pmk_to_ptk(pmk, sizeof(pmk),
+			      spa_addr, bssid,
+			      dhss, sizeof(dhss),
+			      &ptk, WPA_KEY_MGMT_PASN, WPA_CIPHER_CCMP,
+			      WPA_KDK_MAX_LEN);
+
+	if (ret)
+		return ret;
+
+	if (ptk.kck_len != sizeof(kck) ||
+	    os_memcmp(kck, ptk.kck, sizeof(kck)) != 0) {
+		wpa_printf(MSG_ERROR, "PASN: Mismatched KCK");
+		return -1;
+	}
+
+	if (ptk.tk_len != sizeof(tk) ||
+	    os_memcmp(tk, ptk.tk, sizeof(tk)) != 0) {
+		wpa_printf(MSG_ERROR, "PASN: Mismatched TK");
+		return -1;
+	}
+
+	if (ptk.kdk_len != sizeof(kdk) ||
+	    os_memcmp(kdk, ptk.kdk, sizeof(kdk)) != 0) {
+		wpa_printf(MSG_ERROR, "PASN: Mismatched KDK");
+		return -1;
+	}
+
+	return 0;
+}
+
+
+static int pasn_test_no_pasn_auth(void)
+{
+	/* Test vector taken from IEEE P802.11az/D2.6, J.13 */
+	const u8 pmk[] = {
+		0xde, 0xf4, 0x3e, 0x55, 0x67, 0xe0, 0x1c, 0xa6,
+		0x64, 0x92, 0x65, 0xf1, 0x9a, 0x29, 0x0e, 0xef,
+		0xf8, 0xbd, 0x88, 0x8f, 0x6c, 0x1d, 0x9c, 0xc9,
+		0xd1, 0x0f, 0x04, 0xbd, 0x37, 0x8f, 0x3c, 0xad
+	};
+	const u8 aa[] = {
+		0xc0, 0xff, 0xd4, 0xa8, 0xdb, 0xc1
+	};
+	const u8 spa[] = {
+		0x00, 0x90, 0x4c, 0x01, 0xc1, 0x07
+	};
+	const u8 anonce[] = {
+		0xbe, 0x7a, 0x1c, 0xa2, 0x84, 0x34, 0x7b, 0x5b,
+		0xd6, 0x7d, 0xbd, 0x2d, 0xfd, 0xb4, 0xd9, 0x9f,
+		0x1a, 0xfa, 0xe0, 0xb8, 0x8b, 0xa1, 0x8e, 0x00,
+		0x87, 0x18, 0x41, 0x7e, 0x4b, 0x27, 0xef, 0x5f
+	};
+	const u8 snonce[] = {
+		0x40, 0x4b, 0x01, 0x2f, 0xfb, 0x43, 0xed, 0x0f,
+		0xb4, 0x3e, 0xa1, 0xf2, 0x87, 0xc9, 0x1f, 0x25,
+		0x06, 0xd2, 0x1b, 0x4a, 0x92, 0xd7, 0x4b, 0x5e,
+		0xa5, 0x0c, 0x94, 0x33, 0x50, 0xce, 0x86, 0x71
+	};
+	const u8 kck[] = {
+		0xcd, 0x7b, 0x9e, 0x75, 0x55, 0x36, 0x2d, 0xf0,
+		0xb6, 0x35, 0x68, 0x48, 0x4a, 0x81, 0x12, 0xf5
+	};
+	const u8 kek[] = {
+		0x99, 0xca, 0xd3, 0x58, 0x8d, 0xa0, 0xf1, 0xe6,
+		0x3f, 0xd1, 0x90, 0x19, 0x10, 0x39, 0xbb, 0x4b
+	};
+	const u8 tk[] = {
+		0x9e, 0x2e, 0x93, 0x77, 0xe7, 0x53, 0x2e, 0x73,
+		0x7a, 0x1b, 0xc2, 0x50, 0xfe, 0x19, 0x4a, 0x03
+	};
+	const u8 kdk[] = {
+		0x6c, 0x7f, 0xb9, 0x7c, 0xeb, 0x55, 0xb0, 0x1a,
+		0xcf, 0xf0, 0x0f, 0x07, 0x09, 0x42, 0xbd, 0xf5,
+		0x29, 0x1f, 0xeb, 0x4b, 0xee, 0x38, 0xe0, 0x36,
+		0x5b, 0x25, 0xa2, 0x50, 0xbb, 0x2a, 0xc9, 0xff
+	};
+	struct wpa_ptk ptk;
+	int ret;
+
+	ret = wpa_pmk_to_ptk(pmk, sizeof(pmk),
+			     "Pairwise key expansion",
+			     spa, aa, snonce, anonce,
+			     &ptk, WPA_KEY_MGMT_SAE, WPA_CIPHER_CCMP,
+			     NULL, 0, WPA_KDK_MAX_LEN);
+
+	if (ret)
+		return ret;
+
+	if (ptk.kck_len != sizeof(kck) ||
+	    os_memcmp(kck, ptk.kck, sizeof(kck)) != 0) {
+		wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched KCK");
+		return -1;
+	}
+
+	if (ptk.kek_len != sizeof(kek) ||
+	    os_memcmp(kek, ptk.kek, sizeof(kek)) != 0) {
+		wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched KEK");
+		return -1;
+	}
+
+	if (ptk.tk_len != sizeof(tk) ||
+	    os_memcmp(tk, ptk.tk, sizeof(tk)) != 0) {
+		wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched TK");
+		return -1;
+	}
+
+	if (ptk.kdk_len != sizeof(kdk) ||
+	    os_memcmp(kdk, ptk.kdk, sizeof(kdk)) != 0) {
+		wpa_printf(MSG_ERROR, "KDK no PASN auth: Mismatched KDK");
+		return -1;
+	}
+
+	return 0;
+}
+
+#endif /* CONFIG_PASN */
+
+
+static int pasn_tests(void)
+{
+#ifdef CONFIG_PASN
+	if (pasn_test_pasn_auth() ||
+	    pasn_test_no_pasn_auth())
+		return -1;
+#endif /* CONFIG_PASN */
+	return 0;
+}
+
+
 int common_module_tests(void)
 {
 	int ret = 0;
@@ -647,6 +786,7 @@
 	    gas_tests() < 0 ||
 	    sae_tests() < 0 ||
 	    sae_pk_tests() < 0 ||
+	    pasn_tests() < 0 ||
 	    rsn_ie_parse_tests() < 0)
 		ret = -1;
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/defs.h b/src/lynq/packages/thirdpart/lynq-wg870/src/common/defs.h
index bbe3120..d7145e4 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/defs.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/defs.h
@@ -49,6 +49,8 @@
 #define WPA_KEY_MGMT_OWE BIT(22)
 #define WPA_KEY_MGMT_DPP BIT(23)
 #define WPA_KEY_MGMT_FT_IEEE8021X_SHA384 BIT(24)
+#define WPA_KEY_MGMT_PASN BIT(25)
+
 
 #define WPA_KEY_MGMT_FT (WPA_KEY_MGMT_FT_PSK | \
 			 WPA_KEY_MGMT_FT_IEEE8021X | \
@@ -199,6 +201,9 @@
 	WPA_ALG_BIP_GMAC_128,
 	WPA_ALG_BIP_GMAC_256,
 	WPA_ALG_BIP_CMAC_256
+#if defined(WAPI_ANDROID)
+        , WAPI_ALG_SMS4
+#endif 
 };
 
 static inline int wpa_alg_bip(enum wpa_alg alg)
@@ -324,6 +329,9 @@
 	 * fully configured.
 	 */
 	WPA_COMPLETED
+#if defined(WAPI_ANDROID) /* to be detailed out */
+        , WAPI_SPECIFIC
+#endif 
 };
 
 #define MLME_SETPROTECTION_PROTECT_TYPE_NONE 0
@@ -388,9 +396,10 @@
 };
 
 enum set_band {
-	WPA_SETBAND_AUTO,
-	WPA_SETBAND_5G,
-	WPA_SETBAND_2G
+	WPA_SETBAND_AUTO = 0,
+	WPA_SETBAND_5G = BIT(0),
+	WPA_SETBAND_2G = BIT(1),
+	WPA_SETBAND_6G = BIT(2),
 };
 
 enum wpa_radio_work_band {
@@ -402,7 +411,8 @@
 enum beacon_rate_type {
 	BEACON_RATE_LEGACY,
 	BEACON_RATE_HT,
-	BEACON_RATE_VHT
+	BEACON_RATE_VHT,
+	BEACON_RATE_HE
 };
 
 enum eap_proxy_sim_state {
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp.c b/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp.c
index 130e62f..880fd81 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp.c
@@ -8,8 +8,6 @@
  */
 
 #include "utils/includes.h"
-#include <openssl/opensslv.h>
-#include <openssl/err.h>
 
 #include "utils/common.h"
 #include "utils/base64.h"
@@ -30,7 +28,9 @@
 static const char * dpp_netrole_str(enum dpp_netrole netrole);
 
 #ifdef CONFIG_TESTING_OPTIONS
-#ifdef CONFIG_DPP2
+#ifdef CONFIG_DPP3
+int dpp_version_override = 3;
+#elif defined(CONFIG_DPP2)
 int dpp_version_override = 2;
 #else
 int dpp_version_override = 1;
@@ -38,21 +38,6 @@
 enum dpp_test_behavior dpp_test = DPP_TEST_DISABLED;
 #endif /* CONFIG_TESTING_OPTIONS */
 
-#if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && \
-	LIBRESSL_VERSION_NUMBER < 0x20700000L)
-/* Compatibility wrappers for older versions. */
-
-#ifdef CONFIG_DPP2
-static EC_KEY * EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
-{
-	if (pkey->type != EVP_PKEY_EC)
-		return NULL;
-	return pkey->pkey.ec;
-}
-#endif /* CONFIG_DPP2 */
-
-#endif
-
 
 void dpp_auth_fail(struct dpp_authentication *auth, const char *txt)
 {
@@ -179,7 +164,7 @@
 	os_free(info->info);
 	os_free(info->chan);
 	os_free(info->pk);
-	EVP_PKEY_free(info->pubkey);
+	crypto_ec_key_deinit(info->pubkey);
 	str_clear_free(info->configurator_params);
 	os_free(info);
 }
@@ -323,6 +308,8 @@
 		bi->version = 1;
 	else if (*version == '2')
 		bi->version = 2;
+	else if (*version == '3')
+		bi->version = 3;
 	else
 		wpa_printf(MSG_DEBUG, "DPP: Unknown URI version");
 
@@ -645,7 +632,8 @@
 		    macstr,
 		    bi->info ? "I:" : "", bi->info ? bi->info : "",
 		    bi->info ? ";" : "",
-		    DPP_VERSION == 2 ? "V:2;" : "",
+		    DPP_VERSION == 3 ? "V:3;" :
+		    (DPP_VERSION == 2 ? "V:2;" : ""),
 		    bi->pk);
 	return 0;
 }
@@ -1278,9 +1266,9 @@
 	dpp_configuration_free(auth->conf2_ap);
 	dpp_configuration_free(auth->conf_sta);
 	dpp_configuration_free(auth->conf2_sta);
-	EVP_PKEY_free(auth->own_protocol_key);
-	EVP_PKEY_free(auth->peer_protocol_key);
-	EVP_PKEY_free(auth->reconfig_old_protocol_key);
+	crypto_ec_key_deinit(auth->own_protocol_key);
+	crypto_ec_key_deinit(auth->peer_protocol_key);
+	crypto_ec_key_deinit(auth->reconfig_old_protocol_key);
 	wpabuf_free(auth->req_msg);
 	wpabuf_free(auth->resp_msg);
 	wpabuf_free(auth->conf_req);
@@ -1370,14 +1358,15 @@
 }
 
 
-int dpp_build_jwk(struct wpabuf *buf, const char *name, EVP_PKEY *key,
-		  const char *kid, const struct dpp_curve_params *curve)
+int dpp_build_jwk(struct wpabuf *buf, const char *name,
+		  struct crypto_ec_key *key, const char *kid,
+		  const struct dpp_curve_params *curve)
 {
 	struct wpabuf *pub;
 	const u8 *pos;
 	int ret = -1;
 
-	pub = dpp_get_pubkey_point(key, 0);
+	pub = crypto_ec_key_get_pubkey_point(key, 0);
 	if (!pub)
 		goto fail;
 
@@ -1526,6 +1515,10 @@
 		json_value_sep(dppcon);
 		json_add_string(dppcon, "expiry", expiry);
 	}
+#ifdef CONFIG_DPP3
+	json_value_sep(dppcon);
+	json_add_int(dppcon, "version", auth->peer_version);
+#endif /* CONFIG_DPP3 */
 	json_end_object(dppcon);
 	wpa_printf(MSG_DEBUG, "DPP: dppCon: %s",
 		   (const char *) wpabuf_head(dppcon));
@@ -2170,14 +2163,13 @@
 }
 
 
-EVP_PKEY * dpp_parse_jwk(struct json_token *jwk,
-			 const struct dpp_curve_params **key_curve)
+struct crypto_ec_key * dpp_parse_jwk(struct json_token *jwk,
+				     const struct dpp_curve_params **key_curve)
 {
 	struct json_token *token;
 	const struct dpp_curve_params *curve;
 	struct wpabuf *x = NULL, *y = NULL;
-	EC_GROUP *group;
-	EVP_PKEY *pkey = NULL;
+	struct crypto_ec_key *key = NULL;
 
 	token = json_get_member(jwk, "kty");
 	if (!token || token->type != JSON_STRING) {
@@ -2230,22 +2222,18 @@
 		goto fail;
 	}
 
-	group = EC_GROUP_new_by_curve_name(OBJ_txt2nid(curve->name));
-	if (!group) {
-		wpa_printf(MSG_DEBUG, "DPP: Could not prepare group for JWK");
+	key = crypto_ec_key_set_pub(curve->ike_group, wpabuf_head(x),
+				    wpabuf_head(y), wpabuf_len(x));
+	if (!key)
 		goto fail;
-	}
 
-	pkey = dpp_set_pubkey_point_group(group, wpabuf_head(x), wpabuf_head(y),
-					  wpabuf_len(x));
-	EC_GROUP_free(group);
 	*key_curve = curve;
 
 fail:
 	wpabuf_free(x);
 	wpabuf_free(y);
 
-	return pkey;
+	return key;
 }
 
 
@@ -2335,7 +2323,7 @@
 {
 	struct json_token *root, *groups, *netkey, *token;
 	int ret = -1;
-	EVP_PKEY *key = NULL;
+	struct crypto_ec_key *key = NULL;
 	const struct dpp_curve_params *curve;
 	unsigned int rules = 0;
 
@@ -2402,7 +2390,7 @@
 		goto fail;
 	dpp_debug_print_key("DPP: Received netAccessKey", key);
 
-	if (EVP_PKEY_cmp(key, auth->own_protocol_key) != 1) {
+	if (crypto_ec_key_cmp(key, auth->own_protocol_key)) {
 		wpa_printf(MSG_DEBUG,
 			   "DPP: netAccessKey in connector does not match own protocol key");
 #ifdef CONFIG_TESTING_OPTIONS
@@ -2419,47 +2407,45 @@
 
 	ret = 0;
 fail:
-	EVP_PKEY_free(key);
+	crypto_ec_key_deinit(key);
 	json_free(root);
 	return ret;
 }
 
 
-static void dpp_copy_csign(struct dpp_config_obj *conf, EVP_PKEY *csign)
+static void dpp_copy_csign(struct dpp_config_obj *conf,
+			   struct crypto_ec_key *csign)
 {
-	unsigned char *der = NULL;
-	int der_len;
+	struct wpabuf *c_sign_key;
 
-	der_len = i2d_PUBKEY(csign, &der);
-	if (der_len <= 0)
+	c_sign_key = crypto_ec_key_get_subject_public_key(csign);
+	if (!c_sign_key)
 		return;
+
 	wpabuf_free(conf->c_sign_key);
-	conf->c_sign_key = wpabuf_alloc_copy(der, der_len);
-	OPENSSL_free(der);
+	conf->c_sign_key = c_sign_key;
 }
 
 
-static void dpp_copy_ppkey(struct dpp_config_obj *conf, EVP_PKEY *ppkey)
+static void dpp_copy_ppkey(struct dpp_config_obj *conf,
+			   struct crypto_ec_key *ppkey)
 {
-	unsigned char *der = NULL;
-	int der_len;
+	struct wpabuf *pp_key;
 
-	der_len = i2d_PUBKEY(ppkey, &der);
-	if (der_len <= 0)
+	pp_key = crypto_ec_key_get_subject_public_key(ppkey);
+	if (!pp_key)
 		return;
+
 	wpabuf_free(conf->pp_key);
-	conf->pp_key = wpabuf_alloc_copy(der, der_len);
-	OPENSSL_free(der);
+	conf->pp_key = pp_key;
 }
 
 
 static void dpp_copy_netaccesskey(struct dpp_authentication *auth,
 				  struct dpp_config_obj *conf)
 {
-	unsigned char *der = NULL;
-	int der_len;
-	EC_KEY *eckey;
-	EVP_PKEY *own_key;
+	struct wpabuf *net_access_key;
+	struct crypto_ec_key *own_key;
 
 	own_key = auth->own_protocol_key;
 #ifdef CONFIG_DPP2
@@ -2467,19 +2453,13 @@
 	    auth->reconfig_old_protocol_key)
 		own_key = auth->reconfig_old_protocol_key;
 #endif /* CONFIG_DPP2 */
-	eckey = EVP_PKEY_get1_EC_KEY(own_key);
-	if (!eckey)
+
+	net_access_key = crypto_ec_key_get_ecprivate_key(own_key, true);
+	if (!net_access_key)
 		return;
 
-	der_len = i2d_ECPrivateKey(eckey, &der);
-	if (der_len <= 0) {
-		EC_KEY_free(eckey);
-		return;
-	}
 	wpabuf_free(auth->net_access_key);
-	auth->net_access_key = wpabuf_alloc_copy(der, der_len);
-	OPENSSL_free(der);
-	EC_KEY_free(eckey);
+	auth->net_access_key = net_access_key;
 }
 
 
@@ -2490,7 +2470,7 @@
 	struct dpp_signed_connector_info info;
 	struct json_token *token, *csign, *ppkey;
 	int ret = -1;
-	EVP_PKEY *csign_pub = NULL, *pp_pub = NULL;
+	struct crypto_ec_key *csign_pub = NULL, *pp_pub = NULL;
 	const struct dpp_curve_params *key_curve = NULL, *pp_curve = NULL;
 	const char *signed_connector;
 
@@ -2570,8 +2550,8 @@
 
 	ret = 0;
 fail:
-	EVP_PKEY_free(csign_pub);
-	EVP_PKEY_free(pp_pub);
+	crypto_ec_key_deinit(csign_pub);
+	crypto_ec_key_deinit(pp_pub);
 	os_free(info.payload);
 	return ret;
 }
@@ -2596,7 +2576,7 @@
 		return -1;
 	}
 	wpa_hexdump_buf(MSG_MSGDUMP, "DPP: Received certBag", conf->certbag);
-	conf->certs = dpp_pkcs7_certs(conf->certbag);
+	conf->certs = crypto_pkcs7_get_certificates(conf->certbag);
 	if (!conf->certs) {
 		dpp_auth_fail(auth, "No certificates in certBag");
 		return -1;
@@ -3404,11 +3384,11 @@
 {
 	if (!conf)
 		return;
-	EVP_PKEY_free(conf->csign);
+	crypto_ec_key_deinit(conf->csign);
 	os_free(conf->kid);
 	os_free(conf->connector);
-	EVP_PKEY_free(conf->connector_key);
-	EVP_PKEY_free(conf->pp_key);
+	crypto_ec_key_deinit(conf->connector_key);
+	crypto_ec_key_deinit(conf->pp_key);
 	os_free(conf);
 }
 
@@ -3416,23 +3396,19 @@
 int dpp_configurator_get_key(const struct dpp_configurator *conf, char *buf,
 			     size_t buflen)
 {
-	EC_KEY *eckey;
-	int key_len, ret = -1;
-	unsigned char *key = NULL;
+	struct wpabuf *key;
+	int ret = -1;
 
 	if (!conf->csign)
 		return -1;
 
-	eckey = EVP_PKEY_get1_EC_KEY(conf->csign);
-	if (!eckey)
+	key = crypto_ec_key_get_ecprivate_key(conf->csign, true);
+	if (!key)
 		return -1;
 
-	key_len = i2d_ECPrivateKey(eckey, &key);
-	if (key_len > 0)
-		ret = wpa_snprintf_hex(buf, buflen, key, key_len);
+	ret = wpa_snprintf_hex(buf, buflen, wpabuf_head(key), wpabuf_len(key));
 
-	EC_KEY_free(eckey);
-	OPENSSL_free(key);
+	wpabuf_clear_free(key);
 	return ret;
 }
 
@@ -3444,7 +3420,7 @@
 	size_t len[1];
 	int res;
 
-	csign_pub = dpp_get_pubkey_point(conf->csign, 1);
+	csign_pub = crypto_ec_key_get_pubkey_point(conf->csign, 1);
 	if (!csign_pub) {
 		wpa_printf(MSG_INFO, "DPP: Failed to extract C-sign-key");
 		return -1;
@@ -3680,7 +3656,7 @@
 	struct json_token *root = NULL, *netkey, *token;
 	struct json_token *own_root = NULL;
 	enum dpp_status_error ret = 255, res;
-	EVP_PKEY *own_key = NULL, *peer_key = NULL;
+	struct crypto_ec_key *own_key = NULL, *peer_key = NULL;
 	struct wpabuf *own_key_pub = NULL;
 	const struct dpp_curve_params *curve, *own_curve;
 	struct dpp_signed_connector_info info;
@@ -3738,6 +3714,14 @@
 		}
 	}
 
+#ifdef CONFIG_DPP3
+	token = json_get_member(root, "version");
+	if (token && token->type == JSON_NUMBER) {
+		wpa_printf(MSG_DEBUG, "DPP: version = %d", token->number);
+		intro->peer_version = token->number;
+	}
+#endif /* CONFIG_DPP3 */
+
 	netkey = json_get_member(root, "netAccessKey");
 	if (!netkey || netkey->type != JSON_OBJECT) {
 		wpa_printf(MSG_DEBUG, "DPP: No netAccessKey object found");
@@ -3786,15 +3770,35 @@
 		os_memset(intro, 0, sizeof(*intro));
 	os_memset(Nx, 0, sizeof(Nx));
 	os_free(info.payload);
-	EVP_PKEY_free(own_key);
+	crypto_ec_key_deinit(own_key);
 	wpabuf_free(own_key_pub);
-	EVP_PKEY_free(peer_key);
+	crypto_ec_key_deinit(peer_key);
 	json_free(root);
 	json_free(own_root);
 	return ret;
 }
 
 
+#ifdef CONFIG_DPP3
+int dpp_get_connector_version(const char *connector)
+{
+	struct json_token *root, *token;
+	int ver = -1;
+
+	root = dpp_parse_own_connector(connector);
+	if (!root)
+		return -1;
+
+	token = json_get_member(root, "version");
+	if (token && token->type == JSON_NUMBER)
+		ver = token->number;
+
+	json_free(root);
+	return ver;
+}
+#endif /* CONFIG_DPP3 */
+
+
 unsigned int dpp_next_id(struct dpp_global *dpp)
 {
 	struct dpp_bootstrap_info *bi;
@@ -4139,7 +4143,7 @@
 	wpa_printf(MSG_DEBUG,
 		   "DPP: Update own bootstrapping key to match peer curve from NFC handover");
 
-	EVP_PKEY_free(own_bi->pubkey);
+	crypto_ec_key_deinit(own_bi->pubkey);
 	own_bi->pubkey = NULL;
 
 	if (dpp_keygen(own_bi, peer_bi->curve->name, NULL, 0) < 0 ||
@@ -4285,33 +4289,24 @@
 				 struct dpp_asymmetric_key *key)
 {
 	struct dpp_configurator *conf;
-	const EC_KEY *eckey, *eckey_pp;
-	const EC_GROUP *group, *group_pp;
-	int nid;
-	const struct dpp_curve_params *curve;
+	const struct dpp_curve_params *curve, *curve_pp;
 
 	if (!key->csign || !key->pp_key)
 		return -1;
-	eckey = EVP_PKEY_get0_EC_KEY(key->csign);
-	if (!eckey)
-		return -1;
-	group = EC_KEY_get0_group(eckey);
-	if (!group)
-		return -1;
-	nid = EC_GROUP_get_curve_name(group);
-	curve = dpp_get_curve_nid(nid);
+
+	curve = dpp_get_curve_ike_group(crypto_ec_key_group(key->csign));
 	if (!curve) {
 		wpa_printf(MSG_INFO, "DPP: Unsupported group in c-sign-key");
 		return -1;
 	}
-	eckey_pp = EVP_PKEY_get0_EC_KEY(key->pp_key);
-	if (!eckey_pp)
+
+	curve_pp = dpp_get_curve_ike_group(crypto_ec_key_group(key->pp_key));
+	if (!curve_pp) {
+		wpa_printf(MSG_INFO, "DPP: Unsupported group in ppKey");
 		return -1;
-	group_pp = EC_KEY_get0_group(eckey_pp);
-	if (!group_pp)
-		return -1;
-	if (EC_GROUP_get_curve_name(group) !=
-	    EC_GROUP_get_curve_name(group_pp)) {
+	}
+
+	if (curve != curve_pp) {
 		wpa_printf(MSG_INFO,
 			   "DPP: Mismatch in c-sign-key and ppKey groups");
 		return -1;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp.h b/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp.h
index 2fd331b..8d62a0e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp.h
@@ -11,13 +11,11 @@
 #define DPP_H
 
 #ifdef CONFIG_DPP
-#include <openssl/x509.h>
-
 #include "utils/list.h"
 #include "common/wpa_common.h"
 #include "crypto/sha256.h"
+#include "crypto/crypto.h"
 
-struct crypto_ecdh;
 struct hostapd_ip_addr;
 struct dpp_global;
 struct json_token;
@@ -27,7 +25,9 @@
 #define DPP_VERSION (dpp_version_override)
 extern int dpp_version_override;
 #else /* CONFIG_TESTING_OPTIONS */
-#ifdef CONFIG_DPP2
+#ifdef CONFIG_DPP3
+#define DPP_VERSION 3
+#elif defined(CONFIG_DPP2)
 #define DPP_VERSION 2
 #else
 #define DPP_VERSION 1
@@ -43,7 +43,7 @@
 	DPP_PA_AUTHENTICATION_CONF = 2,
 	DPP_PA_PEER_DISCOVERY_REQ = 5,
 	DPP_PA_PEER_DISCOVERY_RESP = 6,
-	DPP_PA_PKEX_EXCHANGE_REQ = 7,
+	DPP_PA_PKEX_V1_EXCHANGE_REQ = 7,
 	DPP_PA_PKEX_EXCHANGE_RESP = 8,
 	DPP_PA_PKEX_COMMIT_REVEAL_REQ = 9,
 	DPP_PA_PKEX_COMMIT_REVEAL_RESP = 10,
@@ -54,6 +54,7 @@
 	DPP_PA_RECONFIG_AUTH_REQ = 15,
 	DPP_PA_RECONFIG_AUTH_RESP = 16,
 	DPP_PA_RECONFIG_AUTH_CONF = 17,
+	DPP_PA_PKEX_EXCHANGE_REQ = 18,
 };
 
 enum dpp_attribute_id {
@@ -157,7 +158,7 @@
 	bool channels_listed;
 	u8 version;
 	int own;
-	EVP_PKEY *pubkey;
+	struct crypto_ec_key *pubkey;
 	u8 pubkey_hash[SHA256_MAC_LEN];
 	u8 pubkey_hash_chirp[SHA256_MAC_LEN];
 	const struct dpp_curve_params *curve;
@@ -175,23 +176,25 @@
 	unsigned int initiator:1;
 	unsigned int exchange_done:1;
 	unsigned int failed:1;
+	unsigned int v2:1;
 	struct dpp_bootstrap_info *own_bi;
 	u8 own_mac[ETH_ALEN];
 	u8 peer_mac[ETH_ALEN];
 	char *identifier;
 	char *code;
-	EVP_PKEY *x;
-	EVP_PKEY *y;
+	struct crypto_ec_key *x;
+	struct crypto_ec_key *y;
 	u8 Mx[DPP_MAX_SHARED_SECRET_LEN];
 	u8 Nx[DPP_MAX_SHARED_SECRET_LEN];
 	u8 z[DPP_MAX_HASH_LEN];
-	EVP_PKEY *peer_bootstrap_key;
+	struct crypto_ec_key *peer_bootstrap_key;
 	struct wpabuf *exchange_req;
 	struct wpabuf *exchange_resp;
 	unsigned int t; /* number of failures on code use */
 	unsigned int exch_req_wait_time;
 	unsigned int exch_req_tries;
 	unsigned int freq;
+	u8 peer_version;
 };
 
 enum dpp_akm {
@@ -234,8 +237,8 @@
 
 struct dpp_asymmetric_key {
 	struct dpp_asymmetric_key *next;
-	EVP_PKEY *csign;
-	EVP_PKEY *pp_key;
+	struct crypto_ec_key *csign;
+	struct crypto_ec_key *pp_key;
 	char *config_template;
 	char *connector_template;
 };
@@ -266,9 +269,9 @@
 	u8 i_capab;
 	u8 r_capab;
 	enum dpp_netrole e_netrole;
-	EVP_PKEY *own_protocol_key;
-	EVP_PKEY *peer_protocol_key;
-	EVP_PKEY *reconfig_old_protocol_key;
+	struct crypto_ec_key *own_protocol_key;
+	struct crypto_ec_key *peer_protocol_key;
+	struct crypto_ec_key *reconfig_old_protocol_key;
 	struct wpabuf *req_msg;
 	struct wpabuf *resp_msg;
 	struct wpabuf *reconfig_req_msg;
@@ -348,6 +351,7 @@
 	struct wpabuf *cacert;
 	struct wpabuf *certbag;
 	void *cert_resp_ctx;
+	void *gas_server_ctx;
 #ifdef CONFIG_TESTING_OPTIONS
 	char *config_obj_override;
 	char *discovery_override;
@@ -360,19 +364,20 @@
 	struct dl_list list;
 	unsigned int id;
 	int own;
-	EVP_PKEY *csign;
+	struct crypto_ec_key *csign;
 	u8 kid_hash[SHA256_MAC_LEN];
 	char *kid;
 	const struct dpp_curve_params *curve;
 	char *connector; /* own Connector for reconfiguration */
-	EVP_PKEY *connector_key;
-	EVP_PKEY *pp_key;
+	struct crypto_ec_key *connector_key;
+	struct crypto_ec_key *pp_key;
 };
 
 struct dpp_introduction {
 	u8 pmkid[PMKID_LEN];
 	u8 pmk[PMK_LEN_MAX];
 	size_t pmk_len;
+	int peer_version;
 };
 
 struct dpp_relay_config {
@@ -492,6 +497,8 @@
 	DPP_TEST_STOP_AT_AUTH_CONF = 89,
 	DPP_TEST_STOP_AT_CONF_REQ = 90,
 	DPP_TEST_REJECT_CONFIG = 91,
+	DPP_TEST_NO_PROTOCOL_VERSION_PEER_DISC_REQ = 92,
+	DPP_TEST_NO_PROTOCOL_VERSION_PEER_DISC_RESP = 93,
 };
 
 extern enum dpp_test_behavior dpp_test;
@@ -594,17 +601,18 @@
 	       const u8 *csign_key, size_t csign_key_len,
 	       const u8 *peer_connector, size_t peer_connector_len,
 	       os_time_t *expiry);
+int dpp_get_connector_version(const char *connector);
 struct dpp_pkex * dpp_pkex_init(void *msg_ctx, struct dpp_bootstrap_info *bi,
 				const u8 *own_mac,
-				const char *identifier,
-				const char *code);
+				const char *identifier, const char *code,
+				bool v2);
 struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx,
 					   struct dpp_bootstrap_info *bi,
 					   const u8 *own_mac,
 					   const u8 *peer_mac,
 					   const char *identifier,
 					   const char *code,
-					   const u8 *buf, size_t len);
+					   const u8 *buf, size_t len, bool v2);
 struct wpabuf * dpp_pkex_rx_exchange_resp(struct dpp_pkex *pkex,
 					  const u8 *peer_mac,
 					  const u8 *buf, size_t len);
@@ -632,7 +640,6 @@
 
 struct wpabuf * dpp_build_csr(struct dpp_authentication *auth,
 			      const char *name);
-struct wpabuf * dpp_pkcs7_certs(const struct wpabuf *pkcs7);
 int dpp_validate_csr(struct dpp_authentication *auth, const struct wpabuf *csr);
 
 struct dpp_bootstrap_info * dpp_add_qr_code(struct dpp_global *dpp,
@@ -668,12 +675,14 @@
 			     struct dpp_relay_config *config);
 int dpp_relay_rx_action(struct dpp_global *dpp, const u8 *src, const u8 *hdr,
 			const u8 *buf, size_t len, unsigned int freq,
-			const u8 *i_bootstrap, const u8 *r_bootstrap);
+			const u8 *i_bootstrap, const u8 *r_bootstrap,
+			void *cb_ctx);
 int dpp_relay_rx_gas_req(struct dpp_global *dpp, const u8 *src, const u8 *data,
 			 size_t data_len);
 int dpp_controller_start(struct dpp_global *dpp,
 			 struct dpp_controller_config *config);
 void dpp_controller_stop(struct dpp_global *dpp);
+void dpp_controller_stop_for_ctx(struct dpp_global *dpp, void *cb_ctx);
 struct dpp_authentication * dpp_controller_get_auth(struct dpp_global *dpp,
 						    unsigned int id);
 void dpp_controller_new_qr_code(struct dpp_global *dpp,
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_auth.c b/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_auth.c
index f79cfef..f81f1ee 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_auth.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_auth.c
@@ -251,6 +251,7 @@
 	u8 *attr_start, *attr_end, *pos;
 
 	auth->waiting_auth_conf = 1;
+	auth->auth_resp_status = status;
 	auth->auth_resp_tries = 0;
 
 	/* Build DPP Authentication Response frame attributes */
@@ -455,7 +456,7 @@
 #endif /* CONFIG_TESTING_OPTIONS */
 	wpa_hexdump(MSG_DEBUG, "DPP: R-nonce", auth->r_nonce, nonce_len);
 
-	EVP_PKEY_free(auth->own_protocol_key);
+	crypto_ec_key_deinit(auth->own_protocol_key);
 #ifdef CONFIG_TESTING_OPTIONS
 	if (dpp_protocol_key_override_len) {
 		const struct dpp_curve_params *tmp_curve;
@@ -474,7 +475,7 @@
 	if (!auth->own_protocol_key)
 		goto fail;
 
-	pr = dpp_get_pubkey_point(auth->own_protocol_key, 0);
+	pr = crypto_ec_key_get_pubkey_point(auth->own_protocol_key, 0);
 	if (!pr)
 		goto fail;
 
@@ -670,8 +671,7 @@
 		unsigned int freq, const u8 *hdr, const u8 *attr_start,
 		size_t attr_len)
 {
-	EVP_PKEY *pi = NULL;
-	EVP_PKEY_CTX *ctx = NULL;
+	struct crypto_ec_key *pi = NULL;
 	size_t secret_len;
 	const u8 *addr[2];
 	size_t len[2];
@@ -927,8 +927,7 @@
 	return auth;
 fail:
 	bin_clear_free(unwrapped, unwrapped_len);
-	EVP_PKEY_free(pi);
-	EVP_PKEY_CTX_free(ctx);
+	crypto_ec_key_deinit(pi);
 	dpp_auth_deinit(auth);
 	return NULL;
 }
@@ -1234,7 +1233,7 @@
 	if (!auth->own_protocol_key)
 		goto fail;
 
-	pi = dpp_get_pubkey_point(auth->own_protocol_key, 0);
+	pi = crypto_ec_key_get_pubkey_point(auth->own_protocol_key, 0);
 	if (!pi)
 		goto fail;
 
@@ -1404,7 +1403,7 @@
 dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *hdr,
 		 const u8 *attr_start, size_t attr_len)
 {
-	EVP_PKEY *pr;
+	struct crypto_ec_key *pr;
 	size_t secret_len;
 	const u8 *addr[2];
 	size_t len[2];
@@ -1566,7 +1565,7 @@
 		dpp_auth_fail(auth, "Failed to derive ECDH shared secret");
 		goto fail;
 	}
-	EVP_PKEY_free(auth->peer_protocol_key);
+	crypto_ec_key_deinit(auth->peer_protocol_key);
 	auth->peer_protocol_key = pr;
 	pr = NULL;
 
@@ -1736,7 +1735,7 @@
 fail:
 	bin_clear_free(unwrapped, unwrapped_len);
 	bin_clear_free(unwrapped2, unwrapped2_len);
-	EVP_PKEY_free(pr);
+	crypto_ec_key_deinit(pr);
 	return NULL;
 }
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_backup.c b/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_backup.c
index c964811..fb3f776 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_backup.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_backup.c
@@ -7,8 +7,6 @@
  */
 
 #include "utils/includes.h"
-#include <openssl/opensslv.h>
-#include <openssl/err.h>
 
 #include "utils/common.h"
 #include "crypto/aes.h"
@@ -19,27 +17,13 @@
 
 #ifdef CONFIG_DPP2
 
-#if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && \
-	LIBRESSL_VERSION_NUMBER < 0x20700000L)
-/* Compatibility wrappers for older versions. */
-
-static EC_KEY * EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
-{
-	if (pkey->type != EVP_PKEY_EC)
-		return NULL;
-	return pkey->pkey.ec;
-}
-
-#endif
-
-
 void dpp_free_asymmetric_key(struct dpp_asymmetric_key *key)
 {
 	while (key) {
 		struct dpp_asymmetric_key *next = key->next;
 
-		EVP_PKEY_free(key->csign);
-		EVP_PKEY_free(key->pp_key);
+		crypto_ec_key_deinit(key->csign);
+		crypto_ec_key_deinit(key->pp_key);
 		str_clear_free(key->config_template);
 		str_clear_free(key->connector_template);
 		os_free(key);
@@ -55,23 +39,13 @@
 	/* TODO: proper template values */
 	const char *conf_template = "{\"wi-fi_tech\":\"infra\",\"discovery\":{\"ssid\":\"test\"},\"cred\":{\"akm\":\"dpp\"}}";
 	const char *connector_template = NULL;
-	EC_KEY *eckey;
-	unsigned char *der = NULL;
-	int der_len;
 
 	if (!conf->pp_key)
 		return NULL;
-	eckey = EVP_PKEY_get0_EC_KEY(conf->pp_key);
-	if (!eckey)
-		return NULL;
 
-	EC_KEY_set_enc_flags(eckey, EC_PKEY_NO_PUBKEY);
-	der_len = i2d_ECPrivateKey(eckey, &der);
-	if (der_len > 0)
-		priv_key = wpabuf_alloc_copy(der, der_len);
-	OPENSSL_free(der);
+	priv_key = crypto_ec_key_get_ecprivate_key(conf->pp_key, false);
 	if (!priv_key)
-		goto fail;
+		return NULL;
 
 	len = 100 + os_strlen(conf_template);
 	if (connector_template)
@@ -177,20 +151,11 @@
 static struct wpabuf * dpp_build_key_pkg(struct dpp_authentication *auth)
 {
 	struct wpabuf *key = NULL, *attr, *alg, *priv_key = NULL;
-	EC_KEY *eckey;
-	unsigned char *der = NULL;
-	int der_len;
 
-	eckey = EVP_PKEY_get0_EC_KEY(auth->conf->csign);
-	if (!eckey)
+	priv_key = crypto_ec_key_get_ecprivate_key(auth->conf->csign, false);
+	if (!priv_key)
 		return NULL;
 
-	EC_KEY_set_enc_flags(eckey, EC_PKEY_NO_PUBKEY);
-	der_len = i2d_ECPrivateKey(eckey, &der);
-	if (der_len > 0)
-		priv_key = wpabuf_alloc_copy(der, der_len);
-	OPENSSL_free(der);
-
 	alg = dpp_build_key_alg(auth->conf->curve);
 
 	/* Attributes ::= SET OF Attribute { { OneAsymmetricKeyAttributes } } */
@@ -591,11 +556,9 @@
 	 * Shall always use the pwri CHOICE.
 	 */
 
-	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC || hdr.tag != 3) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: Expected CHOICE [3] (pwri) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !hdr.constructed ||
+	    !asn1_is_cs_tag(&hdr, 3)) {
+		asn1_unexpected(&hdr, "DPP: Expected CHOICE [3] (pwri)");
 		return -1;
 	}
 	wpa_hexdump(MSG_MSGDUMP, "DPP: PasswordRecipientInfo",
@@ -628,11 +591,10 @@
 	wpa_hexdump(MSG_MSGDUMP, "DPP: Remaining PasswordRecipientInfo after version",
 		    pos, end - pos);
 
-	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC || hdr.tag != 0) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: Expected keyDerivationAlgorithm [0] - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !hdr.constructed ||
+	    !asn1_is_cs_tag(&hdr, 0)) {
+		asn1_unexpected(&hdr,
+				"DPP: Expected keyDerivationAlgorithm [0]");
 		return -1;
 	}
 	pos = hdr.payload;
@@ -671,11 +633,9 @@
 	pos = hdr.payload;
 
 	if (asn1_get_next(pos, e_end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_OCTETSTRING) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: Expected OCTETSTRING (salt.specified) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_octetstring(&hdr)) {
+		asn1_unexpected(&hdr,
+				"DPP: Expected OCTETSTRING (salt.specified)");
 		return -1;
 	}
 	wpa_hexdump(MSG_MSGDUMP, "DPP: salt.specified",
@@ -751,11 +711,9 @@
 	 * EncryptedKey ::= OCTET STRING
 	 */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_OCTETSTRING) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: Expected OCTETSTRING (pwri.encryptedKey) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_octetstring(&hdr)) {
+		asn1_unexpected(&hdr,
+				"DPP: Expected OCTETSTRING (pwri.encryptedKey)");
 		return -1;
 	}
 	wpa_hexdump(MSG_MSGDUMP, "DPP: pwri.encryptedKey",
@@ -824,11 +782,10 @@
 
 	/* encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL
 	 * EncryptedContent ::= OCTET STRING */
-	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC || hdr.tag != 0) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: Expected [0] IMPLICIT (EncryptedContent) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, end - pos, &hdr) < 0 || hdr.constructed ||
+	    !asn1_is_cs_tag(&hdr, 0)) {
+		asn1_unexpected(&hdr,
+				"DPP: Expected [0] IMPLICIT (EncryptedContent)");
 		return -1;
 	}
 	wpa_hexdump(MSG_MSGDUMP, "DPP: EncryptedContent",
@@ -883,11 +840,9 @@
 		return -1;
 	}
 
-	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_SET) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: Expected SET (RecipientInfos) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !asn1_is_set(&hdr)) {
+		asn1_unexpected(&hdr,
+				"DPP: Expected SET (RecipientInfos)");
 		return -1;
 	}
 
@@ -909,7 +864,6 @@
 	struct asn1_oid oid;
 	char txt[80];
 	struct dpp_asymmetric_key *key;
-	EC_KEY *eckey;
 
 	wpa_hexdump_key(MSG_MSGDUMP, "DPP: OneAsymmetricKey", buf, len);
 
@@ -976,28 +930,17 @@
 	 *    (Contains DER encoding of ECPrivateKey)
 	 */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_OCTETSTRING) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: Expected OCTETSTRING (PrivateKey) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_octetstring(&hdr)) {
+		asn1_unexpected(&hdr,
+				"DPP: Expected OCTETSTRING (PrivateKey)");
 		goto fail;
 	}
 	wpa_hexdump_key(MSG_MSGDUMP, "DPP: PrivateKey",
 			hdr.payload, hdr.length);
 	pos = hdr.payload + hdr.length;
-	eckey = d2i_ECPrivateKey(NULL, &hdr.payload, hdr.length);
-	if (!eckey) {
-		wpa_printf(MSG_INFO,
-			   "DPP: OpenSSL: d2i_ECPrivateKey() failed: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
+	key->csign = crypto_ec_key_parse_priv(hdr.payload, hdr.length);
+	if (!key->csign)
 		goto fail;
-	}
-	key->csign = EVP_PKEY_new();
-	if (!key->csign || EVP_PKEY_assign_EC_KEY(key->csign, eckey) != 1) {
-		EC_KEY_free(eckey);
-		goto fail;
-	}
 	if (wpa_debug_show_keys)
 		dpp_debug_print_key("DPP: Received c-sign-key", key->csign);
 
@@ -1006,11 +949,9 @@
 	 *
 	 * Exactly one instance of type Attribute in OneAsymmetricKey.
 	 */
-	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC || hdr.tag != 0) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: Expected [0] Attributes - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !hdr.constructed ||
+	    !asn1_is_cs_tag(&hdr, 0)) {
+		asn1_unexpected(&hdr, "DPP: Expected [0] Attributes");
 		goto fail;
 	}
 	wpa_hexdump_key(MSG_MSGDUMP, "DPP: Attributes",
@@ -1024,11 +965,8 @@
 	pos = hdr.payload;
 	end = hdr.payload + hdr.length;
 
-	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_SET) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: Expected SET (Attributes) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !asn1_is_set(&hdr)) {
+		asn1_unexpected(&hdr, "DPP: Expected SET (Attributes)");
 		goto fail;
 	}
 	if (hdr.payload + hdr.length < end) {
@@ -1074,11 +1012,8 @@
 		goto fail;
 	}
 
-	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_SET) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: Expected SET (Attribute) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !asn1_is_set(&hdr)) {
+		asn1_unexpected(&hdr, "DPP: Expected SET (Attribute)");
 		goto fail;
 	}
 	pos = hdr.payload;
@@ -1108,38 +1043,24 @@
 	 *    (Contains DER encoding of ECPrivateKey)
 	 */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_OCTETSTRING) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: Expected OCTETSTRING (PrivateKey) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_octetstring(&hdr)) {
+		asn1_unexpected(&hdr, "DPP: Expected OCTETSTRING (PrivateKey)");
 		goto fail;
 	}
 	wpa_hexdump_key(MSG_MSGDUMP, "DPP: privacyProtectionKey",
 			hdr.payload, hdr.length);
 	pos = hdr.payload + hdr.length;
-	eckey = d2i_ECPrivateKey(NULL, &hdr.payload, hdr.length);
-	if (!eckey) {
-		wpa_printf(MSG_INFO,
-			   "DPP: OpenSSL: d2i_ECPrivateKey() failed: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
+	key->pp_key = crypto_ec_key_parse_priv(hdr.payload, hdr.length);
+	if (!key->pp_key)
 		goto fail;
-	}
-	key->pp_key = EVP_PKEY_new();
-	if (!key->pp_key || EVP_PKEY_assign_EC_KEY(key->pp_key, eckey) != 1) {
-		EC_KEY_free(eckey);
-		goto fail;
-	}
 	if (wpa_debug_show_keys)
 		dpp_debug_print_key("DPP: Received privacyProtectionKey",
 				    key->pp_key);
 
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_UTF8STRING) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: Expected UTF8STRING (configurationTemplate) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_utf8string(&hdr)) {
+		asn1_unexpected(&hdr,
+				"DPP: Expected UTF8STRING (configurationTemplate)");
 		goto fail;
 	}
 	wpa_hexdump_ascii_key(MSG_MSGDUMP, "DPP: configurationTemplate",
@@ -1153,11 +1074,9 @@
 
 	if (pos < end) {
 		if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-		    hdr.class != ASN1_CLASS_UNIVERSAL ||
-		    hdr.tag != ASN1_TAG_UTF8STRING) {
-			wpa_printf(MSG_DEBUG,
-				   "DPP: Expected UTF8STRING (connectorTemplate) - found class %d tag 0x%x",
-				   hdr.class, hdr.tag);
+		    !asn1_is_utf8string(&hdr)) {
+			asn1_unexpected(&hdr,
+					"DPP: Expected UTF8STRING (connectorTemplate)");
 			goto fail;
 		}
 		wpa_hexdump_ascii_key(MSG_MSGDUMP, "DPP: connectorTemplate",
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_crypto.c b/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_crypto.c
index f3434a9..300416f 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_crypto.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_crypto.c
@@ -8,11 +8,6 @@
  */
 
 #include "utils/includes.h"
-#include <openssl/opensslv.h>
-#include <openssl/err.h>
-#include <openssl/asn1.h>
-#include <openssl/asn1t.h>
-#include <openssl/pem.h>
 
 #include "utils/common.h"
 #include "utils/base64.h"
@@ -22,43 +17,11 @@
 #include "crypto/random.h"
 #include "crypto/sha384.h"
 #include "crypto/sha512.h"
+#include "tls/asn1.h"
 #include "dpp.h"
 #include "dpp_i.h"
 
 
-#if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && \
-	LIBRESSL_VERSION_NUMBER < 0x20700000L)
-/* Compatibility wrappers for older versions. */
-
-static int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
-{
-	sig->r = r;
-	sig->s = s;
-	return 1;
-}
-
-
-static void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr,
-			   const BIGNUM **ps)
-{
-	if (pr)
-		*pr = sig->r;
-	if (ps)
-		*ps = sig->s;
-}
-
-
-#ifndef ABOVE_8_1
-static EC_KEY * EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
-{
-	if (pkey->type != EVP_PKEY_EC)
-		return NULL;
-	return pkey->pkey.ec;
-}
-#endif /* ABOVE_8_1 */
-
-#endif
-
 static const struct dpp_curve_params dpp_curves[] = {
 	/* The mandatory to support and the default NIST P-256 curve needs to
 	 * be the first entry on this list. */
@@ -102,36 +65,6 @@
 }
 
 
-static const struct dpp_curve_params *
-dpp_get_curve_oid(const ASN1_OBJECT *poid)
-{
-	ASN1_OBJECT *oid;
-	int i;
-
-	for (i = 0; dpp_curves[i].name; i++) {
-		oid = OBJ_txt2obj(dpp_curves[i].name, 0);
-		if (oid && OBJ_cmp(poid, oid) == 0)
-			return &dpp_curves[i];
-	}
-	return NULL;
-}
-
-
-const struct dpp_curve_params * dpp_get_curve_nid(int nid)
-{
-	int i, tmp;
-
-	if (!nid)
-		return NULL;
-	for (i = 0; dpp_curves[i].name; i++) {
-		tmp = OBJ_txt2nid(dpp_curves[i].name);
-		if (tmp == nid)
-			return &dpp_curves[i];
-	}
-	return NULL;
-}
-
-
 const struct dpp_curve_params * dpp_get_curve_ike_group(u16 group)
 {
 	int i;
@@ -144,90 +77,22 @@
 }
 
 
-void dpp_debug_print_point(const char *title, const EC_GROUP *group,
-			   const EC_POINT *point)
+void dpp_debug_print_key(const char *title, struct crypto_ec_key *key)
 {
-	BIGNUM *x, *y;
-	BN_CTX *ctx;
-	char *x_str = NULL, *y_str = NULL;
+	struct wpabuf *der = NULL;
 
-	if (!wpa_debug_show_keys)
-		return;
+	crypto_ec_key_debug_print(key, title);
 
-	ctx = BN_CTX_new();
-	x = BN_new();
-	y = BN_new();
-	if (!ctx || !x || !y ||
-	    EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx) != 1)
-		goto fail;
-
-	x_str = BN_bn2hex(x);
-	y_str = BN_bn2hex(y);
-	if (!x_str || !y_str)
-		goto fail;
-
-	wpa_printf(MSG_DEBUG, "%s (%s,%s)", title, x_str, y_str);
-
-fail:
-	OPENSSL_free(x_str);
-	OPENSSL_free(y_str);
-	BN_free(x);
-	BN_free(y);
-	BN_CTX_free(ctx);
-}
-
-
-void dpp_debug_print_key(const char *title, EVP_PKEY *key)
-{
-	EC_KEY *eckey;
-	BIO *out;
-	size_t rlen;
-	char *txt;
-	int res;
-	unsigned char *der = NULL;
-	int der_len;
-	const EC_GROUP *group;
-	const EC_POINT *point;
-
-	out = BIO_new(BIO_s_mem());
-	if (!out)
-		return;
-
-	EVP_PKEY_print_private(out, key, 0, NULL);
-	rlen = BIO_ctrl_pending(out);
-	txt = os_malloc(rlen + 1);
-	if (txt) {
-		res = BIO_read(out, txt, rlen);
-		if (res > 0) {
-			txt[res] = '\0';
-			wpa_printf(MSG_DEBUG, "%s: %s", title, txt);
-		}
-		os_free(txt);
-	}
-	BIO_free(out);
-
-	eckey = EVP_PKEY_get1_EC_KEY(key);
-	if (!eckey)
-		return;
-
-	group = EC_KEY_get0_group(eckey);
-	point = EC_KEY_get0_public_key(eckey);
-	if (group && point)
-		dpp_debug_print_point(title, group, point);
-
-	der_len = i2d_ECPrivateKey(eckey, &der);
-	if (der_len > 0)
-		wpa_hexdump_key(MSG_DEBUG, "DPP: ECPrivateKey", der, der_len);
-	OPENSSL_free(der);
-	if (der_len <= 0) {
-		der = NULL;
-		der_len = i2d_EC_PUBKEY(eckey, &der);
-		if (der_len > 0)
-			wpa_hexdump(MSG_DEBUG, "DPP: EC_PUBKEY", der, der_len);
-		OPENSSL_free(der);
+	der = crypto_ec_key_get_ecprivate_key(key, true);
+	if (der) {
+		wpa_hexdump_buf_key(MSG_DEBUG, "DPP: ECPrivateKey", der);
+	} else {
+		der = crypto_ec_key_get_subject_public_key(key);
+		if (der)
+			wpa_hexdump_buf_key(MSG_DEBUG, "DPP: EC_PUBKEY", der);
 	}
 
-	EC_KEY_free(eckey);
+	wpabuf_clear_free(der);
 }
 
 
@@ -364,336 +229,65 @@
 #endif /* CONFIG_DPP2 */
 
 
-int dpp_bn2bin_pad(const BIGNUM *bn, u8 *pos, size_t len)
+struct crypto_ec_key * dpp_set_pubkey_point(struct crypto_ec_key *group_key,
+					    const u8 *buf, size_t len)
 {
-	int num_bytes, offset;
-
-	num_bytes = BN_num_bytes(bn);
-	if ((size_t) num_bytes > len)
-		return -1;
-	offset = len - num_bytes;
-	os_memset(pos, 0, offset);
-	BN_bn2bin(bn, pos + offset);
-	return 0;
-}
-
-
-struct wpabuf * dpp_get_pubkey_point(EVP_PKEY *pkey, int prefix)
-{
-	int len, res;
-	EC_KEY *eckey;
-	struct wpabuf *buf;
-	unsigned char *pos;
-
-	eckey = EVP_PKEY_get1_EC_KEY(pkey);
-	if (!eckey)
-		return NULL;
-	EC_KEY_set_conv_form(eckey, POINT_CONVERSION_UNCOMPRESSED);
-	len = i2o_ECPublicKey(eckey, NULL);
-	if (len <= 0) {
-		wpa_printf(MSG_ERROR,
-			   "DDP: Failed to determine public key encoding length");
-		EC_KEY_free(eckey);
-		return NULL;
-	}
-
-	buf = wpabuf_alloc(len);
-	if (!buf) {
-		EC_KEY_free(eckey);
-		return NULL;
-	}
-
-	pos = wpabuf_put(buf, len);
-	res = i2o_ECPublicKey(eckey, &pos);
-	EC_KEY_free(eckey);
-	if (res != len) {
-		wpa_printf(MSG_ERROR,
-			   "DDP: Failed to encode public key (res=%d/%d)",
-			   res, len);
-		wpabuf_free(buf);
-		return NULL;
-	}
-
-	if (!prefix) {
-		/* Remove 0x04 prefix to match DPP definition */
-		pos = wpabuf_mhead(buf);
-		os_memmove(pos, pos + 1, len - 1);
-		buf->used--;
-	}
-
-	return buf;
-}
-
-
-EVP_PKEY * dpp_set_pubkey_point_group(const EC_GROUP *group,
-				      const u8 *buf_x, const u8 *buf_y,
-				      size_t len)
-{
-	EC_KEY *eckey = NULL;
-	BN_CTX *ctx;
-	EC_POINT *point = NULL;
-	BIGNUM *x = NULL, *y = NULL;
-	EVP_PKEY *pkey = NULL;
-
-	ctx = BN_CTX_new();
-	if (!ctx) {
-		wpa_printf(MSG_ERROR, "DPP: Out of memory");
-		return NULL;
-	}
-
-	point = EC_POINT_new(group);
-	x = BN_bin2bn(buf_x, len, NULL);
-	y = BN_bin2bn(buf_y, len, NULL);
-	if (!point || !x || !y) {
-		wpa_printf(MSG_ERROR, "DPP: Out of memory");
-		goto fail;
-	}
-
-	if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) {
-		wpa_printf(MSG_ERROR,
-			   "DPP: OpenSSL: EC_POINT_set_affine_coordinates_GFp failed: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
-		goto fail;
-	}
-
-	if (!EC_POINT_is_on_curve(group, point, ctx) ||
-	    EC_POINT_is_at_infinity(group, point)) {
-		wpa_printf(MSG_ERROR, "DPP: Invalid point");
-		goto fail;
-	}
-	dpp_debug_print_point("DPP: dpp_set_pubkey_point_group", group, point);
-
-	eckey = EC_KEY_new();
-	if (!eckey ||
-	    EC_KEY_set_group(eckey, group) != 1 ||
-	    EC_KEY_set_public_key(eckey, point) != 1) {
-		wpa_printf(MSG_ERROR,
-			   "DPP: Failed to set EC_KEY: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
-		goto fail;
-	}
-	EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE);
-
-	pkey = EVP_PKEY_new();
-	if (!pkey || EVP_PKEY_set1_EC_KEY(pkey, eckey) != 1) {
-		wpa_printf(MSG_ERROR, "DPP: Could not create EVP_PKEY");
-		goto fail;
-	}
-
-out:
-	BN_free(x);
-	BN_free(y);
-	EC_KEY_free(eckey);
-	EC_POINT_free(point);
-	BN_CTX_free(ctx);
-	return pkey;
-fail:
-	EVP_PKEY_free(pkey);
-	pkey = NULL;
-	goto out;
-}
-
-
-EVP_PKEY * dpp_set_pubkey_point(EVP_PKEY *group_key, const u8 *buf, size_t len)
-{
-	const EC_KEY *eckey;
-	const EC_GROUP *group;
-	EVP_PKEY *pkey = NULL;
+	int ike_group = crypto_ec_key_group(group_key);
 
 	if (len & 1)
 		return NULL;
 
-	eckey = EVP_PKEY_get0_EC_KEY(group_key);
-	if (!eckey) {
-		wpa_printf(MSG_ERROR,
-			   "DPP: Could not get EC_KEY from group_key");
+	if (ike_group < 0) {
+		wpa_printf(MSG_ERROR, "DPP: Could not get EC group");
 		return NULL;
 	}
 
-	group = EC_KEY_get0_group(eckey);
-	if (group)
-		pkey = dpp_set_pubkey_point_group(group, buf, buf + len / 2,
-						  len / 2);
-	else
-		wpa_printf(MSG_ERROR, "DPP: Could not get EC group");
-
-	return pkey;
+	return crypto_ec_key_set_pub(ike_group, buf, buf + len / 2, len / 2);
 }
 
 
-EVP_PKEY * dpp_gen_keypair(const struct dpp_curve_params *curve)
+struct crypto_ec_key * dpp_gen_keypair(const struct dpp_curve_params *curve)
 {
-	EVP_PKEY_CTX *kctx = NULL;
-	EC_KEY *ec_params = NULL;
-	EVP_PKEY *params = NULL, *key = NULL;
-	int nid;
+	struct crypto_ec_key *key;
 
 	wpa_printf(MSG_DEBUG, "DPP: Generating a keypair");
 
-	nid = OBJ_txt2nid(curve->name);
-	if (nid == NID_undef) {
-		wpa_printf(MSG_INFO, "DPP: Unsupported curve %s", curve->name);
-		return NULL;
-	}
+	key = crypto_ec_key_gen(curve->ike_group);
+	if (key && wpa_debug_show_keys)
+	    dpp_debug_print_key("Own generated key", key);
 
-	ec_params = EC_KEY_new_by_curve_name(nid);
-	if (!ec_params) {
-		wpa_printf(MSG_ERROR,
-			   "DPP: Failed to generate EC_KEY parameters");
-		goto fail;
-	}
-	EC_KEY_set_asn1_flag(ec_params, OPENSSL_EC_NAMED_CURVE);
-	params = EVP_PKEY_new();
-	if (!params || EVP_PKEY_set1_EC_KEY(params, ec_params) != 1) {
-		wpa_printf(MSG_ERROR,
-			   "DPP: Failed to generate EVP_PKEY parameters");
-		goto fail;
-	}
-
-	kctx = EVP_PKEY_CTX_new(params, NULL);
-	if (!kctx ||
-	    EVP_PKEY_keygen_init(kctx) != 1 ||
-	    EVP_PKEY_keygen(kctx, &key) != 1) {
-		wpa_printf(MSG_ERROR, "DPP: Failed to generate EC key");
-		key = NULL;
-		goto fail;
-	}
-
-	if (wpa_debug_show_keys)
-		dpp_debug_print_key("Own generated key", key);
-
-fail:
-	EC_KEY_free(ec_params);
-	EVP_PKEY_free(params);
-	EVP_PKEY_CTX_free(kctx);
 	return key;
 }
 
 
-EVP_PKEY * dpp_set_keypair(const struct dpp_curve_params **curve,
-			   const u8 *privkey, size_t privkey_len)
+struct crypto_ec_key * dpp_set_keypair(const struct dpp_curve_params **curve,
+				       const u8 *privkey, size_t privkey_len)
 {
-	EVP_PKEY *pkey;
-	EC_KEY *eckey;
-	const EC_GROUP *group;
-	int nid;
+	struct crypto_ec_key *key;
+	int group;
 
-	pkey = EVP_PKEY_new();
-	if (!pkey)
-		return NULL;
-	eckey = d2i_ECPrivateKey(NULL, &privkey, privkey_len);
-	if (!eckey) {
-		wpa_printf(MSG_INFO,
-			   "DPP: OpenSSL: d2i_ECPrivateKey() failed: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
-		EVP_PKEY_free(pkey);
+	key = crypto_ec_key_parse_priv(privkey, privkey_len);
+	if (!key) {
+		wpa_printf(MSG_INFO, "DPP: Failed to parse private key");
 		return NULL;
 	}
-	group = EC_KEY_get0_group(eckey);
-	if (!group) {
-		EC_KEY_free(eckey);
-		EVP_PKEY_free(pkey);
+
+	group = crypto_ec_key_group(key);
+	if (group < 0) {
+		crypto_ec_key_deinit(key);
 		return NULL;
 	}
-	nid = EC_GROUP_get_curve_name(group);
-	*curve = dpp_get_curve_nid(nid);
+
+	*curve = dpp_get_curve_ike_group(group);
 	if (!*curve) {
 		wpa_printf(MSG_INFO,
-			   "DPP: Unsupported curve (nid=%d) in pre-assigned key",
-			   nid);
-		EC_KEY_free(eckey);
-		EVP_PKEY_free(pkey);
+			   "DPP: Unsupported curve (group=%d) in pre-assigned key",
+			   group);
+		crypto_ec_key_deinit(key);
 		return NULL;
 	}
 
-	if (EVP_PKEY_assign_EC_KEY(pkey, eckey) != 1) {
-		EC_KEY_free(eckey);
-		EVP_PKEY_free(pkey);
-		return NULL;
-	}
-	return pkey;
-}
-
-
-typedef struct {
-	/* AlgorithmIdentifier ecPublicKey with optional parameters present
-	 * as an OID identifying the curve */
-	X509_ALGOR *alg;
-	/* Compressed format public key per ANSI X9.63 */
-	ASN1_BIT_STRING *pub_key;
-} DPP_BOOTSTRAPPING_KEY;
-
-ASN1_SEQUENCE(DPP_BOOTSTRAPPING_KEY) = {
-	ASN1_SIMPLE(DPP_BOOTSTRAPPING_KEY, alg, X509_ALGOR),
-	ASN1_SIMPLE(DPP_BOOTSTRAPPING_KEY, pub_key, ASN1_BIT_STRING)
-} ASN1_SEQUENCE_END(DPP_BOOTSTRAPPING_KEY);
-
-IMPLEMENT_ASN1_FUNCTIONS(DPP_BOOTSTRAPPING_KEY);
-
-
-static struct wpabuf * dpp_bootstrap_key_der(EVP_PKEY *key)
-{
-	unsigned char *der = NULL;
-	int der_len;
-	const EC_KEY *eckey;
-	struct wpabuf *ret = NULL;
-	size_t len;
-	const EC_GROUP *group;
-	const EC_POINT *point;
-	BN_CTX *ctx;
-	DPP_BOOTSTRAPPING_KEY *bootstrap = NULL;
-	int nid;
-
-	ctx = BN_CTX_new();
-	eckey = EVP_PKEY_get0_EC_KEY(key);
-	if (!ctx || !eckey)
-		goto fail;
-
-	group = EC_KEY_get0_group(eckey);
-	point = EC_KEY_get0_public_key(eckey);
-	if (!group || !point)
-		goto fail;
-	dpp_debug_print_point("DPP: bootstrap public key", group, point);
-	nid = EC_GROUP_get_curve_name(group);
-
-	bootstrap = DPP_BOOTSTRAPPING_KEY_new();
-	if (!bootstrap ||
-	    X509_ALGOR_set0(bootstrap->alg, OBJ_nid2obj(EVP_PKEY_EC),
-			    V_ASN1_OBJECT, (void *) OBJ_nid2obj(nid)) != 1)
-		goto fail;
-
-	len = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED,
-				 NULL, 0, ctx);
-	if (len == 0)
-		goto fail;
-
-	der = OPENSSL_malloc(len);
-	if (!der)
-		goto fail;
-	len = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED,
-				 der, len, ctx);
-
-	OPENSSL_free(bootstrap->pub_key->data);
-	bootstrap->pub_key->data = der;
-	der = NULL;
-	bootstrap->pub_key->length = len;
-	/* No unused bits */
-	bootstrap->pub_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
-	bootstrap->pub_key->flags |= ASN1_STRING_FLAG_BITS_LEFT;
-
-	der_len = i2d_DPP_BOOTSTRAPPING_KEY(bootstrap, &der);
-	if (der_len <= 0) {
-		wpa_printf(MSG_ERROR,
-			   "DDP: Failed to build DER encoded public key");
-		goto fail;
-	}
-
-	ret = wpabuf_alloc_copy(der, der_len);
-fail:
-	DPP_BOOTSTRAPPING_KEY_free(bootstrap);
-	OPENSSL_free(der);
-	BN_CTX_free(ctx);
-	return ret;
+	return key;
 }
 
 
@@ -702,7 +296,7 @@
 	struct wpabuf *der;
 	int res;
 
-	der = dpp_bootstrap_key_der(bi->pubkey);
+	der = crypto_ec_key_get_subject_public_key(bi->pubkey);
 	if (!der)
 		return -1;
 	wpa_hexdump_buf(MSG_DEBUG, "DPP: Compressed public key (DER)",
@@ -737,7 +331,7 @@
 		goto fail;
 	bi->own = 1;
 
-	der = dpp_bootstrap_key_der(bi->pubkey);
+	der = crypto_ec_key_get_subject_public_key(bi->pubkey);
 	if (!der)
 		goto fail;
 	wpa_hexdump_buf(MSG_DEBUG, "DPP: Compressed public key (DER)",
@@ -884,78 +478,48 @@
 }
 
 
-int dpp_ecdh(EVP_PKEY *own, EVP_PKEY *peer, u8 *secret, size_t *secret_len)
+int dpp_ecdh(struct crypto_ec_key *own, struct crypto_ec_key *peer,
+	     u8 *secret, size_t *secret_len)
 {
-	EVP_PKEY_CTX *ctx;
+	struct crypto_ecdh *ecdh;
+	struct wpabuf *peer_pub, *secret_buf = NULL;
 	int ret = -1;
 
-	ERR_clear_error();
 	*secret_len = 0;
 
-	ctx = EVP_PKEY_CTX_new(own, NULL);
-	if (!ctx) {
-		wpa_printf(MSG_ERROR, "DPP: EVP_PKEY_CTX_new failed: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
+	ecdh = crypto_ecdh_init2(crypto_ec_key_group(own), own);
+	if (!ecdh) {
+		wpa_printf(MSG_ERROR, "DPP: crypto_ecdh_init2() failed");
 		return -1;
 	}
 
-	if (EVP_PKEY_derive_init(ctx) != 1) {
-		wpa_printf(MSG_ERROR, "DPP: EVP_PKEY_derive_init failed: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
-		goto fail;
-	}
-
-	if (EVP_PKEY_derive_set_peer(ctx, peer) != 1) {
+	peer_pub = crypto_ec_key_get_pubkey_point(peer, 0);
+	if (!peer_pub) {
 		wpa_printf(MSG_ERROR,
-			   "DPP: EVP_PKEY_derive_set_peet failed: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
+			   "DPP: crypto_ec_key_get_pubkey_point() failed");
 		goto fail;
 	}
 
-	if (EVP_PKEY_derive(ctx, NULL, secret_len) != 1) {
-		wpa_printf(MSG_ERROR, "DPP: EVP_PKEY_derive(NULL) failed: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
+	secret_buf = crypto_ecdh_set_peerkey(ecdh, 1, wpabuf_head(peer_pub),
+					     wpabuf_len(peer_pub));
+	if (!secret_buf) {
+		wpa_printf(MSG_ERROR, "DPP: crypto_ecdh_set_peerkey() failed");
 		goto fail;
 	}
 
-	if (*secret_len > DPP_MAX_SHARED_SECRET_LEN) {
-		u8 buf[200];
-		int level = *secret_len > 200 ? MSG_ERROR : MSG_DEBUG;
-
-		wpa_printf(level,
-			   "DPP: Unexpected secret_len=%d from EVP_PKEY_derive()",
-			   (int) *secret_len);
-		if (*secret_len > 200)
-			goto fail;
-		if (EVP_PKEY_derive(ctx, buf, secret_len) != 1) {
-			wpa_printf(MSG_ERROR, "DPP: EVP_PKEY_derive failed: %s",
-				   ERR_error_string(ERR_get_error(), NULL));
-			goto fail;
-		}
-		if (*secret_len > DPP_MAX_SHARED_SECRET_LEN) {
-			wpa_printf(MSG_ERROR,
-				   "DPP: Unexpected secret_len=%d from EVP_PKEY_derive()",
-				   (int) *secret_len);
-			goto fail;
-		}
-		wpa_hexdump_key(MSG_DEBUG, "DPP: Unexpected secret_len change",
-				buf, *secret_len);
-		os_memcpy(secret, buf, *secret_len);
-		forced_memzero(buf, sizeof(buf));
-		goto done;
-	}
-
-	if (EVP_PKEY_derive(ctx, secret, secret_len) != 1) {
-		wpa_printf(MSG_ERROR, "DPP: EVP_PKEY_derive failed: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
+	if (wpabuf_len(secret_buf) > DPP_MAX_SHARED_SECRET_LEN) {
+		wpa_printf(MSG_ERROR, "DPP: ECDH secret longer than expected");
 		goto fail;
 	}
 
-done:
+	*secret_len = wpabuf_len(secret_buf);
+	os_memcpy(secret, wpabuf_head(secret_buf), wpabuf_len(secret_buf));
 	ret = 0;
 
 fail:
-	EVP_PKEY_CTX_free(ctx);
+	wpabuf_clear_free(secret_buf);
+	wpabuf_free(peer_pub);
+	crypto_ecdh_deinit(ecdh);
 	return ret;
 }
 
@@ -989,117 +553,32 @@
 int dpp_get_subject_public_key(struct dpp_bootstrap_info *bi,
 			       const u8 *data, size_t data_len)
 {
-	EVP_PKEY *pkey;
-	const unsigned char *p;
-	int res;
-	X509_PUBKEY *pub = NULL;
-	ASN1_OBJECT *ppkalg;
-	const unsigned char *pk;
-	int ppklen;
-	X509_ALGOR *pa;
-#if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && \
-	LIBRESSL_VERSION_NUMBER < 0x20800000L)
-	ASN1_OBJECT *pa_oid;
-#else
-	const ASN1_OBJECT *pa_oid;
-#endif
-	const void *pval;
-	int ptype;
-	const ASN1_OBJECT *poid;
-	char buf[100];
+	struct crypto_ec_key *key;
 
 	if (dpp_bi_pubkey_hash(bi, data, data_len) < 0) {
 		wpa_printf(MSG_DEBUG, "DPP: Failed to hash public key");
 		return -1;
 	}
 
-	/* DER encoded ASN.1 SubjectPublicKeyInfo
-	 *
-	 * SubjectPublicKeyInfo  ::=  SEQUENCE  {
-	 *      algorithm            AlgorithmIdentifier,
-	 *      subjectPublicKey     BIT STRING  }
-	 *
-	 * AlgorithmIdentifier  ::=  SEQUENCE  {
-	 *      algorithm               OBJECT IDENTIFIER,
-	 *      parameters              ANY DEFINED BY algorithm OPTIONAL  }
-	 *
-	 * subjectPublicKey = compressed format public key per ANSI X9.63
-	 * algorithm = ecPublicKey (1.2.840.10045.2.1)
-	 * parameters = shall be present and shall be OBJECT IDENTIFIER; e.g.,
-	 *       prime256v1 (1.2.840.10045.3.1.7)
-	 */
-
-	p = data;
-	pkey = d2i_PUBKEY(NULL, &p, data_len);
-
-	if (!pkey) {
+	key = crypto_ec_key_parse_pub(data, data_len);
+	if (!key) {
 		wpa_printf(MSG_DEBUG,
 			   "DPP: Could not parse URI public-key SubjectPublicKeyInfo");
 		return -1;
 	}
 
-	if (EVP_PKEY_type(EVP_PKEY_id(pkey)) != EVP_PKEY_EC) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: SubjectPublicKeyInfo does not describe an EC key");
-		EVP_PKEY_free(pkey);
-		return -1;
-	}
-
-	res = X509_PUBKEY_set(&pub, pkey);
-	if (res != 1) {
-		wpa_printf(MSG_DEBUG, "DPP: Could not set pubkey");
-		goto fail;
-	}
-
-	res = X509_PUBKEY_get0_param(&ppkalg, &pk, &ppklen, &pa, pub);
-	if (res != 1) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: Could not extract SubjectPublicKeyInfo parameters");
-		goto fail;
-	}
-	res = OBJ_obj2txt(buf, sizeof(buf), ppkalg, 0);
-	if (res < 0 || (size_t) res >= sizeof(buf)) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: Could not extract SubjectPublicKeyInfo algorithm");
-		goto fail;
-	}
-	wpa_printf(MSG_DEBUG, "DPP: URI subjectPublicKey algorithm: %s", buf);
-	if (os_strcmp(buf, "id-ecPublicKey") != 0) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: Unsupported SubjectPublicKeyInfo algorithm");
-		goto fail;
-	}
-
-	X509_ALGOR_get0(&pa_oid, &ptype, (void *) &pval, pa);
-	if (ptype != V_ASN1_OBJECT) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: SubjectPublicKeyInfo parameters did not contain an OID");
-		goto fail;
-	}
-	poid = pval;
-	res = OBJ_obj2txt(buf, sizeof(buf), poid, 0);
-	if (res < 0 || (size_t) res >= sizeof(buf)) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: Could not extract SubjectPublicKeyInfo parameters OID");
-		goto fail;
-	}
-	wpa_printf(MSG_DEBUG, "DPP: URI subjectPublicKey parameters: %s", buf);
-	bi->curve = dpp_get_curve_oid(poid);
+	bi->curve = dpp_get_curve_ike_group(crypto_ec_key_group(key));
 	if (!bi->curve) {
 		wpa_printf(MSG_DEBUG,
-			   "DPP: Unsupported SubjectPublicKeyInfo curve: %s",
-			   buf);
+			   "DPP: Unsupported SubjectPublicKeyInfo curve: group %d",
+			   crypto_ec_key_group(key));
 		goto fail;
 	}
 
-	wpa_hexdump(MSG_DEBUG, "DPP: URI subjectPublicKey", pk, ppklen);
-
-	X509_PUBKEY_free(pub);
-	bi->pubkey = pkey;
+	bi->pubkey = key;
 	return 0;
 fail:
-	X509_PUBKEY_free(pub);
-	EVP_PKEY_free(pkey);
+	crypto_ec_key_deinit(key);
 	return -1;
 }
 
@@ -1107,7 +586,7 @@
 static struct wpabuf *
 dpp_parse_jws_prot_hdr(const struct dpp_curve_params *curve,
 		       const u8 *prot_hdr, u16 prot_hdr_len,
-		       const EVP_MD **ret_md)
+		       int *hash_func)
 {
 	struct json_token *root, *token;
 	struct wpabuf *kid = NULL;
@@ -1153,17 +632,16 @@
 		goto fail;
 	}
 	if (os_strcmp(token->string, "ES256") == 0 ||
-	    os_strcmp(token->string, "BS256") == 0)
-		*ret_md = EVP_sha256();
-	else if (os_strcmp(token->string, "ES384") == 0 ||
-		 os_strcmp(token->string, "BS384") == 0)
-		*ret_md = EVP_sha384();
-	else if (os_strcmp(token->string, "ES512") == 0 ||
-		 os_strcmp(token->string, "BS512") == 0)
-		*ret_md = EVP_sha512();
-	else
-		*ret_md = NULL;
-	if (!*ret_md) {
+	    os_strcmp(token->string, "BS256") == 0) {
+		*hash_func = CRYPTO_HASH_ALG_SHA256;
+	} else if (os_strcmp(token->string, "ES384") == 0 ||
+		   os_strcmp(token->string, "BS384") == 0) {
+		*hash_func = CRYPTO_HASH_ALG_SHA384;
+	} else if (os_strcmp(token->string, "ES512") == 0 ||
+		   os_strcmp(token->string, "BS512") == 0) {
+		*hash_func = CRYPTO_HASH_ALG_SHA512;
+	} else {
+		*hash_func = -1;
 		wpa_printf(MSG_DEBUG,
 			   "DPP: Unsupported JWS Protected Header alg=%s",
 			   token->string);
@@ -1184,7 +662,8 @@
 }
 
 
-static int dpp_check_pubkey_match(EVP_PKEY *pub, struct wpabuf *r_hash)
+static int dpp_check_pubkey_match(struct crypto_ec_key *pub,
+				  struct wpabuf *r_hash)
 {
 	struct wpabuf *uncomp;
 	int res;
@@ -1194,7 +673,7 @@
 
 	if (wpabuf_len(r_hash) != SHA256_MAC_LEN)
 		return -1;
-	uncomp = dpp_get_pubkey_point(pub, 1);
+	uncomp = crypto_ec_key_get_pubkey_point(pub, 1);
 	if (!uncomp)
 		return -1;
 	addr[0] = wpabuf_head(uncomp);
@@ -1218,33 +697,19 @@
 
 enum dpp_status_error
 dpp_process_signed_connector(struct dpp_signed_connector_info *info,
-			     EVP_PKEY *csign_pub, const char *connector)
+			     struct crypto_ec_key *csign_pub,
+			     const char *connector)
 {
 	enum dpp_status_error ret = 255;
 	const char *pos, *end, *signed_start, *signed_end;
 	struct wpabuf *kid = NULL;
 	unsigned char *prot_hdr = NULL, *signature = NULL;
-	size_t prot_hdr_len = 0, signature_len = 0;
-	const EVP_MD *sign_md = NULL;
-	unsigned char *der = NULL;
-	int der_len;
-	int res;
-	EVP_MD_CTX *md_ctx = NULL;
-	ECDSA_SIG *sig = NULL;
-	BIGNUM *r = NULL, *s = NULL;
+	size_t prot_hdr_len = 0, signature_len = 0, signed_len;
+	int res, hash_func = -1;
 	const struct dpp_curve_params *curve;
-	const EC_KEY *eckey;
-	const EC_GROUP *group;
-	int nid;
+	u8 *hash = NULL;
 
-	eckey = EVP_PKEY_get0_EC_KEY(csign_pub);
-	if (!eckey)
-		goto fail;
-	group = EC_KEY_get0_group(eckey);
-	if (!group)
-		goto fail;
-	nid = EC_GROUP_get_curve_name(group);
-	curve = dpp_get_curve_nid(nid);
+	curve = dpp_get_curve_ike_group(crypto_ec_key_group(csign_pub));
 	if (!curve)
 		goto fail;
 	wpa_printf(MSG_DEBUG, "DPP: C-sign-key group: %s", curve->jwk_crv);
@@ -1267,7 +732,7 @@
 	wpa_hexdump_ascii(MSG_DEBUG,
 			  "DPP: signedConnector - JWS Protected Header",
 			  prot_hdr, prot_hdr_len);
-	kid = dpp_parse_jws_prot_hdr(curve, prot_hdr, prot_hdr_len, &sign_md);
+	kid = dpp_parse_jws_prot_hdr(curve, prot_hdr, prot_hdr_len, &hash_func);
 	if (!kid) {
 		ret = DPP_STATUS_INVALID_CONNECTOR;
 		goto fail;
@@ -1323,57 +788,45 @@
 		goto fail;
 	}
 
-	/* JWS Signature encodes the signature (r,s) as two octet strings. Need
-	 * to convert that to DER encoded ECDSA_SIG for OpenSSL EVP routines. */
-	r = BN_bin2bn(signature, signature_len / 2, NULL);
-	s = BN_bin2bn(signature + signature_len / 2, signature_len / 2, NULL);
-	sig = ECDSA_SIG_new();
-	if (!r || !s || !sig || ECDSA_SIG_set0(sig, r, s) != 1)
-		goto fail;
-	r = NULL;
-	s = NULL;
-
-	der_len = i2d_ECDSA_SIG(sig, &der);
-	if (der_len <= 0) {
-		wpa_printf(MSG_DEBUG, "DPP: Could not DER encode signature");
-		goto fail;
-	}
-	wpa_hexdump(MSG_DEBUG, "DPP: DER encoded signature", der, der_len);
-	md_ctx = EVP_MD_CTX_create();
-	if (!md_ctx)
+	hash = os_malloc(curve->hash_len);
+	if (!hash)
 		goto fail;
 
-	ERR_clear_error();
-	if (EVP_DigestVerifyInit(md_ctx, NULL, sign_md, NULL, csign_pub) != 1) {
-		wpa_printf(MSG_DEBUG, "DPP: EVP_DigestVerifyInit failed: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
+	signed_len = signed_end - signed_start + 1;
+	if (hash_func == CRYPTO_HASH_ALG_SHA256)
+		res = sha256_vector(1, (const u8 **) &signed_start, &signed_len,
+				    hash);
+	else if (hash_func == CRYPTO_HASH_ALG_SHA384)
+		res = sha384_vector(1, (const u8 **) &signed_start, &signed_len,
+				    hash);
+	else if (hash_func == CRYPTO_HASH_ALG_SHA512)
+		res = sha512_vector(1, (const u8 **) &signed_start, &signed_len,
+				    hash);
+	else
 		goto fail;
-	}
-	if (EVP_DigestVerifyUpdate(md_ctx, signed_start,
-				   signed_end - signed_start + 1) != 1) {
-		wpa_printf(MSG_DEBUG, "DPP: EVP_DigestVerifyUpdate failed: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
+
+	if (res)
 		goto fail;
-	}
-	res = EVP_DigestVerifyFinal(md_ctx, der, der_len);
+
+	res = crypto_ec_key_verify_signature_r_s(csign_pub,
+						 hash, curve->hash_len,
+						 signature, signature_len / 2,
+						 signature + signature_len / 2,
+						 signature_len / 2);
 	if (res != 1) {
 		wpa_printf(MSG_DEBUG,
-			   "DPP: EVP_DigestVerifyFinal failed (res=%d): %s",
-			   res, ERR_error_string(ERR_get_error(), NULL));
+			   "DPP: signedConnector signature check failed (res=%d)",
+			   res);
 		ret = DPP_STATUS_INVALID_CONNECTOR;
 		goto fail;
 	}
 
 	ret = DPP_STATUS_OK;
 fail:
-	EVP_MD_CTX_destroy(md_ctx);
+	os_free(hash);
 	os_free(prot_hdr);
 	wpabuf_free(kid);
 	os_free(signature);
-	ECDSA_SIG_free(sig);
-	BN_free(r);
-	BN_free(s);
-	OPENSSL_free(der);
 	return ret;
 }
 
@@ -1383,13 +836,11 @@
 			   const u8 *csign_key, size_t csign_key_len,
 			   const u8 *peer_connector, size_t peer_connector_len)
 {
-	const unsigned char *p;
-	EVP_PKEY *csign = NULL;
+	struct crypto_ec_key *csign;
 	char *signed_connector = NULL;
 	enum dpp_status_error res = DPP_STATUS_INVALID_CONNECTOR;
 
-	p = csign_key;
-	csign = d2i_PUBKEY(NULL, &p, csign_key_len);
+	csign = crypto_ec_key_parse_pub(csign_key, csign_key_len);
 	if (!csign) {
 		wpa_printf(MSG_ERROR,
 			   "DPP: Failed to parse local C-sign-key information");
@@ -1406,7 +857,7 @@
 	res = dpp_process_signed_connector(info, csign, signed_connector);
 fail:
 	os_free(signed_connector);
-	EVP_PKEY_free(csign);
+	crypto_ec_key_deinit(csign);
 	return res;
 }
 
@@ -1425,21 +876,25 @@
 	nonce_len = auth->curve->nonce_len;
 
 	if (auth->initiator) {
-		pix = dpp_get_pubkey_point(auth->own_protocol_key, 0);
-		prx = dpp_get_pubkey_point(auth->peer_protocol_key, 0);
+		pix = crypto_ec_key_get_pubkey_point(auth->own_protocol_key, 0);
+		prx = crypto_ec_key_get_pubkey_point(auth->peer_protocol_key,
+						     0);
 		if (auth->own_bi)
-			bix = dpp_get_pubkey_point(auth->own_bi->pubkey, 0);
+			bix = crypto_ec_key_get_pubkey_point(
+				auth->own_bi->pubkey, 0);
 		else
 			bix = NULL;
-		brx = dpp_get_pubkey_point(auth->peer_bi->pubkey, 0);
+		brx = crypto_ec_key_get_pubkey_point(auth->peer_bi->pubkey, 0);
 	} else {
-		pix = dpp_get_pubkey_point(auth->peer_protocol_key, 0);
-		prx = dpp_get_pubkey_point(auth->own_protocol_key, 0);
+		pix = crypto_ec_key_get_pubkey_point(auth->peer_protocol_key,
+						     0);
+		prx = crypto_ec_key_get_pubkey_point(auth->own_protocol_key, 0);
 		if (auth->peer_bi)
-			bix = dpp_get_pubkey_point(auth->peer_bi->pubkey, 0);
+			bix = crypto_ec_key_get_pubkey_point(
+				auth->peer_bi->pubkey, 0);
 		else
 			bix = NULL;
-		brx = dpp_get_pubkey_point(auth->own_bi->pubkey, 0);
+		brx = crypto_ec_key_get_pubkey_point(auth->own_bi->pubkey, 0);
 	}
 	if (!pix || !prx || !brx)
 		goto fail;
@@ -1504,25 +959,29 @@
 	nonce_len = auth->curve->nonce_len;
 
 	if (auth->initiator) {
-		pix = dpp_get_pubkey_point(auth->own_protocol_key, 0);
-		prx = dpp_get_pubkey_point(auth->peer_protocol_key, 0);
+		pix = crypto_ec_key_get_pubkey_point(auth->own_protocol_key, 0);
+		prx = crypto_ec_key_get_pubkey_point(auth->peer_protocol_key,
+						     0);
 		if (auth->own_bi)
-			bix = dpp_get_pubkey_point(auth->own_bi->pubkey, 0);
+			bix = crypto_ec_key_get_pubkey_point(
+				auth->own_bi->pubkey, 0);
 		else
 			bix = NULL;
 		if (!auth->peer_bi)
 			goto fail;
-		brx = dpp_get_pubkey_point(auth->peer_bi->pubkey, 0);
+		brx = crypto_ec_key_get_pubkey_point(auth->peer_bi->pubkey, 0);
 	} else {
-		pix = dpp_get_pubkey_point(auth->peer_protocol_key, 0);
-		prx = dpp_get_pubkey_point(auth->own_protocol_key, 0);
+		pix = crypto_ec_key_get_pubkey_point(auth->peer_protocol_key,
+						     0);
+		prx = crypto_ec_key_get_pubkey_point(auth->own_protocol_key, 0);
 		if (auth->peer_bi)
-			bix = dpp_get_pubkey_point(auth->peer_bi->pubkey, 0);
+			bix = crypto_ec_key_get_pubkey_point(
+				auth->peer_bi->pubkey, 0);
 		else
 			bix = NULL;
 		if (!auth->own_bi)
 			goto fail;
-		brx = dpp_get_pubkey_point(auth->own_bi->pubkey, 0);
+		brx = crypto_ec_key_get_pubkey_point(auth->own_bi->pubkey, 0);
 	}
 	if (!pix || !prx || !brx)
 		goto fail;
@@ -1575,122 +1034,83 @@
 
 int dpp_auth_derive_l_responder(struct dpp_authentication *auth)
 {
-	const EC_GROUP *group;
-	EC_POINT *l = NULL;
-	const EC_KEY *BI, *bR, *pR;
-	const EC_POINT *BI_point;
-	BN_CTX *bnctx;
-	BIGNUM *lx, *sum, *q;
-	const BIGNUM *bR_bn, *pR_bn;
+	struct crypto_ec *ec;
+	struct crypto_ec_point *L = NULL;
+	const struct crypto_ec_point *BI;
+	const struct crypto_bignum *bR, *pR, *q;
+	struct crypto_bignum *sum = NULL, *lx = NULL;
 	int ret = -1;
 
 	/* L = ((bR + pR) modulo q) * BI */
 
-	bnctx = BN_CTX_new();
-	sum = BN_new();
-	q = BN_new();
-	lx = BN_new();
-	if (!bnctx || !sum || !q || !lx)
-		goto fail;
-	BI = EVP_PKEY_get0_EC_KEY(auth->peer_bi->pubkey);
-	if (!BI)
-		goto fail;
-	BI_point = EC_KEY_get0_public_key(BI);
-	group = EC_KEY_get0_group(BI);
-	if (!group)
+	ec = crypto_ec_init(crypto_ec_key_group(auth->peer_bi->pubkey));
+	if (!ec)
 		goto fail;
 
-	bR = EVP_PKEY_get0_EC_KEY(auth->own_bi->pubkey);
-	pR = EVP_PKEY_get0_EC_KEY(auth->own_protocol_key);
-	if (!bR || !pR)
+	q = crypto_ec_get_order(ec);
+	BI = crypto_ec_key_get_public_key(auth->peer_bi->pubkey);
+	bR = crypto_ec_key_get_private_key(auth->own_bi->pubkey);
+	pR = crypto_ec_key_get_private_key(auth->own_protocol_key);
+	sum = crypto_bignum_init();
+	L = crypto_ec_point_init(ec);
+	lx = crypto_bignum_init();
+	if (!q || !BI || !bR || !pR || !sum || !L || !lx ||
+	    crypto_bignum_addmod(bR, pR, q, sum) ||
+	    crypto_ec_point_mul(ec, BI, sum, L) ||
+	    crypto_ec_point_x(ec, L, lx) ||
+	    crypto_bignum_to_bin(lx, auth->Lx, sizeof(auth->Lx),
+				 auth->secret_len) < 0)
 		goto fail;
-	bR_bn = EC_KEY_get0_private_key(bR);
-	pR_bn = EC_KEY_get0_private_key(pR);
-	if (!bR_bn || !pR_bn)
-		goto fail;
-	if (EC_GROUP_get_order(group, q, bnctx) != 1 ||
-	    BN_mod_add(sum, bR_bn, pR_bn, q, bnctx) != 1)
-		goto fail;
-	l = EC_POINT_new(group);
-	if (!l ||
-	    EC_POINT_mul(group, l, NULL, BI_point, sum, bnctx) != 1 ||
-	    EC_POINT_get_affine_coordinates_GFp(group, l, lx, NULL,
-						bnctx) != 1) {
-		wpa_printf(MSG_ERROR,
-			   "OpenSSL: failed: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
-		goto fail;
-	}
 
-	if (dpp_bn2bin_pad(lx, auth->Lx, auth->secret_len) < 0)
-		goto fail;
 	wpa_hexdump_key(MSG_DEBUG, "DPP: L.x", auth->Lx, auth->secret_len);
 	auth->Lx_len = auth->secret_len;
 	ret = 0;
 fail:
-	EC_POINT_clear_free(l);
-	BN_clear_free(lx);
-	BN_clear_free(sum);
-	BN_free(q);
-	BN_CTX_free(bnctx);
+	crypto_bignum_deinit(lx, 1);
+	crypto_bignum_deinit(sum, 1);
+	crypto_ec_point_deinit(L, 1);
+	crypto_ec_deinit(ec);
 	return ret;
 }
 
 
 int dpp_auth_derive_l_initiator(struct dpp_authentication *auth)
 {
-	const EC_GROUP *group;
-	EC_POINT *l = NULL, *sum = NULL;
-	const EC_KEY *bI, *BR, *PR;
-	const EC_POINT *BR_point, *PR_point;
-	BN_CTX *bnctx;
-	BIGNUM *lx;
-	const BIGNUM *bI_bn;
+	struct crypto_ec *ec;
+	struct crypto_ec_point *L = NULL, *sum = NULL;
+	const struct crypto_ec_point *BR, *PR;
+	const struct crypto_bignum *bI;
+	struct crypto_bignum *lx = NULL;
 	int ret = -1;
 
 	/* L = bI * (BR + PR) */
 
-	bnctx = BN_CTX_new();
-	lx = BN_new();
-	if (!bnctx || !lx)
+	ec = crypto_ec_init(crypto_ec_key_group(auth->peer_bi->pubkey));
+	if (!ec)
 		goto fail;
-	BR = EVP_PKEY_get0_EC_KEY(auth->peer_bi->pubkey);
-	PR = EVP_PKEY_get0_EC_KEY(auth->peer_protocol_key);
-	if (!BR || !PR)
-		goto fail;
-	BR_point = EC_KEY_get0_public_key(BR);
-	PR_point = EC_KEY_get0_public_key(PR);
 
-	bI = EVP_PKEY_get0_EC_KEY(auth->own_bi->pubkey);
-	if (!bI)
+	BR = crypto_ec_key_get_public_key(auth->peer_bi->pubkey);
+	PR = crypto_ec_key_get_public_key(auth->peer_protocol_key);
+	bI = crypto_ec_key_get_private_key(auth->own_bi->pubkey);
+	sum = crypto_ec_point_init(ec);
+	L = crypto_ec_point_init(ec);
+	lx = crypto_bignum_init();
+	if (!BR || !PR || !bI || !sum || !L || !lx ||
+	    crypto_ec_point_add(ec, BR, PR, sum) ||
+	    crypto_ec_point_mul(ec, sum, bI, L) ||
+	    crypto_ec_point_x(ec, L, lx) ||
+	    crypto_bignum_to_bin(lx, auth->Lx, sizeof(auth->Lx),
+				 auth->secret_len) < 0)
 		goto fail;
-	group = EC_KEY_get0_group(bI);
-	bI_bn = EC_KEY_get0_private_key(bI);
-	if (!group || !bI_bn)
-		goto fail;
-	sum = EC_POINT_new(group);
-	l = EC_POINT_new(group);
-	if (!sum || !l ||
-	    EC_POINT_add(group, sum, BR_point, PR_point, bnctx) != 1 ||
-	    EC_POINT_mul(group, l, NULL, sum, bI_bn, bnctx) != 1 ||
-	    EC_POINT_get_affine_coordinates_GFp(group, l, lx, NULL,
-						bnctx) != 1) {
-		wpa_printf(MSG_ERROR,
-			   "OpenSSL: failed: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
-		goto fail;
-	}
 
-	if (dpp_bn2bin_pad(lx, auth->Lx, auth->secret_len) < 0)
-		goto fail;
 	wpa_hexdump_key(MSG_DEBUG, "DPP: L.x", auth->Lx, auth->secret_len);
 	auth->Lx_len = auth->secret_len;
 	ret = 0;
 fail:
-	EC_POINT_clear_free(l);
-	EC_POINT_clear_free(sum);
-	BN_clear_free(lx);
-	BN_CTX_free(bnctx);
+	crypto_bignum_deinit(lx, 1);
+	crypto_ec_point_deinit(sum, 1);
+	crypto_ec_point_deinit(L, 1);
+	crypto_ec_deinit(ec);
 	return ret;
 }
 
@@ -1723,7 +1143,8 @@
 
 
 int dpp_derive_pmkid(const struct dpp_curve_params *curve,
-		     EVP_PKEY *own_key, EVP_PKEY *peer_key, u8 *pmkid)
+		     struct crypto_ec_key *own_key,
+		     struct crypto_ec_key *peer_key, u8 *pmkid)
 {
 	struct wpabuf *nkx, *pkx;
 	int ret = -1, res;
@@ -1732,8 +1153,8 @@
 	u8 hash[SHA256_MAC_LEN];
 
 	/* PMKID = Truncate-128(H(min(NK.x, PK.x) | max(NK.x, PK.x))) */
-	nkx = dpp_get_pubkey_point(own_key, 0);
-	pkx = dpp_get_pubkey_point(peer_key, 0);
+	nkx = crypto_ec_key_get_pubkey_point(own_key, 0);
+	pkx = crypto_ec_key_get_pubkey_point(peer_key, 0);
 	if (!nkx || !pkx)
 		goto fail;
 	addr[0] = wpabuf_head(nkx);
@@ -1973,13 +1394,10 @@
 };
 
 
-static EVP_PKEY * dpp_pkex_get_role_elem(const struct dpp_curve_params *curve,
-					 int init)
+static struct crypto_ec_key *
+dpp_pkex_get_role_elem(const struct dpp_curve_params *curve, int init)
 {
-	EC_GROUP *group;
-	size_t len = curve->prime_len;
 	const u8 *x, *y;
-	EVP_PKEY *res;
 
 	switch (curve->ike_group) {
 	case 19:
@@ -2010,38 +1428,34 @@
 		return NULL;
 	}
 
-	group = EC_GROUP_new_by_curve_name(OBJ_txt2nid(curve->name));
-	if (!group)
-		return NULL;
-	res = dpp_set_pubkey_point_group(group, x, y, len);
-	EC_GROUP_free(group);
-	return res;
+	return crypto_ec_key_set_pub(curve->ike_group, x, y, curve->prime_len);
 }
 
 
-EC_POINT * dpp_pkex_derive_Qi(const struct dpp_curve_params *curve,
-			      const u8 *mac_init, const char *code,
-			      const char *identifier, BN_CTX *bnctx,
-			      EC_GROUP **ret_group)
+struct crypto_ec_point *
+dpp_pkex_derive_Qi(const struct dpp_curve_params *curve, const u8 *mac_init,
+		   const char *code, const char *identifier,
+		   struct crypto_ec **ret_ec)
 {
 	u8 hash[DPP_MAX_HASH_LEN];
 	const u8 *addr[3];
 	size_t len[3];
 	unsigned int num_elem = 0;
-	EC_POINT *Qi = NULL;
-	EVP_PKEY *Pi = NULL;
-	const EC_KEY *Pi_ec;
-	const EC_POINT *Pi_point;
-	BIGNUM *hash_bn = NULL;
-	const EC_GROUP *group = NULL;
-	EC_GROUP *group2 = NULL;
+	struct crypto_ec_point *Qi = NULL;
+	struct crypto_ec_key *Pi_key = NULL;
+	const struct crypto_ec_point *Pi = NULL;
+	struct crypto_bignum *hash_bn = NULL;
+	struct crypto_ec *ec = NULL;
 
-	/* Qi = H(MAC-Initiator | [identifier |] code) * Pi */
+	/* Qi = H([MAC-Initiator |] [identifier |] code) * Pi */
 
-	wpa_printf(MSG_DEBUG, "DPP: MAC-Initiator: " MACSTR, MAC2STR(mac_init));
-	addr[num_elem] = mac_init;
-	len[num_elem] = ETH_ALEN;
-	num_elem++;
+	if (mac_init) {
+		wpa_printf(MSG_DEBUG, "DPP: MAC-Initiator: " MACSTR,
+			   MAC2STR(mac_init));
+		addr[num_elem] = mac_init;
+		len[num_elem] = ETH_ALEN;
+		num_elem++;
+	}
 	if (identifier) {
 		wpa_printf(MSG_DEBUG, "DPP: code identifier: %s",
 			   identifier);
@@ -2056,75 +1470,67 @@
 	if (dpp_hash_vector(curve, num_elem, addr, len, hash) < 0)
 		goto fail;
 	wpa_hexdump_key(MSG_DEBUG,
-			"DPP: H(MAC-Initiator | [identifier |] code)",
+			"DPP: H([MAC-Initiator |] [identifier |] code)",
 			hash, curve->hash_len);
-	Pi = dpp_pkex_get_role_elem(curve, 1);
-	if (!Pi)
+	Pi_key = dpp_pkex_get_role_elem(curve, 1);
+	if (!Pi_key)
 		goto fail;
-	dpp_debug_print_key("DPP: Pi", Pi);
-	Pi_ec = EVP_PKEY_get0_EC_KEY(Pi);
-	if (!Pi_ec)
-		goto fail;
-	Pi_point = EC_KEY_get0_public_key(Pi_ec);
+	dpp_debug_print_key("DPP: Pi", Pi_key);
 
-	group = EC_KEY_get0_group(Pi_ec);
-	if (!group)
+	ec = crypto_ec_init(curve->ike_group);
+	if (!ec)
 		goto fail;
-	group2 = EC_GROUP_dup(group);
-	if (!group2)
+
+	Pi = crypto_ec_key_get_public_key(Pi_key);
+	Qi = crypto_ec_point_init(ec);
+	hash_bn = crypto_bignum_init_set(hash, curve->hash_len);
+	if (!Pi || !Qi || !hash_bn || crypto_ec_point_mul(ec, Pi, hash_bn, Qi))
 		goto fail;
-	Qi = EC_POINT_new(group2);
-	if (!Qi) {
-		EC_GROUP_free(group2);
-		goto fail;
-	}
-	hash_bn = BN_bin2bn(hash, curve->hash_len, NULL);
-	if (!hash_bn ||
-	    EC_POINT_mul(group2, Qi, NULL, Pi_point, hash_bn, bnctx) != 1)
-		goto fail;
-	if (EC_POINT_is_at_infinity(group, Qi)) {
+
+	if (crypto_ec_point_is_at_infinity(ec, Qi)) {
 		wpa_printf(MSG_INFO, "DPP: Qi is the point-at-infinity");
 		goto fail;
 	}
-	dpp_debug_print_point("DPP: Qi", group, Qi);
+	crypto_ec_point_debug_print(ec, Qi, "DPP: Qi");
 out:
-	EVP_PKEY_free(Pi);
-	BN_clear_free(hash_bn);
-	if (ret_group && Qi)
-		*ret_group = group2;
+	crypto_ec_key_deinit(Pi_key);
+	crypto_bignum_deinit(hash_bn, 1);
+	if (ret_ec && Qi)
+		*ret_ec = ec;
 	else
-		EC_GROUP_free(group2);
+		crypto_ec_deinit(ec);
 	return Qi;
 fail:
-	EC_POINT_free(Qi);
+	crypto_ec_point_deinit(Qi, 1);
 	Qi = NULL;
 	goto out;
 }
 
 
-EC_POINT * dpp_pkex_derive_Qr(const struct dpp_curve_params *curve,
-			      const u8 *mac_resp, const char *code,
-			      const char *identifier, BN_CTX *bnctx,
-			      EC_GROUP **ret_group)
+struct crypto_ec_point *
+dpp_pkex_derive_Qr(const struct dpp_curve_params *curve, const u8 *mac_resp,
+		   const char *code, const char *identifier,
+		   struct crypto_ec **ret_ec)
 {
 	u8 hash[DPP_MAX_HASH_LEN];
 	const u8 *addr[3];
 	size_t len[3];
 	unsigned int num_elem = 0;
-	EC_POINT *Qr = NULL;
-	EVP_PKEY *Pr = NULL;
-	const EC_KEY *Pr_ec;
-	const EC_POINT *Pr_point;
-	BIGNUM *hash_bn = NULL;
-	const EC_GROUP *group = NULL;
-	EC_GROUP *group2 = NULL;
+	struct crypto_ec_point *Qr = NULL;
+	struct crypto_ec_key *Pr_key = NULL;
+	const struct crypto_ec_point *Pr = NULL;
+	struct crypto_bignum *hash_bn = NULL;
+	struct crypto_ec *ec = NULL;
 
-	/* Qr = H(MAC-Responder | | [identifier | ] code) * Pr */
+	/* Qr = H([MAC-Responder |] [identifier |] code) * Pr */
 
-	wpa_printf(MSG_DEBUG, "DPP: MAC-Responder: " MACSTR, MAC2STR(mac_resp));
-	addr[num_elem] = mac_resp;
-	len[num_elem] = ETH_ALEN;
-	num_elem++;
+	if (mac_resp) {
+		wpa_printf(MSG_DEBUG, "DPP: MAC-Responder: " MACSTR,
+			   MAC2STR(mac_resp));
+		addr[num_elem] = mac_resp;
+		len[num_elem] = ETH_ALEN;
+		num_elem++;
+	}
 	if (identifier) {
 		wpa_printf(MSG_DEBUG, "DPP: code identifier: %s",
 			   identifier);
@@ -2139,53 +1545,46 @@
 	if (dpp_hash_vector(curve, num_elem, addr, len, hash) < 0)
 		goto fail;
 	wpa_hexdump_key(MSG_DEBUG,
-			"DPP: H(MAC-Responder | [identifier |] code)",
+			"DPP: H([MAC-Responder |] [identifier |] code)",
 			hash, curve->hash_len);
-	Pr = dpp_pkex_get_role_elem(curve, 0);
-	if (!Pr)
+	Pr_key = dpp_pkex_get_role_elem(curve, 0);
+	if (!Pr_key)
 		goto fail;
-	dpp_debug_print_key("DPP: Pr", Pr);
-	Pr_ec = EVP_PKEY_get0_EC_KEY(Pr);
-	if (!Pr_ec)
-		goto fail;
-	Pr_point = EC_KEY_get0_public_key(Pr_ec);
+	dpp_debug_print_key("DPP: Pr", Pr_key);
 
-	group = EC_KEY_get0_group(Pr_ec);
-	if (!group)
+	ec = crypto_ec_init(curve->ike_group);
+	if (!ec)
 		goto fail;
-	group2 = EC_GROUP_dup(group);
-	if (!group2)
+
+	Pr = crypto_ec_key_get_public_key(Pr_key);
+	Qr = crypto_ec_point_init(ec);
+	hash_bn = crypto_bignum_init_set(hash, curve->hash_len);
+	if (!Pr || !Qr || !hash_bn || crypto_ec_point_mul(ec, Pr, hash_bn, Qr))
 		goto fail;
-	Qr = EC_POINT_new(group2);
-	if (!Qr) {
-		EC_GROUP_free(group2);
-		goto fail;
-	}
-	hash_bn = BN_bin2bn(hash, curve->hash_len, NULL);
-	if (!hash_bn ||
-	    EC_POINT_mul(group2, Qr, NULL, Pr_point, hash_bn, bnctx) != 1)
-		goto fail;
-	if (EC_POINT_is_at_infinity(group, Qr)) {
+
+	if (crypto_ec_point_is_at_infinity(ec, Qr)) {
 		wpa_printf(MSG_INFO, "DPP: Qr is the point-at-infinity");
 		goto fail;
 	}
-	dpp_debug_print_point("DPP: Qr", group, Qr);
+	crypto_ec_point_debug_print(ec, Qr, "DPP: Qr");
+
 out:
-	EVP_PKEY_free(Pr);
-	BN_clear_free(hash_bn);
-	if (ret_group && Qr)
-		*ret_group = group2;
+	crypto_ec_key_deinit(Pr_key);
+	crypto_bignum_deinit(hash_bn, 1);
+	if (ret_ec && Qr)
+		*ret_ec = ec;
 	else
-		EC_GROUP_free(group2);
+		crypto_ec_deinit(ec);
 	return Qr;
 fail:
-	EC_POINT_free(Qr);
+	crypto_ec_point_deinit(Qr, 1);
 	Qr = NULL;
 	goto out;
 }
 
 
 int dpp_pkex_derive_z(const u8 *mac_init, const u8 *mac_resp,
+		      u8 ver_init, u8 ver_resp,
 		      const u8 *Mx, size_t Mx_len,
 		      const u8 *Nx, size_t Nx_len,
 		      const char *code,
@@ -2197,7 +1596,10 @@
 	u8 *info, *pos;
 	size_t info_len;
 
-	/* z = HKDF(<>, MAC-Initiator | MAC-Responder | M.x | N.x | code, K.x)
+	/*
+	 * v1: info = MAC-Initiator | MAC-Responder
+	 * v2: info = Protocol Version-Initiator | Protocol Version-Responder
+	 * z = HKDF(<>, info | M.x | N.x | code, K.x)
 	 */
 
 	/* HKDF-Extract(<>, IKM=K.x) */
@@ -2206,15 +1608,24 @@
 		return -1;
 	wpa_hexdump_key(MSG_DEBUG, "DPP: PRK = HKDF-Extract(<>, IKM)",
 			prk, hash_len);
-	info_len = 2 * ETH_ALEN + Mx_len + Nx_len + os_strlen(code);
+	if (mac_init && mac_resp)
+		info_len = 2 * ETH_ALEN;
+	else
+		info_len = 2;
+	info_len += Mx_len + Nx_len + os_strlen(code);
 	info = os_malloc(info_len);
 	if (!info)
 		return -1;
 	pos = info;
-	os_memcpy(pos, mac_init, ETH_ALEN);
-	pos += ETH_ALEN;
-	os_memcpy(pos, mac_resp, ETH_ALEN);
-	pos += ETH_ALEN;
+	if (mac_init && mac_resp) {
+		os_memcpy(pos, mac_init, ETH_ALEN);
+		pos += ETH_ALEN;
+		os_memcpy(pos, mac_resp, ETH_ALEN);
+		pos += ETH_ALEN;
+	} else {
+		*pos++ = ver_init;
+		*pos++ = ver_resp;
+	}
 	os_memcpy(pos, Mx, Mx_len);
 	pos += Mx_len;
 	os_memcpy(pos, Nx, Nx_len);
@@ -2249,15 +1660,12 @@
 				     size_t net_access_key_len,
 				     struct json_token *peer_net_access_key)
 {
-	BN_CTX *bnctx = NULL;
-	EVP_PKEY *own_key = NULL, *peer_key = NULL;
-	BIGNUM *sum = NULL, *q = NULL, *mx = NULL;
-	EC_POINT *m = NULL;
-	const EC_KEY *cR, *pR;
-	const EC_GROUP *group;
-	const BIGNUM *cR_bn, *pR_bn;
-	const EC_POINT *CI_point;
-	const EC_KEY *CI;
+	struct crypto_ec_key *own_key = NULL, *peer_key = NULL;
+	struct crypto_bignum *sum = NULL;
+	const struct crypto_bignum *q, *cR, *pR;
+	struct crypto_ec *ec = NULL;
+	struct crypto_ec_point *M = NULL;
+	const struct crypto_ec_point *CI;
 	u8 Mx[DPP_MAX_SHARED_SECRET_LEN];
 	u8 prk[DPP_MAX_HASH_LEN];
 	const struct dpp_curve_params *curve;
@@ -2295,37 +1703,23 @@
 			auth->e_nonce, auth->curve->nonce_len);
 
 	/* M = { cR + pR } * CI */
-	cR = EVP_PKEY_get0_EC_KEY(own_key);
-	pR = EVP_PKEY_get0_EC_KEY(auth->own_protocol_key);
-	if (!pR)
+	ec = crypto_ec_init(curve->ike_group);
+	if (!ec)
 		goto fail;
-	group = EC_KEY_get0_group(pR);
-	bnctx = BN_CTX_new();
-	sum = BN_new();
-	mx = BN_new();
-	q = BN_new();
-	m = EC_POINT_new(group);
-	if (!cR || !bnctx || !sum || !mx || !q || !m)
-		goto fail;
-	cR_bn = EC_KEY_get0_private_key(cR);
-	pR_bn = EC_KEY_get0_private_key(pR);
-	if (!cR_bn || !pR_bn)
-		goto fail;
-	CI = EVP_PKEY_get0_EC_KEY(peer_key);
-	CI_point = EC_KEY_get0_public_key(CI);
-	if (EC_GROUP_get_order(group, q, bnctx) != 1 ||
-	    BN_mod_add(sum, cR_bn, pR_bn, q, bnctx) != 1 ||
-	    EC_POINT_mul(group, m, NULL, CI_point, sum, bnctx) != 1 ||
-	    EC_POINT_get_affine_coordinates_GFp(group, m, mx, NULL,
-						bnctx) != 1) {
-		wpa_printf(MSG_ERROR,
-			   "OpenSSL: failed: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
+
+	sum = crypto_bignum_init();
+	q = crypto_ec_get_order(ec);
+	M = crypto_ec_point_init(ec);
+	cR = crypto_ec_key_get_private_key(own_key);
+	pR = crypto_ec_key_get_private_key(auth->own_protocol_key);
+	CI = crypto_ec_key_get_public_key(peer_key);
+	if (!sum || !q || !M || !cR || !pR || !CI ||
+	    crypto_bignum_addmod(cR, pR, q, sum) ||
+	    crypto_ec_point_mul(ec, CI, sum, M) ||
+	    crypto_ec_point_to_bin(ec, M, Mx, NULL)) {
+		wpa_printf(MSG_ERROR, "DPP: Error during M computation");
 		goto fail;
 	}
-
-	if (dpp_bn2bin_pad(mx, Mx, curve->prime_len) < 0)
-		goto fail;
 	wpa_hexdump_key(MSG_DEBUG, "DPP: M.x", Mx, curve->prime_len);
 
 	/* ke = HKDF(C-nonce | E-nonce, "dpp reconfig key", M.x) */
@@ -2347,19 +1741,17 @@
 			auth->ke, curve->hash_len);
 
 	res = 0;
-	EVP_PKEY_free(auth->reconfig_old_protocol_key);
+	crypto_ec_key_deinit(auth->reconfig_old_protocol_key);
 	auth->reconfig_old_protocol_key = own_key;
 	own_key = NULL;
 fail:
 	forced_memzero(prk, sizeof(prk));
 	forced_memzero(Mx, sizeof(Mx));
-	EC_POINT_clear_free(m);
-	BN_free(q);
-	BN_clear_free(mx);
-	BN_clear_free(sum);
-	EVP_PKEY_free(own_key);
-	EVP_PKEY_free(peer_key);
-	BN_CTX_free(bnctx);
+	crypto_ec_point_deinit(M, 1);
+	crypto_bignum_deinit(sum, 1);
+	crypto_ec_key_deinit(own_key);
+	crypto_ec_key_deinit(peer_key);
+	crypto_ec_deinit(ec);
 	return res;
 }
 
@@ -2368,14 +1760,11 @@
 				     const u8 *r_proto, u16 r_proto_len,
 				     struct json_token *net_access_key)
 {
-	BN_CTX *bnctx = NULL;
-	EVP_PKEY *pr = NULL, *peer_key = NULL;
-	EC_POINT *sum = NULL, *m = NULL;
-	BIGNUM *mx = NULL;
-	const EC_KEY *cI, *CR, *PR;
-	const EC_GROUP *group;
-	const EC_POINT *CR_point, *PR_point;
-	const BIGNUM *cI_bn;
+	struct crypto_ec_key *pr = NULL, *peer_key = NULL;
+	const struct crypto_ec_point *CR, *PR;
+	const struct crypto_bignum *cI;
+	struct crypto_ec *ec = NULL;
+	struct crypto_ec_point *sum = NULL, *M = NULL;
 	u8 Mx[DPP_MAX_SHARED_SECRET_LEN];
 	u8 prk[DPP_MAX_HASH_LEN];
 	int res = -1;
@@ -2389,7 +1778,7 @@
 		goto fail;
 	}
 	dpp_debug_print_key("Peer (Responder) Protocol Key", pr);
-	EVP_PKEY_free(auth->peer_protocol_key);
+	crypto_ec_key_deinit(auth->peer_protocol_key);
 	auth->peer_protocol_key = pr;
 	pr = NULL;
 
@@ -2405,25 +1794,23 @@
 	}
 
 	/* M = cI * { CR + PR } */
-	cI = EVP_PKEY_get0_EC_KEY(auth->conf->connector_key);
-	cI_bn = EC_KEY_get0_private_key(cI);
-	group = EC_KEY_get0_group(cI);
-	bnctx = BN_CTX_new();
-	sum = EC_POINT_new(group);
-	m = EC_POINT_new(group);
-	mx = BN_new();
-	CR = EVP_PKEY_get0_EC_KEY(peer_key);
-	PR = EVP_PKEY_get0_EC_KEY(auth->peer_protocol_key);
-	CR_point = EC_KEY_get0_public_key(CR);
-	PR_point = EC_KEY_get0_public_key(PR);
-	if (!bnctx || !sum || !m || !mx ||
-	    EC_POINT_add(group, sum, CR_point, PR_point, bnctx) != 1 ||
-	    EC_POINT_mul(group, m, NULL, sum, cI_bn, bnctx) != 1 ||
-	    EC_POINT_get_affine_coordinates_GFp(group, m, mx, NULL,
-						bnctx) != 1 ||
-	    dpp_bn2bin_pad(mx, Mx, curve->prime_len) < 0)
+	ec = crypto_ec_init(curve->ike_group);
+	if (!ec)
 		goto fail;
 
+	cI = crypto_ec_key_get_private_key(auth->conf->connector_key);
+	sum = crypto_ec_point_init(ec);
+	M = crypto_ec_point_init(ec);
+	CR = crypto_ec_key_get_public_key(peer_key);
+	PR = crypto_ec_key_get_public_key(auth->peer_protocol_key);
+	if (!cI || !sum || !M || !CR || !PR ||
+	    crypto_ec_point_add(ec, CR, PR, sum) ||
+	    crypto_ec_point_mul(ec, sum, cI, M) ||
+	    crypto_ec_point_to_bin(ec, M, Mx, NULL)) {
+		wpa_printf(MSG_ERROR, "DPP: Error during M computation");
+		goto fail;
+	}
+
 	wpa_hexdump_key(MSG_DEBUG, "DPP: M.x", Mx, curve->prime_len);
 
 	/* ke = HKDF(C-nonce | E-nonce, "dpp reconfig key", M.x) */
@@ -2448,12 +1835,11 @@
 fail:
 	forced_memzero(prk, sizeof(prk));
 	forced_memzero(Mx, sizeof(Mx));
-	EVP_PKEY_free(pr);
-	EVP_PKEY_free(peer_key);
-	EC_POINT_clear_free(sum);
-	EC_POINT_clear_free(m);
-	BN_clear_free(mx);
-	BN_CTX_free(bnctx);
+	crypto_ec_key_deinit(pr);
+	crypto_ec_key_deinit(peer_key);
+	crypto_ec_point_deinit(sum, 1);
+	crypto_ec_point_deinit(M, 1);
+	crypto_ec_deinit(ec);
 	return res;
 }
 
@@ -2489,78 +1875,56 @@
 			 size_t *signed3_len)
 {
 	const struct dpp_curve_params *curve;
+	struct wpabuf *sig = NULL;
 	char *signed3 = NULL;
-	unsigned char *signature = NULL;
-	const unsigned char *p;
-	size_t signature_len;
-	EVP_MD_CTX *md_ctx = NULL;
-	ECDSA_SIG *sig = NULL;
 	char *dot = ".";
-	const EVP_MD *sign_md;
-	const BIGNUM *r, *s;
+	const u8 *vector[3];
+	size_t vector_len[3];
+	u8 *hash;
+	int ret;
+
+	vector[0] = (const u8 *) signed1;
+	vector[1] = (const u8 *) dot;
+	vector[2] = (const u8 *) signed2;
+	vector_len[0] = signed1_len;
+	vector_len[1] = 1;
+	vector_len[2] = signed2_len;
 
 	curve = conf->curve;
+	hash = os_malloc(curve->hash_len);
+	if (!hash)
+		goto fail;
 	if (curve->hash_len == SHA256_MAC_LEN) {
-		sign_md = EVP_sha256();
+		ret = sha256_vector(3, vector, vector_len, hash);
 	} else if (curve->hash_len == SHA384_MAC_LEN) {
-		sign_md = EVP_sha384();
+		ret = sha384_vector(3, vector, vector_len, hash);
 	} else if (curve->hash_len == SHA512_MAC_LEN) {
-		sign_md = EVP_sha512();
+		ret = sha512_vector(3, vector, vector_len, hash);
 	} else {
 		wpa_printf(MSG_DEBUG, "DPP: Unknown signature algorithm");
 		goto fail;
 	}
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "DPP: Hash computation failed");
+		goto fail;
+	}
+	wpa_hexdump(MSG_DEBUG, "DPP: Hash value for Connector signature",
+		    hash, curve->hash_len);
 
-	md_ctx = EVP_MD_CTX_create();
-	if (!md_ctx)
+	sig = crypto_ec_key_sign_r_s(conf->csign, hash, curve->hash_len);
+	if (!sig) {
+		wpa_printf(MSG_ERROR, "DPP: Signature computation failed");
 		goto fail;
+	}
 
-	ERR_clear_error();
-	if (EVP_DigestSignInit(md_ctx, NULL, sign_md, NULL, conf->csign) != 1) {
-		wpa_printf(MSG_DEBUG, "DPP: EVP_DigestSignInit failed: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
-		goto fail;
-	}
-	if (EVP_DigestSignUpdate(md_ctx, signed1, signed1_len) != 1 ||
-	    EVP_DigestSignUpdate(md_ctx, dot, 1) != 1 ||
-	    EVP_DigestSignUpdate(md_ctx, signed2, signed2_len) != 1) {
-		wpa_printf(MSG_DEBUG, "DPP: EVP_DigestSignUpdate failed: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
-		goto fail;
-	}
-	if (EVP_DigestSignFinal(md_ctx, NULL, &signature_len) != 1) {
-		wpa_printf(MSG_DEBUG, "DPP: EVP_DigestSignFinal failed: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
-		goto fail;
-	}
-	signature = os_malloc(signature_len);
-	if (!signature)
-		goto fail;
-	if (EVP_DigestSignFinal(md_ctx, signature, &signature_len) != 1) {
-		wpa_printf(MSG_DEBUG, "DPP: EVP_DigestSignFinal failed: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
-		goto fail;
-	}
-	wpa_hexdump(MSG_DEBUG, "DPP: signedConnector ECDSA signature (DER)",
-		    signature, signature_len);
-	/* Convert to raw coordinates r,s */
-	p = signature;
-	sig = d2i_ECDSA_SIG(NULL, &p, signature_len);
-	if (!sig)
-		goto fail;
-	ECDSA_SIG_get0(sig, &r, &s);
-	if (dpp_bn2bin_pad(r, signature, curve->prime_len) < 0 ||
-	    dpp_bn2bin_pad(s, signature + curve->prime_len,
-			   curve->prime_len) < 0)
-		goto fail;
-	signature_len = 2 * curve->prime_len;
 	wpa_hexdump(MSG_DEBUG, "DPP: signedConnector ECDSA signature (raw r,s)",
-		    signature, signature_len);
-	signed3 = base64_url_encode(signature, signature_len, signed3_len);
+		    wpabuf_head(sig), wpabuf_len(sig));
+	signed3 = base64_url_encode(wpabuf_head(sig), wpabuf_len(sig),
+				    signed3_len);
+
 fail:
-	EVP_MD_CTX_destroy(md_ctx);
-	ECDSA_SIG_free(sig);
-	os_free(signature);
+	os_free(hash);
+	wpabuf_free(sig);
 	return signed3;
 }
 
@@ -2610,7 +1974,7 @@
 			      size_t net_access_key_len)
 {
 	struct wpabuf *pub = NULL;
-	EVP_PKEY *own_key;
+	struct crypto_ec_key *own_key;
 	struct dpp_pfs *pfs;
 
 	pfs = os_zalloc(sizeof(*pfs));
@@ -2623,7 +1987,7 @@
 		wpa_printf(MSG_ERROR, "DPP: Failed to parse own netAccessKey");
 		goto fail;
 	}
-	EVP_PKEY_free(own_key);
+	crypto_ec_key_deinit(own_key);
 
 	pfs->ecdh = crypto_ecdh_init(pfs->curve->ike_group);
 	if (!pfs->ecdh)
@@ -2688,19 +2052,15 @@
 
 struct wpabuf * dpp_build_csr(struct dpp_authentication *auth, const char *name)
 {
-	X509_REQ *req = NULL;
+	struct crypto_csr *csr = NULL;
 	struct wpabuf *buf = NULL;
-	unsigned char *der;
-	int der_len;
-	EVP_PKEY *key;
-	const EVP_MD *sign_md;
+	struct crypto_ec_key *key;
 	unsigned int hash_len = auth->curve->hash_len;
-	EC_KEY *eckey;
-	BIO *out = NULL;
+	struct wpabuf *priv_key;
 	u8 cp[DPP_CP_LEN];
-	char *password;
+	char *password = NULL;
 	size_t password_len;
-	int res;
+	int hash_sign_algo;
 
 	/* TODO: use auth->csrattrs */
 
@@ -2708,36 +2068,19 @@
 	 * a specific group to be used */
 	key = auth->own_protocol_key;
 
-	eckey = EVP_PKEY_get1_EC_KEY(key);
-	if (!eckey)
-		goto fail;
-	der = NULL;
-	der_len = i2d_ECPrivateKey(eckey, &der);
-	if (der_len <= 0)
+	priv_key = crypto_ec_key_get_ecprivate_key(key, true);
+	if (!priv_key)
 		goto fail;
 	wpabuf_free(auth->priv_key);
-	auth->priv_key = wpabuf_alloc_copy(der, der_len);
-	OPENSSL_free(der);
-	if (!auth->priv_key)
+	auth->priv_key = priv_key;
+
+	csr = crypto_csr_init();
+	if (!csr || crypto_csr_set_ec_public_key(csr, key))
 		goto fail;
 
-	req = X509_REQ_new();
-	if (!req || !X509_REQ_set_pubkey(req, key))
+	if (name && crypto_csr_set_name(csr, CSR_NAME_CN, name))
 		goto fail;
 
-	if (name) {
-		X509_NAME *n;
-
-		n = X509_REQ_get_subject_name(req);
-		if (!n)
-			goto fail;
-
-		if (X509_NAME_add_entry_by_txt(
-			    n, "CN", MBSTRING_UTF8,
-			    (const unsigned char *) name, -1, -1, 0) != 1)
-			goto fail;
-	}
-
 	/* cp = HKDF-Expand(bk, "CSR challengePassword", 64) */
 	if (dpp_hkdf_expand(hash_len, auth->bk, hash_len,
 			    "CSR challengePassword", cp, DPP_CP_LEN) < 0)
@@ -2747,222 +2090,75 @@
 			cp, DPP_CP_LEN);
 	password = base64_encode_no_lf(cp, DPP_CP_LEN, &password_len);
 	forced_memzero(cp, DPP_CP_LEN);
-	if (!password)
+	if (!password ||
+	    crypto_csr_set_attribute(csr, CSR_ATTR_CHALLENGE_PASSWORD,
+				     ASN1_TAG_UTF8STRING, (const u8 *) password,
+				     password_len))
 		goto fail;
 
-	res = X509_REQ_add1_attr_by_NID(req, NID_pkcs9_challengePassword,
-					V_ASN1_UTF8STRING,
-					(const unsigned char *) password,
-					password_len);
-	bin_clear_free(password, password_len);
-	if (!res)
-		goto fail;
-
-	/* TODO */
-
 	/* TODO: hash func selection based on csrAttrs */
 	if (hash_len == SHA256_MAC_LEN) {
-		sign_md = EVP_sha256();
+		hash_sign_algo = CRYPTO_HASH_ALG_SHA256;
 	} else if (hash_len == SHA384_MAC_LEN) {
-		sign_md = EVP_sha384();
+		hash_sign_algo = CRYPTO_HASH_ALG_SHA384;
 	} else if (hash_len == SHA512_MAC_LEN) {
-		sign_md = EVP_sha512();
+		hash_sign_algo = CRYPTO_HASH_ALG_SHA512;
 	} else {
 		wpa_printf(MSG_DEBUG, "DPP: Unknown signature algorithm");
 		goto fail;
 	}
 
-	if (!X509_REQ_sign(req, key, sign_md))
+	buf = crypto_csr_sign(csr, key, hash_sign_algo);
+	if (!buf)
 		goto fail;
-
-	der = NULL;
-	der_len = i2d_X509_REQ(req, &der);
-	if (der_len < 0)
-		goto fail;
-	buf = wpabuf_alloc_copy(der, der_len);
-	OPENSSL_free(der);
-
 	wpa_hexdump_buf(MSG_DEBUG, "DPP: CSR", buf);
 
 fail:
-	BIO_free_all(out);
-	X509_REQ_free(req);
+	bin_clear_free(password, password_len);
+	crypto_csr_deinit(csr);
 	return buf;
 }
 
 
-struct wpabuf * dpp_pkcs7_certs(const struct wpabuf *pkcs7)
+int dpp_validate_csr(struct dpp_authentication *auth,
+		     const struct wpabuf *csrbuf)
 {
-#ifdef OPENSSL_IS_BORINGSSL
-	CBS pkcs7_cbs;
-#else /* OPENSSL_IS_BORINGSSL */
-	PKCS7 *p7 = NULL;
-	const unsigned char *p = wpabuf_head(pkcs7);
-#endif /* OPENSSL_IS_BORINGSSL */
-	STACK_OF(X509) *certs;
-	int i, num;
-	BIO *out = NULL;
-	size_t rlen;
-	struct wpabuf *pem = NULL;
-	int res;
-
-#ifdef OPENSSL_IS_BORINGSSL
-	certs = sk_X509_new_null();
-	if (!certs)
-		goto fail;
-	CBS_init(&pkcs7_cbs, wpabuf_head(pkcs7), wpabuf_len(pkcs7));
-	if (!PKCS7_get_certificates(certs, &pkcs7_cbs)) {
-		wpa_printf(MSG_INFO, "DPP: Could not parse PKCS#7 object: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
-		goto fail;
-	}
-#else /* OPENSSL_IS_BORINGSSL */
-	p7 = d2i_PKCS7(NULL, &p, wpabuf_len(pkcs7));
-	if (!p7) {
-		wpa_printf(MSG_INFO, "DPP: Could not parse PKCS#7 object: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
-		goto fail;
-	}
-
-	switch (OBJ_obj2nid(p7->type)) {
-	case NID_pkcs7_signed:
-		certs = p7->d.sign->cert;
-		break;
-	case NID_pkcs7_signedAndEnveloped:
-		certs = p7->d.signed_and_enveloped->cert;
-		break;
-	default:
-		certs = NULL;
-		break;
-	}
-#endif /* OPENSSL_IS_BORINGSSL */
-
-	if (!certs || ((num = sk_X509_num(certs)) == 0)) {
-		wpa_printf(MSG_INFO,
-			   "DPP: No certificates found in PKCS#7 object");
-		goto fail;
-	}
-
-	out = BIO_new(BIO_s_mem());
-	if (!out)
-		goto fail;
-
-	for (i = 0; i < num; i++) {
-		X509 *cert = sk_X509_value(certs, i);
-
-		PEM_write_bio_X509(out, cert);
-	}
-
-	rlen = BIO_ctrl_pending(out);
-	pem = wpabuf_alloc(rlen);
-	if (!pem)
-		goto fail;
-	res = BIO_read(out, wpabuf_put(pem, 0), rlen);
-	if (res <= 0) {
-		wpabuf_free(pem);
-		pem = NULL;
-		goto fail;
-	}
-	wpabuf_put(pem, res);
-
-fail:
-#ifdef OPENSSL_IS_BORINGSSL
-	if (certs)
-		sk_X509_pop_free(certs, X509_free);
-#else /* OPENSSL_IS_BORINGSSL */
-	PKCS7_free(p7);
-#endif /* OPENSSL_IS_BORINGSSL */
-	if (out)
-		BIO_free_all(out);
-
-	return pem;
-}
-
-
-int dpp_validate_csr(struct dpp_authentication *auth, const struct wpabuf *csr)
-{
-	X509_REQ *req;
-	const unsigned char *pos;
-	EVP_PKEY *pkey;
-	int res, loc, ret = -1;
-	X509_ATTRIBUTE *attr;
-	ASN1_TYPE *type;
-	ASN1_STRING *str;
-	unsigned char *utf8 = NULL;
+	struct crypto_csr *csr;
+	const u8 *attr;
+	size_t attr_len;
+	int attr_type;
 	unsigned char *cp = NULL;
 	size_t cp_len;
 	u8 exp_cp[DPP_CP_LEN];
 	unsigned int hash_len = auth->curve->hash_len;
+	int ret = -1;
 
-	pos = wpabuf_head(csr);
-	req = d2i_X509_REQ(NULL, &pos, wpabuf_len(csr));
-	if (!req) {
-		wpa_printf(MSG_DEBUG, "DPP: Failed to parse CSR");
-		return -1;
-	}
-
-	pkey = X509_REQ_get_pubkey(req);
-	if (!pkey) {
-		wpa_printf(MSG_DEBUG, "DPP: Failed to get public key from CSR");
-		goto fail;
-	}
-
-	res = X509_REQ_verify(req, pkey);
-	EVP_PKEY_free(pkey);
-	if (res != 1) {
+	csr = crypto_csr_verify(csrbuf);
+	if (!csr) {
 		wpa_printf(MSG_DEBUG,
-			   "DPP: CSR does not have a valid signature");
+			   "DPP: CSR invalid or invalid signature");
 		goto fail;
 	}
 
-	loc = X509_REQ_get_attr_by_NID(req, NID_pkcs9_challengePassword, -1);
-	if (loc < 0) {
+	attr = crypto_csr_get_attribute(csr, CSR_ATTR_CHALLENGE_PASSWORD,
+					&attr_len, &attr_type);
+	if (!attr) {
 		wpa_printf(MSG_DEBUG,
 			   "DPP: CSR does not include challengePassword");
 		goto fail;
 	}
-
-	attr = X509_REQ_get_attr(req, loc);
-	if (!attr) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: Could not get challengePassword attribute");
-		goto fail;
-	}
-
-	type = X509_ATTRIBUTE_get0_type(attr, 0);
-	if (!type) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: Could not get challengePassword attribute type");
-		goto fail;
-	}
-
-	res = ASN1_TYPE_get(type);
 	/* This is supposed to be UTF8String, but allow other strings as well
 	 * since challengePassword is using ASCII (base64 encoded). */
-	if (res != V_ASN1_UTF8STRING && res != V_ASN1_PRINTABLESTRING &&
-	    res != V_ASN1_IA5STRING) {
+	if (attr_type != ASN1_TAG_UTF8STRING &&
+	    attr_type != ASN1_TAG_PRINTABLESTRING &&
+	    attr_type != ASN1_TAG_IA5STRING) {
 		wpa_printf(MSG_DEBUG,
 			   "DPP: Unexpected challengePassword attribute type %d",
-			   res);
+			   attr_type);
 		goto fail;
 	}
 
-	str = X509_ATTRIBUTE_get0_data(attr, 0, res, NULL);
-	if (!str) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: Could not get ASN.1 string for challengePassword");
-		goto fail;
-	}
-
-	res = ASN1_STRING_to_UTF8(&utf8, str);
-	if (res < 0) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: Could not get UTF8 version of challengePassword");
-		goto fail;
-	}
-
-	cp = base64_decode((const char *) utf8, res, &cp_len);
-	OPENSSL_free(utf8);
+	cp = base64_decode((const char *) attr, attr_len, &cp_len);
 	if (!cp) {
 		wpa_printf(MSG_DEBUG,
 			   "DPP: Could not base64 decode challengePassword");
@@ -2993,7 +2189,7 @@
 	ret = 0;
 fail:
 	os_free(cp);
-	X509_REQ_free(req);
+	crypto_csr_deinit(csr);
 	return ret;
 }
 
@@ -3003,50 +2199,46 @@
 					     const u8 *pp_key,
 					     size_t pp_key_len)
 {
-	const unsigned char *p;
-	EVP_PKEY *csign = NULL, *ppkey = NULL;
+	struct crypto_ec_key *csign = NULL, *ppkey = NULL;
 	struct dpp_reconfig_id *id = NULL;
-	BN_CTX *ctx = NULL;
-	BIGNUM *bn = NULL, *q = NULL;
-	const EC_KEY *eckey;
-	const EC_GROUP *group;
-	EC_POINT *e_id = NULL;
+	struct crypto_ec *ec = NULL;
+	const struct crypto_bignum *q;
+	struct crypto_bignum *bn = NULL;
+	struct crypto_ec_point *e_id = NULL;
+	const struct crypto_ec_point *generator;
 
-	p = csign_key;
-	csign = d2i_PUBKEY(NULL, &p, csign_key_len);
+	csign = crypto_ec_key_parse_pub(csign_key, csign_key_len);
 	if (!csign)
 		goto fail;
 
 	if (!pp_key)
 		goto fail;
-	p = pp_key;
-	ppkey = d2i_PUBKEY(NULL, &p, pp_key_len);
+	ppkey = crypto_ec_key_parse_pub(pp_key, pp_key_len);
 	if (!ppkey)
 		goto fail;
 
-	eckey = EVP_PKEY_get0_EC_KEY(csign);
-	if (!eckey)
-		goto fail;
-	group = EC_KEY_get0_group(eckey);
-	if (!group)
+	ec = crypto_ec_init(crypto_ec_key_group(csign));
+	if (!ec)
 		goto fail;
 
-	e_id = EC_POINT_new(group);
-	ctx = BN_CTX_new();
-	bn = BN_new();
-	q = BN_new();
-	if (!e_id || !ctx || !bn || !q ||
-	    !EC_GROUP_get_order(group, q, ctx) ||
-	    !BN_rand_range(bn, q) ||
-	    !EC_POINT_mul(group, e_id, bn, NULL, NULL, ctx))
+	e_id = crypto_ec_point_init(ec);
+	bn = crypto_bignum_init();
+	q = crypto_ec_get_order(ec);
+	generator = crypto_ec_get_generator(ec);
+	if (!e_id || !bn || !q || !generator ||
+	    crypto_bignum_rand(bn, q) ||
+	    crypto_ec_point_mul(ec, generator, bn, e_id))
 		goto fail;
 
-	dpp_debug_print_point("DPP: Generated random point E-id", group, e_id);
+	crypto_ec_point_debug_print(ec, e_id,
+				    "DPP: Generated random point E-id");
 
 	id = os_zalloc(sizeof(*id));
 	if (!id)
 		goto fail;
-	id->group = group;
+
+	id->ec = ec;
+	ec = NULL;
 	id->e_id = e_id;
 	e_id = NULL;
 	id->csign = csign;
@@ -3054,93 +2246,58 @@
 	id->pp_key = ppkey;
 	ppkey = NULL;
 fail:
-	EC_POINT_free(e_id);
-	EVP_PKEY_free(csign);
-	EVP_PKEY_free(ppkey);
-	BN_clear_free(bn);
-	BN_CTX_free(ctx);
+	crypto_ec_point_deinit(e_id, 1);
+	crypto_ec_key_deinit(csign);
+	crypto_ec_key_deinit(ppkey);
+	crypto_bignum_deinit(bn, 1);
+	crypto_ec_deinit(ec);
 	return id;
 }
 
 
-static EVP_PKEY * dpp_pkey_from_point(const EC_GROUP *group,
-				      const EC_POINT *point)
-{
-	EC_KEY *eckey;
-	EVP_PKEY *pkey = NULL;
-
-	eckey = EC_KEY_new();
-	if (!eckey ||
-	    EC_KEY_set_group(eckey, group) != 1 ||
-	    EC_KEY_set_public_key(eckey, point) != 1) {
-		wpa_printf(MSG_ERROR,
-			   "DPP: Failed to set EC_KEY: %s",
-			   ERR_error_string(ERR_get_error(), NULL));
-		goto fail;
-	}
-	EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE);
-
-	pkey = EVP_PKEY_new();
-	if (!pkey || EVP_PKEY_set1_EC_KEY(pkey, eckey) != 1) {
-		wpa_printf(MSG_ERROR, "DPP: Could not create EVP_PKEY");
-		EVP_PKEY_free(pkey);
-		pkey = NULL;
-		goto fail;
-	}
-
-fail:
-	EC_KEY_free(eckey);
-	return pkey;
-}
-
-
 int dpp_update_reconfig_id(struct dpp_reconfig_id *id)
 {
-	BN_CTX *ctx = NULL;
-	BIGNUM *bn = NULL, *q = NULL;
-	EC_POINT *e_prime_id = NULL, *a_nonce = NULL;
+	const struct crypto_bignum *q;
+	struct crypto_bignum *bn;
+	const struct crypto_ec_point *pp, *generator;
+	struct crypto_ec_point *e_prime_id, *a_nonce;
 	int ret = -1;
-	const EC_KEY *pp;
-	const EC_POINT *pp_point;
 
-	pp = EVP_PKEY_get0_EC_KEY(id->pp_key);
-	if (!pp)
-		goto fail;
-	pp_point = EC_KEY_get0_public_key(pp);
-	e_prime_id = EC_POINT_new(id->group);
-	a_nonce = EC_POINT_new(id->group);
-	ctx = BN_CTX_new();
-	bn = BN_new();
-	q = BN_new();
+	pp = crypto_ec_key_get_public_key(id->pp_key);
+	e_prime_id = crypto_ec_point_init(id->ec);
+	a_nonce = crypto_ec_point_init(id->ec);
+	bn = crypto_bignum_init();
+	q = crypto_ec_get_order(id->ec);
+	generator = crypto_ec_get_generator(id->ec);
+
 	/* Generate random 0 <= a-nonce < q
 	 * A-NONCE = a-nonce * G
 	 * E'-id = E-id + a-nonce * P_pk */
-	if (!pp_point || !e_prime_id || !a_nonce || !ctx || !bn || !q ||
-	    !EC_GROUP_get_order(id->group, q, ctx) ||
-	    !BN_rand_range(bn, q) || /* bn = a-nonce */
-	    !EC_POINT_mul(id->group, a_nonce, bn, NULL, NULL, ctx) ||
-	    !EC_POINT_mul(id->group, e_prime_id, NULL, pp_point, bn, ctx) ||
-	    !EC_POINT_add(id->group, e_prime_id, id->e_id, e_prime_id, ctx))
+	if (!pp || !e_prime_id || !a_nonce || !bn || !q || !generator ||
+	    crypto_bignum_rand(bn, q) || /* bn = a-nonce */
+	    crypto_ec_point_mul(id->ec, generator, bn, a_nonce) ||
+	    crypto_ec_point_mul(id->ec, pp, bn, e_prime_id) ||
+	    crypto_ec_point_add(id->ec, id->e_id, e_prime_id, e_prime_id))
 		goto fail;
 
-	dpp_debug_print_point("DPP: Generated A-NONCE", id->group, a_nonce);
-	dpp_debug_print_point("DPP: Encrypted E-id to E'-id",
-			      id->group, e_prime_id);
+	crypto_ec_point_debug_print(id->ec, a_nonce,
+				    "DPP: Generated A-NONCE");
+	crypto_ec_point_debug_print(id->ec, e_prime_id,
+				    "DPP: Encrypted E-id to E'-id");
 
-	EVP_PKEY_free(id->a_nonce);
-	EVP_PKEY_free(id->e_prime_id);
-	id->a_nonce = dpp_pkey_from_point(id->group, a_nonce);
-	id->e_prime_id = dpp_pkey_from_point(id->group, e_prime_id);
+	crypto_ec_key_deinit(id->a_nonce);
+	crypto_ec_key_deinit(id->e_prime_id);
+	id->a_nonce = crypto_ec_key_set_pub_point(id->ec, a_nonce);
+	id->e_prime_id = crypto_ec_key_set_pub_point(id->ec, e_prime_id);
 	if (!id->a_nonce || !id->e_prime_id)
 		goto fail;
 
 	ret = 0;
 
 fail:
-	EC_POINT_free(e_prime_id);
-	EC_POINT_free(a_nonce);
-	BN_clear_free(bn);
-	BN_CTX_free(ctx);
+	crypto_ec_point_deinit(e_prime_id, 1);
+	crypto_ec_point_deinit(a_nonce, 1);
+	crypto_bignum_deinit(bn, 1);
 	return ret;
 }
 
@@ -3148,55 +2305,50 @@
 void dpp_free_reconfig_id(struct dpp_reconfig_id *id)
 {
 	if (id) {
-		EC_POINT_clear_free(id->e_id);
-		EVP_PKEY_free(id->csign);
-		EVP_PKEY_free(id->a_nonce);
-		EVP_PKEY_free(id->e_prime_id);
-		EVP_PKEY_free(id->pp_key);
+		crypto_ec_point_deinit(id->e_id, 1);
+		crypto_ec_key_deinit(id->csign);
+		crypto_ec_key_deinit(id->a_nonce);
+		crypto_ec_key_deinit(id->e_prime_id);
+		crypto_ec_key_deinit(id->pp_key);
+		crypto_ec_deinit(id->ec);
 		os_free(id);
 	}
 }
 
 
-EC_POINT * dpp_decrypt_e_id(EVP_PKEY *ppkey, EVP_PKEY *a_nonce,
-			    EVP_PKEY *e_prime_id)
+struct crypto_ec_point * dpp_decrypt_e_id(struct crypto_ec_key *ppkey,
+					  struct crypto_ec_key *a_nonce,
+					  struct crypto_ec_key *e_prime_id)
 {
-	const EC_KEY *pp_ec, *a_nonce_ec, *e_prime_id_ec;
-	const BIGNUM *pp_bn;
-	const EC_GROUP *group;
-	EC_POINT *e_id = NULL;
-	const EC_POINT *a_nonce_point, *e_prime_id_point;
-	BN_CTX *ctx = NULL;
+	struct crypto_ec *ec;
+	const struct crypto_bignum *pp;
+	struct crypto_ec_point *e_id = NULL;
+	const struct crypto_ec_point *a_nonce_point, *e_prime_id_point;
 
 	if (!ppkey)
 		return NULL;
 
 	/* E-id = E'-id - s_C * A-NONCE */
-	pp_ec = EVP_PKEY_get0_EC_KEY(ppkey);
-	a_nonce_ec = EVP_PKEY_get0_EC_KEY(a_nonce);
-	e_prime_id_ec = EVP_PKEY_get0_EC_KEY(e_prime_id);
-	if (!pp_ec || !a_nonce_ec || !e_prime_id_ec)
+	ec = crypto_ec_init(crypto_ec_key_group(ppkey));
+	if (!ec)
 		return NULL;
-	pp_bn = EC_KEY_get0_private_key(pp_ec);
-	group = EC_KEY_get0_group(pp_ec);
-	a_nonce_point = EC_KEY_get0_public_key(a_nonce_ec);
-	e_prime_id_point = EC_KEY_get0_public_key(e_prime_id_ec);
-	ctx = BN_CTX_new();
-	if (!pp_bn || !group || !a_nonce_point || !e_prime_id_point || !ctx)
-		goto fail;
-	e_id = EC_POINT_new(group);
-	if (!e_id ||
-	    !EC_POINT_mul(group, e_id, NULL, a_nonce_point, pp_bn, ctx) ||
-	    !EC_POINT_invert(group, e_id, ctx) ||
-	    !EC_POINT_add(group, e_id, e_prime_id_point, e_id, ctx)) {
-		EC_POINT_clear_free(e_id);
+
+	pp = crypto_ec_key_get_private_key(ppkey);
+	a_nonce_point = crypto_ec_key_get_public_key(a_nonce);
+	e_prime_id_point = crypto_ec_key_get_public_key(e_prime_id);
+	e_id = crypto_ec_point_init(ec);
+	if (!pp || !a_nonce_point || !e_prime_id_point || !e_id ||
+	    crypto_ec_point_mul(ec, a_nonce_point, pp, e_id) ||
+	    crypto_ec_point_invert(ec, e_id) ||
+	    crypto_ec_point_add(ec, e_id, e_prime_id_point, e_id)) {
+		crypto_ec_point_deinit(e_id, 1);
 		goto fail;
 	}
 
-	dpp_debug_print_point("DPP: Decrypted E-id", group, e_id);
+	crypto_ec_point_debug_print(ec, e_id, "DPP: Decrypted E-id");
 
 fail:
-	BN_CTX_free(ctx);
+	crypto_ec_deinit(ec);
 	return e_id;
 }
 
@@ -3208,64 +2360,46 @@
 int dpp_test_gen_invalid_key(struct wpabuf *msg,
 			     const struct dpp_curve_params *curve)
 {
-	BN_CTX *ctx;
-	BIGNUM *x, *y;
+	struct crypto_ec *ec;
+	struct crypto_ec_key *key = NULL;
+	const struct crypto_ec_point *pub_key;
+	struct crypto_ec_point *p = NULL;
+	u8 *x, *y;
 	int ret = -1;
-	EC_GROUP *group;
-	EC_POINT *point;
 
-	group = EC_GROUP_new_by_curve_name(OBJ_txt2nid(curve->name));
-	if (!group)
-		return -1;
-
-	ctx = BN_CTX_new();
-	point = EC_POINT_new(group);
-	x = BN_new();
-	y = BN_new();
-	if (!ctx || !point || !x || !y)
+	ec = crypto_ec_init(curve->ike_group);
+	x = wpabuf_put(msg, curve->prime_len);
+	y = wpabuf_put(msg, curve->prime_len);
+	if (!ec)
 		goto fail;
 
-	if (BN_rand(x, curve->prime_len * 8, 0, 0) != 1)
+retry:
+	/* Generate valid key pair */
+	key = crypto_ec_key_gen(curve->ike_group);
+	if (!key)
 		goto fail;
 
-	/* Generate a random y coordinate that results in a point that is not
-	 * on the curve. */
-	for (;;) {
-		if (BN_rand(y, curve->prime_len * 8, 0, 0) != 1)
-			goto fail;
+	/* Retrieve public key coordinates */
+	pub_key = crypto_ec_key_get_public_key(key);
+	if (!pub_key)
+		goto fail;
 
-		if (EC_POINT_set_affine_coordinates_GFp(group, point, x, y,
-							ctx) != 1) {
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L || defined(OPENSSL_IS_BORINGSSL)
-		/* Unlike older OpenSSL versions, OpenSSL 1.1.1 and BoringSSL
-		 * return an error from EC_POINT_set_affine_coordinates_GFp()
-		 * when the point is not on the curve. */
-			break;
-#else /* >=1.1.0 or OPENSSL_IS_BORINGSSL */
-			goto fail;
-#endif /* >= 1.1.0 or OPENSSL_IS_BORINGSSL */
-		}
+	crypto_ec_point_to_bin(ec, pub_key, x, y);
 
-		if (!EC_POINT_is_on_curve(group, point, ctx))
-			break;
+	/* And corrupt them */
+	y[curve->prime_len - 1] ^= 0x01;
+	p = crypto_ec_point_from_bin(ec, x);
+	if (p && crypto_ec_point_is_on_curve(ec, p)) {
+		crypto_ec_point_deinit(p, 0);
+		p = NULL;
+		goto retry;
 	}
 
-	if (dpp_bn2bin_pad(x, wpabuf_put(msg, curve->prime_len),
-			   curve->prime_len) < 0 ||
-	    dpp_bn2bin_pad(y, wpabuf_put(msg, curve->prime_len),
-			   curve->prime_len) < 0)
-		goto fail;
-
 	ret = 0;
 fail:
-	if (ret < 0)
-		wpa_printf(MSG_INFO, "DPP: Failed to generate invalid key");
-	BN_free(x);
-	BN_free(y);
-	EC_POINT_free(point);
-	BN_CTX_free(ctx);
-	EC_GROUP_free(group);
-
+	crypto_ec_point_deinit(p, 0);
+	crypto_ec_key_deinit(key);
+	crypto_ec_deinit(ec);
 	return ret;
 }
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_i.h b/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_i.h
index af12467..c00b1ee 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_i.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_i.h
@@ -37,10 +37,11 @@
 struct json_token * dpp_parse_own_connector(const char *own_connector);
 int dpp_connector_match_groups(struct json_token *own_root,
 			       struct json_token *peer_root, bool reconfig);
-int dpp_build_jwk(struct wpabuf *buf, const char *name, EVP_PKEY *key,
-		  const char *kid, const struct dpp_curve_params *curve);
-EVP_PKEY * dpp_parse_jwk(struct json_token *jwk,
-			 const struct dpp_curve_params **key_curve);
+int dpp_build_jwk(struct wpabuf *buf, const char *name,
+		  struct crypto_ec_key *key, const char *kid,
+		  const struct dpp_curve_params *curve);
+struct crypto_ec_key * dpp_parse_jwk(struct json_token *jwk,
+				     const struct dpp_curve_params **key_curve);
 int dpp_prepare_channel_list(struct dpp_authentication *auth,
 			     unsigned int neg_freq,
 			     struct hostapd_hw_modes *own_modes, u16 num_modes);
@@ -65,32 +66,27 @@
 
 enum dpp_status_error
 dpp_process_signed_connector(struct dpp_signed_connector_info *info,
-			     EVP_PKEY *csign_pub, const char *connector);
+			     struct crypto_ec_key *csign_pub,
+			     const char *connector);
 enum dpp_status_error
 dpp_check_signed_connector(struct dpp_signed_connector_info *info,
 			   const u8 *csign_key, size_t csign_key_len,
 			   const u8 *peer_connector, size_t peer_connector_len);
 const struct dpp_curve_params * dpp_get_curve_name(const char *name);
 const struct dpp_curve_params * dpp_get_curve_jwk_crv(const char *name);
-const struct dpp_curve_params * dpp_get_curve_nid(int nid);
 const struct dpp_curve_params * dpp_get_curve_ike_group(u16 group);
 int dpp_bi_pubkey_hash(struct dpp_bootstrap_info *bi,
 		       const u8 *data, size_t data_len);
-struct wpabuf * dpp_get_pubkey_point(EVP_PKEY *pkey, int prefix);
-EVP_PKEY * dpp_set_pubkey_point_group(const EC_GROUP *group,
-				      const u8 *buf_x, const u8 *buf_y,
-				      size_t len);
-EVP_PKEY * dpp_set_pubkey_point(EVP_PKEY *group_key, const u8 *buf, size_t len);
-int dpp_bn2bin_pad(const BIGNUM *bn, u8 *pos, size_t len);
+struct crypto_ec_key * dpp_set_pubkey_point(struct crypto_ec_key *group_key,
+					    const u8 *buf, size_t len);
 int dpp_hkdf_expand(size_t hash_len, const u8 *secret, size_t secret_len,
 		    const char *label, u8 *out, size_t outlen);
 int dpp_hmac_vector(size_t hash_len, const u8 *key, size_t key_len,
 		    size_t num_elem, const u8 *addr[], const size_t *len,
 		    u8 *mac);
-int dpp_ecdh(EVP_PKEY *own, EVP_PKEY *peer, u8 *secret, size_t *secret_len);
-void dpp_debug_print_point(const char *title, const EC_GROUP *group,
-			   const EC_POINT *point);
-void dpp_debug_print_key(const char *title, EVP_PKEY *key);
+int dpp_ecdh(struct crypto_ec_key *own, struct crypto_ec_key *peer,
+	     u8 *secret, size_t *secret_len);
+void dpp_debug_print_key(const char *title, struct crypto_ec_key *key);
 int dpp_pbkdf2(size_t hash_len, const u8 *password, size_t password_len,
 	       const u8 *salt, size_t salt_len, unsigned int iterations,
 	       u8 *buf, size_t buflen);
@@ -99,9 +95,9 @@
 int dpp_bootstrap_key_hash(struct dpp_bootstrap_info *bi);
 int dpp_keygen(struct dpp_bootstrap_info *bi, const char *curve,
 	       const u8 *privkey, size_t privkey_len);
-EVP_PKEY * dpp_set_keypair(const struct dpp_curve_params **curve,
-			   const u8 *privkey, size_t privkey_len);
-EVP_PKEY * dpp_gen_keypair(const struct dpp_curve_params *curve);
+struct crypto_ec_key * dpp_set_keypair(const struct dpp_curve_params **curve,
+				       const u8 *privkey, size_t privkey_len);
+struct crypto_ec_key * dpp_gen_keypair(const struct dpp_curve_params *curve);
 int dpp_derive_k1(const u8 *Mx, size_t Mx_len, u8 *k1, unsigned int hash_len);
 int dpp_derive_k2(const u8 *Nx, size_t Nx_len, u8 *k2, unsigned int hash_len);
 int dpp_derive_bk_ke(struct dpp_authentication *auth);
@@ -111,16 +107,18 @@
 int dpp_auth_derive_l_initiator(struct dpp_authentication *auth);
 int dpp_derive_pmk(const u8 *Nx, size_t Nx_len, u8 *pmk, unsigned int hash_len);
 int dpp_derive_pmkid(const struct dpp_curve_params *curve,
-		     EVP_PKEY *own_key, EVP_PKEY *peer_key, u8 *pmkid);
-EC_POINT * dpp_pkex_derive_Qi(const struct dpp_curve_params *curve,
-			      const u8 *mac_init, const char *code,
-			      const char *identifier, BN_CTX *bnctx,
-			      EC_GROUP **ret_group);
-EC_POINT * dpp_pkex_derive_Qr(const struct dpp_curve_params *curve,
-			      const u8 *mac_resp, const char *code,
-			      const char *identifier, BN_CTX *bnctx,
-			      EC_GROUP **ret_group);
+		     struct crypto_ec_key *own_key,
+		     struct crypto_ec_key *peer_key, u8 *pmkid);
+struct crypto_ec_point *
+dpp_pkex_derive_Qi(const struct dpp_curve_params *curve, const u8 *mac_init,
+		   const char *code, const char *identifier,
+		   struct crypto_ec **ret_ec);
+struct crypto_ec_point *
+dpp_pkex_derive_Qr(const struct dpp_curve_params *curve, const u8 *mac_resp,
+		   const char *code, const char *identifier,
+		   struct crypto_ec **ret_ec);
 int dpp_pkex_derive_z(const u8 *mac_init, const u8 *mac_resp,
+		      u8 ver_init, u8 ver_resp,
 		      const u8 *Mx, size_t Mx_len,
 		      const u8 *Nx, size_t Nx_len,
 		      const char *code,
@@ -133,20 +131,21 @@
 int dpp_reconfig_derive_ke_initiator(struct dpp_authentication *auth,
 				     const u8 *r_proto, u16 r_proto_len,
 				     struct json_token *net_access_key);
-EC_POINT * dpp_decrypt_e_id(EVP_PKEY *ppkey, EVP_PKEY *a_nonce,
-			    EVP_PKEY *e_prime_id);
+struct crypto_ec_point * dpp_decrypt_e_id(struct crypto_ec_key *ppkey,
+					  struct crypto_ec_key *a_nonce,
+					  struct crypto_ec_key *e_prime_id);
 char * dpp_sign_connector(struct dpp_configurator *conf,
 			  const struct wpabuf *dppcon);
 int dpp_test_gen_invalid_key(struct wpabuf *msg,
 			     const struct dpp_curve_params *curve);
 
 struct dpp_reconfig_id {
-	const EC_GROUP *group;
-	EC_POINT *e_id; /* E-id */
-	EVP_PKEY *csign;
-	EVP_PKEY *a_nonce; /* A-NONCE */
-	EVP_PKEY *e_prime_id; /* E'-id */
-	EVP_PKEY *pp_key;
+	struct crypto_ec *ec;
+	struct crypto_ec_point *e_id; /* E-id */
+	struct crypto_ec_key *csign;
+	struct crypto_ec_key *a_nonce; /* A-NONCE */
+	struct crypto_ec_key *e_prime_id; /* E'-id */
+	struct crypto_ec_key *pp_key;
 };
 
 /* dpp_tcp.c */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_pkex.c b/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_pkex.c
index e42f7fb..38349fa 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_pkex.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_pkex.c
@@ -8,8 +8,6 @@
  */
 
 #include "utils/includes.h"
-#include <openssl/opensslv.h>
-#include <openssl/err.h>
 
 #include "utils/common.h"
 #include "common/wpa_ctrl.h"
@@ -27,43 +25,24 @@
 size_t dpp_pkex_ephemeral_key_override_len = 0;
 #endif /* CONFIG_TESTING_OPTIONS */
 
-#if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && \
-	LIBRESSL_VERSION_NUMBER < 0x20700000L)
-/* Compatibility wrappers for older versions. */
 
-#ifndef ABOVE_8_1
-static EC_KEY * EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
+static struct wpabuf * dpp_pkex_build_exchange_req(struct dpp_pkex *pkex,
+						   bool v2)
 {
-	if (pkey->type != EVP_PKEY_EC)
-		return NULL;
-	return pkey->pkey.ec;
-}
-#endif /* ABOVE_8_1 */
-
-#endif
-
-
-static struct wpabuf * dpp_pkex_build_exchange_req(struct dpp_pkex *pkex)
-{
-	const EC_KEY *X_ec;
-	const EC_POINT *X_point;
-	BN_CTX *bnctx = NULL;
-	EC_GROUP *group = NULL;
-	EC_POINT *Qi = NULL, *M = NULL;
-	struct wpabuf *M_buf = NULL;
-	BIGNUM *Mx = NULL, *My = NULL;
+	struct crypto_ec *ec = NULL;
+	const struct crypto_ec_point *X;
+	struct crypto_ec_point *Qi = NULL, *M = NULL;
+	u8 *Mx, *My;
 	struct wpabuf *msg = NULL;
 	size_t attr_len;
 	const struct dpp_curve_params *curve = pkex->own_bi->curve;
 
-	wpa_printf(MSG_DEBUG, "DPP: Build PKEX Exchange Request");
+	wpa_printf(MSG_DEBUG, "DPP: Build PKEX %sExchange Request",
+		   v2 ? "" : "Version 1 ");
 
-	/* Qi = H(MAC-Initiator | [identifier |] code) * Pi */
-	bnctx = BN_CTX_new();
-	if (!bnctx)
-		goto fail;
-	Qi = dpp_pkex_derive_Qi(curve, pkex->own_mac, pkex->code,
-				pkex->identifier, bnctx, &group);
+	/* Qi = H([MAC-Initiator |] [identifier |] code) * Pi */
+	Qi = dpp_pkex_derive_Qi(curve, v2 ? NULL : pkex->own_mac, pkex->code,
+				pkex->identifier, &ec);
 	if (!Qi)
 		goto fail;
 
@@ -87,31 +66,39 @@
 		goto fail;
 
 	/* M = X + Qi */
-	X_ec = EVP_PKEY_get0_EC_KEY(pkex->x);
-	if (!X_ec)
+	X = crypto_ec_key_get_public_key(pkex->x);
+	M = crypto_ec_point_init(ec);
+	if (!X || !M)
 		goto fail;
-	X_point = EC_KEY_get0_public_key(X_ec);
-	if (!X_point)
+	crypto_ec_point_debug_print(ec, X, "DPP: X");
+
+	if (crypto_ec_point_add(ec, X, Qi, M))
 		goto fail;
-	dpp_debug_print_point("DPP: X", group, X_point);
-	M = EC_POINT_new(group);
-	Mx = BN_new();
-	My = BN_new();
-	if (!M || !Mx || !My ||
-	    EC_POINT_add(group, M, X_point, Qi, bnctx) != 1 ||
-	    EC_POINT_get_affine_coordinates_GFp(group, M, Mx, My, bnctx) != 1)
-		goto fail;
-	dpp_debug_print_point("DPP: M", group, M);
+	crypto_ec_point_debug_print(ec, M, "DPP: M");
 
 	/* Initiator -> Responder: group, [identifier,] M */
 	attr_len = 4 + 2;
+#ifdef CONFIG_DPP2
+	if (v2)
+		attr_len += 4 + 1;
+#endif /* CONFIG_DPP2 */
 	if (pkex->identifier)
 		attr_len += 4 + os_strlen(pkex->identifier);
 	attr_len += 4 + 2 * curve->prime_len;
-	msg = dpp_alloc_msg(DPP_PA_PKEX_EXCHANGE_REQ, attr_len);
+	msg = dpp_alloc_msg(v2 ? DPP_PA_PKEX_EXCHANGE_REQ :
+			    DPP_PA_PKEX_V1_EXCHANGE_REQ, attr_len);
 	if (!msg)
 		goto fail;
 
+#ifdef CONFIG_DPP2
+	if (v2) {
+		/* Protocol Version */
+		wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
+		wpabuf_put_le16(msg, 1);
+		wpabuf_put_u8(msg, DPP_VERSION);
+	}
+#endif /* CONFIG_DPP2 */
+
 #ifdef CONFIG_TESTING_OPTIONS
 	if (dpp_test == DPP_TEST_NO_FINITE_CYCLIC_GROUP_PKEX_EXCHANGE_REQ) {
 		wpa_printf(MSG_INFO, "DPP: TESTING - no Finite Cyclic Group");
@@ -155,21 +142,17 @@
 	}
 #endif /* CONFIG_TESTING_OPTIONS */
 
-	if (dpp_bn2bin_pad(Mx, wpabuf_put(msg, curve->prime_len),
-			   curve->prime_len) < 0 ||
-	    dpp_bn2bin_pad(Mx, pkex->Mx, curve->prime_len) < 0 ||
-	    dpp_bn2bin_pad(My, wpabuf_put(msg, curve->prime_len),
-			   curve->prime_len) < 0)
+	Mx = wpabuf_put(msg, curve->prime_len);
+	My = wpabuf_put(msg, curve->prime_len);
+	if (crypto_ec_point_to_bin(ec, M, Mx, My))
 		goto fail;
 
+	os_memcpy(pkex->Mx, Mx, curve->prime_len);
+
 out:
-	wpabuf_free(M_buf);
-	EC_POINT_free(M);
-	EC_POINT_free(Qi);
-	BN_clear_free(Mx);
-	BN_clear_free(My);
-	BN_CTX_free(bnctx);
-	EC_GROUP_free(group);
+	crypto_ec_point_deinit(M, 1);
+	crypto_ec_point_deinit(Qi, 1);
+	crypto_ec_deinit(ec);
 	return msg;
 fail:
 	wpa_printf(MSG_INFO, "DPP: Failed to build PKEX Exchange Request");
@@ -187,8 +170,8 @@
 
 struct dpp_pkex * dpp_pkex_init(void *msg_ctx, struct dpp_bootstrap_info *bi,
 				const u8 *own_mac,
-				const char *identifier,
-				const char *code)
+				const char *identifier, const char *code,
+				bool v2)
 {
 	struct dpp_pkex *pkex;
 
@@ -205,6 +188,7 @@
 		return NULL;
 	pkex->msg_ctx = msg_ctx;
 	pkex->initiator = 1;
+	pkex->v2 = v2;
 	pkex->own_bi = bi;
 	os_memcpy(pkex->own_mac, own_mac, ETH_ALEN);
 	if (identifier) {
@@ -215,7 +199,7 @@
 	pkex->code = os_strdup(code);
 	if (!pkex->code)
 		goto fail;
-	pkex->exchange_req = dpp_pkex_build_exchange_req(pkex);
+	pkex->exchange_req = dpp_pkex_build_exchange_req(pkex, v2);
 	if (!pkex->exchange_req)
 		goto fail;
 	return pkex;
@@ -228,14 +212,19 @@
 static struct wpabuf *
 dpp_pkex_build_exchange_resp(struct dpp_pkex *pkex,
 			     enum dpp_status_error status,
-			     const BIGNUM *Nx, const BIGNUM *Ny)
+			     const u8 *Nx, const u8 *Ny)
 {
 	struct wpabuf *msg = NULL;
 	size_t attr_len;
 	const struct dpp_curve_params *curve = pkex->own_bi->curve;
 
-	/* Initiator -> Responder: DPP Status, [identifier,] N */
+	/* Initiator -> Responder: DPP Status, [Protocol Version,] [identifier,]
+	 * N */
 	attr_len = 4 + 1;
+#ifdef CONFIG_DPP2
+	if (pkex->v2)
+		attr_len += 4 + 1;
+#endif /* CONFIG_DPP2 */
 	if (pkex->identifier)
 		attr_len += 4 + os_strlen(pkex->identifier);
 	attr_len += 4 + 2 * curve->prime_len;
@@ -262,6 +251,15 @@
 skip_status:
 #endif /* CONFIG_TESTING_OPTIONS */
 
+#ifdef CONFIG_DPP2
+	if (pkex->v2) {
+		/* Protocol Version */
+		wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
+		wpabuf_put_le16(msg, 1);
+		wpabuf_put_u8(msg, DPP_VERSION);
+	}
+#endif /* CONFIG_DPP2 */
+
 	/* Code Identifier attribute */
 	if (pkex->identifier) {
 		wpabuf_put_le16(msg, DPP_ATTR_CODE_IDENTIFIER);
@@ -292,12 +290,9 @@
 	}
 #endif /* CONFIG_TESTING_OPTIONS */
 
-	if (dpp_bn2bin_pad(Nx, wpabuf_put(msg, curve->prime_len),
-			   curve->prime_len) < 0 ||
-	    dpp_bn2bin_pad(Nx, pkex->Nx, curve->prime_len) < 0 ||
-	    dpp_bn2bin_pad(Ny, wpabuf_put(msg, curve->prime_len),
-			   curve->prime_len) < 0)
-		goto fail;
+	wpabuf_put_data(msg, Nx, curve->prime_len);
+	wpabuf_put_data(msg, Ny, curve->prime_len);
+	os_memcpy(pkex->Nx, Nx, curve->prime_len);
 
 skip_encrypted_key:
 	if (status == DPP_STATUS_BAD_GROUP) {
@@ -346,24 +341,22 @@
 					   const u8 *peer_mac,
 					   const char *identifier,
 					   const char *code,
-					   const u8 *buf, size_t len)
+					   const u8 *buf, size_t len, bool v2)
 {
 	const u8 *attr_group, *attr_id, *attr_key;
 	u16 attr_group_len, attr_id_len, attr_key_len;
 	const struct dpp_curve_params *curve = bi->curve;
 	u16 ike_group;
 	struct dpp_pkex *pkex = NULL;
-	EC_POINT *Qi = NULL, *Qr = NULL, *M = NULL, *X = NULL, *N = NULL;
-	BN_CTX *bnctx = NULL;
-	EC_GROUP *group = NULL;
-	BIGNUM *Mx = NULL, *My = NULL;
-	const EC_KEY *Y_ec;
-	EC_KEY *X_ec = NULL;
-	const EC_POINT *Y_point;
-	BIGNUM *Nx = NULL, *Ny = NULL;
+	struct crypto_ec_point *Qi = NULL, *Qr = NULL, *M = NULL, *X = NULL,
+		*N = NULL;
+	struct crypto_ec *ec = NULL;
+	const struct crypto_ec_point *Y;
+	u8 *x_coord = NULL, *y_coord = NULL;
 	u8 Kx[DPP_MAX_SHARED_SECRET_LEN];
 	size_t Kx_len;
 	int res;
+	u8 peer_version = 0;
 
 	if (bi->pkex_t >= PKEX_COUNTER_T_LIMIT) {
 		wpa_msg(msg_ctx, MSG_INFO, DPP_EVENT_FAIL
@@ -371,6 +364,24 @@
 		return NULL;
 	}
 
+#ifdef CONFIG_DPP2
+	if (v2) {
+		const u8 *version;
+		u16 version_len;
+
+		version = dpp_get_attr(buf, len, DPP_ATTR_PROTOCOL_VERSION,
+				       &version_len);
+		if (!version || version_len < 1 || version[0] == 0) {
+			wpa_msg(msg_ctx, MSG_INFO,
+				"Missing or invalid Protocol Version attribute");
+			return NULL;
+		}
+		peer_version = version[0];
+		wpa_printf(MSG_DEBUG, "DPP: Peer protocol version %u",
+			   peer_version);
+	}
+#endif /* CONFIG_DPP2 */
+
 #ifdef CONFIG_TESTING_OPTIONS
 	if (!is_zero_ether_addr(dpp_pkex_peer_mac_override)) {
 		wpa_printf(MSG_INFO, "DPP: TESTING - peer_mac override " MACSTR,
@@ -405,6 +416,8 @@
 		pkex = os_zalloc(sizeof(*pkex));
 		if (!pkex)
 			goto fail;
+		pkex->v2 = v2;
+		pkex->peer_version = peer_version;
 		pkex->own_bi = bi;
 		pkex->failed = 1;
 		pkex->exchange_resp = dpp_pkex_build_exchange_resp(
@@ -424,39 +437,35 @@
 		return NULL;
 	}
 
-	/* Qi = H(MAC-Initiator | [identifier |] code) * Pi */
-	bnctx = BN_CTX_new();
-	if (!bnctx)
-		goto fail;
-	Qi = dpp_pkex_derive_Qi(curve, peer_mac, code, identifier, bnctx,
-				&group);
+	/* Qi = H([MAC-Initiator |] [identifier |] code) * Pi */
+	Qi = dpp_pkex_derive_Qi(curve, v2 ? NULL : peer_mac, code, identifier,
+				&ec);
 	if (!Qi)
 		goto fail;
 
 	/* X' = M - Qi */
-	X = EC_POINT_new(group);
-	M = EC_POINT_new(group);
-	Mx = BN_bin2bn(attr_key, attr_key_len / 2, NULL);
-	My = BN_bin2bn(attr_key + attr_key_len / 2, attr_key_len / 2, NULL);
-	if (!X || !M || !Mx || !My ||
-	    EC_POINT_set_affine_coordinates_GFp(group, M, Mx, My, bnctx) != 1 ||
-	    EC_POINT_is_at_infinity(group, M) ||
-	    !EC_POINT_is_on_curve(group, M, bnctx) ||
-	    EC_POINT_invert(group, Qi, bnctx) != 1 ||
-	    EC_POINT_add(group, X, M, Qi, bnctx) != 1 ||
-	    EC_POINT_is_at_infinity(group, X) ||
-	    !EC_POINT_is_on_curve(group, X, bnctx)) {
+	X = crypto_ec_point_init(ec);
+	M = crypto_ec_point_from_bin(ec, attr_key);
+	if (!X || !M ||
+	    crypto_ec_point_is_at_infinity(ec, M) ||
+	    !crypto_ec_point_is_on_curve(ec, M) ||
+	    crypto_ec_point_invert(ec, Qi) ||
+	    crypto_ec_point_add(ec, M, Qi, X) ||
+	    crypto_ec_point_is_at_infinity(ec, X) ||
+	    !crypto_ec_point_is_on_curve(ec, X)) {
 		wpa_msg(msg_ctx, MSG_INFO, DPP_EVENT_FAIL
 			"Invalid Encrypted Key value");
 		bi->pkex_t++;
 		goto fail;
 	}
-	dpp_debug_print_point("DPP: M", group, M);
-	dpp_debug_print_point("DPP: X'", group, X);
+	crypto_ec_point_debug_print(ec, M, "DPP: M");
+	crypto_ec_point_debug_print(ec, X, "DPP: X'");
 
 	pkex = os_zalloc(sizeof(*pkex));
 	if (!pkex)
 		goto fail;
+	pkex->v2 = v2;
+	pkex->peer_version = peer_version;
 	pkex->t = bi->pkex_t;
 	pkex->msg_ctx = msg_ctx;
 	pkex->own_bi = bi;
@@ -473,18 +482,20 @@
 
 	os_memcpy(pkex->Mx, attr_key, attr_key_len / 2);
 
-	X_ec = EC_KEY_new();
-	if (!X_ec ||
-	    EC_KEY_set_group(X_ec, group) != 1 ||
-	    EC_KEY_set_public_key(X_ec, X) != 1)
-		goto fail;
-	pkex->x = EVP_PKEY_new();
-	if (!pkex->x ||
-	    EVP_PKEY_set1_EC_KEY(pkex->x, X_ec) != 1)
+	x_coord = os_malloc(curve->prime_len);
+	y_coord = os_malloc(curve->prime_len);
+	if (!x_coord || !y_coord ||
+	    crypto_ec_point_to_bin(ec, X, x_coord, y_coord))
 		goto fail;
 
-	/* Qr = H(MAC-Responder | | [identifier | ] code) * Pr */
-	Qr = dpp_pkex_derive_Qr(curve, own_mac, code, identifier, bnctx, NULL);
+	pkex->x = crypto_ec_key_set_pub(curve->ike_group, x_coord,
+					y_coord, crypto_ec_prime_len(ec));
+	if (!pkex->x)
+		goto fail;
+
+	/* Qr = H([MAC-Responder |] [identifier |] code) * Pr */
+	Qr = dpp_pkex_derive_Qr(curve, v2 ? NULL : own_mac, code, identifier,
+				NULL);
 	if (!Qr)
 		goto fail;
 
@@ -508,24 +519,20 @@
 		goto fail;
 
 	/* N = Y + Qr */
-	Y_ec = EVP_PKEY_get0_EC_KEY(pkex->y);
-	if (!Y_ec)
+	Y = crypto_ec_key_get_public_key(pkex->y);
+	if (!Y)
 		goto fail;
-	Y_point = EC_KEY_get0_public_key(Y_ec);
-	if (!Y_point)
+	crypto_ec_point_debug_print(ec, Y, "DPP: Y");
+
+	N = crypto_ec_point_init(ec);
+	if (!N ||
+	    crypto_ec_point_add(ec, Y, Qr, N) ||
+	    crypto_ec_point_to_bin(ec, N, x_coord, y_coord))
 		goto fail;
-	dpp_debug_print_point("DPP: Y", group, Y_point);
-	N = EC_POINT_new(group);
-	Nx = BN_new();
-	Ny = BN_new();
-	if (!N || !Nx || !Ny ||
-	    EC_POINT_add(group, N, Y_point, Qr, bnctx) != 1 ||
-	    EC_POINT_get_affine_coordinates_GFp(group, N, Nx, Ny, bnctx) != 1)
-		goto fail;
-	dpp_debug_print_point("DPP: N", group, N);
+	crypto_ec_point_debug_print(ec, N, "DPP: N");
 
 	pkex->exchange_resp = dpp_pkex_build_exchange_resp(pkex, DPP_STATUS_OK,
-							   Nx, Ny);
+							   x_coord, y_coord);
 	if (!pkex->exchange_resp)
 		goto fail;
 
@@ -536,9 +543,10 @@
 	wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (K.x)",
 			Kx, Kx_len);
 
-	/* z = HKDF(<>, MAC-Initiator | MAC-Responder | M.x | N.x | code, K.x)
-	 */
-	res = dpp_pkex_derive_z(pkex->peer_mac, pkex->own_mac,
+	/* z = HKDF(<>, info | M.x | N.x | code, K.x) */
+	res = dpp_pkex_derive_z(pkex->v2 ? NULL : pkex->peer_mac,
+				pkex->v2 ? NULL : pkex->own_mac,
+				pkex->peer_version, DPP_VERSION,
 				pkex->Mx, curve->prime_len,
 				pkex->Nx, curve->prime_len, pkex->code,
 				Kx, Kx_len, pkex->z, curve->hash_len);
@@ -549,18 +557,14 @@
 	pkex->exchange_done = 1;
 
 out:
-	BN_CTX_free(bnctx);
-	EC_POINT_free(Qi);
-	EC_POINT_free(Qr);
-	BN_free(Mx);
-	BN_free(My);
-	BN_free(Nx);
-	BN_free(Ny);
-	EC_POINT_free(M);
-	EC_POINT_free(N);
-	EC_POINT_free(X);
-	EC_KEY_free(X_ec);
-	EC_GROUP_free(group);
+	os_free(x_coord);
+	os_free(y_coord);
+	crypto_ec_point_deinit(Qi, 1);
+	crypto_ec_point_deinit(Qr, 1);
+	crypto_ec_point_deinit(M, 1);
+	crypto_ec_point_deinit(N, 1);
+	crypto_ec_point_deinit(X, 1);
+	crypto_ec_deinit(ec);
 	return pkex;
 fail:
 	wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Request processing failed");
@@ -689,17 +693,16 @@
 {
 	const u8 *attr_status, *attr_id, *attr_key, *attr_group;
 	u16 attr_status_len, attr_id_len, attr_key_len, attr_group_len;
-	EC_GROUP *group = NULL;
-	BN_CTX *bnctx = NULL;
+	struct crypto_ec *ec = NULL;
 	struct wpabuf *msg = NULL, *A_pub = NULL, *X_pub = NULL, *Y_pub = NULL;
 	const struct dpp_curve_params *curve = pkex->own_bi->curve;
-	EC_POINT *Qr = NULL, *Y = NULL, *N = NULL;
-	BIGNUM *Nx = NULL, *Ny = NULL;
-	EC_KEY *Y_ec = NULL;
+	struct crypto_ec_point *Qr = NULL, *Y = NULL, *N = NULL;
+	u8 *x_coord = NULL, *y_coord = NULL;
 	size_t Jx_len, Kx_len;
 	u8 Jx[DPP_MAX_SHARED_SECRET_LEN], Kx[DPP_MAX_SHARED_SECRET_LEN];
 	const u8 *addr[4];
 	size_t len[4];
+	size_t num_elem;
 	u8 u[DPP_MAX_HASH_LEN];
 	int res;
 
@@ -721,6 +724,24 @@
 	}
 #endif /* CONFIG_TESTING_OPTIONS */
 
+#ifdef CONFIG_DPP2
+	if (pkex->v2) {
+		const u8 *version;
+		u16 version_len;
+
+		version = dpp_get_attr(buf, buflen, DPP_ATTR_PROTOCOL_VERSION,
+				       &version_len);
+		if (!version || version_len < 1 || version[0] == 0) {
+		dpp_pkex_fail(pkex,
+			      "Missing or invalid Protocol Version attribute");
+			return NULL;
+		}
+		pkex->peer_version = version[0];
+		wpa_printf(MSG_DEBUG, "DPP: Peer protocol version %u",
+			   pkex->peer_version);
+	}
+#endif /* CONFIG_DPP2 */
+
 	os_memcpy(pkex->peer_mac, peer_mac, ETH_ALEN);
 
 	attr_status = dpp_get_attr(buf, buflen, DPP_ATTR_STATUS,
@@ -765,46 +786,40 @@
 		return NULL;
 	}
 
-	/* Qr = H(MAC-Responder | [identifier |] code) * Pr */
-	bnctx = BN_CTX_new();
-	if (!bnctx)
-		goto fail;
-	Qr = dpp_pkex_derive_Qr(curve, pkex->peer_mac, pkex->code,
-				pkex->identifier, bnctx, &group);
+	/* Qr = H([MAC-Responder |] [identifier |] code) * Pr */
+	Qr = dpp_pkex_derive_Qr(curve, pkex->v2 ? NULL : pkex->peer_mac,
+				pkex->code, pkex->identifier, &ec);
 	if (!Qr)
 		goto fail;
 
 	/* Y' = N - Qr */
-	Y = EC_POINT_new(group);
-	N = EC_POINT_new(group);
-	Nx = BN_bin2bn(attr_key, attr_key_len / 2, NULL);
-	Ny = BN_bin2bn(attr_key + attr_key_len / 2, attr_key_len / 2, NULL);
-	if (!Y || !N || !Nx || !Ny ||
-	    EC_POINT_set_affine_coordinates_GFp(group, N, Nx, Ny, bnctx) != 1 ||
-	    EC_POINT_is_at_infinity(group, N) ||
-	    !EC_POINT_is_on_curve(group, N, bnctx) ||
-	    EC_POINT_invert(group, Qr, bnctx) != 1 ||
-	    EC_POINT_add(group, Y, N, Qr, bnctx) != 1 ||
-	    EC_POINT_is_at_infinity(group, Y) ||
-	    !EC_POINT_is_on_curve(group, Y, bnctx)) {
+	Y = crypto_ec_point_init(ec);
+	N = crypto_ec_point_from_bin(ec, attr_key);
+	if (!Y || !N ||
+	    crypto_ec_point_is_at_infinity(ec, N) ||
+	    !crypto_ec_point_is_on_curve(ec, N) ||
+	    crypto_ec_point_invert(ec, Qr) ||
+	    crypto_ec_point_add(ec, N, Qr, Y) ||
+	    crypto_ec_point_is_at_infinity(ec, Y) ||
+	    !crypto_ec_point_is_on_curve(ec, Y)) {
 		dpp_pkex_fail(pkex, "Invalid Encrypted Key value");
 		pkex->t++;
 		goto fail;
 	}
-	dpp_debug_print_point("DPP: N", group, N);
-	dpp_debug_print_point("DPP: Y'", group, Y);
+	crypto_ec_point_debug_print(ec, N, "DPP: N");
+	crypto_ec_point_debug_print(ec, Y, "DPP: Y'");
 
 	pkex->exchange_done = 1;
 
 	/* ECDH: J = a * Y' */
-	Y_ec = EC_KEY_new();
-	if (!Y_ec ||
-	    EC_KEY_set_group(Y_ec, group) != 1 ||
-	    EC_KEY_set_public_key(Y_ec, Y) != 1)
+	x_coord = os_malloc(curve->prime_len);
+	y_coord = os_malloc(curve->prime_len);
+	if (!x_coord || !y_coord ||
+	    crypto_ec_point_to_bin(ec, Y, x_coord, y_coord))
 		goto fail;
-	pkex->y = EVP_PKEY_new();
-	if (!pkex->y ||
-	    EVP_PKEY_set1_EC_KEY(pkex->y, Y_ec) != 1)
+	pkex->y = crypto_ec_key_set_pub(curve->ike_group, x_coord, y_coord,
+					curve->prime_len);
+	if (!pkex->y)
 		goto fail;
 	if (dpp_ecdh(pkex->own_bi->pubkey, pkex->y, Jx, &Jx_len) < 0)
 		goto fail;
@@ -812,21 +827,29 @@
 	wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (J.x)",
 			Jx, Jx_len);
 
-	/* u = HMAC(J.x, MAC-Initiator | A.x | Y'.x | X.x) */
-	A_pub = dpp_get_pubkey_point(pkex->own_bi->pubkey, 0);
-	Y_pub = dpp_get_pubkey_point(pkex->y, 0);
-	X_pub = dpp_get_pubkey_point(pkex->x, 0);
+	/* u = HMAC(J.x, [MAC-Initiator |] A.x | Y'.x | X.x) */
+	A_pub = crypto_ec_key_get_pubkey_point(pkex->own_bi->pubkey, 0);
+	Y_pub = crypto_ec_key_get_pubkey_point(pkex->y, 0);
+	X_pub = crypto_ec_key_get_pubkey_point(pkex->x, 0);
 	if (!A_pub || !Y_pub || !X_pub)
 		goto fail;
-	addr[0] = pkex->own_mac;
-	len[0] = ETH_ALEN;
-	addr[1] = wpabuf_head(A_pub);
-	len[1] = wpabuf_len(A_pub) / 2;
-	addr[2] = wpabuf_head(Y_pub);
-	len[2] = wpabuf_len(Y_pub) / 2;
-	addr[3] = wpabuf_head(X_pub);
-	len[3] = wpabuf_len(X_pub) / 2;
-	if (dpp_hmac_vector(curve->hash_len, Jx, Jx_len, 4, addr, len, u) < 0)
+	num_elem = 0;
+	if (!pkex->v2) {
+		addr[num_elem] = pkex->own_mac;
+		len[num_elem] = ETH_ALEN;
+		num_elem++;
+	}
+	addr[num_elem] = wpabuf_head(A_pub);
+	len[num_elem] = wpabuf_len(A_pub) / 2;
+	num_elem++;
+	addr[num_elem] = wpabuf_head(Y_pub);
+	len[num_elem] = wpabuf_len(Y_pub) / 2;
+	num_elem++;
+	addr[num_elem] = wpabuf_head(X_pub);
+	len[num_elem] = wpabuf_len(X_pub) / 2;
+	num_elem++;
+	if (dpp_hmac_vector(curve->hash_len, Jx, Jx_len, num_elem, addr, len, u)
+	    < 0)
 		goto fail;
 	wpa_hexdump(MSG_DEBUG, "DPP: u", u, curve->hash_len);
 
@@ -837,9 +860,10 @@
 	wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (K.x)",
 			Kx, Kx_len);
 
-	/* z = HKDF(<>, MAC-Initiator | MAC-Responder | M.x | N.x | code, K.x)
-	 */
-	res = dpp_pkex_derive_z(pkex->own_mac, pkex->peer_mac,
+	/* z = HKDF(<>, info | M.x | N.x | code, K.x) */
+	res = dpp_pkex_derive_z(pkex->v2 ? NULL : pkex->own_mac,
+				pkex->v2 ? NULL : pkex->peer_mac,
+				DPP_VERSION, pkex->peer_version,
 				pkex->Mx, curve->prime_len,
 				attr_key /* N.x */, attr_key_len / 2,
 				pkex->code, Kx, Kx_len,
@@ -856,14 +880,12 @@
 	wpabuf_free(A_pub);
 	wpabuf_free(X_pub);
 	wpabuf_free(Y_pub);
-	EC_POINT_free(Qr);
-	EC_POINT_free(Y);
-	EC_POINT_free(N);
-	BN_free(Nx);
-	BN_free(Ny);
-	EC_KEY_free(Y_ec);
-	BN_CTX_free(bnctx);
-	EC_GROUP_free(group);
+	os_free(x_coord);
+	os_free(y_coord);
+	crypto_ec_point_deinit(Qr, 1);
+	crypto_ec_point_deinit(Y, 1);
+	crypto_ec_point_deinit(N, 1);
+	crypto_ec_deinit(ec);
 	return msg;
 fail:
 	wpa_printf(MSG_DEBUG, "DPP: PKEX Exchange Response processing failed");
@@ -996,6 +1018,7 @@
 	u16 wrapped_data_len, b_key_len, peer_u_len = 0;
 	const u8 *addr[4];
 	size_t len[4];
+	size_t num_elem;
 	u8 octet;
 	u8 *unwrapped = NULL;
 	size_t unwrapped_len = 0;
@@ -1078,21 +1101,29 @@
 	wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (J.x)",
 			Jx, Jx_len);
 
-	/* u' = HMAC(J'.x, MAC-Initiator | A'.x | Y.x | X'.x) */
-	A_pub = dpp_get_pubkey_point(pkex->peer_bootstrap_key, 0);
-	Y_pub = dpp_get_pubkey_point(pkex->y, 0);
-	X_pub = dpp_get_pubkey_point(pkex->x, 0);
+	/* u' = HMAC(J'.x, [MAC-Initiator |] A'.x | Y.x | X'.x) */
+	A_pub = crypto_ec_key_get_pubkey_point(pkex->peer_bootstrap_key, 0);
+	Y_pub = crypto_ec_key_get_pubkey_point(pkex->y, 0);
+	X_pub = crypto_ec_key_get_pubkey_point(pkex->x, 0);
 	if (!A_pub || !Y_pub || !X_pub)
 		goto fail;
-	addr[0] = pkex->peer_mac;
-	len[0] = ETH_ALEN;
-	addr[1] = wpabuf_head(A_pub);
-	len[1] = wpabuf_len(A_pub) / 2;
-	addr[2] = wpabuf_head(Y_pub);
-	len[2] = wpabuf_len(Y_pub) / 2;
-	addr[3] = wpabuf_head(X_pub);
-	len[3] = wpabuf_len(X_pub) / 2;
-	if (dpp_hmac_vector(curve->hash_len, Jx, Jx_len, 4, addr, len, u) < 0)
+	num_elem = 0;
+	if (!pkex->v2) {
+		addr[num_elem] = pkex->peer_mac;
+		len[num_elem] = ETH_ALEN;
+		num_elem++;
+	}
+	addr[num_elem] = wpabuf_head(A_pub);
+	len[num_elem] = wpabuf_len(A_pub) / 2;
+	num_elem++;
+	addr[num_elem] = wpabuf_head(Y_pub);
+	len[num_elem] = wpabuf_len(Y_pub) / 2;
+	num_elem++;
+	addr[num_elem] = wpabuf_head(X_pub);
+	len[num_elem] = wpabuf_len(X_pub) / 2;
+	num_elem++;
+	if (dpp_hmac_vector(curve->hash_len, Jx, Jx_len, num_elem, addr, len, u)
+	    < 0)
 		goto fail;
 
 	peer_u = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_AUTH_TAG,
@@ -1115,19 +1146,27 @@
 	wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (L.x)",
 			Lx, Lx_len);
 
-	/* v = HMAC(L.x, MAC-Responder | B.x | X'.x | Y.x) */
-	B_pub = dpp_get_pubkey_point(pkex->own_bi->pubkey, 0);
+	/* v = HMAC(L.x, [MAC-Responder |] B.x | X'.x | Y.x) */
+	B_pub = crypto_ec_key_get_pubkey_point(pkex->own_bi->pubkey, 0);
 	if (!B_pub)
 		goto fail;
-	addr[0] = pkex->own_mac;
-	len[0] = ETH_ALEN;
-	addr[1] = wpabuf_head(B_pub);
-	len[1] = wpabuf_len(B_pub) / 2;
-	addr[2] = wpabuf_head(X_pub);
-	len[2] = wpabuf_len(X_pub) / 2;
-	addr[3] = wpabuf_head(Y_pub);
-	len[3] = wpabuf_len(Y_pub) / 2;
-	if (dpp_hmac_vector(curve->hash_len, Lx, Lx_len, 4, addr, len, v) < 0)
+	num_elem = 0;
+	if (!pkex->v2) {
+		addr[num_elem] = pkex->own_mac;
+		len[num_elem] = ETH_ALEN;
+		num_elem++;
+	}
+	addr[num_elem] = wpabuf_head(B_pub);
+	len[num_elem] = wpabuf_len(B_pub) / 2;
+	num_elem++;
+	addr[num_elem] = wpabuf_head(X_pub);
+	len[num_elem] = wpabuf_len(X_pub) / 2;
+	num_elem++;
+	addr[num_elem] = wpabuf_head(Y_pub);
+	len[num_elem] = wpabuf_len(Y_pub) / 2;
+	num_elem++;
+	if (dpp_hmac_vector(curve->hash_len, Lx, Lx_len, num_elem, addr, len, v)
+	    < 0)
 		goto fail;
 	wpa_hexdump(MSG_DEBUG, "DPP: v", v, curve->hash_len);
 
@@ -1157,6 +1196,7 @@
 	u16 wrapped_data_len, b_key_len, peer_v_len = 0;
 	const u8 *addr[4];
 	size_t len[4];
+	size_t num_elem;
 	u8 octet;
 	u8 *unwrapped = NULL;
 	size_t unwrapped_len = 0;
@@ -1240,21 +1280,29 @@
 	wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (L.x)",
 			Lx, Lx_len);
 
-	/* v' = HMAC(L.x, MAC-Responder | B'.x | X.x | Y'.x) */
-	B_pub = dpp_get_pubkey_point(pkex->peer_bootstrap_key, 0);
-	X_pub = dpp_get_pubkey_point(pkex->x, 0);
-	Y_pub = dpp_get_pubkey_point(pkex->y, 0);
+	/* v' = HMAC(L.x, [MAC-Responder |] B'.x | X.x | Y'.x) */
+	B_pub = crypto_ec_key_get_pubkey_point(pkex->peer_bootstrap_key, 0);
+	X_pub = crypto_ec_key_get_pubkey_point(pkex->x, 0);
+	Y_pub = crypto_ec_key_get_pubkey_point(pkex->y, 0);
 	if (!B_pub || !X_pub || !Y_pub)
 		goto fail;
-	addr[0] = pkex->peer_mac;
-	len[0] = ETH_ALEN;
-	addr[1] = wpabuf_head(B_pub);
-	len[1] = wpabuf_len(B_pub) / 2;
-	addr[2] = wpabuf_head(X_pub);
-	len[2] = wpabuf_len(X_pub) / 2;
-	addr[3] = wpabuf_head(Y_pub);
-	len[3] = wpabuf_len(Y_pub) / 2;
-	if (dpp_hmac_vector(curve->hash_len, Lx, Lx_len, 4, addr, len, v) < 0)
+	num_elem = 0;
+	if (!pkex->v2) {
+		addr[num_elem] = pkex->peer_mac;
+		len[num_elem] = ETH_ALEN;
+		num_elem++;
+	}
+	addr[num_elem] = wpabuf_head(B_pub);
+	len[num_elem] = wpabuf_len(B_pub) / 2;
+	num_elem++;
+	addr[num_elem] = wpabuf_head(X_pub);
+	len[num_elem] = wpabuf_len(X_pub) / 2;
+	num_elem++;
+	addr[num_elem] = wpabuf_head(Y_pub);
+	len[num_elem] = wpabuf_len(Y_pub) / 2;
+	num_elem++;
+	if (dpp_hmac_vector(curve->hash_len, Lx, Lx_len, num_elem, addr, len, v)
+	    < 0)
 		goto fail;
 
 	peer_v = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_R_AUTH_TAG,
@@ -1316,9 +1364,9 @@
 
 	os_free(pkex->identifier);
 	os_free(pkex->code);
-	EVP_PKEY_free(pkex->x);
-	EVP_PKEY_free(pkex->y);
-	EVP_PKEY_free(pkex->peer_bootstrap_key);
+	crypto_ec_key_deinit(pkex->x);
+	crypto_ec_key_deinit(pkex->y);
+	crypto_ec_key_deinit(pkex->peer_bootstrap_key);
 	wpabuf_free(pkex->exchange_req);
 	wpabuf_free(pkex->exchange_resp);
 	os_free(pkex);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_reconfig.c b/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_reconfig.c
index c4a0273..7137bc5 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_reconfig.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_reconfig.c
@@ -7,8 +7,6 @@
  */
 
 #include "utils/includes.h"
-#include <openssl/opensslv.h>
-#include <openssl/err.h>
 
 #include "utils/common.h"
 #include "utils/json.h"
@@ -40,8 +38,7 @@
 						struct dpp_reconfig_id *id)
 {
 	struct wpabuf *msg = NULL;
-	EVP_PKEY *csign = NULL;
-	const unsigned char *p;
+	struct crypto_ec_key *csign = NULL;
 	struct wpabuf *uncomp;
 	u8 hash[SHA256_MAC_LEN];
 	const u8 *addr[1];
@@ -49,7 +46,7 @@
 	int res;
 	size_t attr_len;
 	const struct dpp_curve_params *own_curve;
-	EVP_PKEY *own_key;
+	struct crypto_ec_key *own_key;
 	struct wpabuf *a_nonce = NULL, *e_id = NULL;
 
 	wpa_printf(MSG_DEBUG, "DPP: Build Reconfig Announcement frame");
@@ -61,16 +58,15 @@
 		goto fail;
 	}
 
-	p = csign_key;
-	csign = d2i_PUBKEY(NULL, &p, csign_key_len);
+	csign = crypto_ec_key_parse_pub(csign_key, csign_key_len);
 	if (!csign) {
 		wpa_printf(MSG_ERROR,
 			   "DPP: Failed to parse local C-sign-key information");
 		goto fail;
 	}
 
-	uncomp = dpp_get_pubkey_point(csign, 1);
-	EVP_PKEY_free(csign);
+	uncomp = crypto_ec_key_get_pubkey_point(csign, 1);
+	crypto_ec_key_deinit(csign);
 	if (!uncomp)
 		goto fail;
 	addr[0] = wpabuf_head(uncomp);
@@ -88,8 +84,8 @@
 		goto fail;
 	}
 
-	a_nonce = dpp_get_pubkey_point(id->a_nonce, 0);
-	e_id = dpp_get_pubkey_point(id->e_prime_id, 0);
+	a_nonce = crypto_ec_key_get_pubkey_point(id->a_nonce, 0);
+	e_id = crypto_ec_key_get_pubkey_point(id->e_prime_id, 0);
 	if (!a_nonce || !e_id)
 		goto fail;
 
@@ -126,7 +122,7 @@
 fail:
 	wpabuf_free(a_nonce);
 	wpabuf_free(e_id);
-	EVP_PKEY_free(own_key);
+	crypto_ec_key_deinit(own_key);
 	return msg;
 }
 
@@ -230,8 +226,8 @@
 {
 	struct dpp_authentication *auth;
 	const struct dpp_curve_params *curve;
-	EVP_PKEY *a_nonce, *e_prime_id;
-	EC_POINT *e_id;
+	struct crypto_ec_key *a_nonce, *e_prime_id;
+	struct crypto_ec_point *e_id;
 
 	curve = dpp_get_curve_ike_group(group);
 	if (!curve) {
@@ -260,13 +256,13 @@
 	e_prime_id = dpp_set_pubkey_point(conf->csign, e_id_attr, e_id_len);
 	if (!e_prime_id) {
 		wpa_printf(MSG_INFO, "DPP: Invalid E'-id");
-		EVP_PKEY_free(a_nonce);
+		crypto_ec_key_deinit(a_nonce);
 		return NULL;
 	}
 	dpp_debug_print_key("E'-id", e_prime_id);
 	e_id = dpp_decrypt_e_id(conf->pp_key, a_nonce, e_prime_id);
-	EVP_PKEY_free(a_nonce);
-	EVP_PKEY_free(e_prime_id);
+	crypto_ec_key_deinit(a_nonce);
+	crypto_ec_key_deinit(e_prime_id);
 	if (!e_id) {
 		wpa_printf(MSG_INFO, "DPP: Could not decrypt E'-id");
 		return NULL;
@@ -275,7 +271,7 @@
 	 * Enrollee has already been started and is waiting for updated
 	 * configuration instead of replying again before such configuration
 	 * becomes available */
-	EC_POINT_clear_free(e_id);
+	crypto_ec_point_deinit(e_id, 1);
 
 	auth = dpp_alloc_auth(dpp, msg_ctx);
 	if (!auth)
@@ -341,7 +337,7 @@
 	wpabuf_put_le16(clear, wpabuf_len(conn_status));
 	wpabuf_put_buf(clear, conn_status);
 
-	pr = dpp_get_pubkey_point(auth->own_protocol_key, 0);
+	pr = crypto_ec_key_get_pubkey_point(auth->own_protocol_key, 0);
 	if (!pr)
 		goto fail;
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_tcp.c b/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_tcp.c
index 7e330d6..fb8ef1c 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_tcp.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/dpp_tcp.c
@@ -82,6 +82,7 @@
 					int initiator);
 static void dpp_tcp_build_csr(void *eloop_ctx, void *timeout_ctx);
 static void dpp_tcp_gas_query_comeback(void *eloop_ctx, void *timeout_ctx);
+static void dpp_relay_conn_timeout(void *eloop_ctx, void *timeout_ctx);
 
 
 static void dpp_connection_free(struct dpp_connection *conn)
@@ -97,6 +98,7 @@
 			     conn, NULL);
 	eloop_cancel_timeout(dpp_tcp_build_csr, conn, NULL);
 	eloop_cancel_timeout(dpp_tcp_gas_query_comeback, conn, NULL);
+	eloop_cancel_timeout(dpp_relay_conn_timeout, conn, NULL);
 	wpabuf_free(conn->msg);
 	wpabuf_free(conn->msg_out);
 	dpp_auth_deinit(conn->auth);
@@ -154,6 +156,24 @@
 }
 
 
+static struct dpp_relay_controller *
+dpp_relay_controller_get_ctx(struct dpp_global *dpp, void *cb_ctx)
+{
+	struct dpp_relay_controller *ctrl;
+
+	if (!dpp)
+		return NULL;
+
+	dl_list_for_each(ctrl, &dpp->controllers, struct dpp_relay_controller,
+			 list) {
+		if (cb_ctx == ctrl->cb_ctx)
+			return ctrl;
+	}
+
+	return NULL;
+}
+
+
 static void dpp_controller_gas_done(struct dpp_connection *conn)
 {
 	struct dpp_authentication *auth = conn->auth;
@@ -352,6 +372,16 @@
 }
 
 
+static void dpp_relay_conn_timeout(void *eloop_ctx, void *timeout_ctx)
+{
+	struct dpp_connection *conn = eloop_ctx;
+
+	wpa_printf(MSG_DEBUG,
+		   "DPP: Timeout while waiting for relayed connection to complete");
+	dpp_connection_remove(conn);
+}
+
+
 static struct dpp_connection *
 dpp_relay_new_conn(struct dpp_relay_controller *ctrl, const u8 *src,
 		   unsigned int freq)
@@ -412,8 +442,8 @@
 		goto fail;
 	conn->write_eloop = 1;
 
-	/* TODO: eloop timeout to clear a connection if it does not complete
-	 * properly */
+	eloop_cancel_timeout(dpp_relay_conn_timeout, conn, NULL);
+	eloop_register_timeout(20, 0, dpp_relay_conn_timeout, conn, NULL);
 
 	dl_list_add(&ctrl->conn, &conn->list);
 	return conn;
@@ -465,7 +495,8 @@
 
 int dpp_relay_rx_action(struct dpp_global *dpp, const u8 *src, const u8 *hdr,
 			const u8 *buf, size_t len, unsigned int freq,
-			const u8 *i_bootstrap, const u8 *r_bootstrap)
+			const u8 *i_bootstrap, const u8 *r_bootstrap,
+			void *cb_ctx)
 {
 	struct dpp_relay_controller *ctrl;
 	struct dpp_connection *conn;
@@ -493,8 +524,7 @@
 	    type == DPP_PA_RECONFIG_ANNOUNCEMENT) {
 		/* TODO: Could send this to all configured Controllers. For now,
 		 * only the first Controller is supported. */
-		ctrl = dl_list_first(&dpp->controllers,
-				     struct dpp_relay_controller, list);
+		ctrl = dpp_relay_controller_get_ctx(dpp, cb_ctx);
 	} else {
 		if (!r_bootstrap)
 			return -1;
@@ -641,10 +671,8 @@
 	}
 
 	if (dpp_set_configurator(conn->auth,
-				 conn->ctrl->configurator_params) < 0) {
-		dpp_connection_remove(conn);
+				 conn->ctrl->configurator_params) < 0)
 		return -1;
-	}
 
 	return dpp_tcp_send_msg(conn, conn->auth->resp_msg);
 }
@@ -670,7 +698,6 @@
 			return 0;
 		}
 		wpa_printf(MSG_DEBUG, "DPP: No confirm generated");
-		dpp_connection_remove(conn);
 		return -1;
 	}
 
@@ -832,7 +859,6 @@
 		return -1;
 	if (dpp_set_configurator(auth, conn->ctrl->configurator_params) < 0) {
 		dpp_auth_deinit(auth);
-		dpp_connection_remove(conn);
 		return -1;
 	}
 
@@ -1279,7 +1305,7 @@
 	const u8 *pos, *end, *next, *adv_proto;
 	u16 status, slen, comeback_delay;
 
-	if (len < 5 + 2 + (comeback ? 1 : 0))
+	if (len < (size_t) (5 + 2 + (comeback ? 1 : 0)))
 		return -1;
 
 	wpa_printf(MSG_DEBUG,
@@ -1693,6 +1719,13 @@
 }
 
 
+void dpp_controller_stop_for_ctx(struct dpp_global *dpp, void *cb_ctx)
+{
+	if (dpp && dpp->controller && dpp->controller->cb_ctx == cb_ctx)
+		dpp_controller_stop(dpp);
+}
+
+
 static bool dpp_tcp_peer_id_match(struct dpp_authentication *auth,
 				  unsigned int id)
 {
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/gas_server.c b/src/lynq/packages/thirdpart/lynq-wg870/src/common/gas_server.c
index c000aeb..5f44ffe 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/gas_server.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/gas_server.c
@@ -489,6 +489,21 @@
 }
 
 
+bool gas_server_response_sent(struct gas_server *gas, void *resp_ctx)
+{
+	struct gas_server_response *tmp;
+
+	dl_list_for_each(tmp, &gas->responses, struct gas_server_response,
+			 list) {
+		if (tmp == resp_ctx)
+			return tmp->resp &&
+				tmp->offset == wpabuf_len(tmp->resp);
+	}
+
+	return false;
+}
+
+
 struct gas_server * gas_server_init(void *ctx,
 				    void (*tx)(void *ctx, int freq,
 					       const u8 *da,
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/gas_server.h b/src/lynq/packages/thirdpart/lynq-wg870/src/common/gas_server.h
index 2611dde..db00f87 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/gas_server.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/gas_server.h
@@ -36,6 +36,7 @@
 			  size_t data_len, int ack);
 int gas_server_set_resp(struct gas_server *gas, void *resp_ctx,
 			struct wpabuf *resp);
+bool gas_server_response_sent(struct gas_server *gas, void *resp_ctx);
 
 #else /* CONFIG_GAS_SERVER */
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/hw_features_common.c b/src/lynq/packages/thirdpart/lynq-wg870/src/common/hw_features_common.c
index 511e68f..f168d4e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/hw_features_common.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/hw_features_common.c
@@ -41,10 +41,30 @@
 
 
 struct hostapd_channel_data *
+hw_mode_get_channel(struct hostapd_hw_modes *mode, int freq, int *chan)
+{
+	int i;
+
+	for (i = 0; i < mode->num_channels; i++) {
+		struct hostapd_channel_data *ch = &mode->channels[i];
+
+		if (ch->freq == freq) {
+			if (chan)
+				*chan = ch->chan;
+			return ch;
+		}
+	}
+
+	return NULL;
+}
+
+
+struct hostapd_channel_data *
 hw_get_channel_freq(enum hostapd_hw_mode mode, int freq, int *chan,
 		    struct hostapd_hw_modes *hw_features, int num_hw_features)
 {
-	int i, j;
+	struct hostapd_channel_data *chan_data;
+	int i;
 
 	if (chan)
 		*chan = 0;
@@ -52,21 +72,15 @@
 	if (!hw_features)
 		return NULL;
 
-	for (j = 0; j < num_hw_features; j++) {
-		struct hostapd_hw_modes *curr_mode = &hw_features[j];
+	for (i = 0; i < num_hw_features; i++) {
+		struct hostapd_hw_modes *curr_mode = &hw_features[i];
 
 		if (curr_mode->mode != mode)
 			continue;
-		for (i = 0; i < curr_mode->num_channels; i++) {
-			struct hostapd_channel_data *ch =
-				&curr_mode->channels[i];
 
-			if (ch->freq == freq) {
-				if (chan)
-					*chan = ch->chan;
-				return ch;
-			}
-		}
+		chan_data = hw_mode_get_channel(curr_mode, freq, chan);
+		if (chan_data)
+			return chan_data;
 	}
 
 	return NULL;
@@ -100,7 +114,7 @@
 {
 	int ok, first;
 	int allowed[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 140,
-			  149, 157, 165, 184, 192 };
+			  149, 157, 165, 173, 184, 192 };
 	size_t k;
 	int ht40_plus, pri_chan, sec_chan;
 
@@ -279,87 +293,12 @@
 }
 
 
-/*
- * Returns:
- * 0: no impact
- * 1: overlapping BSS
- * 2: overlapping BSS with 40 MHz intolerant advertisement
- */
-int check_bss_coex_40mhz(struct wpa_scan_res *bss, int pri_freq, int sec_freq)
-{
-	int affected_start, affected_end;
-	struct ieee802_11_elems elems;
-	int pri_chan, sec_chan;
-	int pri = bss->freq;
-	int sec = pri;
-
-	if (pri_freq == sec_freq)
-		return 1;
-
-	affected_start = (pri_freq + sec_freq) / 2 - 25;
-	affected_end = (pri_freq + sec_freq) / 2 + 25;
-
-	/* Check for overlapping 20 MHz BSS */
-	if (check_20mhz_bss(bss, pri_freq, affected_start, affected_end)) {
-		wpa_printf(MSG_DEBUG, "Overlapping 20 MHz BSS is found");
-		return 1;
-	}
-
-	get_pri_sec_chan(bss, &pri_chan, &sec_chan);
-
-	if (sec_chan) {
-		if (sec_chan < pri_chan)
-			sec = pri - 20;
-		else
-			sec = pri + 20;
-	}
-
-	if ((pri < affected_start || pri > affected_end) &&
-	    (sec < affected_start || sec > affected_end))
-		return 0; /* not within affected channel range */
-
-	wpa_printf(MSG_DEBUG, "Neighboring BSS: " MACSTR
-		   " freq=%d pri=%d sec=%d",
-		   MAC2STR(bss->bssid), bss->freq, pri_chan, sec_chan);
-
-	if (sec_chan) {
-		if (pri_freq != pri || sec_freq != sec) {
-			wpa_printf(MSG_DEBUG,
-				   "40 MHz pri/sec mismatch with BSS "
-				   MACSTR
-				   " <%d,%d> (chan=%d%c) vs. <%d,%d>",
-				   MAC2STR(bss->bssid),
-				   pri, sec, pri_chan,
-				   sec > pri ? '+' : '-',
-				   pri_freq, sec_freq);
-			return 1;
-		}
-	}
-
-	ieee802_11_parse_elems((u8 *) (bss + 1), bss->ie_len, &elems, 0);
-	if (elems.ht_capabilities) {
-		struct ieee80211_ht_capabilities *ht_cap =
-			(struct ieee80211_ht_capabilities *)
-			elems.ht_capabilities;
-
-		if (le_to_host16(ht_cap->ht_capabilities_info) &
-		    HT_CAP_INFO_40MHZ_INTOLERANT) {
-			wpa_printf(MSG_DEBUG,
-				   "40 MHz Intolerant is set on channel %d in BSS "
-				   MACSTR, pri, MAC2STR(bss->bssid));
-			return 2;
-		}
-	}
-
-	return 0;
-}
-
-
 int check_40mhz_2g4(struct hostapd_hw_modes *mode,
 		    struct wpa_scan_results *scan_res, int pri_chan,
 		    int sec_chan)
 {
 	int pri_freq, sec_freq;
+	int affected_start, affected_end;
 	size_t i;
 
 	if (!mode || !scan_res || !pri_chan || !sec_chan ||
@@ -369,12 +308,70 @@
 	pri_freq = hw_get_freq(mode, pri_chan);
 	sec_freq = hw_get_freq(mode, sec_chan);
 
+	affected_start = (pri_freq + sec_freq) / 2 - 25;
+	affected_end = (pri_freq + sec_freq) / 2 + 25;
 	wpa_printf(MSG_DEBUG, "40 MHz affected channel range: [%d,%d] MHz",
-		   (pri_freq + sec_freq) / 2 - 25,
-		   (pri_freq + sec_freq) / 2 + 25);
+		   affected_start, affected_end);
 	for (i = 0; i < scan_res->num; i++) {
-		if (check_bss_coex_40mhz(scan_res->res[i], pri_freq, sec_freq))
+		struct wpa_scan_res *bss = scan_res->res[i];
+		int pri = bss->freq;
+		int sec = pri;
+		struct ieee802_11_elems elems;
+
+		/* Check for overlapping 20 MHz BSS */
+		if (check_20mhz_bss(bss, pri_freq, affected_start,
+				    affected_end)) {
+			wpa_printf(MSG_DEBUG,
+				   "Overlapping 20 MHz BSS is found");
 			return 0;
+		}
+
+		get_pri_sec_chan(bss, &pri_chan, &sec_chan);
+
+		if (sec_chan) {
+			if (sec_chan < pri_chan)
+				sec = pri - 20;
+			else
+				sec = pri + 20;
+		}
+
+		if ((pri < affected_start || pri > affected_end) &&
+		    (sec < affected_start || sec > affected_end))
+			continue; /* not within affected channel range */
+
+		wpa_printf(MSG_DEBUG, "Neighboring BSS: " MACSTR
+			   " freq=%d pri=%d sec=%d",
+			   MAC2STR(bss->bssid), bss->freq, pri_chan, sec_chan);
+
+		if (sec_chan) {
+			if (pri_freq != pri || sec_freq != sec) {
+				wpa_printf(MSG_DEBUG,
+					   "40 MHz pri/sec mismatch with BSS "
+					   MACSTR
+					   " <%d,%d> (chan=%d%c) vs. <%d,%d>",
+					   MAC2STR(bss->bssid),
+					   pri, sec, pri_chan,
+					   sec > pri ? '+' : '-',
+					   pri_freq, sec_freq);
+				return 0;
+			}
+		}
+
+		ieee802_11_parse_elems((u8 *) (bss + 1), bss->ie_len, &elems,
+				       0);
+		if (elems.ht_capabilities) {
+			struct ieee80211_ht_capabilities *ht_cap =
+				(struct ieee80211_ht_capabilities *)
+				elems.ht_capabilities;
+
+			if (le_to_host16(ht_cap->ht_capabilities_info) &
+			    HT_CAP_INFO_40MHZ_INTOLERANT) {
+				wpa_printf(MSG_DEBUG,
+					   "40 MHz Intolerant is set on channel %d in BSS "
+					   MACSTR, pri, MAC2STR(bss->bssid));
+				return 0;
+			}
+		}
 	}
 
 	return 1;
@@ -391,7 +388,7 @@
 			    int center_segment1, u32 vht_caps,
 			    struct he_capabilities *he_cap)
 {
-	if (!he_cap)
+	if (!he_cap || !he_cap->he_supported)
 		he_enabled = 0;
 	os_memset(data, 0, sizeof(*data));
 	data->mode = mode;
@@ -403,7 +400,16 @@
 	data->sec_channel_offset = sec_channel_offset;
 	data->center_freq1 = freq + sec_channel_offset * 10;
 	data->center_freq2 = 0;
-	data->bandwidth = sec_channel_offset ? 40 : 20;
+	if (oper_chwidth == CHANWIDTH_80MHZ)
+		data->bandwidth = 80;
+	else if (oper_chwidth == CHANWIDTH_160MHZ ||
+		 oper_chwidth == CHANWIDTH_80P80MHZ)
+		data->bandwidth = 160;
+	else if (sec_channel_offset)
+		data->bandwidth = 40;
+	else
+		data->bandwidth = 20;
+
 
 	hostapd_encode_edmg_chan(enable_edmg, edmg_channel, channel,
 				 &data->edmg);
@@ -427,9 +433,8 @@
 					   "Segment 0 center frequency isn't set");
 				return -1;
 			}
-
-			data->center_freq1 = data->freq;
-			data->bandwidth = 20;
+			if (!sec_channel_offset)
+				data->center_freq1 = data->freq;
 		} else {
 			int freq1, freq2 = 0;
 			int bw = center_idx_to_bw_6ghz(center_segment0);
@@ -477,7 +482,10 @@
 
 	if (data->he_enabled) switch (oper_chwidth) {
 	case CHANWIDTH_USE_HT:
-		if (mode == HOSTAPD_MODE_IEEE80211G && sec_channel_offset) {
+		if (sec_channel_offset == 0)
+			break;
+
+		if (mode == HOSTAPD_MODE_IEEE80211G) {
 			if (!(he_cap->phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
 			      HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_IN_2G)) {
 				wpa_printf(MSG_ERROR,
@@ -558,13 +566,19 @@
 		/* fall through */
 	case CHANWIDTH_80MHZ:
 		data->bandwidth = 80;
-		if ((oper_chwidth == CHANWIDTH_80MHZ &&
-		     center_segment1) ||
-		    (oper_chwidth == CHANWIDTH_80P80MHZ &&
-		     !center_segment1) ||
-		    !sec_channel_offset) {
+		if (!sec_channel_offset) {
 			wpa_printf(MSG_ERROR,
-				   "80/80+80 MHz: center segment 1 wrong or no second channel offset");
+				   "80/80+80 MHz: no second channel offset");
+			return -1;
+		}
+		if (oper_chwidth == CHANWIDTH_80MHZ && center_segment1) {
+			wpa_printf(MSG_ERROR,
+				   "80 MHz: center segment 1 configured");
+			return -1;
+		}
+		if (oper_chwidth == CHANWIDTH_80P80MHZ && !center_segment1) {
+			wpa_printf(MSG_ERROR,
+				   "80+80 MHz: center segment 1 not configured");
 			return -1;
 		}
 		if (!center_segment0) {
@@ -580,6 +594,8 @@
 				center_segment0 = 138;
 			else if (channel <= 161)
 				center_segment0 = 155;
+			else if (channel <= 177)
+				center_segment0 = 171;
 			data->center_freq1 = 5000 + center_segment0 * 5;
 		} else {
 			/*
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/hw_features_common.h b/src/lynq/packages/thirdpart/lynq-wg870/src/common/hw_features_common.h
index e57a8d6..0e92aa0 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/hw_features_common.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/hw_features_common.h
@@ -15,6 +15,9 @@
 struct hostapd_channel_data * hw_get_channel_chan(struct hostapd_hw_modes *mode,
 						  int chan, int *freq);
 struct hostapd_channel_data *
+hw_mode_get_channel(struct hostapd_hw_modes *mode, int freq, int *chan);
+
+struct hostapd_channel_data *
 hw_get_channel_freq(enum hostapd_hw_mode mode, int freq, int *chan,
 		    struct hostapd_hw_modes *hw_features, int num_hw_features);
 
@@ -29,7 +32,6 @@
 int check_40mhz_5g(struct wpa_scan_results *scan_res,
 		   struct hostapd_channel_data *pri_chan,
 		   struct hostapd_channel_data *sec_chan);
-int check_bss_coex_40mhz(struct wpa_scan_res *bss, int pri_freq, int sec_freq);
 int check_40mhz_2g4(struct hostapd_hw_modes *mode,
 		    struct wpa_scan_results *scan_res, int pri_chan,
 		    int sec_chan);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/ieee802_11_common.c b/src/lynq/packages/thirdpart/lynq-wg870/src/common/ieee802_11_common.c
index f76994d..7658e3d 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/ieee802_11_common.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/ieee802_11_common.c
@@ -303,6 +303,10 @@
 			break;
 		elems->he_6ghz_band_cap = pos;
 		break;
+	case WLAN_EID_EXT_PASN_PARAMS:
+		elems->pasn_params = pos;
+		elems->pasn_params_len = elen;
+		break;
 	default:
 		if (show_errors) {
 			wpa_printf(MSG_MSGDUMP,
@@ -566,6 +570,11 @@
 			elems->dils = pos;
 			elems->dils_len = elen;
 			break;
+		case WLAN_EID_S1G_CAPABILITIES:
+			if (elen < 15)
+				break;
+			elems->s1g_capab = pos;
+			break;
 		case WLAN_EID_FRAGMENT:
 			ieee802_11_parse_fragment(&elems->frag_ies, pos, elen);
 			break;
@@ -874,7 +883,7 @@
 
 /**
  * ieee80211_freq_to_channel_ext - Convert frequency into channel info
- * for HT40 and VHT. DFS channels are not covered.
+ * for HT40, VHT, and HE. DFS channels are not covered.
  * @freq: Frequency (MHz) to convert
  * @sec_channel: 0 = non-HT40, 1 = sec. channel above, -1 = sec. channel below
  * @chanwidth: VHT/EDMG channel width (CHANWIDTH_*)
@@ -985,8 +994,8 @@
 		return HOSTAPD_MODE_IEEE80211A;
 	}
 
-	/* 5 GHz, channels 149..169 */
-	if (freq >= 5745 && freq <= 5845) {
+	/* 5 GHz, channels 149..177 */
+	if (freq >= 5745 && freq <= 5885) {
 		if ((freq - 5000) % 5)
 			return NUM_HOSTAPD_MODES;
 
@@ -1006,8 +1015,8 @@
 		return HOSTAPD_MODE_IEEE80211A;
 	}
 
-	/* 5 GHz, channels 100..140 */
-	if (freq >= 5000 && freq <= 5700) {
+	/* 5 GHz, channels 100..144 */
+	if (freq >= 5500 && freq <= 5720) {
 		if ((freq - 5000) % 5)
 			return NUM_HOSTAPD_MODES;
 
@@ -1383,7 +1392,7 @@
 
 static int ieee80211_chan_to_freq_global(u8 op_class, u8 chan)
 {
-	/* Table E-4 in IEEE Std 802.11-2012 - Global operating classes */
+	/* Table E-4 in IEEE Std 802.11-2020 - Global operating classes */
 	switch (op_class) {
 	case 81:
 		/* channels 1..13 */
@@ -1412,26 +1421,26 @@
 	case 121: /* channels 100-140 */
 	case 122: /* channels 100-142; 40 MHz */
 	case 123: /* channels 104-136; 40 MHz */
-		if (chan < 100 || chan > 140)
+		if (chan < 100 || chan > 144)
 			return -1;
 		return 5000 + 5 * chan;
 	case 124: /* channels 149,153,157,161 */
-	case 126: /* channels 149,157; 40 MHz */
-	case 127: /* channels 153,161; 40 MHz */
 		if (chan < 149 || chan > 161)
 			return -1;
 		return 5000 + 5 * chan;
-	case 125: /* channels 149,153,157,161,165,169 */
-		if (chan < 149 || chan > 169)
+	case 125: /* channels 149,153,157,161,165,169,173,177 */
+	case 126: /* channels 149,157,165,173; 40 MHz */
+	case 127: /* channels 153,161,169,177; 40 MHz */
+		if (chan < 149 || chan > 177)
 			return -1;
 		return 5000 + 5 * chan;
-	case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
-	case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
-		if (chan < 36 || chan > 161)
+	case 128: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80 MHz */
+	case 130: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80 MHz */
+		if (chan < 36 || chan > 177)
 			return -1;
 		return 5000 + 5 * chan;
-	case 129: /* center freqs 50, 114; 160 MHz */
-		if (chan < 36 || chan > 128)
+	case 129: /* center freqs 50, 114, 163; 160 MHz */
+		if (chan < 36 || chan > 177)
 			return -1;
 		return 5000 + 5 * chan;
 	case 131: /* UHB channels, 20 MHz: 1, 5, 9.. */
@@ -1526,6 +1535,16 @@
 }
 
 
+/*
+ * 802.11-2020: Table E-4 - Global operating classes
+ * DFS_50_100_Behavior: 118, 119, 120, 121, 122, 123
+ */
+int is_dfs_global_op_class(u8 op_class)
+{
+    return (op_class >= 118) && (op_class <= 123);
+}
+
+
 static int is_11b(u8 rate)
 {
 	return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16
@@ -1879,24 +1898,24 @@
 	{ HOSTAPD_MODE_IEEE80211A, 122, 100, 132, 8, BW40PLUS, NO_P2P_SUPP },
 	{ HOSTAPD_MODE_IEEE80211A, 123, 104, 136, 8, BW40MINUS, NO_P2P_SUPP },
 	{ HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20, P2P_SUPP },
-	{ HOSTAPD_MODE_IEEE80211A, 125, 149, 169, 4, BW20, P2P_SUPP },
-	{ HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8, BW40PLUS, P2P_SUPP },
-	{ HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8, BW40MINUS, P2P_SUPP },
+	{ HOSTAPD_MODE_IEEE80211A, 125, 149, 177, 4, BW20, P2P_SUPP },
+	{ HOSTAPD_MODE_IEEE80211A, 126, 149, 173, 8, BW40PLUS, P2P_SUPP },
+	{ HOSTAPD_MODE_IEEE80211A, 127, 153, 177, 8, BW40MINUS, P2P_SUPP },
 
 	/*
-	 * IEEE P802.11ac/D7.0 Table E-4 actually talks about channel center
-	 * frequency index 42, 58, 106, 122, 138, 155 with channel spacing of
-	 * 80 MHz, but currently use the following definition for simplicity
+	 * IEEE P802.11ax/D8.0 Table E-4 actually talks about channel center
+	 * frequency index 42, 58, 106, 122, 138, 155, 171 with channel spacing
+	 * of 80 MHz, but currently use the following definition for simplicity
 	 * (these center frequencies are not actual channels, which makes
-	 * wpas_p2p_allow_channel() fail). wpas_p2p_verify_80mhz() should take
+	 * wpas_p2p_verify_channel() fail). wpas_p2p_verify_80mhz() should take
 	 * care of removing invalid channels.
 	 */
-	{ HOSTAPD_MODE_IEEE80211A, 128, 36, 161, 4, BW80, P2P_SUPP },
-	{ HOSTAPD_MODE_IEEE80211A, 129, 50, 114, 16, BW160, P2P_SUPP },
-	{ HOSTAPD_MODE_IEEE80211A, 131, 1, 233, 4, BW20, NO_P2P_SUPP },
-	{ HOSTAPD_MODE_IEEE80211A, 132, 1, 233, 8, BW40, NO_P2P_SUPP },
-	{ HOSTAPD_MODE_IEEE80211A, 133, 1, 233, 16, BW80, NO_P2P_SUPP },
-	{ HOSTAPD_MODE_IEEE80211A, 134, 1, 233, 32, BW160, NO_P2P_SUPP },
+	{ HOSTAPD_MODE_IEEE80211A, 128, 36, 177, 4, BW80, P2P_SUPP },
+	{ HOSTAPD_MODE_IEEE80211A, 129, 36, 177, 4, BW160, P2P_SUPP },
+	{ HOSTAPD_MODE_IEEE80211A, 131, 1, 233, 4, BW20, P2P_SUPP },
+	{ HOSTAPD_MODE_IEEE80211A, 132, 1, 233, 8, BW40, P2P_SUPP },
+	{ HOSTAPD_MODE_IEEE80211A, 133, 1, 233, 16, BW80, P2P_SUPP },
+	{ HOSTAPD_MODE_IEEE80211A, 134, 1, 233, 32, BW160, P2P_SUPP },
 	{ HOSTAPD_MODE_IEEE80211A, 135, 1, 233, 16, BW80P80, NO_P2P_SUPP },
 	{ HOSTAPD_MODE_IEEE80211A, 136, 2, 2, 4, BW20, NO_P2P_SUPP },
 
@@ -1910,7 +1929,7 @@
 	{ HOSTAPD_MODE_IEEE80211AD, 182, 17, 20, 1, BW6480, P2P_SUPP },
 	{ HOSTAPD_MODE_IEEE80211AD, 183, 25, 27, 1, BW8640, P2P_SUPP },
 
-	{ HOSTAPD_MODE_IEEE80211A, 130, 36, 161, 4, BW80P80, P2P_SUPP },
+	{ HOSTAPD_MODE_IEEE80211A, 130, 36, 177, 4, BW80P80, P2P_SUPP },
 	{ -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP }
 };
 
@@ -2227,6 +2246,9 @@
 
 int center_idx_to_bw_6ghz(u8 idx)
 {
+	/* Channel: 2 */
+	if (idx == 2)
+		return 0; /* 20 MHz */
 	/* channels: 1, 5, 9, 13... */
 	if ((idx & 0x3) == 0x1)
 		return 0; /* 20 MHz */
@@ -2244,44 +2266,68 @@
 }
 
 
-int is_6ghz_freq(int freq)
+bool is_6ghz_freq(int freq)
 {
 	if (freq < 5935 || freq > 7115)
-		return 0;
+		return false;
 
 	if (freq == 5935)
-		return 1;
+		return true;
 
 	if (center_idx_to_bw_6ghz((freq - 5950) / 5) < 0)
-		return 0;
+		return false;
 
-	return 1;
+	return true;
 }
 
 
-int is_6ghz_op_class(u8 op_class)
+bool is_6ghz_op_class(u8 op_class)
 {
 	return op_class >= 131 && op_class <= 136;
 }
 
 
-int is_6ghz_psc_frequency(int freq)
+bool is_6ghz_psc_frequency(int freq)
 {
 	int i;
 
 	if (!is_6ghz_freq(freq) || freq == 5935)
-		return 0;
+		return false;
 	if ((((freq - 5950) / 5) & 0x3) != 0x1)
-		return 0;
+		return false;
 
 	i = (freq - 5950 + 55) % 80;
 	if (i == 0)
 		i = (freq - 5950 + 55) / 80;
 
 	if (i >= 1 && i <= 15)
-		return 1;
+		return true;
 
-	return 0;
+	return false;
+}
+
+
+/**
+ * get_6ghz_sec_channel - Get the relative position of the secondary channel
+ * to the primary channel in 6 GHz
+ * @channel: Primary channel to be checked for (in global op class 131)
+ * Returns: 1 = secondary channel above, -1 = secondary channel below
+ */
+
+int get_6ghz_sec_channel(int channel)
+{
+	/*
+	 * In the 6 GHz band, primary channels are numbered as 1, 5, 9, 13.., so
+	 * the 40 MHz channels are formed with the channel pairs as (1,5),
+	 * (9,13), (17,21)..
+	 * The secondary channel for a given primary channel is below the
+	 * primary channel for the channels 5, 13, 21.. and it is above the
+	 * primary channel for the channels 1, 9, 17..
+	 */
+
+	if (((channel - 1) / 4) % 2)
+		return -1;
+	return 1;
 }
 
 
@@ -2395,6 +2441,35 @@
 }
 
 
+bool ieee802_11_rsnx_capab_len(const u8 *rsnxe, size_t rsnxe_len,
+			       unsigned int capab)
+{
+	const u8 *end;
+	size_t flen, i;
+	u32 capabs = 0;
+
+	if (!rsnxe || rsnxe_len == 0)
+		return false;
+	end = rsnxe + rsnxe_len;
+	flen = (rsnxe[0] & 0x0f) + 1;
+	if (rsnxe + flen > end)
+		return false;
+	if (flen > 4)
+		flen = 4;
+	for (i = 0; i < flen; i++)
+		capabs |= rsnxe[i] << (8 * i);
+
+	return capabs & BIT(capab);
+}
+
+
+bool ieee802_11_rsnx_capab(const u8 *rsnxe, unsigned int capab)
+{
+	return ieee802_11_rsnx_capab_len(rsnxe ? rsnxe + 2 : NULL,
+					 rsnxe ? rsnxe[1] : 0, capab);
+}
+
+
 void hostapd_encode_edmg_chan(int edmg_enable, u8 edmg_channel,
 			      int primary_channel,
 			      struct ieee80211_edmg_config *edmg)
@@ -2492,16 +2567,16 @@
 	case 123: /* channels 104-136; 40 MHz */
 		return 40;
 	case 124: /* channels 149,153,157,161 */
-	case 125: /* channels 149,153,157,161,165,169 */
+	case 125: /* channels 149,153,157,161,165,169,173,177 */
 		return 20;
-	case 126: /* channels 149,157; 40 MHz */
-	case 127: /* channels 153,161; 40 MHz */
+	case 126: /* channels 149,157,161,165,169,173; 40 MHz */
+	case 127: /* channels 153..177; 40 MHz */
 		return 40;
-	case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
+	case 128: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80 MHz */
 		return 80;
-	case 129: /* center freqs 50, 114; 160 MHz */
+	case 129: /* center freqs 50, 114, 163; 160 MHz */
 		return 160;
-	case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80+80 MHz */
+	case 130: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80+80 MHz */
 		return 80;
 	case 131: /* UHB channels, 20 MHz: 1, 5, 9.. */
 		return 20;
@@ -2553,16 +2628,16 @@
 	case 123: /* channels 104-136; 40 MHz */
 		return CHANWIDTH_USE_HT;
 	case 124: /* channels 149,153,157,161 */
-	case 125: /* channels 149,153,157,161,165,169 */
+	case 125: /* channels 149,153,157,161,165,169,171 */
 		return CHANWIDTH_USE_HT;
-	case 126: /* channels 149,157; 40 MHz */
-	case 127: /* channels 153,161; 40 MHz */
+	case 126: /* channels 149,157,165, 173; 40 MHz */
+	case 127: /* channels 153,161,169,177; 40 MHz */
 		return CHANWIDTH_USE_HT;
-	case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
+	case 128: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80 MHz */
 		return CHANWIDTH_80MHZ;
-	case 129: /* center freqs 50, 114; 160 MHz */
+	case 129: /* center freqs 50, 114, 163; 160 MHz */
 		return CHANWIDTH_160MHZ;
-	case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80+80 MHz */
+	case 130: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80+80 MHz */
 		return CHANWIDTH_80P80MHZ;
 	case 131: /* UHB channels, 20 MHz: 1, 5, 9.. */
 		return CHANWIDTH_USE_HT;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/ieee802_11_common.h b/src/lynq/packages/thirdpart/lynq-wg870/src/common/ieee802_11_common.h
index 0ae0fa4..2e816c0 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/ieee802_11_common.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/ieee802_11_common.h
@@ -115,6 +115,8 @@
 	const u8 *short_ssid_list;
 	const u8 *he_6ghz_band_cap;
 	const u8 *sae_pk;
+	const u8 *s1g_capab;
+	const u8 *pasn_params;
 
 	u8 ssid_len;
 	u8 supp_rates_len;
@@ -168,9 +170,14 @@
 	u8 he_operation_len;
 	u8 short_ssid_list_len;
 	u8 sae_pk_len;
+	u8 pasn_params_len;
 
 	struct mb_ies_info mb_ies;
 	struct frag_ies_info frag_ies;
+#if defined(WAPI_ANDROID)
+	const u8 *wapi_ie;
+	u8 wapi_ie_len;
+#endif 
 };
 
 typedef enum { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 } ParseRes;
@@ -215,6 +222,7 @@
 				  int sec_channel, u8 *op_class, u8 *channel);
 int ieee80211_is_dfs(int freq, const struct hostapd_hw_modes *modes,
 		     u16 num_modes);
+int is_dfs_global_op_class(u8 op_class);
 enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht);
 
 int supp_rates_11b_only(struct ieee802_11_elems *elems);
@@ -258,14 +266,18 @@
 const struct oper_class_map * get_oper_class(const char *country, u8 op_class);
 int oper_class_bw_to_int(const struct oper_class_map *map);
 int center_idx_to_bw_6ghz(u8 idx);
-int is_6ghz_freq(int freq);
-int is_6ghz_op_class(u8 op_class);
-int is_6ghz_psc_frequency(int freq);
+bool is_6ghz_freq(int freq);
+bool is_6ghz_op_class(u8 op_class);
+bool is_6ghz_psc_frequency(int freq);
+int get_6ghz_sec_channel(int channel);
 
 int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
 				    size_t nei_rep_len);
 
 int ieee802_11_ext_capab(const u8 *ie, unsigned int capab);
+bool ieee802_11_rsnx_capab_len(const u8 *rsnxe, size_t rsnxe_len,
+			       unsigned int capab);
+bool ieee802_11_rsnx_capab(const u8 *rsnxe, unsigned int capab);
 int op_class_to_bandwidth(u8 op_class);
 int op_class_to_ch_width(u8 op_class);
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/ieee802_11_defs.h b/src/lynq/packages/thirdpart/lynq-wg870/src/common/ieee802_11_defs.h
index f3ae1b1..0f7b82e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/ieee802_11_defs.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/ieee802_11_defs.h
@@ -22,7 +22,7 @@
 #define WLAN_FC_PWRMGT		0x1000
 #define WLAN_FC_MOREDATA	0x2000
 #define WLAN_FC_ISWEP		0x4000
-#define WLAN_FC_ORDER		0x8000
+#define WLAN_FC_HTC		0x8000
 
 #define WLAN_FC_GET_TYPE(fc)	(((fc) & 0x000c) >> 2)
 #define WLAN_FC_GET_STYPE(fc)	(((fc) & 0x00f0) >> 4)
@@ -50,6 +50,7 @@
 #define WLAN_FC_STYPE_AUTH		11
 #define WLAN_FC_STYPE_DEAUTH		12
 #define WLAN_FC_STYPE_ACTION		13
+#define WLAN_FC_STYPE_ACTION_NO_ACK	14
 
 /* control */
 #define WLAN_FC_STYPE_PSPOLL		10
@@ -84,6 +85,7 @@
 #define WLAN_AUTH_FILS_SK		4
 #define WLAN_AUTH_FILS_SK_PFS		5
 #define WLAN_AUTH_FILS_PK		6
+#define WLAN_AUTH_PASN			7
 #define WLAN_AUTH_LEAP			128
 
 #define WLAN_AUTH_CHALLENGE_LEN 128
@@ -445,7 +447,7 @@
 #define WLAN_EID_VHT_OPERATION 192
 #define WLAN_EID_VHT_EXTENDED_BSS_LOAD 193
 #define WLAN_EID_VHT_WIDE_BW_CHSWITCH  194
-#define WLAN_EID_VHT_TRANSMIT_POWER_ENVELOPE 195
+#define WLAN_EID_TRANSMIT_POWER_ENVELOPE 195
 #define WLAN_EID_VHT_CHANNEL_SWITCH_WRAPPER 196
 #define WLAN_EID_VHT_AID 197
 #define WLAN_EID_VHT_QUIET_CHANNEL 198
@@ -456,7 +458,11 @@
 #define WLAN_EID_DEVICE_LOCATION 204
 #define WLAN_EID_WHITE_SPACE_MAP 205
 #define WLAN_EID_FTM_PARAMETERS 206
+#define WLAN_EID_S1G_BCN_COMPAT 213
+#define WLAN_EID_TWT 216
+#define WLAN_EID_S1G_CAPABILITIES 217
 #define WLAN_EID_VENDOR_SPECIFIC 221
+#define WLAN_EID_S1G_OPERATION 232
 #define WLAN_EID_CAG_NUMBER 237
 #define WLAN_EID_AP_CSN 239
 #define WLAN_EID_FILS_INDICATION 240
@@ -495,6 +501,7 @@
 #define WLAN_EID_EXT_TCLAS_MASK 89
 #define WLAN_EID_EXT_REJECTED_GROUPS 92
 #define WLAN_EID_EXT_ANTI_CLOGGING_TOKEN 93
+#define WLAN_EID_EXT_PASN_PARAMS 100
 
 /* Extended Capabilities field */
 #define WLAN_EXT_CAPAB_20_40_COEX 0
@@ -538,7 +545,6 @@
 #define WLAN_EXT_CAPAB_TDLS_PROHIBITED 38
 #define WLAN_EXT_CAPAB_TDLS_CHANNEL_SWITCH_PROHIBITED 39
 #define WLAN_EXT_CAPAB_REJECT_UNADMITTED_FRAME 40
-#define WLAN_EXT_CAPAB_
 /* 41-43 - Service Interval Granularity */
 #define WLAN_EXT_CAPAB_IDENTIFIER_LOCATION 44
 #define WLAN_EXT_CAPAB_U_APSD_COEX 45
@@ -559,7 +565,6 @@
 #define WLAN_EXT_CAPAB_PROT_QLOAD_REPORT 60
 #define WLAN_EXT_CAPAB_TDLS_WIDER_BW 61
 #define WLAN_EXT_CAPAB_OPMODE_NOTIF 62
-#define WLAN_EXT_CAPAB_
 /* 63-64 - Max Number of MSDUs In A-MSDU */
 #define WLAN_EXT_CAPAB_CHANNEL_SCHEDULE_MGMT 65
 #define WLAN_EXT_CAPAB_GEODB_INBAND_ENABLING_SIGNAL 66
@@ -585,6 +590,9 @@
 #define WLAN_RSNX_CAPAB_PROTECTED_TWT 4
 #define WLAN_RSNX_CAPAB_SAE_H2E 5
 #define WLAN_RSNX_CAPAB_SAE_PK 6
+#define WLAN_RSNX_CAPAB_SECURE_LTF 8
+#define WLAN_RSNX_CAPAB_SECURE_RTT 9
+#define WLAN_RSNX_CAPAB_PROT_RANGE_NEG 10
 
 /* Action frame categories (IEEE Std 802.11-2016, 9.4.1.11, Table 9-76) */
 #define WLAN_ACTION_SPECTRUM_MGMT 0
@@ -609,7 +617,12 @@
 #define WLAN_ACTION_ROBUST_AV_STREAMING 19
 #define WLAN_ACTION_UNPROTECTED_DMG 20
 #define WLAN_ACTION_VHT 21
+#define WLAN_ACTION_S1G 22
+#define WLAN_ACTION_S1G_RELAY 23
+#define WLAN_ACTION_FLOW_CONTROL 24
+#define WLAN_ACTION_CTRL_RESP_MCS_NEG 25
 #define WLAN_ACTION_FILS 26
+#define WLAN_ACTION_PROTECTED_FTM 34
 #define WLAN_ACTION_VENDOR_SPECIFIC_PROTECTED 126
 #define WLAN_ACTION_VENDOR_SPECIFIC 127
 /* Note: 128-255 used to report errors by setting category | 0x80 */
@@ -650,6 +663,7 @@
 #define WLAN_PA_FTM_REQUEST 32
 #define WLAN_PA_FTM 33
 #define WLAN_PA_FILS_DISCOVERY 34
+#define WLAN_PA_LOCATION_MEASUREMENT_REPORT 47
 
 /* Protected Dual of Public Action frames (IEEE Std 802.11-2016, 9.6.11,
  * Table 9-332) */
@@ -707,6 +721,11 @@
 #define WLAN_RRM_NEIGHBOR_REPORT_REQUEST 4
 #define WLAN_RRM_NEIGHBOR_REPORT_RESPONSE 5
 
+/* Protected Fine Timing Frame Action Field value */
+#define WLAN_PROT_FTM_REQUEST 1
+#define WLAN_PROT_FTM 2
+#define WLAN_PROT_FTM_REPORT 3
+
 /* Radio Measurement capabilities (from RM Enabled Capabilities element)
  * IEEE Std 802.11-2016, 9.4.2.45, Table 9-157 */
 /* byte 1 (out of 5) */
@@ -819,6 +838,19 @@
 	NAI_REALM_CRED_TYPE_VENDOR_SPECIFIC = 10
 };
 
+/* Unprotected S1G Action field values for WLAN_ACTION_S1G */
+#define S1G_ACT_AID_SWITCH_REQUEST   0
+#define S1G_ACT_AID_SWITCH_RESPONSE  1
+#define S1G_ACT_SYNC_CONTROL         2
+#define S1G_ACT_STA_INFO_ANNOUNCE    3
+#define S1G_ACT_EDCA_PARAM_SET       4
+#define S1G_ACT_EL_OPERATION         5
+#define S1G_ACT_TWT_SETUP            6
+#define S1G_ACT_TWT_TEARDOWN         7
+#define S1G_ACT_SECT_GROUP_ID_LIST   8
+#define S1G_ACT_SECT_ID_FEEDBACK     9
+#define S1G_ACT_TWT_INFORMATION      11
+
 /*
  * IEEE P802.11-REVmc/D5.0 Table 9-81 - Measurement type definitions for
  * measurement requests
@@ -1318,6 +1350,7 @@
 #define CHANWIDTH_4320MHZ	5
 #define CHANWIDTH_6480MHZ	6
 #define CHANWIDTH_8640MHZ	7
+#define CHANWIDTH_40MHZ_6GHZ	8
 
 #define HE_NSS_MAX_STREAMS			    8
 
@@ -1344,6 +1377,10 @@
 #define DPP_CC_OUI_TYPE 0x1e
 #define SAE_PK_IE_VENDOR_TYPE 0x506f9a1f
 #define SAE_PK_OUI_TYPE 0x1f
+#define QM_IE_VENDOR_TYPE 0x506f9a22
+#define QM_IE_OUI_TYPE 0x22
+#define WFA_CAPA_IE_VENDOR_TYPE 0x506f9a23
+#define WFA_CAPA_OUI_TYPE 0x23
 
 #define MULTI_AP_SUB_ELEM_TYPE 0x06
 #define MULTI_AP_TEAR_DOWN BIT(4)
@@ -1641,6 +1678,7 @@
 #define P2P_DEV_CAPAB_INFRA_MANAGED BIT(3)
 #define P2P_DEV_CAPAB_DEVICE_LIMIT BIT(4)
 #define P2P_DEV_CAPAB_INVITATION_PROCEDURE BIT(5)
+#define P2P_DEV_CAPAB_6GHZ_BAND_CAPABLE BIT(6)
 
 /* P2P Capability - Group Capability bitmap */
 #define P2P_GROUP_CAPAB_GROUP_OWNER BIT(0)
@@ -1766,6 +1804,10 @@
 #define WLAN_AKM_SUITE_FT_PSK		0x000FAC04
 #define WLAN_AKM_SUITE_8021X_SHA256	0x000FAC05
 #define WLAN_AKM_SUITE_PSK_SHA256	0x000FAC06
+#if defined(WAPI_ANDROID)
+#define WLAN_AKM_SUITE_WAPI_PSK		0x000FAC04
+#define WLAN_AKM_SUITE_WAPI_CERT	0x000FAC12
+#endif 
 #define WLAN_AKM_SUITE_8021X_SUITE_B	0x000FAC11
 #define WLAN_AKM_SUITE_8021X_SUITE_B_192	0x000FAC12
 #define WLAN_AKM_SUITE_CCKM		0x00409600
@@ -1850,6 +1892,10 @@
 #define WLAN_AKM_SUITE_FT_PSK           0x000FAC04
 #define WLAN_AKM_SUITE_8021X_SHA256     0x000FAC05
 #define WLAN_AKM_SUITE_PSK_SHA256       0x000FAC06
+#if defined(WAPI_ANDROID)
+#define WLAN_AKM_SUITE_WAPI_PSK         0x000FAC04
+#define WLAN_AKM_SUITE_WAPI_CERT        0x000FAC12
+#endif 
 #define WLAN_AKM_SUITE_8021X_SUITE_B    0x000FAC11
 #define WLAN_AKM_SUITE_8021X_SUITE_B_192        0x000FAC12
 #define WLAN_AKM_SUITE_CCKM             0x00409600
@@ -2244,6 +2290,7 @@
 	* and optional variable length PPE Thresholds field. */
 	u8 optional[37];
 } STRUCT_PACKED;
+#define IEEE80211_HE_CAPAB_MIN_LEN (6 + 11)
 
 struct ieee80211_he_operation {
 	le32 he_oper_params; /* HE Operation Parameters[3] and
@@ -2401,6 +2448,26 @@
 /* B7: Reserved if sent by an AP; More Data Ack if sent by a non-AP STA */
 #define HE_QOS_INFO_MORE_DATA_ACK ((u8) (BIT(7)))
 
+/*
+ * IEEE Std 802.11-2020 and IEEE Std 802.11ax-2021
+ * 9.4.2.170 Reduced Neighbor Report element
+ */
+#define RNR_HEADER_LEN                              2
+#define RNR_TBTT_HEADER_LEN                         4
+#define RNR_TBTT_INFO_COUNT(x)                      (((x) & 0xf) << 4)
+#define RNR_TBTT_INFO_COUNT_MAX                     16
+#define RNR_TBTT_INFO_LEN                           13
+#define RNR_NEIGHBOR_AP_OFFSET_UNKNOWN              255
+/* Figure 9-632a - BSS Parameters subfield format */
+#define RNR_BSS_PARAM_OCT_RECOMMENDED               BIT(0)
+#define RNR_BSS_PARAM_SAME_SSID                     BIT(1)
+#define RNR_BSS_PARAM_MULTIPLE_BSSID                BIT(2)
+#define RNR_BSS_PARAM_TRANSMITTED_BSSID             BIT(3)
+#define RNR_BSS_PARAM_MEMBER_CO_LOCATED_ESS         BIT(4)
+#define RNR_BSS_PARAM_UNSOLIC_PROBE_RESP_ACTIVE     BIT(5)
+#define RNR_BSS_PARAM_CO_LOCATED                    BIT(6)
+#define RNR_20_MHZ_PSD_MAX_TXPOWER                  255 /* dBm */
+
 /* IEEE P802.11ay/D4.0, 9.4.2.251 - EDMG Operation element */
 #define EDMG_BSS_OPERATING_CHANNELS_OFFSET	6
 #define EDMG_OPERATING_CHANNEL_WIDTH_OFFSET	7
@@ -2458,4 +2525,83 @@
 	MCSC_SUBELEM_STATUS = 1,
 };
 
+/*
+ * IEEE Std 802.11ai-2016, 9.6.8.36 FILS Discovery frame format,
+ * Figure 9-687b - FILS Discovery Frame Control subfield format
+ */
+#define FD_FRAME_CTL_CAP_PRESENT			((u16) BIT(5))
+#define FD_FRAME_CTL_SHORT_SSID_PRESENT			((u16) BIT(6))
+#define FD_FRAME_CTL_AP_CSN_PRESENT			((u16) BIT(7))
+#define FD_FRAME_CTL_ANO_PRESENT			((u16) BIT(8))
+#define FD_FRAME_CTL_FREQ_SEG1_PRESENT			((u16) BIT(9))
+#define FD_FRAME_CTL_PRI_CHAN_PRESENT			((u16) BIT(10))
+#define FD_FRAME_CTL_RSN_INFO_PRESENT			((u16) BIT(11))
+#define FD_FRAME_CTL_LENGTH_PRESENT			((u16) BIT(12))
+#define FD_FRAME_CTL_MD_PRESENT				((u16) BIT(13))
+
+/*
+ * IEEE Std 802.11ai-2016, 9.6.8.36 FILS Discovery frame format,
+ * Figure 9-687c - FD Capability subfield format
+ */
+#define FD_CAP_ESS					BIT(0)
+#define FD_CAP_PRIVACY					BIT(1)
+#define FD_CAP_MULTI_BSSID_PRESENT			BIT(9)
+
+#define FD_CAP_BSS_CHWIDTH_20				0
+#define FD_CAP_BSS_CHWIDTH_40				1
+#define FD_CAP_BSS_CHWIDTH_80				2
+#define FD_CAP_BSS_CHWIDTH_160_80_80			3
+#define FD_CAP_BSS_CHWIDTH_SHIFT			2
+
+#define FD_CAP_NSS_1					0
+#define FD_CAP_NSS_2					1
+#define FD_CAP_NSS_3					2
+#define FD_CAP_NSS_4					3
+#define FD_CAP_NSS_5_8					4
+#define FD_CAP_NSS_SHIFT				5
+
+#define FD_CAP_PHY_INDEX_HR_DSSS			0
+#define FD_CAP_PHY_INDEX_ERP_OFDM			1
+#define FD_CAP_PHY_INDEX_HT				2
+#define FD_CAP_PHY_INDEX_VHT				3
+#define FD_CAP_PHY_INDEX_HE				4 /* P802.11ax */
+#define FD_CAP_PHY_INDEX_SHIFT				10
+
+/*
+ * IEEE P802.11ax/D8.0 26.17.2.3.2, AP behavior for fast passive scanning
+ */
+#define FD_MAX_INTERVAL_6GHZ                  20 /* TUs */
+
+/* Protected Vendor-specific QoS Management Action frame identifiers - WFA */
+#define QM_ACTION_VENDOR_TYPE 0x506f9a1a
+#define QM_ACTION_OUI_TYPE 0x1a
+
+/* QoS Management Action frame OUI subtypes */
+#define QM_DSCP_POLICY_QUERY 0
+#define QM_DSCP_POLICY_REQ 1
+#define QM_DSCP_POLICY_RESP 2
+
+/* QoS Management attributes */
+enum qm_attr_id {
+	QM_ATTR_PORT_RANGE = 1,
+	QM_ATTR_DSCP_POLICY = 2,
+	QM_ATTR_TCLAS = 3,
+	QM_ATTR_DOMAIN_NAME = 4,
+};
+
+/* DSCP Policy attribute - Request Type */
+enum dscp_policy_request_type {
+	DSCP_POLICY_REQ_ADD = 0, /* ADD/UPDATE */
+	DSCP_POLICY_REQ_REMOVE = 1,
+};
+
+/* Request/Response Control field of DSCP Policy Request/Response frame */
+#define DSCP_POLICY_CTRL_MORE	BIT(0)
+#define DSCP_POLICY_CTRL_RESET	BIT(1)
+
+/* Wi-Fi Alliance Capabilities element - Capabilities field */
+#define WFA_CAPA_QM_DSCP_POLICY BIT(0)
+#define WFA_CAPA_QM_UNSOLIC_DSCP BIT(1)
+#define ETHER_IS_LOCALADDR(ea)  (((unsigned char *)(ea))[0] & 2)
+
 #endif /* IEEE802_11_DEFS_H */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/ifx_vendor.h b/src/lynq/packages/thirdpart/lynq-wg870/src/common/ifx_vendor.h
new file mode 100755
index 0000000..4601b0f
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/ifx_vendor.h
@@ -0,0 +1,251 @@
+/*
+ * Infineon Technologies OUI and vendor specific assignments
+ *
+ * $ Copyright Infineon $
+ *
+ *
+ * <<Infineon-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#ifndef IFX_VENDOR_H
+#define IFX_VENDOR_H
+
+/*
+ * This file is a registry of identifier assignments from the Infineon
+ * OUI 00:03:19 for purposes other than MAC address assignment. New identifiers
+ * can be assigned through normal review process for changes to the upstream
+ * hostap.git repository.
+ */
+#define OUI_IFX		0x000319
+
+/*
+ * enum ifx_nl80211_vendor_subcmds - IFX nl80211 vendor command identifiers
+ *
+ * @IFX_VENDOR_SCMD_UNSPEC: Reserved value 0
+ *
+ * @IFX_VENDOR_SCMD_FRAMEBURST: Vendor command to enable/disable Frameburst
+ *
+ * @IFX_VENDOR_SCMD_MUEDCA_OPT_ENABLE: Vendor command to enable/disable HE MU-EDCA opt
+ *
+ * @IFX_VENDOR_SCMD_LDPC_CAP: Vendor command enable/disable LDPC Capability
+ *
+ * @IFX_VENDOR_SCMD_AMSDU: Vendor command to enable/disable AMSDU on all the TID queues
+ *
+ * @IFX_VENDOR_SCMD_TWT: Vendor subcommand to configure TWT
+ *	Uses attributes defined in enum ifx_vendor_attr_twt.
+ *
+ * @IFX_VENDOR_SCMD_OCE_ENABLE: Vendor command to enable/disable OCE Capability
+ *
+ * @IFX_VENDOR_SCMD_RANDMAC: Vendor command to enable/disable RANDMAC Capability
+ *
+ * @IFX_VENDOR_SCMD_MAX: This acts as a the tail of cmds list.
+ *      Make sure it located at the end of the list.
+ */
+enum ifx_nl80211_vendor_subcmds {
+	/*
+	 * TODO: IFX Vendor subcmd enum IDs between 1-10 are reserved
+	 * to be be filled later with BRCM Vendor subcmds that are
+	 * already used by IFX.
+	 */
+	IFX_VENDOR_SCMD_UNSPEC		= 0,
+	/* Reserved 1-5 */
+	IFX_VENDOR_SCMD_FRAMEBURST	= 6,
+	/* Reserved 7-9 */
+	IFX_VENDOR_SCMD_SET_P2P_RAND_MAC = 10,
+	IFX_VENDOR_SCMD_MUEDCA_OPT_ENABLE = 11,
+	IFX_VENDOR_SCMD_LDPC_CAP	= 12,
+	IFX_VENDOR_SCMD_AMSDU		= 13,
+	IFX_VENDOR_SCMD_TWT		= 14,
+        IFX_VENDOR_SCMD_OCE_ENABLE      = 15,
+        /* Reserved 16 */
+        IFX_VENDOR_SCMD_RANDMAC         = 17,
+	IFX_VENDOR_SCMD_MAX
+};
+
+/*
+ * enum ifx_vendor_attr - IFX nl80211 vendor attributes
+ *
+ * @IFX_VENDOR_ATTR_UNSPEC: Reserved value 0
+ *
+ * @IFX_VENDOR_ATTR_MAX: This acts as a the tail of attrs list.
+ *      Make sure it located at the end of the list.
+ */
+enum ifx_vendor_attr {
+	/*
+	 * TODO: IFX Vendor attr enum IDs between 0-10 are reserved
+	 * to be filled later with BRCM Vendor attrs that are
+	 * already used by IFX.
+	 */
+	IFX_VENDOR_ATTR_UNSPEC		= 0,
+	IFX_VENDOR_ATTR_MAC_ADDR        = 2,
+	/* Reserved 1-10 */
+	IFX_VENDOR_ATTR_MAX		= 11
+};
+
+/*
+ * enum ifx_vendor_attr_twt - Attributes for the TWT vendor command
+ *
+ * @IFX_VENDOR_ATTR_TWT_UNSPEC: Reserved value 0
+ *
+ * @IFX_VENDOR_ATTR_TWT_OPER: To specify the type of TWT operation
+ *	to be performed. Uses attributes defined in enum ifx_twt_oper.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAMS: Nester attributes representing the
+ *	parameters configured for TWT. These parameters are defined in
+ *	the enum ifx_vendor_attr_twt_param.
+ *
+ * @IFX_VENDOR_ATTR_TWT_MAX: This acts as a the tail of cmds list.
+ *      Make sure it located at the end of the list.
+ */
+enum ifx_vendor_attr_twt {
+	IFX_VENDOR_ATTR_TWT_UNSPEC,
+	IFX_VENDOR_ATTR_TWT_OPER,
+	IFX_VENDOR_ATTR_TWT_PARAMS,
+	IFX_VENDOR_ATTR_TWT_MAX
+};
+
+/*
+ * enum ifx_twt_oper - TWT operation to be specified using the vendor
+ * attribute IFX_VENDOR_ATTR_TWT_OPER
+ *
+ * @IFX_TWT_OPER_UNSPEC: Reserved value 0
+ *
+ * @IFX_TWT_OPER_SETUP: Setup a TWT session. Required parameters are
+ *	obtained through the nested attrs under IFX_VENDOR_ATTR_TWT_PARAMS.
+ *
+ * @IFX_TWT_OPER_TEARDOWN: Teardown the already negotiated TWT session.
+ *	Required parameters are obtained through the nested attrs under
+ *	IFX_VENDOR_ATTR_TWT_PARAMS.
+ *
+ * @IFX_TWT_OPER_MAX: This acts as a the tail of the list.
+ *      Make sure it located at the end of the list.
+ */
+enum ifx_twt_oper {
+	IFX_TWT_OPER_UNSPEC,
+	IFX_TWT_OPER_SETUP,
+	IFX_TWT_OPER_TEARDOWN,
+	IFX_TWT_OPER_MAX
+};
+
+/*
+ * enum ifx_vendor_attr_twt_param - TWT parameters
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_UNSPEC: Reserved value 0
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_NEGO_TYPE: Specifies the type of Negotiation to be
+ *	done during Setup. The four possible types are
+ *	0 - Individual TWT Negotiation
+ *	1 - Wake TBTT Negotiation
+ *	2 - Broadcast TWT in Beacon
+ *	3 - Broadcast TWT Membership Negotiation
+ *
+ *	The possible values are defined in the enum ifx_twt_param_nego_type
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_SETUP_CMD_TYPE: Specifies the type of TWT Setup frame
+ *	when sent by the TWT Requesting STA
+ *	0 - Request
+ *	1 - Suggest
+ *	2 - Demand
+ *
+ *	when sent by the TWT Responding STA.
+ *	3 - Grouping
+ *	4 - Accept
+ *	5 - Alternate
+ *	6 - Dictate
+ *	7 - Reject
+ *
+ *	The possible values are defined in the enum ifx_twt_oper_setup_cmd_type.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_DIALOG_TOKEN: Dialog Token used by the TWT Requesting STA to
+ *	identify the TWT Setup request/response transaction.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME: Target Wake Time.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME_OFFSET: Target Wake Time Offset.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION: Nominal Minimum TWT Wake Duration.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_EXPONENT: TWT Wake Interval Exponent.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_MANTISSA: TWT Wake Interval Mantissa.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_REQUESTOR: Specify this is a TWT Requesting / Responding STA.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_TRIGGER: Specify Trigger based / Non-Trigger based TWT Session.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_IMPLICIT: Specify Implicit / Explicit TWT session.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_FLOW_TYPE: Specify Un-Announced / Announced TWT session.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_FLOW_ID: Flow ID of an iTWT session.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_BCAST_TWT_ID: Brocast TWT ID of a bTWT session.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_PROTECTION: Specifies whether Tx within SP is protected.
+ *	Set to 1 to indicate that TXOPs within the TWT SPs shall be initiated
+ *	with a NAV protection mechanism, such as (MU) RTS/CTS or CTS-to-self frame;
+ *	otherwise, it shall set it to 0.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_CHANNEL: TWT channel field which is set to 0, unless
+ * 	the HE STA sets up a subchannel selective transmission operation.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_TWT_INFO_FRAME_DISABLED: TWT Information frame RX handing
+ *	disabled / enabled.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION_UNIT: Nominal Minimum TWT Wake Duration
+ *	Unit. 0 represents unit in "256 usecs" and 1 represents unit in "TUs".
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_TEARDOWN_ALL_TWT: Teardown all negotiated TWT sessions.
+ *
+ * @IFX_VENDOR_ATTR_TWT_PARAM_MAX: This acts as a the tail of the list.
+ *      Make sure it located at the end of the list.
+ */
+enum ifx_vendor_attr_twt_param {
+	IFX_VENDOR_ATTR_TWT_PARAM_UNSPEC,
+	IFX_VENDOR_ATTR_TWT_PARAM_NEGO_TYPE,
+	IFX_VENDOR_ATTR_TWT_PARAM_SETUP_CMD_TYPE,
+	IFX_VENDOR_ATTR_TWT_PARAM_DIALOG_TOKEN,
+	IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME,
+	IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME_OFFSET,
+	IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION,
+	IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_EXPONENT,
+	IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_MANTISSA,
+	IFX_VENDOR_ATTR_TWT_PARAM_REQUESTOR,
+	IFX_VENDOR_ATTR_TWT_PARAM_TRIGGER,
+	IFX_VENDOR_ATTR_TWT_PARAM_IMPLICIT,
+	IFX_VENDOR_ATTR_TWT_PARAM_FLOW_TYPE,
+	IFX_VENDOR_ATTR_TWT_PARAM_FLOW_ID,
+	IFX_VENDOR_ATTR_TWT_PARAM_BCAST_TWT_ID,
+	IFX_VENDOR_ATTR_TWT_PARAM_PROTECTION,
+	IFX_VENDOR_ATTR_TWT_PARAM_CHANNEL,
+	IFX_VENDOR_ATTR_TWT_PARAM_TWT_INFO_FRAME_DISABLED,
+	IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION_UNIT,
+	IFX_VENDOR_ATTR_TWT_PARAM_TEARDOWN_ALL_TWT,
+	IFX_VENDOR_ATTR_TWT_PARAM_MAX
+};
+
+enum ifx_twt_param_nego_type {
+	IFX_TWT_PARAM_NEGO_TYPE_INVALID			= -1,
+	IFX_TWT_PARAM_NEGO_TYPE_ITWT			= 0,
+	IFX_TWT_PARAM_NEGO_TYPE_WAKE_TBTT		= 1,
+	IFX_TWT_PARAM_NEGO_TYPE_BTWT_IE_BCN		= 2,
+	IFX_TWT_PARAM_NEGO_TYPE_BTWT			= 3,
+	IFX_TWT_PARAM_NEGO_TYPE_MAX			= 4
+};
+
+enum ifx_twt_oper_setup_cmd_type {
+	IFX_TWT_OPER_SETUP_CMD_TYPE_INVALID	= -1,
+	IFX_TWT_OPER_SETUP_CMD_TYPE_REQUEST	= 0,
+	IFX_TWT_OPER_SETUP_CMD_TYPE_SUGGEST	= 1,
+	IFX_TWT_OPER_SETUP_CMD_TYPE_DEMAND	= 2,
+	IFX_TWT_OPER_SETUP_CMD_TYPE_GROUPING	= 3,
+	IFX_TWT_OPER_SETUP_CMD_TYPE_ACCEPT	= 4,
+	IFX_TWT_OPER_SETUP_CMD_TYPE_ALTERNATE	= 5,
+	IFX_TWT_OPER_SETUP_CMD_TYPE_DICTATE	= 6,
+	IFX_TWT_OPER_SETUP_CMD_TYPE_REJECT	= 7,
+	IFX_TWT_OPER_SETUP_CMD_TYPE_MAX		= 8
+};
+
+#endif /* IFX_VENDOR_H */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/ptksa_cache.c b/src/lynq/packages/thirdpart/lynq-wg870/src/common/ptksa_cache.c
new file mode 100755
index 0000000..8fcb135
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/ptksa_cache.c
@@ -0,0 +1,321 @@
+/*
+ * RSN PTKSA cache implementation
+ *
+ * Copyright (C) 2019 Intel Corporation
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "includes.h"
+#include "utils/common.h"
+#include "eloop.h"
+#include "common/ptksa_cache.h"
+
+#define PTKSA_CACHE_MAX_ENTRIES 16
+
+struct ptksa_cache {
+	struct dl_list ptksa;
+	unsigned int n_ptksa;
+};
+
+static void ptksa_cache_set_expiration(struct ptksa_cache *ptksa);
+
+
+static void ptksa_cache_free_entry(struct ptksa_cache *ptksa,
+				   struct ptksa_cache_entry *entry)
+{
+	ptksa->n_ptksa--;
+
+	dl_list_del(&entry->list);
+	bin_clear_free(entry, sizeof(*entry));
+}
+
+
+static void ptksa_cache_expire(void *eloop_ctx, void *timeout_ctx)
+{
+	struct ptksa_cache *ptksa = eloop_ctx;
+	struct ptksa_cache_entry *e, *next;
+	struct os_reltime now;
+
+	if (!ptksa)
+		return;
+
+	os_get_reltime(&now);
+
+	dl_list_for_each_safe(e, next, &ptksa->ptksa,
+			      struct ptksa_cache_entry, list) {
+		if (e->expiration > now.sec)
+			continue;
+
+		wpa_printf(MSG_DEBUG, "Expired PTKSA cache entry for " MACSTR,
+			   MAC2STR(e->addr));
+
+		ptksa_cache_free_entry(ptksa, e);
+	}
+
+	ptksa_cache_set_expiration(ptksa);
+}
+
+
+static void ptksa_cache_set_expiration(struct ptksa_cache *ptksa)
+{
+	struct ptksa_cache_entry *e;
+	int sec;
+	struct os_reltime now;
+
+	eloop_cancel_timeout(ptksa_cache_expire, ptksa, NULL);
+
+	if (!ptksa || !ptksa->n_ptksa)
+		return;
+
+	e = dl_list_first(&ptksa->ptksa, struct ptksa_cache_entry, list);
+	if (!e)
+		return;
+
+	os_get_reltime(&now);
+	sec = e->expiration - now.sec;
+	if (sec < 0)
+		sec = 0;
+
+	eloop_register_timeout(sec + 1, 0, ptksa_cache_expire, ptksa, NULL);
+}
+
+
+/*
+ * ptksa_cache_init - Initialize PTKSA cache
+ *
+ * Returns: Pointer to PTKSA cache data or %NULL on failure
+ */
+struct ptksa_cache * ptksa_cache_init(void)
+{
+	struct ptksa_cache *ptksa = os_zalloc(sizeof(struct ptksa_cache));
+
+	wpa_printf(MSG_DEBUG, "PTKSA: Initializing");
+
+	if (ptksa)
+		dl_list_init(&ptksa->ptksa);
+
+	return ptksa;
+}
+
+
+/*
+ * ptksa_cache_deinit - Free all entries in PTKSA cache
+ * @ptksa: Pointer to PTKSA cache data from ptksa_cache_init()
+ */
+void ptksa_cache_deinit(struct ptksa_cache *ptksa)
+{
+	struct ptksa_cache_entry *e, *next;
+
+	if (!ptksa)
+		return;
+
+	wpa_printf(MSG_DEBUG, "PTKSA: Deinit. n_ptksa=%u", ptksa->n_ptksa);
+
+	dl_list_for_each_safe(e, next, &ptksa->ptksa,
+			      struct ptksa_cache_entry, list)
+		ptksa_cache_free_entry(ptksa, e);
+
+	eloop_cancel_timeout(ptksa_cache_expire, ptksa, NULL);
+	os_free(ptksa);
+}
+
+
+/*
+ * ptksa_cache_get - Fetch a PTKSA cache entry
+ * @ptksa: Pointer to PTKSA cache data from ptksa_cache_init()
+ * @addr: Peer address or %NULL to match any
+ * @cipher: Specific cipher suite to search for or WPA_CIPHER_NONE for any
+ * Returns: Pointer to PTKSA cache entry or %NULL if no match was found
+ */
+struct ptksa_cache_entry * ptksa_cache_get(struct ptksa_cache *ptksa,
+					   const u8 *addr, u32 cipher)
+{
+	struct ptksa_cache_entry *e;
+
+	if (!ptksa)
+		return NULL;
+
+	dl_list_for_each(e, &ptksa->ptksa, struct ptksa_cache_entry, list) {
+		if ((!addr || os_memcmp(e->addr, addr, ETH_ALEN) == 0) &&
+		    (cipher == WPA_CIPHER_NONE || cipher == e->cipher))
+			return e;
+	}
+
+	return NULL;
+}
+
+
+/*
+ * ptksa_cache_list - Dump text list of entries in PTKSA cache
+ * @ptksa: Pointer to PTKSA cache data from ptksa_cache_init()
+ * @buf: Buffer for the list
+ * @len: Length of the buffer
+ * Returns: Number of bytes written to buffer
+ *
+ * This function is used to generate a text format representation of the
+ * current PTKSA cache contents for the ctrl_iface PTKSA command.
+ */
+int ptksa_cache_list(struct ptksa_cache *ptksa, char *buf, size_t len)
+{
+	struct ptksa_cache_entry *e;
+	int i = 0, ret;
+	char *pos = buf;
+	struct os_reltime now;
+
+	if (!ptksa)
+		return 0;
+
+	os_get_reltime(&now);
+
+	ret = os_snprintf(pos, buf + len - pos,
+			  "Index / ADDR / Cipher / expiration (secs) / TK / KDK\n");
+	if (os_snprintf_error(buf + len - pos, ret))
+		return pos - buf;
+	pos += ret;
+
+	dl_list_for_each(e, &ptksa->ptksa, struct ptksa_cache_entry, list) {
+		ret = os_snprintf(pos, buf + len - pos, "%u " MACSTR,
+				  i, MAC2STR(e->addr));
+		if (os_snprintf_error(buf + len - pos, ret))
+			return pos - buf;
+		pos += ret;
+
+		ret = os_snprintf(pos, buf + len - pos, " %s %lu ",
+				  wpa_cipher_txt(e->cipher),
+				  e->expiration - now.sec);
+		if (os_snprintf_error(buf + len - pos, ret))
+			return pos - buf;
+		pos += ret;
+
+		ret = wpa_snprintf_hex(pos, buf + len - pos, e->ptk.tk,
+				       e->ptk.tk_len);
+		if (os_snprintf_error(buf + len - pos, ret))
+			return pos - buf;
+		pos += ret;
+
+		ret = os_snprintf(pos, buf + len - pos, " ");
+		if (os_snprintf_error(buf + len - pos, ret))
+			return pos - buf;
+		pos += ret;
+
+		ret = wpa_snprintf_hex(pos, buf + len - pos, e->ptk.kdk,
+				       e->ptk.kdk_len);
+		if (os_snprintf_error(buf + len - pos, ret))
+			return pos - buf;
+		pos += ret;
+
+		ret = os_snprintf(pos, buf + len - pos, "\n");
+		if (os_snprintf_error(buf + len - pos, ret))
+			return pos - buf;
+		pos += ret;
+
+		i++;
+	}
+
+	return pos - buf;
+}
+
+
+/*
+ * ptksa_cache_flush - Flush PTKSA cache entries
+ *
+ * @ptksa: Pointer to PTKSA cache data from ptksa_cache_init()
+ * @addr: Peer address or %NULL to match any
+ * @cipher: Specific cipher suite to search for or WPA_CIPHER_NONE for any
+ */
+void ptksa_cache_flush(struct ptksa_cache *ptksa, const u8 *addr, u32 cipher)
+{
+	struct ptksa_cache_entry *e, *next;
+	bool removed = false;
+
+	if (!ptksa)
+		return;
+
+	dl_list_for_each_safe(e, next, &ptksa->ptksa, struct ptksa_cache_entry,
+			      list) {
+		if ((!addr || os_memcmp(e->addr, addr, ETH_ALEN) == 0) &&
+		    (cipher == WPA_CIPHER_NONE || cipher == e->cipher)) {
+			wpa_printf(MSG_DEBUG,
+				   "Flush PTKSA cache entry for " MACSTR,
+				   MAC2STR(e->addr));
+
+			ptksa_cache_free_entry(ptksa, e);
+			removed = true;
+		}
+	}
+
+	if (removed)
+		ptksa_cache_set_expiration(ptksa);
+}
+
+
+/*
+ * ptksa_cache_add - Add a PTKSA cache entry
+ * @ptksa: Pointer to PTKSA cache data from ptksa_cache_init()
+ * @addr: Peer address
+ * @cipher: The cipher used
+ * @life_time: The PTK life time in seconds
+ * @ptk: The PTK
+ * Returns: Pointer to the added PTKSA cache entry or %NULL on error
+ *
+ * This function creates a PTKSA entry and adds it to the PTKSA cache.
+ * If an old entry is already in the cache for the same peer and cipher
+ * this entry will be replaced with the new entry.
+ */
+struct ptksa_cache_entry * ptksa_cache_add(struct ptksa_cache *ptksa,
+					   const u8 *addr, u32 cipher,
+					   u32 life_time,
+					   const struct wpa_ptk *ptk)
+{
+	struct ptksa_cache_entry *entry, *tmp, *tmp2 = NULL;
+	struct os_reltime now;
+
+	if (!ptksa || !ptk || !addr || !life_time || cipher == WPA_CIPHER_NONE)
+		return NULL;
+
+	/* remove a previous entry if present */
+	ptksa_cache_flush(ptksa, addr, cipher);
+
+	/* no place to add another entry */
+	if (ptksa->n_ptksa >= PTKSA_CACHE_MAX_ENTRIES)
+		return NULL;
+
+	entry = os_zalloc(sizeof(*entry));
+	if (!entry)
+		return NULL;
+
+	dl_list_init(&entry->list);
+	os_memcpy(entry->addr, addr, ETH_ALEN);
+	entry->cipher = cipher;
+
+	os_memcpy(&entry->ptk, ptk, sizeof(entry->ptk));
+
+	os_get_reltime(&now);
+	entry->expiration = now.sec + life_time;
+
+	dl_list_for_each(tmp, &ptksa->ptksa, struct ptksa_cache_entry, list) {
+		if (tmp->expiration > entry->expiration) {
+			tmp2 = tmp;
+			break;
+		}
+	}
+
+	/*
+	 * If the expiration is later then all other or the list is empty
+	 * entries, add it to the end of the list;
+	 * otherwise add it before the relevant entry.
+	 */
+	if (tmp2)
+		dl_list_add(&tmp2->list, &entry->list);
+	else
+		dl_list_add_tail(&ptksa->ptksa, &entry->list);
+
+	ptksa->n_ptksa++;
+	wpa_printf(MSG_DEBUG,
+		   "Added PTKSA cache entry addr=" MACSTR " cipher=%u",
+		   MAC2STR(addr), cipher);
+
+	return entry;
+}
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/ptksa_cache.h b/src/lynq/packages/thirdpart/lynq-wg870/src/common/ptksa_cache.h
new file mode 100755
index 0000000..28ef291
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/ptksa_cache.h
@@ -0,0 +1,79 @@
+/*
+ * RSN PTKSA cache interface
+ *
+ * Copyright (C) 2019 Intel Corporation
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef PTKSA_CACHE_H
+#define PTKSA_CACHE_H
+
+#include "wpa_common.h"
+#include "defs.h"
+#include "list.h"
+
+/**
+ * struct ptksa_cache_entry - PTKSA cache entry
+ */
+struct ptksa_cache_entry {
+	struct dl_list list;
+	struct wpa_ptk ptk;
+	os_time_t expiration;
+	u32 cipher;
+	u8 addr[ETH_ALEN];
+};
+
+#ifdef CONFIG_PTKSA_CACHE
+
+struct ptksa_cache;
+
+struct ptksa_cache * ptksa_cache_init(void);
+void ptksa_cache_deinit(struct ptksa_cache *ptksa);
+struct ptksa_cache_entry * ptksa_cache_get(struct ptksa_cache *ptksa,
+					   const u8 *addr, u32 cipher);
+int ptksa_cache_list(struct ptksa_cache *ptksa, char *buf, size_t len);
+struct ptksa_cache_entry * ptksa_cache_add(struct ptksa_cache *ptksa,
+					   const u8 *addr, u32 cipher,
+					   u32 life_time,
+					   const struct wpa_ptk *ptk);
+void ptksa_cache_flush(struct ptksa_cache *ptksa, const u8 *addr, u32 cipher);
+
+#else /* CONFIG_PTKSA_CACHE */
+
+static inline struct ptksa_cache * ptksa_cache_init(void)
+{
+	return (struct ptksa_cache *) 1;
+}
+
+static inline void ptksa_cache_deinit(struct ptksa_cache *ptksa)
+{
+}
+
+static inline struct ptksa_cache_entry *
+ptksa_cache_get(struct ptksa_cache *ptksa, const u8 *addr, u32 cipher)
+{
+	return NULL;
+}
+
+static inline int ptksa_cache_list(struct ptksa_cache *ptksa,
+				   char *buf, size_t len)
+{
+	return -1;
+}
+
+static inline struct ptksa_cache_entry *
+ptksa_cache_add(struct ptksa_cache *ptksa, const u8 *addr, u32 cipher,
+		u32 life_time, const struct wpa_ptk *ptk)
+{
+	return NULL;
+}
+
+static inline void ptksa_cache_flush(struct ptksa_cache *ptksa,
+				     const u8 *addr, u32 cipher)
+{
+}
+
+#endif /* CONFIG_PTKSA_CACHE */
+#endif /* PTKSA_CACHE_H */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/qca-vendor.h b/src/lynq/packages/thirdpart/lynq-wg870/src/common/qca-vendor.h
index d4c1da7..b77e299 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/qca-vendor.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/qca-vendor.h
@@ -512,7 +512,9 @@
  * @QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG: This command is used to
  *	configure parameters per peer to capture Channel Frequency Response
  *	(CFR) and enable Periodic CFR capture. The attributes for this command
- *	are defined in enum qca_wlan_vendor_peer_cfr_capture_attr.
+ *	are defined in enum qca_wlan_vendor_peer_cfr_capture_attr. This command
+ *	can also be used to send CFR data from the driver to userspace when
+ *	netlink events are used to send CFR data.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT: Event to indicate changes
  *	in throughput dynamically. The driver estimates the throughput based on
@@ -620,7 +622,14 @@
  *	This new command is alternative to existing command
  *	QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY since existing command/event
  *	is using stream of bytes instead of structured data using vendor
- *	attributes.
+ *	attributes. User space sends unsafe frequency ranges to the driver using
+ *	a nested attribute %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE. On
+ *	reception of this command, the driver shall check if an interface is
+ *	operating on an unsafe frequency and the driver shall try to move to a
+ *	safe channel when needed. If the driver is not able to find a safe
+ *	channel the interface can keep operating on an unsafe channel with the
+ *	TX power limit derived based on internal configurations	like
+ *	regulatory/SAR rules.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_ADD_STA_NODE: This vendor subcommand is used to
  *	add the STA node details in driver/firmware. Attributes for this event
@@ -699,7 +708,60 @@
  *	The host driver selects Tx VDEV, and notifies user. The attributes
  *	used with this event are defined in enum
  *	qca_wlan_vendor_attr_mbssid_tx_vdev_status.
+ *	This event contains Tx VDEV group information, other VDEVs
+ *	interface index, and status information.
  *
+ * @QCA_NL80211_VENDOR_SUBCMD_CONCURRENT_MULTI_STA_POLICY: Vendor command to
+ *	configure the concurrent session policies when multiple STA interfaces
+ *	are (getting) active. The attributes used by this command are defined
+ *	in enum qca_wlan_vendor_attr_concurrent_sta_policy.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS: Userspace can use this command
+ *	to query usable channels for different interface types such as STA,
+ *	AP, P2P GO, P2P Client, NAN, etc. The driver shall report all usable
+ *	channels in the response based on country code, different static
+ *	configurations, concurrency combinations, etc. The attributes used
+ *	with this command are defined in
+ *	enum qca_wlan_vendor_attr_usable_channels.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_GET_RADAR_HISTORY: This vendor subcommand is used
+ *	to get DFS radar history from the driver to userspace. The driver
+ *	returns QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES attribute with an
+ *	array of nested entries.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_MDNS_OFFLOAD: Userspace can use this command to
+ *	enable/disable mDNS offload to the firmware. The attributes used with
+ *	this command are defined in enum qca_wlan_vendor_attr_mdns_offload.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_SET_MONITOR_MODE: This vendor subcommand is used
+ *	to set packet monitor mode that aims to send the specified set of TX and
+ *	RX frames on the current client interface to an active monitor
+ *	interface. If this monitor mode is set, the driver will send the
+ *	configured frames, from the interface on which the command is issued, to
+ *	an active monitor interface. The attributes used with this command are
+ *	defined in enum qca_wlan_vendor_attr_set_monitor_mode.
+ *
+ *	Though the monitor mode is configured for the respective
+ *	Data/Management/Control frames, it is up to the respective WLAN
+ *	driver/firmware/hardware designs to consider the possibility of sending
+ *	these frames over the monitor interface. For example, the Control frames
+ *	are handled within the hardware and thus passing such frames over the
+ *	monitor interface is left to the respective designs.
+ *
+ *	Also, this monitor mode is governed to behave accordingly in
+ *	suspend/resume states. If the firmware handles any of such frames in
+ *	suspend state without waking up the host and if the monitor mode is
+ *	configured to notify all such frames, the firmware is expected to resume
+ *	the host and forward the respective frames to the monitor interface.
+ *	Please note that such a request to get the frames over the monitor
+ *	interface will have a definite power implication.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS: This vendor subcommand is used both
+ *	as a request to set the driver/firmware with the parameters to trigger
+ *	the roaming events, and also used by the driver/firmware to pass on the
+ *	various roam events to userspace.
+ *	Applicable only for the STA mode. The attributes used with this command
+ *	are defined in enum qca_wlan_vendor_attr_roam_events.
  */
 enum qca_nl80211_vendor_subcmds {
 	QCA_NL80211_VENDOR_SUBCMD_UNSPEC = 0,
@@ -886,6 +948,13 @@
 	QCA_NL80211_VENDOR_SUBCMD_UPDATE_SSID = 194,
 	QCA_NL80211_VENDOR_SUBCMD_WIFI_FW_STATS = 195,
 	QCA_NL80211_VENDOR_SUBCMD_MBSSID_TX_VDEV_STATUS = 196,
+	QCA_NL80211_VENDOR_SUBCMD_CONCURRENT_MULTI_STA_POLICY = 197,
+	QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS = 198,
+	QCA_NL80211_VENDOR_SUBCMD_GET_RADAR_HISTORY = 199,
+	QCA_NL80211_VENDOR_SUBCMD_MDNS_OFFLOAD = 200,
+	/* 201 - reserved for QCA */
+	QCA_NL80211_VENDOR_SUBCMD_SET_MONITOR_MODE = 202,
+	QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS = 203,
 };
 
 enum qca_wlan_vendor_attr {
@@ -1124,7 +1193,7 @@
  * @QCA_ROAM_REASON_CONGESTION: Roam triggered considering the connected channel
  * or environment being very noisy or congested.
  *
- * @QCA_ROAM_REASON_EXPLICIT_REQUEST: Roam triggered due to an explicit request
+ * @QCA_ROAM_REASON_USER_TRIGGER: Roam triggered due to an explicit request
  * from the user (user space).
  *
  * @QCA_ROAM_REASON_BTM: Roam triggered due to BTM Request frame received from
@@ -1132,6 +1201,26 @@
  *
  * @QCA_ROAM_REASON_BSS_LOAD: Roam triggered due to the channel utilization
  * breaching out the configured threshold.
+ *
+ * @QCA_ROAM_REASON_WTC: Roam triggered due to Wireless to Cellular BSS
+ * transition request.
+ *
+ * @QCA_ROAM_REASON_IDLE: Roam triggered when device is suspended, there is no
+ * data activity with the AP and the current RSSI falls below a certain
+ * threshold.
+ *
+ * @QCA_ROAM_REASON_DISCONNECTION: Roam triggered due to Deauthentication or
+ * Disassociation frames received from the connected AP.
+ *
+ * @QCA_ROAM_REASON_PERIODIC_TIMER: Roam triggered as part of the periodic scan
+ * that happens when there is no candidate AP found during the poor RSSI scan
+ * trigger.
+ *
+ * @QCA_ROAM_REASON_BACKGROUND_SCAN: Roam triggered based on the scan results
+ * obtained from an external scan (not aimed at roaming).
+ *
+ * @QCA_ROAM_REASON_BT_ACTIVITY: Roam triggered due to Bluetooth connection is
+ * established when the station is connected in the 2.4 GHz band.
  */
 enum qca_roam_reason {
 	QCA_ROAM_REASON_UNKNOWN,
@@ -1143,6 +1232,12 @@
 	QCA_ROAM_REASON_USER_TRIGGER,
 	QCA_ROAM_REASON_BTM,
 	QCA_ROAM_REASON_BSS_LOAD,
+	QCA_ROAM_REASON_WTC,
+	QCA_ROAM_REASON_IDLE,
+	QCA_ROAM_REASON_DISCONNECTION,
+	QCA_ROAM_REASON_PERIODIC_TIMER,
+	QCA_ROAM_REASON_BACKGROUND_SCAN,
+	QCA_ROAM_REASON_BT_ACTIVITY,
 };
 
 enum qca_wlan_vendor_attr_roam_auth {
@@ -1362,6 +1457,16 @@
  * Used with event to notify the EDMG channel number selected in ACS
  * operation.
  * EDMG primary channel is indicated by QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ACS_PUNCTURE_BITMAP: Optional (u16).
+ * Used with event to notify the puncture pattern selected in ACS operation.
+ * Encoding for this attribute will follow the convention used in the Disabled
+ * Subchannel Bitmap field of the EHT Operation IE.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ACS_EHT_ENABLED: Flag attribute.
+ * Used with command to configure ACS operation for EHT mode.
+ * Disable (flag attribute not present) - EHT disabled and
+ * Enable (flag attribute present) - EHT enabled.
  */
 enum qca_wlan_vendor_attr_acs_offload {
 	QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_INVALID = 0,
@@ -1382,6 +1487,8 @@
 	QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_FREQUENCY = 15,
 	QCA_WLAN_VENDOR_ATTR_ACS_EDMG_ENABLED = 16,
 	QCA_WLAN_VENDOR_ATTR_ACS_EDMG_CHANNEL = 17,
+	QCA_WLAN_VENDOR_ATTR_ACS_PUNCTURE_BITMAP = 18,
+	QCA_WLAN_VENDOR_ATTR_ACS_EHT_ENABLED = 19,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_ACS_AFTER_LAST,
@@ -1458,6 +1565,12 @@
  *	concurrent network sessions on different Wi-Fi bands. This feature
  *	capability is attributed to the hardware's capability to support
  *	the same (e.g., DBS).
+ * @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT: Flag indicating whether the
+ *	responses for the respective TWT operations are asynchronous (separate
+ *	event message) from the driver. If not specified, the responses are
+ *	synchronous (in vendor command reply) to the request. Each TWT
+ *	operation is specifically mentioned (against its respective
+ *	documentation) to support either of these or both modes.
  * @NUM_QCA_WLAN_VENDOR_FEATURES: Number of assigned feature bits
  */
 enum qca_wlan_vendor_features {
@@ -1475,6 +1588,7 @@
 	QCA_WLAN_VENDOR_FEATURE_THERMAL_CONFIG		= 11,
 	QCA_WLAN_VENDOR_FEATURE_ADAPTIVE_11R		= 12,
 	QCA_WLAN_VENDOR_FEATURE_CONCURRENT_BAND_SESSIONS = 13,
+	QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT	= 14,
 	NUM_QCA_WLAN_VENDOR_FEATURES /* keep last */
 };
 
@@ -1680,32 +1794,62 @@
 };
 
 /**
- * enum qca_vendor_attr_get_tsf: Vendor attributes for TSF capture
- * @QCA_WLAN_VENDOR_ATTR_TSF_CMD: enum qca_tsf_operation (u32)
- * @QCA_WLAN_VENDOR_ATTR_TSF_TIMER_VALUE: Unsigned 64 bit TSF timer value
- * @QCA_WLAN_VENDOR_ATTR_TSF_SOC_TIMER_VALUE: Unsigned 64 bit Synchronized
- *	SOC timer value at TSF capture
+ * enum qca_vendor_attr_tsf_cmd: Vendor attributes for TSF capture
+ * @QCA_WLAN_VENDOR_ATTR_TSF_CMD: Required (u32)
+ * Specify the TSF command. Possible values are defined in
+ * &enum qca_tsf_cmd.
+ * @QCA_WLAN_VENDOR_ATTR_TSF_TIMER_VALUE: Optional (u64)
+ * This attribute contains TSF timer value. This attribute is only available
+ * in %QCA_TSF_GET or %QCA_TSF_SYNC_GET response.
+ * @QCA_WLAN_VENDOR_ATTR_TSF_SOC_TIMER_VALUE: Optional (u64)
+ * This attribute contains SOC timer value at TSF capture. This attribute is
+ * only available in %QCA_TSF_GET or %QCA_TSF_SYNC_GET response.
+ * @QCA_WLAN_VENDOR_ATTR_TSF_SYNC_INTERVAL: Optional (u32)
+ * This attribute is used to provide TSF sync interval and only applicable when
+ * TSF command is %QCA_TSF_SYNC_START. If this attribute is not provided, the
+ * driver will use the default value. Time unit is in milliseconds.
  */
 enum qca_vendor_attr_tsf_cmd {
 	QCA_WLAN_VENDOR_ATTR_TSF_INVALID = 0,
 	QCA_WLAN_VENDOR_ATTR_TSF_CMD,
 	QCA_WLAN_VENDOR_ATTR_TSF_TIMER_VALUE,
 	QCA_WLAN_VENDOR_ATTR_TSF_SOC_TIMER_VALUE,
+	QCA_WLAN_VENDOR_ATTR_TSF_SYNC_INTERVAL,
 	QCA_WLAN_VENDOR_ATTR_TSF_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_TSF_MAX =
 	QCA_WLAN_VENDOR_ATTR_TSF_AFTER_LAST - 1
 };
 
 /**
- * enum qca_tsf_operation: TSF driver commands
+ * enum qca_tsf_cmd: TSF driver commands
  * @QCA_TSF_CAPTURE: Initiate TSF Capture
  * @QCA_TSF_GET: Get TSF capture value
  * @QCA_TSF_SYNC_GET: Initiate TSF capture and return with captured value
+ * @QCA_TSF_AUTO_REPORT_ENABLE: Used in STA mode only. Once set, the target
+ * will automatically send TSF report to the host. To query
+ * %QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY, this operation needs to be
+ * initiated first.
+ * @QCA_TSF_AUTO_REPORT_DISABLE: Used in STA mode only. Once set, the target
+ * will not automatically send TSF report to the host. If
+ * %QCA_TSF_AUTO_REPORT_ENABLE is initiated and
+ * %QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY is not queried anymore, this
+ * operation needs to be initiated.
+ * @QCA_TSF_SYNC_START: Start periodic TSF sync feature. The driver periodically
+ * fetches TSF and host time mapping from the firmware with interval configured
+ * through the %QCA_WLAN_VENDOR_ATTR_TSF_SYNC_INTERVAL attribute. If the
+ * interval value is not provided the driver will use the default value. The
+ * userspace can query the TSF and host time mapping via the %QCA_TSF_GET
+ * command.
+ * @QCA_TSF_SYNC_STOP: Stop periodic TSF sync feature.
  */
 enum qca_tsf_cmd {
 	QCA_TSF_CAPTURE,
 	QCA_TSF_GET,
 	QCA_TSF_SYNC_GET,
+	QCA_TSF_AUTO_REPORT_ENABLE,
+	QCA_TSF_AUTO_REPORT_DISABLE,
+	QCA_TSF_SYNC_START,
+	QCA_TSF_SYNC_STOP,
 };
 
 /**
@@ -1799,6 +1943,23 @@
 };
 
 /**
+ * enum qca_wlan_vendor_scan_priority - Specifies the valid values that the
+ * vendor scan attribute QCA_WLAN_VENDOR_ATTR_SCAN_PRIORITY can take.
+ * @QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_LOW: Very low priority
+ * @QCA_WLAN_VENDOR_SCAN_PRIORITY_LOW: Low priority
+ * @QCA_WLAN_VENDOR_SCAN_PRIORITY_MEDIUM: Medium priority
+ * @QCA_WLAN_VENDOR_SCAN_PRIORITY_HIGH: High priority
+ * @QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_HIGH: Very high priority
+ */
+enum qca_wlan_vendor_scan_priority {
+	QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_LOW = 0,
+	QCA_WLAN_VENDOR_SCAN_PRIORITY_LOW = 1,
+	QCA_WLAN_VENDOR_SCAN_PRIORITY_MEDIUM = 2,
+	QCA_WLAN_VENDOR_SCAN_PRIORITY_HIGH = 3,
+	QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_HIGH = 4,
+};
+
+/**
  * enum qca_wlan_vendor_attr_scan - Specifies vendor scan attributes
  *
  * @QCA_WLAN_VENDOR_ATTR_SCAN_IE: IEs that should be included as part of scan
@@ -1823,6 +1984,11 @@
  * @QCA_WLAN_VENDOR_ATTR_SCAN_DWELL_TIME: Unsigned 64-bit dwell time in
  *	microseconds. This is a common value which applies across all
  *	frequencies specified by QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES.
+ * @QCA_WLAN_VENDOR_ATTR_SCAN_PRIORITY: Priority of vendor scan relative to
+ *	other scan requests. It is a u32 attribute and takes values from enum
+ *	qca_wlan_vendor_scan_priority. This is an optional attribute.
+ *	If this attribute is not configured, the driver shall use
+ *	QCA_WLAN_VENDOR_SCAN_PRIORITY_HIGH as the priority of vendor scan.
  */
 enum qca_wlan_vendor_attr_scan {
 	QCA_WLAN_VENDOR_ATTR_SCAN_INVALID_PARAM = 0,
@@ -1838,6 +2004,7 @@
 	QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK = 10,
 	QCA_WLAN_VENDOR_ATTR_SCAN_BSSID = 11,
 	QCA_WLAN_VENDOR_ATTR_SCAN_DWELL_TIME = 12,
+	QCA_WLAN_VENDOR_ATTR_SCAN_PRIORITY = 13,
 	QCA_WLAN_VENDOR_ATTR_SCAN_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_SCAN_MAX =
 	QCA_WLAN_VENDOR_ATTR_SCAN_AFTER_LAST - 1
@@ -2300,6 +2467,10 @@
 	 * frame. The updated NSS value after the connection shall not be
 	 * greater than the one negotiated during the connection. Any such
 	 * higher value configuration shall be returned with a failure.
+	 * Only symmetric NSS configuration (such as 2X2 or 1X1) can be done
+	 * using this attribute. QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS and
+	 * QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS attributes shall be used to
+	 * configure the asymmetric NSS configuration (such as 1X2).
 	 */
 	QCA_WLAN_VENDOR_ATTR_CONFIG_NSS = 70,
 	/* 8-bit unsigned value to trigger Optimized Power Management:
@@ -2348,6 +2519,86 @@
 	 */
 	QCA_WLAN_VENDOR_ATTR_CONFIG_ANI_LEVEL = 76,
 
+	/* 8-bit unsigned value. This attribute is used to dynamically configure
+	 * the number of spatial streams used for transmitting the data. When
+	 * configured in the disconnected state, the configured value will
+	 * be considered for the following connection attempt.
+	 * If the NSS is updated after the connection, the updated NSS value
+	 * is notified to the peer using the Operating Mode Notification/Spatial
+	 * Multiplexing Power Save frame.
+	 * The TX NSS value configured after the connection shall not be greater
+	 * than the value negotiated during the connection. Any such higher
+	 * value configuration shall be treated as invalid configuration by
+	 * the driver. This attribute shall be configured along with
+	 * QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS attribute to define the symmetric
+	 * configuration (such as 2X2 or 1X1) or the asymmetric
+	 * configuration (such as 1X2).
+	 * If QCA_WLAN_VENDOR_ATTR_CONFIG_NSS attribute is also provided along
+	 * with this QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS attribute the driver
+	 * will update the TX NSS based on QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS.
+	 */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS = 77,
+
+	/* 8-bit unsigned value. This attribute is used to dynamically configure
+	 * the number of spatial streams used for receiving the data. When
+	 * configured in the disconnected state, the configured value will
+	 * be considered for the following connection attempt.
+	 * If the NSS is updated after the connection, the updated NSS value
+	 * is notified to the peer using the Operating Mode Notification/Spatial
+	 * Multiplexing Power Save frame.
+	 * The RX NSS value configured after the connection shall not be greater
+	 * than the value negotiated during the connection. Any such higher
+	 * value configuration shall be treated as invalid configuration by
+	 * the driver. This attribute shall be configured along with
+	 * QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS attribute to define the symmetric
+	 * configuration (such as 2X2 or 1X1) or the asymmetric
+	 * configuration (such as 1X2).
+	 * If QCA_WLAN_VENDOR_ATTR_CONFIG_NSS attribute is also provided along
+	 * with this QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS attribute the driver
+	 * will update the RX NSS based on QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS.
+	 */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS = 78,
+
+	/*
+	 * 8-bit unsigned value. This attribute, when set, indicates whether the
+	 * specified interface is the primary STA interface when there are more
+	 * than one STA interfaces concurrently active.
+	 *
+	 * This configuration helps the firmware/hardware to support certain
+	 * features (e.g., roaming) on this primary interface, if the same
+	 * cannot be supported on the concurrent STA interfaces simultaneously.
+	 *
+	 * This configuration is only applicable for a single STA interface on
+	 * a device and gives the priority for it only over other concurrent STA
+	 * interfaces.
+	 *
+	 * If the device is a multi wiphy/soc, this configuration applies to a
+	 * single STA interface across the wiphys.
+	 *
+	 * 1-Enable (is the primary STA), 0-Disable (is not the primary STA)
+	 */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_CONCURRENT_STA_PRIMARY = 79,
+
+	/*
+	 * 8-bit unsigned value. This attribute can be used to configure the
+	 * driver to enable/disable FT-over-DS feature. Possible values for
+	 * this attribute are 1-Enable and 0-Disable.
+	 */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS = 80,
+
+	/*
+	 * 8-bit unsigned value. This attribute can be used to configure the
+	 * firmware to enable/disable ARP/NS offload feature. Possible values
+	 * for this attribute are 0-Disable and 1-Enable.
+	 *
+	 * This attribute is only applicable for STA/P2P-Client interface,
+	 * and is optional, default behavior is ARP/NS offload enabled.
+	 *
+	 * This attribute can be set in disconnected and connected state, and
+	 * will restore to the default behavior if the interface is closed.
+	 */
+	QCA_WLAN_VENDOR_ATTR_CONFIG_ARP_NS_OFFLOAD = 81,
+
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_CONFIG_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_CONFIG_MAX =
@@ -3767,6 +4018,14 @@
 	 * QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO.
 	 */
 	QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_RX_TIME = 85,
+	/* u8 value representing the channel load percentage. Possible values
+	 * are 0-100.
+	 */
+	QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_LOAD_PERCENTAGE = 86,
+	/* u8 value representing the time slicing duty cycle percentage.
+	 * Possible values are 0-100.
+	 */
+	QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_TS_DUTY_CYCLE = 87,
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_LL_STATS_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX =
@@ -4192,6 +4451,139 @@
 	QCA_ROAM_TRIGGER_REASON_EXTERNAL_SCAN	= 1 << 12,
 };
 
+/*
+ * enum qca_vendor_roam_fail_reasons: Defines the various roam
+ * fail reasons. This enum value is used in
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_FAIL_REASON attribute.
+ *
+ * @QCA_ROAM_FAIL_REASON_SCAN_NOT_ALLOWED: Roam module in the firmware is not
+ * able to trigger the scan.
+ * @QCA_ROAM_FAIL_REASON_NO_AP_FOUND: No roamable APs found during roam scan.
+ * @QCA_ROAM_FAIL_REASON_NO_CAND_AP_FOUND: No candidate APs found during roam
+ * scan.
+ * @QCA_ROAM_FAIL_REASON_HOST: Roam fail due to disconnect issued from host.
+ * @QCA_ROAM_FAIL_REASON_AUTH_SEND: Unable to send Authentication frame.
+ * @QCA_ROAM_FAIL_REASON_AUTH_RECV: Received Authentication frame with error
+ * status code.
+ * @QCA_ROAM_FAIL_REASON_NO_AUTH_RESP: Authentication frame not received.
+ * @QCA_ROAM_FAIL_REASON_REASSOC_SEND: Unable to send Reassociation Request
+ * frame.
+ * @QCA_ROAM_FAIL_REASON_REASSOC_RECV: Received Reassociation Response frame
+ * with error status code.
+ * @QCA_ROAM_FAIL_REASON_NO_REASSOC_RESP: Reassociation Response frame not
+ * received.
+ * @QCA_ROAM_FAIL_REASON_SCAN_FAIL: Scan module not able to start scan.
+ * @QCA_ROAM_FAIL_REASON_AUTH_NO_ACK: No ACK is received for Authentication
+ * frame.
+ * @QCA_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP: Authentication frame is dropped
+ * internally before transmission.
+ * @QCA_ROAM_FAIL_REASON_REASSOC_NO_ACK: No ACK is received for Reassociation
+ * Request frame.
+ * @QCA_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP: Reassociation Request frame is
+ * dropped internally.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M1_TIMEOUT: EAPOL-Key M1 is not received and
+ * times out.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M2_SEND: Unable to send EAPOL-Key M2 frame.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP: EAPOL-Key M2 frame dropped
+ * internally.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK: No ACK is received for EAPOL-Key
+ * M2 frame.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT: EAPOL-Key M3 frame is not received.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M4_SEND: Unable to send EAPOL-Key M4 frame.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP: EAPOL-Key M4 frame dropped
+ * internally.
+ * @QCA_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK: No ACK is received for EAPOL-Key M4
+ * frame.
+ * @QCA_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BEACON_MISS: Roam scan is not
+ * started for final beacon miss case.
+ * @QCA_ROAM_FAIL_REASON_DISCONNECT: Deauthentication or Disassociation frame
+ * received from the AP during roaming handoff.
+ * @QCA_ROAM_FAIL_REASON_RESUME_ABORT: Firmware roams to the AP when the Apps
+ * or host is suspended and gives the indication of the last roamed AP only
+ * when the Apps is resumed. If the Apps is resumed while the roaming is in
+ * progress, this ongoing roaming is aborted and the last roamed AP is
+ * indicated to host.
+ * @QCA_ROAM_FAIL_REASON_SAE_INVALID_PMKID: WPA3-SAE invalid PMKID.
+ * @QCA_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT: WPA3-SAE pre-authentication times
+ * out.
+ * @QCA_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL: WPA3-SAE pre-authentication fails.
+ */
+enum qca_vendor_roam_fail_reasons {
+	QCA_ROAM_FAIL_REASON_NONE = 0,
+	QCA_ROAM_FAIL_REASON_SCAN_NOT_ALLOWED = 1,
+	QCA_ROAM_FAIL_REASON_NO_AP_FOUND = 2,
+	QCA_ROAM_FAIL_REASON_NO_CAND_AP_FOUND = 3,
+	QCA_ROAM_FAIL_REASON_HOST = 4,
+	QCA_ROAM_FAIL_REASON_AUTH_SEND = 5,
+	QCA_ROAM_FAIL_REASON_AUTH_RECV = 6,
+	QCA_ROAM_FAIL_REASON_NO_AUTH_RESP = 7,
+	QCA_ROAM_FAIL_REASON_REASSOC_SEND = 8,
+	QCA_ROAM_FAIL_REASON_REASSOC_RECV = 9,
+	QCA_ROAM_FAIL_REASON_NO_REASSOC_RESP = 10,
+	QCA_ROAM_FAIL_REASON_SCAN_FAIL = 11,
+	QCA_ROAM_FAIL_REASON_AUTH_NO_ACK = 12,
+	QCA_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP = 13,
+	QCA_ROAM_FAIL_REASON_REASSOC_NO_ACK = 14,
+	QCA_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP = 15,
+	QCA_ROAM_FAIL_REASON_EAPOL_M1_TIMEOUT = 16,
+	QCA_ROAM_FAIL_REASON_EAPOL_M2_SEND = 17,
+	QCA_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP = 18,
+	QCA_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK = 19,
+	QCA_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT = 20,
+	QCA_ROAM_FAIL_REASON_EAPOL_M4_SEND = 21,
+	QCA_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP = 22,
+	QCA_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK = 23,
+	QCA_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BEACON_MISS = 24,
+	QCA_ROAM_FAIL_REASON_DISCONNECT = 25,
+	QCA_ROAM_FAIL_REASON_RESUME_ABORT = 26,
+	QCA_ROAM_FAIL_REASON_SAE_INVALID_PMKID = 27,
+	QCA_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT = 28,
+	QCA_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL = 29,
+};
+
+/*
+ * enum qca_vendor_roam_invoke_fail_reasons: Defines the various roam
+ * invoke fail reasons. This enum value is used in
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_INVOKE_FAIL_REASON attribute.
+ *
+ * @QCA_ROAM_INVOKE_STATUS_IFACE_INVALID: Invalid interface ID is passed
+ * in roam invoke command.
+ * @QCA_ROAM_INVOKE_STATUS_OFFLOAD_DISABLE: Roam offload in firmware is not
+ * enabled.
+ * @QCA_ROAM_INVOKE_STATUS_AP_SSID_LENGTH_INVALID: Connected AP profile SSID
+ * length is invalid.
+ * @QCA_ROAM_INVOKE_STATUS_ROAM_DISALLOW: Firmware internal roaming is already
+ * in progress.
+ * @QCA_ROAM_INVOKE_STATUS_NON_ROAMABLE_AP: Host sends the Beacon/Probe Response
+ * of the AP in the roam invoke command to firmware. This reason is sent by the
+ * firmware when the given AP is configured to be ignored or SSID/security
+ * does not match.
+ * @QCA_ROAM_INVOKE_STATUS_ROAM_INTERNAL_FAIL: Roam handoff failed because of
+ * firmware internal reasons.
+ * @QCA_ROAM_INVOKE_STATUS_DISALLOW: Roam invoke trigger is not enabled.
+ * @QCA_ROAM_INVOKE_STATUS_SCAN_FAIL: Scan start fail for roam invoke.
+ * @QCA_ROAM_INVOKE_STATUS_START_ROAM_FAIL: Roam handoff start fail.
+ * @QCA_ROAM_INVOKE_STATUS_INVALID_PARAMS: Roam invoke parameters are invalid.
+ * @QCA_ROAM_INVOKE_STATUS_NO_CAND_AP: No candidate AP found to roam to.
+ * @QCA_ROAM_INVOKE_STATUS_ROAM_FAIL: Roam handoff failed.
+ */
+enum qca_vendor_roam_invoke_fail_reasons {
+	QCA_ROAM_INVOKE_STATUS_NONE = 0,
+	QCA_ROAM_INVOKE_STATUS_IFACE_INVALID = 1,
+	QCA_ROAM_INVOKE_STATUS_OFFLOAD_DISABLE = 2,
+	QCA_ROAM_INVOKE_STATUS_AP_SSID_LENGTH_INVALID = 3,
+	QCA_ROAM_INVOKE_STATUS_ROAM_DISALLOW = 4,
+	QCA_ROAM_INVOKE_STATUS_NON_ROAMABLE_AP = 5,
+	QCA_ROAM_INVOKE_STATUS_ROAM_INTERNAL_FAIL = 6,
+	QCA_ROAM_INVOKE_STATUS_DISALLOW = 7,
+	QCA_ROAM_INVOKE_STATUS_SCAN_FAIL = 8,
+	QCA_ROAM_INVOKE_STATUS_START_ROAM_FAIL = 9,
+	QCA_ROAM_INVOKE_STATUS_INVALID_PARAMS = 10,
+	QCA_ROAM_INVOKE_STATUS_NO_CAND_AP = 11,
+	QCA_ROAM_INVOKE_STATUS_ROAM_FAIL = 12,
+
+};
+
 /**
  * enum qca_vendor_attr_roam_candidate_selection_criteria:
  *
@@ -4361,7 +4753,13 @@
  * @QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD: Signed 32-bit value in dBm,
  *	signifying the RSSI threshold of the candidate AP, indicating
  *	the driver to trigger roam only to the candidate AP with RSSI
- *	better than this threshold.
+ *	better than this threshold. If RSSI thresholds for candidate APs found
+ *	in the 2.4 GHz, 5 GHz, and 6 GHz bands are configured separately using
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_2P4GHZ,
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_5GHZ, and/or
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_6GHZ, those values will
+ *	take precedence over the value configured using the
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD attribute.
  *
  * @QCA_ATTR_ROAM_CONTROL_USER_REASON: Unsigned 32-bit value. Represents the
  *	user defined reason code to be sent to the AP in response to AP's
@@ -4380,6 +4778,69 @@
  *	If both QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME and
  *	QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME_TRIGGERS are not specified, the
  *	driver shall proceed with the default behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_2P4GHZ: Signed 32-bit value
+ *	in dBm, signifying the RSSI threshold of the candidate AP found in the
+ *	2.4 GHz band. The driver/firmware shall trigger roaming to the candidate
+ *	AP found in the 2.4 GHz band only if its RSSI value is better than this
+ *	threshold. Optional attribute. If this attribute is not included, the
+ *	threshold value specified by the
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD attribute shall be used.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_5GHZ: Signed 32-bit value in
+ *	dBm, signifying the RSSI threshold of the candidate AP found in the 5
+ *	GHz band. The driver/firmware shall trigger roaming to the candidate AP
+ *	found in the 5 GHz band only if its RSSI value is better than this
+ *	threshold. Optional attribute. If this attribute is not included, the
+ *	threshold value specified by tge
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD attribute shall be used.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_6GHZ: Signed 32-bit value in
+ *	dBm, signifying the RSSI threshold of the candidate AP found in the 6
+ *	GHz band. The driver/firmware shall trigger roaming to the candidate AP
+ *	found in the 6 GHz band only if its RSSI value is better than this
+ *	threshold. Optional attribute. If this attribute is not included, the
+ *	threshold value specified by the
+ *	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD attribute shall be used.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_BAND_MASK: Unsigned 32-bit value.
+ *	Carries bitmask value of bits from &enum qca_set_band and represents
+ *	all the bands in which roaming is allowed. The configuration is valid
+ *	until next disconnection. If this attribute is not present, the
+ *	existing configuration shall be used. By default, roaming is allowed on
+ *	all bands supported by the local device. When the value is set to
+ *	%QCA_SETBAND_AUTO, all supported bands shall be enabled.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_ACTIVE_CH_DWELL_TIME: u16 value in milliseconds.
+ *	Optional parameter. Scan dwell time for active channels in the 2.4/5 GHz
+ *	bands. If this attribute is not configured, the driver shall proceed
+ *	with default behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_PASSIVE_CH_DWELL_TIME: u16 value in milliseconds.
+ *	Optional parameter. Scan dwell time for passive channels in the 5 GHz
+ *	band. If this attribute is not configured, the driver shall proceed with
+ *	default behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_HOME_CHANNEL_TIME: u16 value in milliseconds.
+ *	Optional parameter. The minimum duration to stay on the connected AP
+ *	channel during the channel scanning. If this attribute is not
+ *	configured, the driver shall proceed with default behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_MAXIMUM_AWAY_TIME: u16 value in milliseconds.
+ *	Optional parameter. The maximum duration for which the radio can scan
+ *	foreign channels consecutively without coming back to home channel. If
+ *	this attribute is not configured, the driver shall proceed with default
+ *	behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_SCAN_6G_PSC_DWELL_TIME: u16 value in milliseconds.
+ *	Optional parameter. Scan dwell time for 6G Preferred Scanning Channels.
+ *	If this attribute is not configured, the driver shall proceed with
+ *	default behavior.
+ *
+ * @QCA_ATTR_ROAM_CONTROL_SCAN_6G_NON_PSC_DWELL_TIME: u16 value in milliseconds.
+ *	Optional parameter. Scan dwell time for 6G Non Preferred Scanning
+ *	Channels. If this attribute is not configured, the driver shall proceed
+ *	with default behavior.
  */
 enum qca_vendor_attr_roam_control {
 	QCA_ATTR_ROAM_CONTROL_ENABLE = 1,
@@ -4395,6 +4856,16 @@
 	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD = 11,
 	QCA_ATTR_ROAM_CONTROL_USER_REASON = 12,
 	QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME_TRIGGERS = 13,
+	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_2P4GHZ = 14,
+	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_5GHZ = 15,
+	QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_6GHZ = 16,
+	QCA_ATTR_ROAM_CONTROL_BAND_MASK = 17,
+	QCA_ATTR_ROAM_CONTROL_ACTIVE_CH_DWELL_TIME = 18,
+	QCA_ATTR_ROAM_CONTROL_PASSIVE_CH_DWELL_TIME = 19,
+	QCA_ATTR_ROAM_CONTROL_HOME_CHANNEL_TIME = 20,
+	QCA_ATTR_ROAM_CONTROL_MAXIMUM_AWAY_TIME = 21,
+	QCA_ATTR_ROAM_CONTROL_SCAN_6G_PSC_DWELL_TIME = 22,
+	QCA_ATTR_ROAM_CONTROL_SCAN_6G_NON_PSC_DWELL_TIME = 23,
 
 	/* keep last */
 	QCA_ATTR_ROAM_CONTROL_AFTER_LAST,
@@ -6002,6 +6473,14 @@
 	 * u32 attribute.
 	 */
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY_2 = 29,
+	/* This attribute specifies the bandwidth to be used for spectral scan
+	 * operation. This is an u8 attribute and uses the values in enum
+	 * nl80211_chan_width. This is an optional attribute.
+	 * If this attribute is not populated, the driver should configure the
+	 * spectral scan bandwidth to the maximum value supported by the target
+	 * for the current operating bandwidth.
+	 */
+	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_BANDWIDTH = 30,
 
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_MAX =
@@ -6112,6 +6591,14 @@
 	 * u32 attribute.
 	 */
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_80P80_MHZ = 18,
+	/* Flag attribute to indicate agile spectral scan capability
+	 * for 320 MHz mode.
+	 */
+	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AGILE_SPECTRAL_320 = 19,
+	/* Number of spectral detectors used for scan in 320 MHz.
+	 * u32 attribute.
+	 */
+	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_320_MHZ = 20,
 
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_MAX =
@@ -6302,6 +6789,8 @@
 	QCA_WLAN_HANG_SUSPEND_NO_CREDIT = 25,
 	/* Bus failure */
 	QCA_WLAN_HANG_BUS_FAILURE = 26,
+	/* tasklet/credit latency found */
+	QCA_WLAN_HANG_TASKLET_CREDIT_LATENCY_DETECT = 27,
 };
 
 /**
@@ -7019,6 +7508,15 @@
 	 * there is any critical ongoing operation.
 	 */
 	QCA_WLAN_VENDOR_ATTR_THERMAL_COMPLETION_WINDOW = 3,
+	/* Nested attribute, the driver/firmware uses this attribute to report
+	 * thermal statistics of different thermal levels to userspace when
+	 * requested using the
+	 * QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS command
+	 * type. This attribute contains a nested array of records of thermal
+	 * statistics of multiple levels. The attributes used inside this nested
+	 * attribute are defined in enum qca_wlan_vendor_attr_thermal_stats.
+	 */
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS = 4,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_AFTER_LAST,
@@ -7047,6 +7545,13 @@
  * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_LEVEL: Request to get the current
  * thermal level from the driver/firmware. The driver should respond with a
  * thermal level defined in enum qca_wlan_vendor_thermal_level.
+ * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS: Request to get the
+ * current thermal statistics from the driver/firmware. The driver should
+ * respond with statistics of all thermal levels encapsulated in the attribute
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS.
+ * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_CLEAR_THERMAL_STATS: Request to clear
+ * the current thermal statistics for all thermal levels maintained in the
+ * driver/firmware and start counting from zero again.
  */
 enum qca_wlan_vendor_attr_thermal_cmd_type {
 	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_PARAMS,
@@ -7055,6 +7560,8 @@
 	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_RESUME,
 	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SET_LEVEL,
 	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_LEVEL,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_CLEAR_THERMAL_STATS,
 };
 
 /**
@@ -7150,6 +7657,35 @@
 };
 
 /**
+ * enum qca_wlan_vendor_attr_thermal_stats - vendor subcmd attributes
+ * to get thermal status from the driver/firmware.
+ * enum values are used for NL attributes encapsulated inside the
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS nested attribute.
+ *
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MIN_TEMPERATURE: Minimum temperature
+ * of a thermal level in Celsius. u32 size.
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MAX_TEMPERATURE: Maximum temperature
+ * of a thermal level in Celsius. u32 size.
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_DWELL_TIME: The total time spent on each
+ * thermal level in milliseconds. u32 size.
+ * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_TEMP_LEVEL_COUNTER: Indicates the number
+ * of times the temperature crossed into the temperature range defined by the
+ * thermal level from both higher and lower directions. u32 size.
+ */
+enum qca_wlan_vendor_attr_thermal_stats {
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MIN_TEMPERATURE,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MAX_TEMPERATURE,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_DWELL_TIME,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_TEMP_LEVEL_COUNTER,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MAX =
+	QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_AFTER_LAST - 1,
+};
+
+/**
  * enum he_fragmentation_val - HE fragmentation support values
  * Indicates level of dynamic fragmentation that is supported by
  * a STA as a recipient.
@@ -7308,6 +7844,21 @@
 };
 
 /**
+ * enum qca_wlan_keep_alive_data_type - Keep alive data type configuration
+ *
+ * Indicates the frame types to use for keep alive data.
+ *
+ * @QCA_WLAN_KEEP_ALIVE_DEFAULT: Driver default type used for keep alive.
+ * @QCA_WLAN_KEEP_ALIVE_DATA: Data frame type for keep alive.
+ * @QCA_WLAN_KEEP_ALIVE_MGMT: Management frame type for keep alive.
+ */
+enum qca_wlan_keep_alive_data_type {
+	QCA_WLAN_KEEP_ALIVE_DEFAULT = 0,
+	QCA_WLAN_KEEP_ALIVE_DATA = 1,
+	QCA_WLAN_KEEP_ALIVE_MGMT = 2,
+};
+
+/**
  * enum qca_wlan_vendor_attr_he_omi_tx: Represents attributes for
  * HE operating mode control transmit request. These attributes are
  * sent as part of QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX and
@@ -7774,6 +8325,109 @@
 	 */
 	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FULL_BW_UL_MU_MIMO = 45,
 
+	/* 16-bit unsigned value to configure the driver with a specific BSS
+	 * max idle period to advertise in the BSS Max Idle Period element
+	 * (IEEE Std 802.11-2016, 9.4.2.79) in (Re)Association Request frames.
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD = 46,
+
+	/* 8-bit unsigned value to configure the driver to use only RU 242 tone
+	 * for data transmission.
+	 * 0 - Default behavior, 1 - Configure RU 242 tone for data Tx.
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RU_242_TONE_TX = 47,
+
+	/* 8-bit unsigned value to configure the driver to disable data and
+	 * management response frame transmission to test the BSS max idle
+	 * feature.
+	 * 0 - Default behavior, 1 - Disable data and management response Tx.
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISABLE_DATA_MGMT_RSP_TX = 48,
+
+	/* 8-bit unsigned value to configure the driver/firmware to enable or
+	 * disable Punctured Preamble Rx subfield in the HE PHY capabilities
+	 * information field.
+	 * 0 - Disable Punctured Preamble Rx subfield
+	 * 1 - Enable Punctured Preamble Rx subfield
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PUNCTURED_PREAMBLE_RX = 49,
+
+	/* 8-bit unsigned value to configure the driver to ignore the SAE H2E
+	 * requirement mismatch for 6 GHz connection.
+	 * 0 - Default behavior, 1 - Ignore SAE H2E requirement mismatch.
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_H2E_RSNXE = 50,
+
+	/* 8-bit unsigned value to configure the driver to allow 6 GHz
+	 * connection with all security modes.
+	 * 0 - Default behavior, 1 - Allow 6 GHz connection with all security
+	 * modes.
+	 * This attribute is used for testing purposes.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_6GHZ_SECURITY_TEST_MODE = 51,
+
+	/* 8-bit unsigned value to configure the driver to transmit data with
+	 * ER SU PPDU type.
+	 *
+	 * 0 - Default behavior, 1 - Enable ER SU PPDU type TX.
+	 * This attribute is used for testing purposes.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ER_SU_PPDU_TYPE = 52,
+
+	/* 8-bit unsigned value to configure the driver to use Data or
+	 * Management frame type for keep alive data.
+	 * Uses enum qca_wlan_keep_alive_data_type values.
+	 *
+	 * This attribute is used for testing purposes.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_KEEP_ALIVE_FRAME_TYPE = 53,
+
+	/* 8-bit unsigned value to configure the driver to use scan request
+	 * BSSID value in Probe Request frame RA(A1) during the scan. The
+	 * driver saves this configuration and applies this setting to all user
+	 * space scan requests until the setting is cleared. If this
+	 * configuration is set, the driver uses the BSSID value from the scan
+	 * request to set the RA(A1) in the Probe Request frames during the
+	 * scan.
+	 *
+	 * 0 - Default behavior uses the broadcast RA in Probe Request frames.
+	 * 1 - Uses the scan request BSSID in RA in Probe Request frames.
+	 * This attribute is used for testing purposes.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_USE_BSSID_IN_PROBE_REQ_RA = 54,
+
+	/* 8-bit unsigned value to configure the driver to enable/disable the
+	 * BSS max idle period support.
+	 *
+	 * 0 - Disable the BSS max idle support.
+	 * 1 - Enable the BSS max idle support.
+	 * This attribute is used for testing purposes.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD_ENABLE = 55,
+
+	/* 8-bit unsigned value to configure the driver/firmware to enable or
+	 * disable Rx control frame to MultiBSS subfield in the HE MAC
+	 * capabilities information field.
+	 * 0 - Disable Rx control frame to MultiBSS subfield
+	 * 1 - Enable Rx control frame to MultiBSS subfield
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RX_CTRL_FRAME_TO_MBSS = 56,
+
+	/* 8-bit unsigned value to configure the driver/firmware to enable or
+	 * disable Broadcast TWT support subfield in the HE MAC capabilities
+	 * information field.
+	 * 0 - Disable Broadcast TWT support subfield
+	 * 1 - Enable Broadcast TWT support subfield
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BCAST_TWT_SUPPORT = 57,
+
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX =
@@ -7783,32 +8437,73 @@
 /**
  * enum qca_wlan_twt_operation - Operation of the config TWT request
  * Values for %QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION.
+ * The response for the respective operations can be either synchronous or
+ * asynchronous (wherever specified). If synchronous, the response to this
+ * operation is obtained in the corresponding vendor command reply to the user
+ * space. For the asynchronous case the response is obtained as an event with
+ * the same operation type.
+ *
+ * Drivers shall support either of these modes but not both simultaneously.
+ * This support for asynchronous mode is advertised through the flag
+ * QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT. If this flag is not advertised,
+ * the driver shall support synchronous mode.
  *
  * @QCA_WLAN_TWT_SET: Setup a TWT session. Required parameters are configured
  * through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum
- * qca_wlan_vendor_attr_twt_setup.
+ * qca_wlan_vendor_attr_twt_setup. Depending upon the
+ * @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT capability, this is either a
+ * synchronous or asynchronous operation.
  *
  * @QCA_WLAN_TWT_GET: Get the configured TWT parameters. Required parameters are
  * obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum
- * qca_wlan_vendor_attr_twt_setup.
+ * qca_wlan_vendor_attr_twt_setup. This is a synchronous operation.
  *
  * @QCA_WLAN_TWT_TERMINATE: Terminate the TWT session. Required parameters are
  * obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum
  * qca_wlan_vendor_attr_twt_setup. Valid only after the TWT session is setup.
+ * This terminate can either get triggered by the user space or can as well be
+ * a notification from the firmware if it initiates a terminate.
+ * Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT capability,
+ * the request from user space can either be a synchronous or asynchronous
+ * operation.
  *
  * @QCA_WLAN_TWT_SUSPEND: Suspend the TWT session. Required parameters are
  * obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum
  * qca_wlan_vendor_attr_twt_setup. Valid only after the TWT session is setup.
+ * Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT capability,
+ * this is either a synchronous or asynchronous operation.
  *
  * @QCA_WLAN_TWT_RESUME: Resume the TWT session. Required parameters are
  * configured through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum
  * qca_wlan_vendor_attr_twt_resume. Valid only after the TWT session is setup.
+ * This can as well be a notification from the firmware on a QCA_WLAN_TWT_NUDGE
+ * request. Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT
+ * capability, this is either a synchronous or asynchronous operation.
  *
  * @QCA_WLAN_TWT_NUDGE: Suspend and resume the TWT session. TWT nudge is a
  * combination of suspend and resume in a single request. Required parameters
  * are configured through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the
  * enum qca_wlan_vendor_attr_twt_nudge. Valid only after the TWT session is
- * setup.
+ * setup. Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT
+ * capability, this is either a synchronous or asynchronous operation.
+ *
+ * @QCA_WLAN_TWT_GET_STATS: Get the TWT session traffic statistics information.
+ * Refers the enum qca_wlan_vendor_attr_twt_stats. Valid only after the TWT
+ * session is setup. It's a synchronous operation.
+ *
+ * @QCA_WLAN_TWT_CLEAR_STATS: Clear TWT session traffic statistics information.
+ * Valid only after the TWT session is setup. It's a synchronous operation.
+ *
+ * @QCA_WLAN_TWT_GET_CAPABILITIES: Get TWT capabilities of this device and its
+ * peer. Refers the enum qca_wlan_vendor_attr_twt_capability. It's a synchronous
+ * operation.
+ *
+ * @QCA_WLAN_TWT_SETUP_READY_NOTIFY: Notify userspace that the firmare is
+ * ready for a new TWT session setup after it issued a TWT teardown.
+ *
+ * @QCA_WLAN_TWT_SET_PARAM: Configure TWT related parameters. Required
+ * parameters are obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refer
+ * the enum qca_wlan_vendor_attr_twt_set_param.
  */
 enum qca_wlan_twt_operation {
 	QCA_WLAN_TWT_SET = 0,
@@ -7817,6 +8512,11 @@
 	QCA_WLAN_TWT_SUSPEND = 3,
 	QCA_WLAN_TWT_RESUME = 4,
 	QCA_WLAN_TWT_NUDGE = 5,
+	QCA_WLAN_TWT_GET_STATS = 6,
+	QCA_WLAN_TWT_CLEAR_STATS = 7,
+	QCA_WLAN_TWT_GET_CAPABILITIES = 8,
+	QCA_WLAN_TWT_SETUP_READY_NOTIFY = 9,
+	QCA_WLAN_TWT_SET_PARAM = 10,
 };
 
 /**
@@ -7830,8 +8530,9 @@
  *
  * @QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS: Nested attribute representing the
  * parameters configured for TWT. These parameters are represented by
- * enum qca_wlan_vendor_attr_twt_setup or enum qca_wlan_vendor_attr_twt_resume
- * based on the operation.
+ * enum qca_wlan_vendor_attr_twt_setup, enum qca_wlan_vendor_attr_twt_resume,
+ * enum qca_wlan_vendor_attr_twt_set_param, or
+ * enum qca_wlan_vendor_attr_twt_stats based on the operation.
  */
 enum qca_wlan_vendor_attr_config_twt {
 	QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_INVALID = 0,
@@ -7992,6 +8693,19 @@
 };
 
 /**
+ * qca_wlan_twt_setup_state: Represents the TWT session states.
+ *
+ * QCA_WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED: TWT session not established.
+ * QCA_WLAN_TWT_SETUP_STATE_ACTIVE: TWT session is active.
+ * QCA_WLAN_TWT_SETUP_STATE_SUSPEND: TWT session is in suspended state.
+ */
+enum qca_wlan_twt_setup_state {
+	QCA_WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED = 0,
+	QCA_WLAN_TWT_SETUP_STATE_ACTIVE = 1,
+	QCA_WLAN_TWT_SETUP_STATE_SUSPEND = 2,
+};
+
+/**
  * enum qca_wlan_vendor_attr_twt_setup: Represents attributes for
  * TWT (Target Wake Time) setup request. These attributes are sent as part of
  * %QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP and
@@ -8041,6 +8755,14 @@
  * 2. TWT GET Request and Response
  * 3. TWT TERMINATE Request and Response
  * 4. TWT SUSPEND Request and Response
+ * Flow ID values from 0 to 254 represent a single TWT session
+ * Flow ID value of 255 represents all TWT sessions for the following
+ * 1. TWT TERMINATE Request and Response
+ * 2. TWT SUSPEND Request and Response
+ * 4. TWT CLEAR STATISTICS request
+ * 5. TWT GET STATISTICS request and response
+ * If an invalid dialog ID is provided, status
+ * QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST will be returned.
  *
  * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP: Required (u8)
  * This attribute (exp) is used along with the mantissa to derive the
@@ -8101,9 +8823,13 @@
  * response.
  *
  * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME_TSF: Required (u64)
- * This field is applicable for TWT response only.
- * This field contains absolute TSF value of the wake time received
- * from the TWT responder and is passed to the userspace.
+ * In TWT setup command this field contains absolute TSF that will
+ * be used by TWT requester during setup.
+ * In TWT response this field contains absolute TSF value of the
+ * wake time received from the TWT responder and is passed to
+ * the userspace.
+ * This is an optional parameter for
+ * 1. TWT SET Request
  * This is a required parameter for
  * 1. TWT SET Response
  * 2. TWT GET Response
@@ -8120,14 +8846,87 @@
  * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAC_ADDR: 6-byte MAC address
  * Represents the MAC address of the peer for which the TWT session
  * is being configured. This is used in AP mode to represent the respective
- * client. In AP mode, this is an optional parameter for response and is
- * a required parameter for
- * 1. TWT SET Request
- * 2. TWT GET Request
- * 3. TWT TERMINATE Request
- * 4. TWT SUSPEND Request
+ * client.
+ * In AP mode, this is a required parameter in response for
+ * 1. TWT SET
+ * 2. TWT GET
+ * 3. TWT TERMINATE
+ * 4. TWT SUSPEND
  * In STA mode, this is an optional parameter in request and response for
  * the above four TWT operations.
+ * In AP mode, this is a required parameter in request for
+ * 1. TWT GET
+ * 2. TWT TERMINATE
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_INTVL: Optional (u32)
+ * Minimum tolerance limit of wake interval parameter in microseconds.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_INTVL: Optional (u32)
+ * Maximum tolerance limit of wake interval parameter in microseconds.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_DURATION: Optional (u32)
+ * Minimum tolerance limit of wake duration parameter in microseconds.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_DURATION: Optional (u32)
+ * Maximum tolerance limit of wake duration parameter in microseconds.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATE: Optional (u32)
+ * TWT state for the given dialog id. The values for this are represented
+ * by enum qca_wlan_twt_setup_state.
+ * This is obtained through TWT GET operation.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL2_MANTISSA: Optional (u32)
+ * This attribute is used to configure wake interval mantissa.
+ * The unit is microseconds. This attribute, when specified, takes
+ * precedence over QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA.
+ * This parameter is used for
+ * 1. TWT SET Request and Response
+ * 2. TWT GET Response
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID: Optional (u8)
+ * This attribute is used to configure Broadcast TWT ID.
+ * The Broadcast TWT ID indicates a specific Broadcast TWT for which the
+ * transmitting STA is providing TWT parameters. The allowed values are 0 to 31.
+ * This parameter is used for
+ * 1. TWT SET Request
+ * 2. TWT TERMINATE Request
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_RECOMMENDATION: Optional (u8)
+ * This attribute is used to configure Broadcast TWT recommendation.
+ * The Broadcast TWT Recommendation subfield contains a value that indicates
+ * recommendations on the types of frames that are transmitted by TWT
+ * scheduled STAs and scheduling AP during the broadcast TWT SP.
+ * The allowed values are 0 - 3.
+ * This parameter is used for
+ * 1. TWT SET Request
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_PERSISTENCE: Optional (u8)
+ * This attribute is used to configure Broadcast TWT Persistence.
+ * The Broadcast TWT Persistence subfield indicates the number of
+ * TBTTs during which the Broadcast TWT SPs corresponding to this
+ * broadcast TWT Parameter set are present. The number of beacon intervals
+ * during which the Broadcast TWT SPs are present is equal to the value in the
+ * Broadcast TWT Persistence subfield plus 1 except that the value 255
+ * indicates that the Broadcast TWT SPs are present until explicitly terminated.
+ * This parameter is used for
+ * 1. TWT SET Request
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESPONDER_PM_MODE: Optional (u8)
+ * This attribute contains the value of the Responder PM Mode subfield (0 or 1)
+ * from TWT response frame.
+ * This parameter is used for
+ * 1. TWT SET Response
+ * 2. TWT GET Response
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_ANNOUNCE_TIMEOUT: Optional (u32)
+ * This attribute is used to configure the announce timeout value (in us) in
+ * the firmware. This timeout value is only applicable for the announced TWT. If
+ * the timeout value is non-zero the firmware waits up to the timeout value to
+ * use Data frame as an announcement frame. If the timeout value is 0 the
+ * firmware sends an explicit QoS NULL frame as the announcement frame on SP
+ * start. The default value in the firmware is 0.
+ * This parameter is used for
+ * 1. TWT SET Request
  */
 enum qca_wlan_vendor_attr_twt_setup {
 	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_INVALID = 0,
@@ -8149,6 +8948,20 @@
 	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TWT_INFO_ENABLED = 14,
 
 	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAC_ADDR = 15,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_INTVL = 16,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_INTVL = 17,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_DURATION = 18,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_DURATION = 19,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATE = 20,
+
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL2_MANTISSA = 21,
+
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID = 22,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_RECOMMENDATION = 23,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_PERSISTENCE = 24,
+
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESPONDER_PM_MODE = 25,
+	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_ANNOUNCE_TIMEOUT = 26,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_TWT_SETUP_AFTER_LAST,
@@ -8178,6 +8991,28 @@
  * unknown reason
  * @QCA_WLAN_VENDOR_TWT_STATUS_ALREADY_SUSPENDED: TWT session already in
  * suspend state
+ * @QCA_WLAN_VENDOR_TWT_STATUS_IE_INVALID: FW has dropped the frame due to
+ * invalid IE in the received TWT frame
+ * @QCA_WLAN_VENDOR_TWT_STATUS_PARAMS_NOT_IN_RANGE: Parameters received from
+ * the responder are not in the specified range
+ * @QCA_WLAN_VENDOR_TWT_STATUS_PEER_INITIATED_TERMINATE: FW terminated the TWT
+ * session due to request from the responder. Used on the TWT_TERMINATE
+ * notification from the firmware.
+ * @QCA_WLAN_VENDOR_TWT_STATUS_ROAM_INITIATED_TERMINATE: FW terminated the TWT
+ * session due to roaming. Used on the TWT_TERMINATE notification from the
+ * firmware.
+ * @QCA_WLAN_VENDOR_TWT_STATUS_SCC_MCC_CONCURRENCY_TERMINATE: FW terminated the
+ * TWT session due to SCC (Single Channel Concurrency) and MCC (Multi Channel
+ * Concurrency). Used on the TWT_TERMINATE notification from the firmware.
+ * @QCA_WLAN_VENDOR_TWT_STATUS_ROAMING_IN_PROGRESS: FW rejected the TWT setup
+ * request due to roaming in progress.
+ * @QCA_WLAN_VENDOR_TWT_STATUS_CHANNEL_SWITCH_IN_PROGRESS: FW rejected the TWT
+ * setup request due to channel switch in progress.
+ * @QCA_WLAN_VENDOR_TWT_STATUS_SCAN_IN_PROGRESS: FW rejected the TWT setup
+ * request due to scan in progress.
+ * QCA_WLAN_VENDOR_TWT_STATUS_POWER_SAVE_EXIT_TERMINATE: The driver requested to
+ * terminate an existing TWT session on power save exit request from userspace.
+ * Used on the TWT_TERMINATE notification from the driver/firmware.
  */
 enum qca_wlan_vendor_twt_status {
 	QCA_WLAN_VENDOR_TWT_STATUS_OK = 0,
@@ -8194,6 +9029,15 @@
 	QCA_WLAN_VENDOR_TWT_STATUS_DENIED = 11,
 	QCA_WLAN_VENDOR_TWT_STATUS_UNKNOWN_ERROR = 12,
 	QCA_WLAN_VENDOR_TWT_STATUS_ALREADY_SUSPENDED = 13,
+	QCA_WLAN_VENDOR_TWT_STATUS_IE_INVALID = 14,
+	QCA_WLAN_VENDOR_TWT_STATUS_PARAMS_NOT_IN_RANGE = 15,
+	QCA_WLAN_VENDOR_TWT_STATUS_PEER_INITIATED_TERMINATE = 16,
+	QCA_WLAN_VENDOR_TWT_STATUS_ROAM_INITIATED_TERMINATE = 17,
+	QCA_WLAN_VENDOR_TWT_STATUS_SCC_MCC_CONCURRENCY_TERMINATE = 18,
+	QCA_WLAN_VENDOR_TWT_STATUS_ROAMING_IN_PROGRESS = 19,
+	QCA_WLAN_VENDOR_TWT_STATUS_CHANNEL_SWITCH_IN_PROGRESS = 20,
+	QCA_WLAN_VENDOR_TWT_STATUS_SCAN_IN_PROGRESS = 21,
+	QCA_WLAN_VENDOR_TWT_STATUS_POWER_SAVE_EXIT_TERMINATE = 22,
 };
 
 /**
@@ -8220,6 +9064,10 @@
  * @QCA_WLAN_VENDOR_ATTR_TWT_RESUME_FLOW_ID: Required (u8).
  * Flow ID is the unique identifier for each TWT session. This attribute
  * represents the respective TWT session to resume.
+ * Flow ID values from 0 to 254 represent a single TWT session
+ * Flow ID value of 255 represents all TWT sessions.
+ * If an invalid dialog id is provided, status
+ * QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST will be returned.
  *
  * @QCA_WLAN_VENDOR_ATTR_TWT_RESUME_MAC_ADDR: 6-byte MAC address
  * Represents the MAC address of the peer to which TWT Resume is
@@ -8250,6 +9098,11 @@
  * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID: Required (u8)
  * Flow ID is the unique identifier for each TWT session. This attribute
  * represents the respective TWT session to suspend and resume.
+ * Flow ID values from 0 to 254 represent a single TWT session
+ * Flow ID value of 255 represents all TWT sessions in TWT NUDGE request
+ * and response.
+ * If an invalid dialog id is provided, status
+ * QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST will be returned.
  *
  * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME: Required (u32)
  * This attribute is used as the SP offset which is the offset from
@@ -8265,6 +9118,10 @@
  * being sent. This is used in AP mode to represent the respective
  * client and is a required parameter. In STA mode, this is an optional
  * parameter.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME_TSF: Optional (u64)
+ * This field contains absolute TSF value of the time at which the TWT
+ * session will be resumed.
  */
 enum qca_wlan_vendor_attr_twt_nudge {
 	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_INVALID = 0,
@@ -8272,6 +9129,7 @@
 	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME = 2,
 	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE = 3,
 	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_MAC_ADDR = 4,
+	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME_TSF = 5,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_AFTER_LAST,
@@ -8280,6 +9138,183 @@
 };
 
 /**
+ * enum qca_wlan_vendor_attr_twt_stats: Represents attributes for
+ * TWT (Target Wake Time) get statistics and clear statistics request.
+ * These attributes are sent as part of
+ * %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_FLOW_ID: Required (u8)
+ * Flow ID is the unique identifier for each TWT session. This attribute
+ * represents the respective TWT session for get and clear TWT statistics.
+ * Flow ID values from 0 to 254 represent a single TWT session
+ * Flow ID value of 255 represents all TWT sessions in
+ * 1) TWT GET STATISTICS request and response
+ * 2) TWT CLEAR STATISTICS request
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAC_ADDR: 6-byte MAC address
+ * Represents the MAC address of the peer for which TWT Statistics
+ * is required.
+ * In AP mode this is used to represent the respective
+ * client and is a required parameter for
+ * 1) TWT GET STATISTICS request and response
+ * 2) TWT CLEAR STATISTICS request and response
+ * In STA mode, this is an optional parameter.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_SESSION_WAKE_DURATION: Required (u32)
+ * This is the duration of the service period in microseconds.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVG_WAKE_DURATION: Required (u32)
+ * Average of the actual wake duration observed so far. Unit is microseconds.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS: Required (u32)
+ * The number of TWT service periods elapsed so far.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_MIN_WAKE_DURATION: Required (u32)
+ * This is the minimum value of the wake duration observed across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS. Unit is
+ * microseconds.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX_WAKE_DURATION: Required (u32)
+ * This is the maximum value of wake duration observed across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS. Unit is
+ * microseconds.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_MPDU: Required (u32)
+ * Average number of MPDUs transmitted successfully across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_MPDU: Required (u32)
+ * Average number of MPDUs received successfully across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_PACKET_SIZE: Required (u32)
+ * Average number of bytes transmitted successfully across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_PACKET_SIZE: Required (u32)
+ * Average number of bytes received successfully across
+ * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS.
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_STATUS: Required (u32)
+ * Status of the TWT GET STATISTICS request.
+ * This contains status values in enum qca_wlan_vendor_twt_status
+ * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware.
+ */
+enum qca_wlan_vendor_attr_twt_stats {
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_FLOW_ID = 1,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAC_ADDR = 2,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_SESSION_WAKE_DURATION = 3,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVG_WAKE_DURATION = 4,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS = 5,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_MIN_WAKE_DURATION = 6,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX_WAKE_DURATION = 7,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_MPDU = 8,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_MPDU = 9,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_PACKET_SIZE = 10,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_PACKET_SIZE = 11,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_STATUS = 12,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX =
+	QCA_WLAN_VENDOR_ATTR_TWT_STATS_AFTER_LAST - 1,
+};
+
+/**
+ * qca_wlan_twt_get_capa  - Represents the bitmap of TWT capabilities
+ * supported by the device and the peer.
+ * Values for %QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_GET_CAPABILITIES
+ *
+ * @QCA_WLAN_TWT_CAPA_REQUESTOR: TWT requestor support is advertised by
+ * TWT non-scheduling STA. This capability is advertised in the HE
+ * Capability/Extended Capabilities information element in the
+ * Association Request frame by the device.
+ *
+ * @QCA_WLAN_TWT_CAPA_RESPONDER: TWT responder support is advertised by
+ * the TWT scheduling AP. This capability is advertised in the Extended
+ * Capabilities/HE Capabilities information element.
+ *
+ * @QCA_WLAN_TWT_CAPA_BROADCAST: On the requestor side, this indicates support
+ * for the broadcast TWT functionality. On the responder side, this indicates
+ * support for the role of broadcast TWT scheduling functionality. This
+ * capability is advertised in the HE Capabilities information element.
+ *
+ * @QCA_WLAN_TWT_CAPA_TWT_FLEXIBLE: The device supports flexible TWT schedule.
+ * This capability is advertised in the HE Capabilities information element.
+ *
+ * @QCA_WLAN_TWT_CAPA_REQUIRED: The TWT Required is advertised by AP to indicate
+ * that it mandates the associated HE STAs to support TWT. This capability is
+ * advertised by AP in the HE Operation Parameters field of the HE Operation
+ * information element.
+ */
+enum qca_wlan_twt_capa {
+	QCA_WLAN_TWT_CAPA_REQUESTOR = BIT(0),
+	QCA_WLAN_TWT_CAPA_RESPONDER = BIT(1),
+	QCA_WLAN_TWT_CAPA_BROADCAST = BIT(2),
+	QCA_WLAN_TWT_CAPA_FLEXIBLE =  BIT(3),
+	QCA_WLAN_TWT_CAPA_REQUIRED =  BIT(4),
+};
+
+/**
+ * enum qca_wlan_vendor_attr_twt_capability  - Represents attributes for TWT
+ * get capabilities request type. Used by QCA_WLAN_TWT_GET_CAPABILITIES TWT
+ * operation.
+ * @QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_MAC_ADDR: 6-byte MAC address
+ * Represents the MAC address of the peer for which the TWT capabilities
+ * are being queried. This is used in AP mode to represent the respective
+ * client. In STA mode, this is an optional parameter.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_SELF: (u16).
+ * Self TWT capabilities. Carries a bitmap of TWT capabilities specified in
+ * enum qca_wlan_twt_capa.
+ * @QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_PEER: (u16).
+ * Peer TWT capabilities. Carries a bitmap of TWT capabilities specified in
+ * enum qca_wlan_twt_capa.
+ */
+enum qca_wlan_vendor_attr_twt_capability {
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_MAC_ADDR = 1,
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_SELF = 2,
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_PEER = 3,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_MAX =
+	QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_twt_set_param: Represents attributes for
+ * TWT (Target Wake Time) related parameters. It is used when
+ * %QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION is set to %QCA_WLAN_TWT_SET_PARAM.
+ * These attributes are sent as part of %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AP_AC_VALUE: Optional (u8)
+ * This attribute configures AC parameters to be used for all TWT
+ * sessions in AP mode.
+ * Uses the enum qca_wlan_ac_type values.
+ */
+enum qca_wlan_vendor_attr_twt_set_param {
+	QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AP_AC_VALUE = 1,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_MAX =
+	QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AFTER_LAST - 1,
+};
+
+/**
  * enum qca_wlan_vendor_twt_setup_resp_type - Represents the response type by
  * the TWT responder
  *
@@ -8370,6 +9405,22 @@
 };
 
 /**
+ * enum qca_wlan_vendor_cfr_data_transport_modes - Defines QCA vendor CFR data
+ * transport modes and is used by the attribute
+ * QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE as a part of the vendor
+ * command QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG.
+ * @QCA_WLAN_VENDOR_CFR_DATA_RELAY_FS: Use relayfs to send CFR data.
+ * @QCA_WLAN_VENDOR_CFR_DATA_NETLINK_EVENTS: Use netlink events to send CFR
+ * data. The data shall be encapsulated within
+ * QCA_WLAN_VENDOR_ATTR_PEER_CFR_RESP_DATA along with the vendor sub command
+ * QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG as an asynchronous event.
+ */
+enum qca_wlan_vendor_cfr_data_transport_modes {
+	QCA_WLAN_VENDOR_CFR_DATA_RELAY_FS = 0,
+	QCA_WLAN_VENDOR_CFR_DATA_NETLINK_EVENTS = 1,
+};
+
+/**
  * enum qca_wlan_vendor_cfr_method - QCA vendor CFR methods used by
  * attribute QCA_WLAN_VENDOR_ATTR_PEER_CFR_METHOD as part of vendor
  * command QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG.
@@ -8559,6 +9610,27 @@
  * MAC for CFR capture. This is a bitmask in which each bit represents the
  * corresponding Data frame subtype value per IEEE Std 802.11-2016,
  * 9.2.4.1.3 Type and Subtype subfields. This is for CFR version 2 only.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE: Optional (u8)
+ * Userspace can use this attribute to specify the driver about which transport
+ * mode shall be used by the driver to send CFR data to userspace. Uses values
+ * from enum qca_wlan_vendor_cfr_data_transport_modes. When this attribute is
+ * not present, the driver shall use the default transport mechanism which is
+ * QCA_WLAN_VENDOR_CFR_DATA_RELAY_FS.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_RECEIVER_PID: Optional (u32)
+ * Userspace can use this attribute to specify the nl port id of the application
+ * which receives the CFR data and processes it further so that the drivers can
+ * unicast the netlink events to a specific application. Optionally included
+ * when QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE is set to
+ * QCA_WLAN_VENDOR_CFR_DATA_NETLINK_EVENTS, not required otherwise. The drivers
+ * shall multicast the netlink events when this attribute is not included.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_RESP_DATA: Required (NLA_BINARY).
+ * This attribute will be used by the driver to encapsulate and send CFR data
+ * to userspace along with QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG as an
+ * asynchronous event when the driver is configured to send CFR data using
+ * netlink events with %QCA_WLAN_VENDOR_CFR_DATA_NETLINK_EVENTS.
  */
 enum qca_wlan_vendor_peer_cfr_capture_attr {
 	QCA_WLAN_VENDOR_ATTR_PEER_CFR_CAPTURE_INVALID = 0,
@@ -8587,6 +9659,9 @@
 	QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_MGMT_FILTER = 23,
 	QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_CTRL_FILTER = 24,
 	QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_DATA_FILTER = 25,
+	QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE = 26,
+	QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_RECEIVER_PID = 27,
+	QCA_WLAN_VENDOR_ATTR_PEER_CFR_RESP_DATA = 28,
 
 	/* Keep last */
 	QCA_WLAN_VENDOR_ATTR_PEER_CFR_AFTER_LAST,
@@ -9273,20 +10348,48 @@
  *
  * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE: Required
  * Nested attribute containing multiple ranges with following attributes:
- *	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START and
- *	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END.
+ *	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START,
+ *	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END, and
+ *	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM.
  *
  * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START: Required (u32)
  * Starting center frequency in MHz.
  *
  * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END: Required (u32)
  * Ending center frequency in MHz.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM:
+ * s32 attribute, optional. It is a per frequency range attribute.
+ * The maximum TX power limit from user space is to be applied on an
+ * unrestricted interface for corresponding frequency range. It is also
+ * possible that the actual TX power may be even lower than this cap due to
+ * other considerations such as regulatory compliance, SAR, etc. In absence of
+ * this attribute the driver shall follow current behavior which means
+ * interface (SAP/P2P) function can keep operating on an unsafe channel with TX
+ * power derived by the driver based on regulatory/SAR during interface up.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_IFACES_BITMASK:
+ * u32 attribute, optional. Indicates all the interface types which are
+ * restricted for all frequency ranges provided in
+ * %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START and
+ * %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END.
+ * This attribute encapsulates bitmasks of interface types defined in
+ * enum nl80211_iftype. If an interface is marked as restricted the driver must
+ * move to a safe channel and if no safe channel is available the driver shall
+ * terminate that interface functionality. In absence of this attribute,
+ * interface (SAP/P2P) can still continue operating on an unsafe channel with
+ * TX power limit derived from either
+ * %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM or based on
+ * regulatory/SAE limits if %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM
+ * is not provided.
  */
 enum qca_wlan_vendor_attr_avoid_frequency_ext {
 	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_INVALID = 0,
 	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE = 1,
 	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START = 2,
 	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END = 3,
+	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM = 4,
+	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_IFACES_BITMASK = 5,
 
 	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_MAX =
@@ -9623,6 +10726,45 @@
  * include this attribute in response to the
  * QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO command if there is no connection
  * failure observed in the last attempted connection.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_RATE: u32, latest TX rate (Kbps)
+ * used by the station in its last TX frame while communicating to the AP in the
+ * connected state. When queried in the disconnected state, this represents the
+ * rate used by the STA in the last TX frame to the AP when it was connected.
+ * This attribute is used for STA mode only.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_RIX: u32, used in STA mode only.
+ * This represents the rate index used by the STA for the last TX frame to the
+ * AP. When queried in the disconnected state, this gives the last RIX used by
+ * the STA in the last TX frame to the AP when it was connected.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TSF_OUT_OF_SYNC_COUNT: u32, used in STA
+ * mode only. This represents the number of times the STA TSF goes out of sync
+ * from the AP after the connection. If queried in the disconnected state, this
+ * gives the count of TSF out of sync for the last connection.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_TRIGGER_REASON: u32, used in STA
+ * mode only. This represents the roam trigger reason for the last roaming
+ * attempted by the firmware. This can be queried either in connected state or
+ * disconnected state. Each bit of this attribute represents the different
+ * roam trigger reason code which are defined in enum qca_vendor_roam_triggers.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_FAIL_REASON: u32, used in STA mode
+ * only. This represents the roam fail reason for the last failed roaming
+ * attempt by the firmware. Different roam failure reason codes are specified
+ * in enum qca_vendor_roam_fail_reasons. This can be queried either in
+ * connected state or disconnected state.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_INVOKE_FAIL_REASON: u32, used in
+ * STA mode only. This represents the roam invoke fail reason for the last
+ * failed roam invoke. Different roam invoke failure reason codes
+ * are specified in enum qca_vendor_roam_invoke_fail_reasons. This can be
+ * queried either in connected state or disconnected state.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY: u32, used in STA mode only.
+ * This represents the average congestion duration of uplink frames in MAC
+ * queue in unit of ms. This can be queried either in connected state or
+ * disconnected state.
  */
 enum qca_wlan_vendor_attr_get_sta_info {
 	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_INVALID = 0,
@@ -9669,6 +10811,13 @@
 	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT = 41,
 	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT = 42,
 	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE = 43,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_RATE = 44,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_RIX = 45,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TSF_OUT_OF_SYNC_COUNT = 46,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_TRIGGER_REASON = 47,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_FAIL_REASON = 48,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_INVOKE_FAIL_REASON = 49,
+	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY = 50,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_AFTER_LAST,
@@ -10107,10 +11256,25 @@
  * u8 attribute. Notify the TX VDEV status. Possible values 0, 1
  * belonging to MBSSID/EMA_AP configuration. 0 means Non-Tx VDEV,
  * 1 means Tx VDEV. Mandatory attribute for all MBSSID VDEV status events.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_EVENT:
+ * u8 attribute, required. 1 means Tx VDEV up event. 0 means Tx VDEV down event.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_ID:
+ * u8 attribute, required. Indicates group id of Tx VDEV.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO:
+ * Nested attribute. This attribute shall be used by the driver to send
+ * group information. The attributes defined in enum
+ * qca_wlan_vendor_attr_mbssid_tx_vdev_group_info
+ * are nested in this attribute.
  */
 enum qca_wlan_vendor_attr_mbssid_tx_vdev_status {
 	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_INVALID = 0,
 	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_VAL = 1,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_EVENT = 2,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_ID = 3,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO = 4,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_AFTER_LAST,
@@ -10119,6 +11283,79 @@
 };
 
 /**
+ * enum qca_wlan_vendor_attr_mbssid_tx_vdev_group_info - Attributes used
+ * inside %QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO nested attribute.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_IF_INDEX:
+ * u32 attribute, required. Contains interface index.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_STATUS:
+ * u8 attribute, required. 0 - means vdev is in down state.
+ * 1 - means vdev is in up state.
+ */
+enum qca_wlan_vendor_attr_mbssid_tx_vdev_group_info {
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_IF_INDEX = 1,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_STATUS = 2,
+
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_MAX =
+	QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO - 1,
+};
+
+/**
+ * enum qca_wlan_concurrent_sta_policy_config - Concurrent STA policies
+ *
+ * @QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY: Preference to the primary
+ * STA interface has to be given while selecting the connection policies
+ * (e.g., BSSID, band, TX/RX chains, etc.) for the subsequent STA interface.
+ * An interface is set as primary through the attribute
+ * QCA_WLAN_VENDOR_ATTR_CONFIG_CONCURRENT_STA_PRIMARY. This policy is not
+ * applicable if the primary interface has not been set earlier.
+ *
+ * The intention is not to downgrade the primary STA performance, such as:
+ * - Do not reduce the number of TX/RX chains of primary connection.
+ * - Do not optimize DBS vs. MCC/SCC, if DBS ends up reducing the number of
+ *   chains.
+ * - If using MCC, should set the MCC duty cycle of the primary connection to
+ *   be higher than the secondary connection.
+ *
+ * @QCA_WLAN_CONCURRENT_STA_POLICY_UNBIASED: The connection policies for the
+ * subsequent STA connection shall be chosen to balance with the existing
+ * concurrent STA's performance.
+ * Such as
+ * - Can choose MCC or DBS mode depending on the MCC efficiency and hardware
+ *   capability.
+ * - If using MCC, set the MCC duty cycle of the primary connection to be equal
+ *   to the secondary.
+ * - Prefer BSSID candidates which will help provide the best "overall"
+ *   performance for all the STA connections.
+ */
+enum qca_wlan_concurrent_sta_policy_config {
+	QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY = 0,
+	QCA_WLAN_CONCURRENT_STA_POLICY_UNBIASED = 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_concurrent_sta_policy - Defines attributes
+ * used by QCA_NL80211_VENDOR_SUBCMD_CONCURRENT_MULTI_STA_POLICY vendor command.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_CONFIG:
+ * u8 attribute. Configures the concurrent STA policy configuration.
+ * Possible values are defined in enum qca_wlan_concurrent_sta_policy_config.
+ */
+enum qca_wlan_vendor_attr_concurrent_sta_policy {
+	QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_CONFIG = 1,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_MAX =
+	QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_AFTER_LAST - 1,
+
+};
+
+/**
  * enum qca_sta_connect_fail_reason_codes - Defines values carried
  * by QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE vendor
  * attribute.
@@ -10146,4 +11383,465 @@
 	QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_RESP_RECEIVED = 7,
 };
 
+/**
+ * enum qca_wlan_vendor_usable_channels_filter - Bitmask of different
+ * filters defined in this enum are used in attribute
+ * %QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK.
+ *
+ * @QCA_WLAN_VENDOR_FILTER_CELLULAR_COEX: When this bit is set, the driver
+ * shall filter the channels which are not usable because of coexistence with
+ * cellular radio.
+ * @QCA_WLAN_VENDOR_FILTER_WLAN_CONCURRENCY: When this bit is set, the driver
+ * shall filter the channels which are not usable because of existing active
+ * interfaces in the driver and will result in Multi Channel Concurrency, etc.
+ *
+ */
+enum qca_wlan_vendor_usable_channels_filter {
+	QCA_WLAN_VENDOR_FILTER_CELLULAR_COEX = 0,
+	QCA_WLAN_VENDOR_FILTER_WLAN_CONCURRENCY = 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_chan_info - Attributes used inside
+ * %QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO nested attribute.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_PRIMARY_FREQ:
+ * u32 attribute, required. Indicates the center frequency of the primary
+ * channel in MHz.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG0_FREQ:
+ * u32 attribute. Indicates the center frequency of the primary segment of the
+ * channel in MHz. This attribute is required when reporting 40 MHz, 80 MHz,
+ * 160 MHz, and 320 MHz channels.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG1_FREQ:
+ * u32 attribute. Indicates the center frequency of the secondary segment of
+ * 80+80 channel in MHz. This attribute is required only when
+ * QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH is set to NL80211_CHAN_WIDTH_80P80.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH:
+ * u32 attribute, required. Indicates the bandwidth of the channel, possible
+ * values are defined in enum nl80211_chan_width.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_IFACE_MODE_MASK:
+ * u32 attribute, required. Indicates all the interface types for which this
+ * channel is usable. This attribute encapsulates bitmasks of interface types
+ * defined in enum nl80211_iftype.
+ *
+ */
+enum qca_wlan_vendor_attr_chan_info {
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_PRIMARY_FREQ = 1,
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG0_FREQ = 2,
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG1_FREQ = 3,
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH = 4,
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_IFACE_MODE_MASK = 5,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_MAX =
+	QCA_WLAN_VENDOR_ATTR_CHAN_INFO_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_usable_channels - Attributes used by
+ * %QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS vendor command.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_BAND_MASK:
+ * u32 attribute. Indicates the bands from which the channels should be reported
+ * in response. This attribute encapsulates bit masks of bands defined in enum
+ * nl80211_band. Optional attribute, if not present in the request the driver
+ * shall return channels from all supported bands.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_IFACE_MODE_MASK:
+ * u32 attribute. Indicates all the interface types for which the usable
+ * channels information is requested. This attribute encapsulates bitmasks of
+ * interface types defined in enum nl80211_iftype. Optional attribute, if not
+ * present in the request the driver shall send information of all supported
+ * interface modes.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK:
+ * u32 attribute. This attribute carries information of all filters that shall
+ * be applied while populating usable channels information by the driver. This
+ * attribute carries bit masks of different filters defined in enum
+ * qca_wlan_vendor_usable_channels_filter. Optional attribute, if not present
+ * in the request the driver shall send information of channels without applying
+ * any of the filters that can be configured through this attribute.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO:
+ * Nested attribute. This attribute shall be used by the driver to send
+ * usability information of each channel. The attributes defined in enum
+ * qca_wlan_vendor_attr_chan_info are used inside this attribute.
+ */
+enum qca_wlan_vendor_attr_usable_channels {
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_BAND_MASK = 1,
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_IFACE_MODE_MASK = 2,
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK = 3,
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO = 4,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_MAX =
+	QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_radar_history: Used by the vendor command
+ * QCA_NL80211_VENDOR_SUBCMD_GET_RADAR_HISTORY to get DFS radar history.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES: Nested attribute to carry
+ *	the list of radar history entries.
+ *	Each entry contains freq, timestamp, and radar signal detect flag.
+ *	The driver shall add an entry when CAC has finished, or radar signal
+ *	has been detected post AP beaconing. The driver shall maintain at least
+ *	8 entries in order to save CAC result for a 160 MHz channel.
+ * @QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_FREQ: u32 attribute.
+ *	Channel frequency in MHz.
+ * @QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_TIMESTAMP: u64 nanoseconds.
+ *	CLOCK_BOOTTIME timestamp when this entry is updated due to CAC
+ *	or radar detection.
+ * @QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_DETECTED: NLA_FLAG attribute.
+ *	This flag indicates radar signal has been detected.
+ */
+enum qca_wlan_vendor_attr_radar_history {
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_INVALID = 0,
+
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES = 1,
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_FREQ = 2,
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_TIMESTAMP = 3,
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_DETECTED = 4,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_LAST,
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX =
+	QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_mdns_offload - Attributes used by
+ * %QCA_NL80211_VENDOR_SUBCMD_MDNS_OFFLOAD vendor command.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENABLE: Required (flag)
+ * Enable mDNS offload. This attribute is mandatory to enable
+ * mDNS offload feature. If this attribute is not present, mDNS offload
+ * is disabled.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_TABLE: Nested attribute containing
+ * one or more %QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENTRY attributes. This
+ * attribute is mandatory when enabling the feature, and not required when
+ * disabling the feature.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENTRY: Nested attribute containing
+ * the following attributes:
+ *	%QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_FQDN
+ *	%QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_RESOURCE_RECORDS_COUNT
+ *	%QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_PAYLOAD
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_FQDN: Required string attribute.
+ * It consists of a hostname and ".local" as the domain name. The character
+ * set is limited to UTF-8 encoding. The maximum allowed size is 63 bytes.
+ * It is used to compare the domain in the "QU" query. Only 1 FQDN is
+ * supported per vdev.
+ * For example: myphone.local
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_RESOURCE_RECORDS_COUNT: Required
+ * u16 attribute. It specifies the total number of resource records present
+ * in the answer section of the answer payload. This attribute is needed by the
+ * firmware to populate the mDNS response frame for mDNS queries without having
+ * to parse the answer payload.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_PAYLOAD: Required binary blob
+ * attribute sent by the mdnsResponder from userspace. It contains resource
+ * records of various types (e.g., A, AAAA, PTR, TXT) and service list. This
+ * payload is passed down to the firmware and is transmitted in response to
+ * mDNS queries.
+ * The maximum supported size of the answer payload is 512 bytes.
+ */
+enum qca_wlan_vendor_attr_mdns_offload {
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENABLE = 1,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_TABLE = 2,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENTRY = 3,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_FQDN = 4,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_RESOURCE_RECORDS_COUNT = 5,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_PAYLOAD = 6,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_MAX =
+	QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_AFTER_LAST - 1,
+};
+
+/**
+ * qca_wlan_vendor_monitor_data_frame_type - Represent the various
+ * Data frame types to be sent over the monitor interface.
+ */
+enum qca_wlan_vendor_monitor_data_frame_type {
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ALL = BIT(0),
+	/* valid only if QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ALL is not set
+	 */
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ARP = BIT(1),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DHCPV4 = BIT(2),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DHCPV6 = BIT(3),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_EAPOL = BIT(4),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DNSV4 = BIT(5),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DNSV6 = BIT(6),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_SYN = BIT(7),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_SYNACK = BIT(8),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_FIN = BIT(9),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_FINACK = BIT(10),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_ACK = BIT(11),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_RST = BIT(12),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ICMPV4 = BIT(13),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ICMPV6 = BIT(14),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_RTP = BIT(15),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_SIP = BIT(16),
+	QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_QOS_NULL = BIT(17),
+};
+
+/**
+ * qca_wlan_vendor_monitor_mgmt_frame_type - Represent the various
+ * Management frame types to be sent over the monitor interface.
+ * @QCA_WLAN_VENDOR_MONITOR_MGMT_FRAME_TYPE_ALL: All the Management Frames.
+ * @QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_NO_BEACON: All the Management frames
+ * except the Beacon frame.
+ * @QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_BEACON: Only the connected
+ * BSSID Beacon frames. Valid only in the connected state.
+ * @QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_SCAN_BEACON: Represents
+ * the Beacon frames obtained during the scan (off channel and connected
+ * channel), when in connected state.
+ */
+
+enum qca_wlan_vendor_monitor_mgmt_frame_type {
+	QCA_WLAN_VENDOR_MONITOR_MGMT_FRAME_TYPE_ALL = BIT(0),
+	/* valid only if QCA_WLAN_VENDOR_MONITOR_MGMT_FRAME_TYPE_ALL is not set
+	 */
+	QCA_WLAN_VENDOR_MONITOR_MGMT_NO_BEACON = BIT(1),
+	QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_BEACON = BIT(2),
+	QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_SCAN_BEACON = BIT(3),
+};
+
+/**
+ * qca_wlan_vendor_monitor_ctrl_frame_type - Represent the various
+ * Control frame types to be sent over the monitor interface.
+ * @QCA_WLAN_VENDOR_MONITOR_CTRL_FRAME_TYPE_ALL: All the Control frames
+ * @QCA_WLAN_VENDOR_MONITOR_CTRL_TRIGGER_FRAME: Trigger frame
+ */
+enum qca_wlan_vendor_monitor_ctrl_frame_type {
+	QCA_WLAN_VENDOR_MONITOR_CTRL_FRAME_TYPE_ALL = BIT(0),
+	/* valid only if QCA_WLAN_VENDOR_MONITOR_CTRL_FRAME_TYPE_ALL is not set
+	 */
+	QCA_WLAN_VENDOR_MONITOR_CTRL_TRIGGER_FRAME = BIT(1),
+};
+
+/**
+ * enum qca_wlan_vendor_attr_set_monitor_mode - Used by the
+ * vendor command QCA_NL80211_VENDOR_SUBCMD_SET_MONITOR_MODE to set the
+ * monitor mode.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_TX_FRAME_TYPE: u32 attribute.
+ * Represents the TX Data frame types to be monitored (u32). These Data frames
+ * are represented by enum qca_wlan_vendor_monitor_data_frame_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_RX_FRAME_TYPE: u32 attribute.
+ * Represents the RX Data frame types to be monitored (u32). These Data frames
+ * are represented by enum qca_wlan_vendor_monitor_data_frame_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_TX_FRAME_TYPE: u32 attribute.
+ * Represents the TX Management frame types to be monitored (u32). These
+ * Management frames are represented by
+ * enum qca_wlan_vendor_monitor_mgmt_frame_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_RX_FRAME_TYPE: u32 attribute.
+ * Represents the RX Management frame types to be monitored (u32). These
+ * Management frames are represented by
+ * enum qca_wlan_vendor_monitor_mgmt_frame_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_TX_FRAME_TYPE: u32 attribute.
+ * Represents the TX Control frame types to be monitored (u32). These Control
+ * frames are represented by enum qca_wlan_vendor_monitor_ctrl_frame_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_RX_FRAME_TYPE: u32 attribute.
+ * Represents the RX Control frame types to be monitored (u32). These Control
+ * frames are represented by enum qca_wlan_vendor_monitor_ctrl_frame_type.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CONNECTED_BEACON_INTERVAL: u32
+ * attribute.
+ * Represents the interval in milliseconds only for the connected Beacon frames,
+ * expecting the connected BSS's Beacon frames to be sent on the monitor
+ * interface at this specific interval.
+ */
+enum qca_wlan_vendor_attr_set_monitor_mode
+{
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_TX_FRAME_TYPE = 1,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_RX_FRAME_TYPE = 2,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_TX_FRAME_TYPE = 3,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_RX_FRAME_TYPE = 4,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_TX_FRAME_TYPE = 5,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_RX_FRAME_TYPE = 6,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CONNECTED_BEACON_INTERVAL = 7,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MAX =
+	QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_roam_scan_state - Roam scan state flags.
+ * Bits will be set to 1 if the corresponding state is enabled.
+ *
+ * @QCA_VENDOR_WLAN_ROAM_SCAN_STATE_START: Scan Start.
+ * @QCA_VENDOR_WLAN_ROAM_SCAN_STATE_END: Scan end.
+ */
+enum qca_wlan_vendor_roam_scan_state {
+	QCA_WLAN_VENDOR_ROAM_SCAN_STATE_START = BIT(0),
+	QCA_WLAN_VENDOR_ROAM_SCAN_STATE_END = BIT(1),
+};
+
+/**
+ * enum qca_wlan_vendor_roam_event_type - Roam event type flags.
+ * Bits will be set to 1 if the corresponding event is notified.
+ *
+ * @QCA_WLAN_VENDOR_ROAM_EVENT_TRIGGER_REASON: Represents that the roam event
+ * carries the trigger reason. When set, it is expected that the roam event
+ * carries the respective reason via the attribute
+ * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TRIGGER_REASON. This event also carries
+ * the BSSID, RSSI, frequency info of the AP to which the roam is attempted.
+ *
+ * @QCA_WLAN_VENDOR_ROAM_EVENT_FAIL_REASON: Represents that the roam event
+ * carries the roam fail reason. When set, it is expected that the roam event
+ * carries the respective reason via the attribute
+ * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_FAIL_REASON. This event also carries the
+ * BSSID, RSSI, frequency info of the AP to which the roam was attempted.
+ *
+ * @QCA_WLAN_VENDOR_ROAM_EVENT_INVOKE_FAIL_REASON: Represents that the roam
+ * event carries the roam invoke fail reason. When set, it is expected that
+ * the roam event carries the respective reason via the attribute
+ * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVOKE_FAIL_REASON.
+ *
+ * @QCA_WLAN_VENDOR_ROAM_EVENT_SCAN_STATE: Represents that the roam event
+ * carries the roam scan state. When set, it is expected that the roam event
+ * carries the respective scan state via the attribute
+ * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_STATE and the corresponding
+ * frequency info via QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_FREQ_LIST.
+ */
+enum qca_wlan_vendor_roam_event_type {
+	QCA_WLAN_VENDOR_ROAM_EVENT_TRIGGER_REASON = BIT(0),
+	QCA_WLAN_VENDOR_ROAM_EVENT_FAIL_REASON = BIT(1),
+	QCA_WLAN_VENDOR_ROAM_EVENT_INVOKE_FAIL_REASON = BIT(2),
+	QCA_WLAN_VENDOR_ROAM_EVENT_ROAM_SCAN_STATE = BIT(3),
+};
+
+/**
+ * enum qca_wlan_vendor_attr_roam_events_candidate_info: Roam candidate info.
+ * Referred by QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_BSSID: 6-byte MAC address
+ * representing the BSSID of the AP to which the roam is attempted.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_RSSI: Signed 32-bit value
+ * in dBm, signifying the RSSI of the candidate BSSID to which the Roaming is
+ * attempted.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FREQ: u32, frequency in MHz
+ * on which the roam is attempted.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FAIL_REASON: u32, used in
+ * STA mode only. This represents the roam fail reason for the last failed
+ * roaming attempt by the firmware for the specific BSSID. Different roam
+ * failure reason codes are specified in enum qca_vendor_roam_fail_reasons.
+ */
+enum qca_wlan_vendor_attr_roam_events_candidate_info {
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_BSSID = 1,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_RSSI = 2,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FREQ = 3,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FAIL_REASON = 4,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_MAX =
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_roam_events - Used by the
+ * vendor command QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS to either configure the
+ * roam events to the driver or notify these events from the driver.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CONFIGURE: u8 attribute. Configures the
+ * driver/firmware to enable/disable the notification of roam events. It's a
+ * mandatory attribute and used only in the request from the userspace to the
+ * host driver. 1-Enable, 0-Disable.
+ * If the roaming is totally offloaded to the firmware, this request when
+ * enabled shall mandate the firmware to notify all the relevant roam events
+ * represented by the below attributes. If the host is in the suspend mode,
+ * the behavior of the firmware to notify these events is guided by
+ * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_DEVICE_STATE, and if the request is to get
+ * these events in the suspend state, the firmware is expected to wake up the
+ * host before the respective events are notified. Please note that such a
+ * request to get the events in the suspend state will have a definite power
+ * implication.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_SUSPEND_STATE: flag attribute. Represents
+ * that the roam events need to be notified in the suspend state too. By
+ * default, these roam events are notified in the resume state. With this flag,
+ * the roam events are notified in both resume and suspend states.
+ * This attribute is used in the request from the userspace to the host driver.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TYPE: u32, used in STA mode only.
+ * Represents the different roam event types, signified by the enum
+ * qca_wlan_vendor_roam_event_type.
+ * Each bit of this attribute represents the different roam even types reported
+ * through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
+ * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TRIGGER_REASON: u32, used in STA
+ * mode only. This represents the roam trigger reason for the last roaming
+ * attempted by the firmware. Each bit of this attribute represents the
+ * different roam trigger reason code which are defined in enum
+ * qca_vendor_roam_triggers.
+ * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVOKE_FAIL_REASON: u32, used in
+ * STA mode only. This represents the roam invoke fail reason for the last
+ * failed roam invoke. Different roam invoke failure reason codes
+ * are specified in enum qca_vendor_roam_invoke_fail_reasons.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO: Array of candidates info
+ * for which the roam is attempted. Each entry is a nested attribute defined
+ * by enum qca_wlan_vendor_attr_roam_events_candidate_info.
+ * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_STATE: u8 attribute. Represents
+ * the scan state on which the roam events need to be notified. The values for
+ * this attribute are referred from enum qca_wlan_vendor_roam_scan_state.
+ * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_FREQ_LIST: Nested attribute of
+ * u32 values. List of frequencies in MHz considered for a roam scan.
+ * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
+ */
+
+enum qca_wlan_vendor_attr_roam_events
+{
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CONFIGURE = 1,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_SUSPEND_STATE = 2,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TYPE = 3,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TRIGGER_REASON = 4,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVOKE_FAIL_REASON = 5,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO = 6,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_STATE = 7,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_FREQ_LIST = 8,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_MAX =
+	QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_AFTER_LAST -1,
+};
+
 #endif /* QCA_VENDOR_H */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/sae.c b/src/lynq/packages/thirdpart/lynq-wg870/src/common/sae.c
index 88cbe53..c0f154e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/sae.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/sae.c
@@ -280,14 +280,13 @@
 
 static int sae_derive_pwe_ecc(struct sae_data *sae, const u8 *addr1,
 			      const u8 *addr2, const u8 *password,
-			      size_t password_len, const char *identifier)
+			      size_t password_len)
 {
 	u8 counter, k;
 	u8 addrs[2 * ETH_ALEN];
-	const u8 *addr[3];
-	size_t len[3];
-	size_t num_elem;
-	u8 *dummy_password, *tmp_password;
+	const u8 *addr[2];
+	size_t len[2];
+	u8 *stub_password, *tmp_password;
 	int pwd_seed_odd = 0;
 	u8 prime[SAE_MAX_ECC_PRIME_LEN];
 	size_t prime_len;
@@ -304,10 +303,10 @@
 
 	os_memset(x_bin, 0, sizeof(x_bin));
 
-	dummy_password = os_malloc(password_len);
+	stub_password = os_malloc(password_len);
 	tmp_password = os_malloc(password_len);
-	if (!dummy_password || !tmp_password ||
-	    random_get_bytes(dummy_password, password_len) < 0)
+	if (!stub_password || !tmp_password ||
+	    random_get_bytes(stub_password, password_len) < 0)
 		goto fail;
 
 	prime_len = sae->tmp->prime_len;
@@ -326,13 +325,10 @@
 
 	wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
 			      password, password_len);
-	if (identifier)
-		wpa_printf(MSG_DEBUG, "SAE: password identifier: %s",
-			   identifier);
 
 	/*
 	 * H(salt, ikm) = HMAC-SHA256(salt, ikm)
-	 * base = password [|| identifier]
+	 * base = password
 	 * pwd-seed = H(MAX(STA-A-MAC, STA-B-MAC) || MIN(STA-A-MAC, STA-B-MAC),
 	 *              base || counter)
 	 */
@@ -340,15 +336,8 @@
 
 	addr[0] = tmp_password;
 	len[0] = password_len;
-	num_elem = 1;
-	if (identifier) {
-		addr[num_elem] = (const u8 *) identifier;
-		len[num_elem] = os_strlen(identifier);
-		num_elem++;
-	}
-	addr[num_elem] = &counter;
-	len[num_elem] = sizeof(counter);
-	num_elem++;
+	addr[1] = &counter;
+	len[1] = sizeof(counter);
 
 	/*
 	 * Continue for at least k iterations to protect against side-channel
@@ -367,9 +356,9 @@
 		}
 
 		wpa_printf(MSG_DEBUG, "SAE: counter = %03u", counter);
-		const_time_select_bin(found, dummy_password, password,
+		const_time_select_bin(found, stub_password, password,
 				      password_len, tmp_password);
-		if (hmac_sha256_vector(addrs, sizeof(addrs), num_elem,
+		if (hmac_sha256_vector(addrs, sizeof(addrs), 2,
 				       addr, len, pwd_seed) < 0)
 			break;
 
@@ -445,7 +434,7 @@
 	crypto_bignum_deinit(qr, 0);
 	crypto_bignum_deinit(qnr, 0);
 	crypto_bignum_deinit(y, 1);
-	os_free(dummy_password);
+	os_free(stub_password);
 	bin_clear_free(tmp_password, password_len);
 	crypto_bignum_deinit(x, 1);
 	os_memset(x_bin, 0, sizeof(x_bin));
@@ -457,13 +446,12 @@
 
 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)
+			      size_t password_len)
 {
 	u8 counter, k, sel_counter = 0;
 	u8 addrs[2 * ETH_ALEN];
-	const u8 *addr[3];
-	size_t len[3];
-	size_t num_elem;
+	const u8 *addr[2];
+	size_t len[2];
 	u8 found = 0; /* 0 (false) or 0xff (true) to be used as const_time_*
 		       * mask */
 	u8 mask;
@@ -487,21 +475,14 @@
 	/*
 	 * H(salt, ikm) = HMAC-SHA256(salt, ikm)
 	 * pwd-seed = H(MAX(STA-A-MAC, STA-B-MAC) || MIN(STA-A-MAC, STA-B-MAC),
-	 *              password [|| identifier] || counter)
+	 *              password || counter)
 	 */
 	sae_pwd_seed_key(addr1, addr2, addrs);
 
 	addr[0] = password;
 	len[0] = password_len;
-	num_elem = 1;
-	if (identifier) {
-		addr[num_elem] = (const u8 *) identifier;
-		len[num_elem] = os_strlen(identifier);
-		num_elem++;
-	}
-	addr[num_elem] = &counter;
-	len[num_elem] = sizeof(counter);
-	num_elem++;
+	addr[1] = &counter;
+	len[1] = sizeof(counter);
 
 	k = dragonfly_min_pwe_loop_iter(sae->group);
 
@@ -516,7 +497,7 @@
 		}
 
 		wpa_printf(MSG_DEBUG, "SAE: counter = %02u", counter);
-		if (hmac_sha256_vector(addrs, sizeof(addrs), num_elem,
+		if (hmac_sha256_vector(addrs, sizeof(addrs), 2,
 				       addr, len, pwd_seed) < 0)
 			break;
 		res = sae_test_pwd_seed_ffc(sae, pwd_seed, pwe);
@@ -785,19 +766,9 @@
 	const_time_select_bin(is_qr, bin1, bin2, prime_len, x_y);
 	wpa_hexdump_key(MSG_DEBUG, "SSWU: x = CSEL(l, x1, x2)", x_y, prime_len);
 
-	/* y = sqrt(v)
-	 * For prime p such that p = 3 mod 4 --> v^((p+1)/4) */
-	if (crypto_bignum_to_bin(prime, bin1, sizeof(bin1), prime_len) < 0)
-		goto fail;
-	if ((bin1[prime_len - 1] & 0x03) != 3) {
-		wpa_printf(MSG_DEBUG, "SSWU: prime does not have p = 3 mod 4");
-		goto fail;
-	}
+	/* y = sqrt(v) */
 	y = crypto_bignum_init();
-	if (!y ||
-	    crypto_bignum_add(prime, one, t1) < 0 ||
-	    crypto_bignum_rshift(t1, 2, t1) < 0 ||
-	    crypto_bignum_exptmod(v, t1, prime, y) < 0)
+	if (!y || dragonfly_sqrt(ec, v, y) < 0)
 		goto fail;
 	debug_print_bignum("SSWU: y = sqrt(v)", y, prime_len);
 
@@ -1373,15 +1344,13 @@
 
 int sae_prepare_commit(const u8 *addr1, const u8 *addr2,
 		       const u8 *password, size_t password_len,
-		       const char *identifier, struct sae_data *sae)
+		       struct sae_data *sae)
 {
 	if (sae->tmp == NULL ||
 	    (sae->tmp->ec && sae_derive_pwe_ecc(sae, addr1, addr2, password,
-						password_len,
-						identifier) < 0) ||
+						password_len) < 0) ||
 	    (sae->tmp->dh && sae_derive_pwe_ffc(sae, addr1, addr2, password,
-						password_len,
-						identifier) < 0))
+						password_len) < 0))
 		return -1;
 
 	sae->h2e = 0;
@@ -2042,6 +2011,9 @@
 static int sae_parse_password_identifier(struct sae_data *sae,
 					 const u8 **pos, const u8 *end)
 {
+	const u8 *epos;
+	u8 len;
+
 	wpa_hexdump(MSG_DEBUG, "SAE: Possible elements at the end of the frame",
 		    *pos, end - *pos);
 	if (!sae_is_password_id_elem(*pos, end)) {
@@ -2056,9 +2028,17 @@
 		return WLAN_STATUS_SUCCESS; /* No Password Identifier */
 	}
 
+	epos = *pos;
+	epos++; /* skip IE type */
+	len = *epos++; /* IE length */
+	if (len > end - epos || len < 1)
+		return WLAN_STATUS_UNSPECIFIED_FAILURE;
+	epos++; /* skip ext ID */
+	len--;
+
 	if (sae->tmp->pw_id &&
-	    ((*pos)[1] - 1 != (int) os_strlen(sae->tmp->pw_id) ||
-	     os_memcmp(sae->tmp->pw_id, (*pos) + 3, (*pos)[1] - 1) != 0)) {
+	    (len != os_strlen(sae->tmp->pw_id) ||
+	     os_memcmp(sae->tmp->pw_id, epos, len) != 0)) {
 		wpa_printf(MSG_DEBUG,
 			   "SAE: The included Password Identifier does not match the expected one (%s)",
 			   sae->tmp->pw_id);
@@ -2066,14 +2046,14 @@
 	}
 
 	os_free(sae->tmp->pw_id);
-	sae->tmp->pw_id = os_malloc((*pos)[1]);
+	sae->tmp->pw_id = os_malloc(len + 1);
 	if (!sae->tmp->pw_id)
 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
-	os_memcpy(sae->tmp->pw_id, (*pos) + 3, (*pos)[1] - 1);
-	sae->tmp->pw_id[(*pos)[1] - 1] = '\0';
+	os_memcpy(sae->tmp->pw_id, epos, len);
+	sae->tmp->pw_id[len] = '\0';
 	wpa_hexdump_ascii(MSG_DEBUG, "SAE: Received Password Identifier",
-			  sae->tmp->pw_id, (*pos)[1] -  1);
-	*pos = *pos + 2 + (*pos)[1];
+			  sae->tmp->pw_id, len);
+	*pos = epos + len;
 	return WLAN_STATUS_SUCCESS;
 }
 
@@ -2081,19 +2061,30 @@
 static int sae_parse_rejected_groups(struct sae_data *sae,
 				     const u8 **pos, const u8 *end)
 {
+	const u8 *epos;
+	u8 len;
+
 	wpa_hexdump(MSG_DEBUG, "SAE: Possible elements at the end of the frame",
 		    *pos, end - *pos);
 	if (!sae_is_rejected_groups_elem(*pos, end))
 		return WLAN_STATUS_SUCCESS;
+
+	epos = *pos;
+	epos++; /* skip IE type */
+	len = *epos++; /* IE length */
+	if (len > end - epos || len < 1)
+		return WLAN_STATUS_UNSPECIFIED_FAILURE;
+	epos++; /* skip ext ID */
+	len--;
+
 	wpabuf_free(sae->tmp->peer_rejected_groups);
-	sae->tmp->peer_rejected_groups = wpabuf_alloc((*pos)[1] - 1);
+	sae->tmp->peer_rejected_groups = wpabuf_alloc(len);
 	if (!sae->tmp->peer_rejected_groups)
 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
-	wpabuf_put_data(sae->tmp->peer_rejected_groups, (*pos) + 3,
-			(*pos)[1] - 1);
+	wpabuf_put_data(sae->tmp->peer_rejected_groups, epos, len);
 	wpa_hexdump_buf(MSG_DEBUG, "SAE: Received Rejected Groups list",
 			sae->tmp->peer_rejected_groups);
-	*pos = *pos + 2 + (*pos)[1];
+	*pos = epos + len;
 	return WLAN_STATUS_SUCCESS;
 }
 
@@ -2265,10 +2256,10 @@
 	hash_len = sae->tmp->kck_len;
 
 	/* Send-Confirm */
-	sc = wpabuf_put(buf, 0);
-	wpabuf_put_le16(buf, sae->send_confirm);
 	if (sae->send_confirm < 0xffff)
 		sae->send_confirm++;
+	sc = wpabuf_put(buf, 0);
+	wpabuf_put_le16(buf, sae->send_confirm);
 
 	if (sae->tmp->ec)
 		res = sae_cn_confirm_ecc(sae, sc, sae->tmp->own_commit_scalar,
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/sae.h b/src/lynq/packages/thirdpart/lynq-wg870/src/common/sae.h
index 2243c0f..93fc5fb 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/sae.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/sae.h
@@ -122,7 +122,7 @@
 
 int sae_prepare_commit(const u8 *addr1, const u8 *addr2,
 		       const u8 *password, size_t password_len,
-		       const char *identifier, struct sae_data *sae);
+		       struct sae_data *sae);
 int sae_prepare_commit_pt(struct sae_data *sae, const struct sae_pt *pt,
 			  const u8 *addr1, const u8 *addr2,
 			  int *rejected_groups, const struct sae_pk *pk);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/version.h b/src/lynq/packages/thirdpart/lynq-wg870/src/common/version.h
index 665dd23..fef2142 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/version.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/version.h
@@ -9,16 +9,16 @@
 #define GIT_VERSION_STR_POSTFIX ""
 #endif /* GIT_VERSION_STR_POSTFIX */
 
-#define BRCM_MAJOR_VER		"201"
-#define BRCM_MINOR_VER		"19"
+#define BRCM_MAJOR_VER		"202"
+#define BRCM_MINOR_VER		"11"
 #define BRCM_VER_INFO		" BRCM_VER:" BRCM_MAJOR_VER "." BRCM_MINOR_VER
 
 #define BRCM_STR_POSTFIX BRCM_VER_INFO
 
 #if defined(ANDROID_P2P)
-#define VERSION_STR "2.10-devel" VERSION_STR_POSTFIX  BRCM_STR_POSTFIX
+#define VERSION_STR "2.10" VERSION_STR_POSTFIX  BRCM_STR_POSTFIX
 #else
-#define VERSION_STR "2.10-devel" VERSION_STR_POSTFIX GIT_VERSION_STR_POSTFIX
+#define VERSION_STR "2.10" VERSION_STR_POSTFIX GIT_VERSION_STR_POSTFIX
 #endif
 
 #endif /* VERSION_H */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/wpa_common.c b/src/lynq/packages/thirdpart/lynq-wg870/src/common/wpa_common.c
index b5143d1..a4bb02b 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/wpa_common.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/wpa_common.c
@@ -333,6 +333,7 @@
  * @ptk: Buffer for pairwise transient key
  * @akmp: Negotiated AKM
  * @cipher: Negotiated pairwise cipher
+ * @kdk_len: The length in octets that should be derived for KDK
  * Returns: 0 on success, -1 on failure
  *
  * IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
@@ -348,12 +349,13 @@
 		   const u8 *addr1, const u8 *addr2,
 		   const u8 *nonce1, const u8 *nonce2,
 		   struct wpa_ptk *ptk, int akmp, int cipher,
-		   const u8 *z, size_t z_len)
+		   const u8 *z, size_t z_len, size_t kdk_len)
 {
 #define MAX_Z_LEN 66 /* with NIST P-521 */
 	u8 data[2 * ETH_ALEN + 2 * WPA_NONCE_LEN + MAX_Z_LEN];
 	size_t data_len = 2 * ETH_ALEN + 2 * WPA_NONCE_LEN;
-	u8 tmp[WPA_KCK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN];
+	u8 tmp[WPA_KCK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN +
+		WPA_KDK_MAX_LEN];
 	size_t ptk_len;
 #ifdef CONFIG_OWE
 	int owe_ptk_workaround = 0;
@@ -395,16 +397,24 @@
 		data_len += z_len;
 	}
 
+	if (kdk_len > WPA_KDK_MAX_LEN) {
+		wpa_printf(MSG_ERROR,
+			   "WPA: KDK len=%zu exceeds max supported len",
+			   kdk_len);
+		return -1;
+	}
+
 	ptk->kck_len = wpa_kck_len(akmp, pmk_len);
 	ptk->kek_len = wpa_kek_len(akmp, pmk_len);
 	ptk->tk_len = wpa_cipher_key_len(cipher);
+	ptk->kdk_len = kdk_len;
 	if (ptk->tk_len == 0) {
 		wpa_printf(MSG_ERROR,
 			   "WPA: Unsupported cipher (0x%x) used in PTK derivation",
 			   cipher);
 		return -1;
 	}
-	ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len;
+	ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len + ptk->kdk_len;
 
 	if (wpa_key_mgmt_sha384(akmp)) {
 #if defined(CONFIG_SUITEB192) || defined(CONFIG_FILS)
@@ -488,6 +498,12 @@
 	os_memcpy(ptk->tk, tmp + ptk->kck_len + ptk->kek_len, ptk->tk_len);
 	wpa_hexdump_key(MSG_DEBUG, "WPA: TK", ptk->tk, ptk->tk_len);
 
+	if (kdk_len) {
+		os_memcpy(ptk->kdk, tmp + ptk->kck_len + ptk->kek_len +
+			  ptk->tk_len, ptk->kdk_len);
+		wpa_hexdump_key(MSG_DEBUG, "WPA: KDK", ptk->kdk, ptk->kdk_len);
+	}
+
 	ptk->kek2_len = 0;
 	ptk->kck2_len = 0;
 
@@ -576,15 +592,16 @@
 		    const u8 *snonce, const u8 *anonce, const u8 *dhss,
 		    size_t dhss_len, struct wpa_ptk *ptk,
 		    u8 *ick, size_t *ick_len, int akmp, int cipher,
-		    u8 *fils_ft, size_t *fils_ft_len)
+		    u8 *fils_ft, size_t *fils_ft_len, size_t kdk_len)
 {
 	u8 *data, *pos;
 	size_t data_len;
 	u8 tmp[FILS_ICK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN +
-	       FILS_FT_MAX_LEN];
+	       FILS_FT_MAX_LEN + WPA_KDK_MAX_LEN];
 	size_t key_data_len;
 	const char *label = "FILS PTK Derivation";
 	int ret = -1;
+	size_t offset;
 
 	/*
 	 * FILS-Key-Data = PRF-X(PMK, "FILS PTK Derivation",
@@ -595,6 +612,9 @@
 	 * If doing FT initial mobility domain association:
 	 * FILS-FT = L(FILS-Key-Data, ICK_bits + KEK_bits + TK_bits,
 	 *             FILS-FT_bits)
+	 * When a KDK is derived:
+	 * KDK = L(FILS-Key-Data, ICK_bits + KEK_bits + TK_bits + FILS-FT_bits,
+	 *	   KDK_bits)
 	 */
 	data_len = 2 * ETH_ALEN + 2 * FILS_NONCE_LEN + dhss_len;
 	data = os_malloc(data_len);
@@ -623,6 +643,19 @@
 		goto err;
 	key_data_len = *ick_len + ptk->kek_len + ptk->tk_len;
 
+	if (kdk_len) {
+		if (kdk_len > WPA_KDK_MAX_LEN) {
+			wpa_printf(MSG_ERROR, "FILS: KDK len=%zu too big",
+				   kdk_len);
+			goto err;
+		}
+
+		ptk->kdk_len = kdk_len;
+		key_data_len += kdk_len;
+	} else {
+		ptk->kdk_len = 0;
+	}
+
 	if (fils_ft && fils_ft_len) {
 		if (akmp == WPA_KEY_MGMT_FT_FILS_SHA256) {
 			*fils_ft_len = 32;
@@ -657,19 +690,27 @@
 	wpa_hexdump_key(MSG_DEBUG, "FILS: FILS-Key-Data", tmp, key_data_len);
 
 	os_memcpy(ick, tmp, *ick_len);
+	offset = *ick_len;
 	wpa_hexdump_key(MSG_DEBUG, "FILS: ICK", ick, *ick_len);
 
-	os_memcpy(ptk->kek, tmp + *ick_len, ptk->kek_len);
+	os_memcpy(ptk->kek, tmp + offset, ptk->kek_len);
 	wpa_hexdump_key(MSG_DEBUG, "FILS: KEK", ptk->kek, ptk->kek_len);
+	offset += ptk->kek_len;
 
-	os_memcpy(ptk->tk, tmp + *ick_len + ptk->kek_len, ptk->tk_len);
+	os_memcpy(ptk->tk, tmp + offset, ptk->tk_len);
 	wpa_hexdump_key(MSG_DEBUG, "FILS: TK", ptk->tk, ptk->tk_len);
+	offset += ptk->tk_len;
 
 	if (fils_ft && fils_ft_len) {
-		os_memcpy(fils_ft, tmp + *ick_len + ptk->kek_len + ptk->tk_len,
-			  *fils_ft_len);
+		os_memcpy(fils_ft, tmp + offset, *fils_ft_len);
 		wpa_hexdump_key(MSG_DEBUG, "FILS: FILS-FT",
 				fils_ft, *fils_ft_len);
+		offset += *fils_ft_len;
+	}
+
+	if (ptk->kdk_len) {
+		os_memcpy(ptk->kdk, tmp + offset, ptk->kdk_len);
+		wpa_hexdump_key(MSG_DEBUG, "FILS: KDK", ptk->kdk, ptk->kdk_len);
 	}
 
 	ptk->kek2_len = 0;
@@ -1127,6 +1168,266 @@
 #endif /* CONFIG_IEEE80211R */
 
 
+#ifdef CONFIG_PASN
+
+/*
+ * pasn_use_sha384 - Should SHA384 be used or SHA256
+ *
+ * @akmp: Authentication and key management protocol
+ * @cipher: The cipher suite
+ *
+ * According to IEEE P802.11az/D2.7, 12.12.7, the hash algorithm to use is the
+ * hash algorithm defined for the Base AKM (see Table 9-151 (AKM suite
+ * selectors)). When there is no Base AKM, the hash algorithm is selected based
+ * on the pairwise cipher suite provided in the RSNE by the AP in the second
+ * PASN frame. SHA-256 is used as the hash algorithm, except for the ciphers
+ * 00-0F-AC:9 and 00-0F-AC:10 for which SHA-384 is used.
+ */
+static bool pasn_use_sha384(int akmp, int cipher)
+{
+	return (akmp == WPA_KEY_MGMT_PASN && (cipher == WPA_CIPHER_CCMP_256 ||
+					      cipher == WPA_CIPHER_GCMP_256)) ||
+		wpa_key_mgmt_sha384(akmp);
+}
+
+
+/**
+ * pasn_pmk_to_ptk - Calculate PASN PTK from PMK, addresses, etc.
+ * @pmk: Pairwise master key
+ * @pmk_len: Length of PMK
+ * @spa: Suppplicant address
+ * @bssid: AP BSSID
+ * @dhss: Is the shared secret (DHss) derived from the PASN ephemeral key
+ *	exchange encoded as an octet string
+ * @dhss_len: The length of dhss in octets
+ * @ptk: Buffer for pairwise transient key
+ * @akmp: Negotiated AKM
+ * @cipher: Negotiated pairwise cipher
+ * @kdk_len: the length in octets that should be derived for HTLK. Can be zero.
+ * Returns: 0 on success, -1 on failure
+ */
+int pasn_pmk_to_ptk(const u8 *pmk, size_t pmk_len,
+		    const u8 *spa, const u8 *bssid,
+		    const u8 *dhss, size_t dhss_len,
+		    struct wpa_ptk *ptk, int akmp, int cipher,
+		    size_t kdk_len)
+{
+	u8 tmp[WPA_KCK_MAX_LEN + WPA_TK_MAX_LEN + WPA_KDK_MAX_LEN];
+	u8 *data;
+	size_t data_len, ptk_len;
+	int ret = -1;
+	const char *label = "PASN PTK Derivation";
+
+	if (!pmk || !pmk_len) {
+		wpa_printf(MSG_ERROR, "PASN: No PMK set for PTK derivation");
+		return -1;
+	}
+
+	if (!dhss || !dhss_len) {
+		wpa_printf(MSG_ERROR, "PASN: No DHss set for PTK derivation");
+		return -1;
+	}
+
+	/*
+	 * PASN-PTK = KDF(PMK, “PASN PTK Derivation”, SPA || BSSID || DHss)
+	 *
+	 * KCK = L(PASN-PTK, 0, 256)
+	 * TK = L(PASN-PTK, 256, TK_bits)
+	 * KDK = L(PASN-PTK, 256 + TK_bits, kdk_len * 8)
+	 */
+	data_len = 2 * ETH_ALEN + dhss_len;
+	data = os_zalloc(data_len);
+	if (!data)
+		return -1;
+
+	os_memcpy(data, spa, ETH_ALEN);
+	os_memcpy(data + ETH_ALEN, bssid, ETH_ALEN);
+	os_memcpy(data + 2 * ETH_ALEN, dhss, dhss_len);
+
+	ptk->kck_len = WPA_PASN_KCK_LEN;
+	ptk->tk_len = wpa_cipher_key_len(cipher);
+	ptk->kdk_len = kdk_len;
+	ptk->kek_len = 0;
+	ptk->kek2_len = 0;
+	ptk->kck2_len = 0;
+
+	if (ptk->tk_len == 0) {
+		wpa_printf(MSG_ERROR,
+			   "PASN: Unsupported cipher (0x%x) used in PTK derivation",
+			   cipher);
+		goto err;
+	}
+
+	ptk_len = ptk->kck_len + ptk->tk_len + ptk->kdk_len;
+	if (ptk_len > sizeof(tmp))
+		goto err;
+
+	if (pasn_use_sha384(akmp, cipher)) {
+		wpa_printf(MSG_DEBUG, "PASN: PTK derivation using SHA384");
+
+		if (sha384_prf(pmk, pmk_len, label, data, data_len, tmp,
+			       ptk_len) < 0)
+			goto err;
+	} else {
+		wpa_printf(MSG_DEBUG, "PASN: PTK derivation using SHA256");
+
+		if (sha256_prf(pmk, pmk_len, label, data, data_len, tmp,
+			       ptk_len) < 0)
+			goto err;
+	}
+
+	wpa_printf(MSG_DEBUG,
+		   "PASN: PTK derivation: SPA=" MACSTR " BSSID=" MACSTR,
+		   MAC2STR(spa), MAC2STR(bssid));
+
+	wpa_hexdump_key(MSG_DEBUG, "PASN: DHss", dhss, dhss_len);
+	wpa_hexdump_key(MSG_DEBUG, "PASN: PMK", pmk, pmk_len);
+	wpa_hexdump_key(MSG_DEBUG, "PASN: PASN-PTK", tmp, ptk_len);
+
+	os_memcpy(ptk->kck, tmp, WPA_PASN_KCK_LEN);
+	wpa_hexdump_key(MSG_DEBUG, "PASN: KCK:", ptk->kck, WPA_PASN_KCK_LEN);
+
+	os_memcpy(ptk->tk, tmp + WPA_PASN_KCK_LEN, ptk->tk_len);
+	wpa_hexdump_key(MSG_DEBUG, "PASN: TK:", ptk->tk, ptk->tk_len);
+
+	if (kdk_len) {
+		os_memcpy(ptk->kdk, tmp + WPA_PASN_KCK_LEN + ptk->tk_len,
+			  ptk->kdk_len);
+		wpa_hexdump_key(MSG_DEBUG, "PASN: KDK:",
+				ptk->kdk, ptk->kdk_len);
+	}
+
+	forced_memzero(tmp, sizeof(tmp));
+	ret = 0;
+err:
+	bin_clear_free(data, data_len);
+	return ret;
+}
+
+
+/*
+ * pasn_mic_len - Returns the MIC length for PASN authentication
+ */
+u8 pasn_mic_len(int akmp, int cipher)
+{
+	if (pasn_use_sha384(akmp, cipher))
+		return 24;
+
+	return 16;
+}
+
+
+/**
+ * pasn_mic - Calculate PASN MIC
+ * @kck: The key confirmation key for the PASN PTKSA
+ * @akmp: Negotiated AKM
+ * @cipher: Negotiated pairwise cipher
+ * @addr1: For the 2nd PASN frame supplicant address; for the 3rd frame the
+ *	BSSID
+ * @addr2: For the 2nd PASN frame the BSSID; for the 3rd frame the supplicant
+ *	address
+ * @data: For calculating the MIC for the 2nd PASN frame, this should hold the
+ *	Beacon frame RSNE + RSNXE. For calculating the MIC for the 3rd PASN
+ *	frame, this should hold the hash of the body of the PASN 1st frame.
+ * @data_len: The length of data
+ * @frame: The body of the PASN frame including the MIC element with the octets
+ *	in the MIC field of the MIC element set to 0.
+ * @frame_len: The length of frame
+ * @mic: Buffer to hold the MIC on success. Should be big enough to handle the
+ *	maximal MIC length
+ * Returns: 0 on success, -1 on failure
+ */
+int pasn_mic(const u8 *kck, int akmp, int cipher,
+	     const u8 *addr1, const u8 *addr2,
+	     const u8 *data, size_t data_len,
+	     const u8 *frame, size_t frame_len, u8 *mic)
+{
+	u8 *buf;
+	u8 hash[SHA384_MAC_LEN];
+	size_t buf_len = 2 * ETH_ALEN + data_len + frame_len;
+	int ret = -1;
+
+	if (!kck) {
+		wpa_printf(MSG_ERROR, "PASN: No KCK for MIC calculation");
+		return -1;
+	}
+
+	if (!data || !data_len) {
+		wpa_printf(MSG_ERROR, "PASN: invalid data for MIC calculation");
+		return -1;
+	}
+
+	if (!frame || !frame_len) {
+		wpa_printf(MSG_ERROR, "PASN: invalid data for MIC calculation");
+		return -1;
+	}
+
+	buf = os_zalloc(buf_len);
+	if (!buf)
+		return -1;
+
+	os_memcpy(buf, addr1, ETH_ALEN);
+	os_memcpy(buf + ETH_ALEN, addr2, ETH_ALEN);
+
+	wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: data", data, data_len);
+	os_memcpy(buf + 2 * ETH_ALEN, data, data_len);
+
+	wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: frame", frame, frame_len);
+	os_memcpy(buf + 2 * ETH_ALEN + data_len, frame, frame_len);
+
+	wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: KCK", kck, WPA_PASN_KCK_LEN);
+	wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: buf", buf, buf_len);
+
+	if (pasn_use_sha384(akmp, cipher)) {
+		wpa_printf(MSG_DEBUG, "PASN: MIC using HMAC-SHA384");
+
+		if (hmac_sha384(kck, WPA_PASN_KCK_LEN, buf, buf_len, hash))
+			goto err;
+
+		os_memcpy(mic, hash, 24);
+		wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: mic: ", mic, 24);
+	} else {
+		wpa_printf(MSG_DEBUG, "PASN: MIC using HMAC-SHA256");
+
+		if (hmac_sha256(kck, WPA_PASN_KCK_LEN, buf, buf_len, hash))
+			goto err;
+
+		os_memcpy(mic, hash, 16);
+		wpa_hexdump_key(MSG_DEBUG, "PASN: MIC: mic: ", mic, 16);
+	}
+
+	ret = 0;
+err:
+	bin_clear_free(buf, buf_len);
+	return ret;
+}
+
+
+/**
+ * pasn_auth_frame_hash - Computes a hash of an Authentication frame body
+ * @akmp: Negotiated AKM
+ * @cipher: Negotiated pairwise cipher
+ * @data: Pointer to the Authentication frame body
+ * @len: Length of the Authentication frame body
+ * @hash: On return would hold the computed hash. Should be big enough to handle
+ *	SHA384.
+ * Returns: 0 on success, -1 on failure
+ */
+int pasn_auth_frame_hash(int akmp, int cipher, const u8 *data, size_t len,
+			 u8 *hash)
+{
+	if (pasn_use_sha384(akmp, cipher)) {
+		wpa_printf(MSG_DEBUG, "PASN: Frame hash using SHA-384");
+		return sha384_vector(1, &data, &len, hash);
+	} else {
+		wpa_printf(MSG_DEBUG, "PASN: Frame hash using SHA-256");
+		return sha256_vector(1, &data, &len, hash);
+	}
+}
+
+#endif /* CONFIG_PASN */
+
+
 static int rsn_selector_to_bitfield(const u8 *s)
 {
 	if (RSN_SELECTOR_GET(s) == RSN_CIPHER_SUITE_NONE)
@@ -1203,6 +1504,10 @@
 #endif /* CONFIG_DPP */
 	if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_OSEN)
 		return WPA_KEY_MGMT_OSEN;
+#ifdef CONFIG_PASN
+	if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_PASN)
+		return WPA_KEY_MGMT_PASN;
+#endif /* CONFIG_PASN */
 	return 0;
 }
 
@@ -1216,7 +1521,8 @@
 
 int wpa_cipher_valid_mgmt_group(int cipher)
 {
-	return cipher == WPA_CIPHER_AES_128_CMAC ||
+	return cipher == WPA_CIPHER_GTK_NOT_USED ||
+		cipher == WPA_CIPHER_AES_128_CMAC ||
 		cipher == WPA_CIPHER_BIP_GMAC_128 ||
 		cipher == WPA_CIPHER_BIP_GMAC_256 ||
 		cipher == WPA_CIPHER_BIP_CMAC_256;
@@ -1823,16 +2129,25 @@
 		      const u8 *snonce, const u8 *anonce,
 		      const u8 *sta_addr, const u8 *bssid,
 		      const u8 *pmk_r1_name,
-		      struct wpa_ptk *ptk, u8 *ptk_name, int akmp, int cipher)
+		      struct wpa_ptk *ptk, u8 *ptk_name, int akmp, int cipher,
+		      size_t kdk_len)
 {
 	u8 buf[2 * WPA_NONCE_LEN + 2 * ETH_ALEN];
 	u8 *pos, hash[32];
 	const u8 *addr[6];
 	size_t len[6];
-	u8 tmp[2 * WPA_KCK_MAX_LEN + 2 * WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN];
+	u8 tmp[2 * WPA_KCK_MAX_LEN + 2 * WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN +
+	       WPA_KDK_MAX_LEN];
 	size_t ptk_len, offset;
 	int use_sha384 = wpa_key_mgmt_sha384(akmp);
 
+	if (kdk_len > WPA_KDK_MAX_LEN) {
+		wpa_printf(MSG_ERROR,
+			   "FT: KDK len=%zu exceeds max supported len",
+			   kdk_len);
+		return -1;
+	}
+
 	/*
 	 * PTK = KDF-PTKLen(PMK-R1, "FT-PTK", SNonce || ANonce ||
 	 *                  BSSID || STA-ADDR)
@@ -1859,8 +2174,9 @@
 	ptk->kek_len = wpa_kek_len(akmp, PMK_LEN);
 	ptk->kek2_len = wpa_kek2_len(akmp);
 	ptk->tk_len = wpa_cipher_key_len(cipher);
+	ptk->kdk_len = kdk_len;
 	ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len +
-		ptk->kck2_len + ptk->kek2_len;
+		ptk->kck2_len + ptk->kek2_len + ptk->kdk_len;
 
 #ifdef CONFIG_SHA384
 	if (use_sha384) {
@@ -1919,6 +2235,8 @@
 	os_memcpy(ptk->kck2, tmp + offset, ptk->kck2_len);
 	offset += ptk->kck2_len;
 	os_memcpy(ptk->kek2, tmp + offset, ptk->kek2_len);
+	offset += ptk->kek2_len;
+	os_memcpy(ptk->kdk, tmp + offset, ptk->kdk_len);
 
 	wpa_hexdump_key(MSG_DEBUG, "FT: KCK", ptk->kck, ptk->kck_len);
 	wpa_hexdump_key(MSG_DEBUG, "FT: KEK", ptk->kek, ptk->kek_len);
@@ -1928,6 +2246,9 @@
 	if (ptk->kek2_len)
 		wpa_hexdump_key(MSG_DEBUG, "FT: KEK2",
 				ptk->kek2, ptk->kek2_len);
+	if (ptk->kdk_len)
+		wpa_hexdump_key(MSG_DEBUG, "FT: KDK", ptk->kdk, ptk->kdk_len);
+
 	wpa_hexdump_key(MSG_DEBUG, "FT: TK", ptk->tk, ptk->tk_len);
 	wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN);
 
@@ -2161,6 +2482,8 @@
 		return "OWE";
 	case WPA_KEY_MGMT_DPP:
 		return "DPP";
+	case WPA_KEY_MGMT_PASN:
+		return "PASN";
 	default:
 		return "UNKNOWN";
 	}
@@ -2589,6 +2912,10 @@
 			val |= WPA_CIPHER_NONE;
 		else if (os_strcmp(start, "GTK_NOT_USED") == 0)
 			val |= WPA_CIPHER_GTK_NOT_USED;
+#if defined(WAPI_ANDROID)
+		else if (os_strcmp(start, "SMS4") == 0)
+			val |= WPA_CIPHER_SMS4;
+#endif 
 		else if (os_strcmp(start, "AES-128-CMAC") == 0)
 			val |= WPA_CIPHER_AES_128_CMAC;
 		else if (os_strcmp(start, "BIP-GMAC-128") == 0)
@@ -2993,6 +3320,16 @@
 			   pos[1] >= sizeof(struct ieee80211_vht_capabilities))
 		{
 			ie->vht_capabilities = pos + 2;
+		} else if (*pos == WLAN_EID_EXTENSION &&
+			   pos[1] >= 1 + IEEE80211_HE_CAPAB_MIN_LEN &&
+			   pos[2] == WLAN_EID_EXT_HE_CAPABILITIES) {
+			ie->he_capabilities = pos + 3;
+			ie->he_capab_len = pos[1] - 1;
+		} else if (*pos == WLAN_EID_EXTENSION &&
+			   pos[1] >= 1 +
+			   sizeof(struct ieee80211_he_6ghz_band_cap) &&
+			   pos[2] == WLAN_EID_EXT_HE_6GHZ_BAND_CAP) {
+			ie->he_6ghz_capabilities = pos + 3;
 		} else if (*pos == WLAN_EID_QOS && pos[1] >= 1) {
 			ie->qosinfo = pos[2];
 		} else if (*pos == WLAN_EID_SUPPORTED_CHANNELS) {
@@ -3032,3 +3369,463 @@
 
 	return ret;
 }
+
+
+#ifdef CONFIG_PASN
+
+/*
+ * wpa_pasn_build_auth_header - Add the MAC header and initialize Authentication
+ * frame for PASN
+ *
+ * @buf: Buffer in which the header will be added
+ * @bssid: The BSSID of the AP
+ * @src: Source address
+ * @dst: Destination address
+ * @trans_seq: Authentication transaction sequence number
+ * @status: Authentication status
+ */
+void wpa_pasn_build_auth_header(struct wpabuf *buf, const u8 *bssid,
+				const u8 *src, const u8 *dst,
+				u8 trans_seq, u16 status)
+{
+	struct ieee80211_mgmt *auth;
+
+	wpa_printf(MSG_DEBUG, "PASN: Add authentication header. trans_seq=%u",
+		   trans_seq);
+
+	auth = wpabuf_put(buf, offsetof(struct ieee80211_mgmt,
+					u.auth.variable));
+
+	auth->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
+					   (WLAN_FC_STYPE_AUTH << 4));
+
+	os_memcpy(auth->da, dst, ETH_ALEN);
+	os_memcpy(auth->sa, src, ETH_ALEN);
+	os_memcpy(auth->bssid, bssid, ETH_ALEN);
+	auth->seq_ctrl = 0;
+
+	auth->u.auth.auth_alg = host_to_le16(WLAN_AUTH_PASN);
+	auth->u.auth.auth_transaction = host_to_le16(trans_seq);
+	auth->u.auth.status_code = host_to_le16(status);
+}
+
+
+/*
+ * wpa_pasn_add_rsne - Add an RSNE for PASN authentication
+ * @buf: Buffer in which the IE will be added
+ * @pmkid: Optional PMKID. Can be NULL.
+ * @akmp: Authentication and key management protocol
+ * @cipher: The cipher suite
+ */
+int wpa_pasn_add_rsne(struct wpabuf *buf, const u8 *pmkid, int akmp, int cipher)
+{
+	struct rsn_ie_hdr *hdr;
+	u32 suite;
+	u16 capab;
+	u8 *pos;
+	u8 rsne_len;
+
+	wpa_printf(MSG_DEBUG, "PASN: Add RSNE");
+
+	rsne_len = sizeof(*hdr) + RSN_SELECTOR_LEN +
+		2 + RSN_SELECTOR_LEN + 2 + RSN_SELECTOR_LEN +
+		2 + RSN_SELECTOR_LEN + 2 + (pmkid ? PMKID_LEN : 0);
+
+	if (wpabuf_tailroom(buf) < rsne_len)
+		return -1;
+	hdr = wpabuf_put(buf, rsne_len);
+	hdr->elem_id = WLAN_EID_RSN;
+	hdr->len = rsne_len - 2;
+	WPA_PUT_LE16(hdr->version, RSN_VERSION);
+	pos = (u8 *) (hdr + 1);
+
+	/* Group addressed data is not allowed */
+	RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
+	pos += RSN_SELECTOR_LEN;
+
+	/* Add the pairwise cipher */
+	WPA_PUT_LE16(pos, 1);
+	pos += 2;
+	suite = wpa_cipher_to_suite(WPA_PROTO_RSN, cipher);
+	RSN_SELECTOR_PUT(pos, suite);
+	pos += RSN_SELECTOR_LEN;
+
+	/* Add the AKM suite */
+	WPA_PUT_LE16(pos, 1);
+	pos += 2;
+
+	switch (akmp) {
+	case WPA_KEY_MGMT_PASN:
+		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PASN);
+		break;
+#ifdef CONFIG_SAE
+	case WPA_KEY_MGMT_SAE:
+		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE);
+		break;
+#endif /* CONFIG_SAE */
+#ifdef CONFIG_FILS
+	case WPA_KEY_MGMT_FILS_SHA256:
+		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FILS_SHA256);
+		break;
+	case WPA_KEY_MGMT_FILS_SHA384:
+		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FILS_SHA384);
+		break;
+#endif /* CONFIG_FILS */
+#ifdef CONFIG_IEEE80211R
+	case WPA_KEY_MGMT_FT_PSK:
+		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_PSK);
+		break;
+	case WPA_KEY_MGMT_FT_IEEE8021X:
+		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X);
+		break;
+	case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
+		RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X_SHA384);
+		break;
+#endif /* CONFIG_IEEE80211R */
+	default:
+		wpa_printf(MSG_ERROR, "PASN: Invalid AKMP=0x%x", akmp);
+		return -1;
+	}
+	pos += RSN_SELECTOR_LEN;
+
+	/* RSN Capabilities: PASN mandates both MFP capable and required */
+	capab = WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR;
+	WPA_PUT_LE16(pos, capab);
+	pos += 2;
+
+	if (pmkid) {
+		wpa_printf(MSG_DEBUG, "PASN: Adding PMKID");
+
+		WPA_PUT_LE16(pos, 1);
+		pos += 2;
+		os_memcpy(pos, pmkid, PMKID_LEN);
+		pos += PMKID_LEN;
+	} else {
+		WPA_PUT_LE16(pos, 0);
+		pos += 2;
+	}
+
+	/* Group addressed management is not allowed */
+	RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
+
+	return 0;
+}
+
+
+/*
+ * wpa_pasn_add_parameter_ie - Add PASN Parameters IE for PASN authentication
+ * @buf: Buffer in which the IE will be added
+ * @pasn_group: Finite Cyclic Group ID for PASN authentication
+ * @wrapped_data_format: Format of the data in the Wrapped Data IE
+ * @pubkey: A buffer holding the local public key. Can be NULL
+ * @compressed: In case pubkey is included, indicates if the public key is
+ *     compressed (only x coordinate is included) or not (both x and y
+ *     coordinates are included)
+ * @comeback: A buffer holding the comeback token. Can be NULL
+ * @after: If comeback is set, defined the comeback time in seconds. -1 to not
+ *	include the Comeback After field (frames from non-AP STA).
+ */
+void wpa_pasn_add_parameter_ie(struct wpabuf *buf, u16 pasn_group,
+			       u8 wrapped_data_format,
+			       const struct wpabuf *pubkey, bool compressed,
+			       const struct wpabuf *comeback, int after)
+{
+	struct pasn_parameter_ie *params;
+
+	wpa_printf(MSG_DEBUG, "PASN: Add PASN Parameters element");
+
+	params = wpabuf_put(buf, sizeof(*params));
+
+	params->id = WLAN_EID_EXTENSION;
+	params->len = sizeof(*params) - 2;
+	params->id_ext = WLAN_EID_EXT_PASN_PARAMS;
+	params->control = 0;
+	params->wrapped_data_format = wrapped_data_format;
+
+	if (comeback) {
+		wpa_printf(MSG_DEBUG, "PASN: Adding comeback data");
+
+		/*
+		 * 2 octets for the 'after' field + 1 octet for the length +
+		 * actual cookie data
+		 */
+		if (after >= 0)
+			params->len += 2;
+		params->len += 1 + wpabuf_len(comeback);
+		params->control |= WPA_PASN_CTRL_COMEBACK_INFO_PRESENT;
+
+		if (after >= 0)
+			wpabuf_put_le16(buf, after);
+		wpabuf_put_u8(buf, wpabuf_len(comeback));
+		wpabuf_put_buf(buf, comeback);
+	}
+
+	if (pubkey) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: Adding public key and group ID %u",
+			   pasn_group);
+
+		/*
+		 * 2 octets for the finite cyclic group + 2 octets public key
+		 * length + 1 octet for the compressed/uncompressed indication +
+		 * the actual key.
+		 */
+		params->len += 2 + 1 + 1 + wpabuf_len(pubkey);
+		params->control |= WPA_PASN_CTRL_GROUP_AND_KEY_PRESENT;
+
+		wpabuf_put_le16(buf, pasn_group);
+
+		/*
+		 * The first octet indicates whether the public key is
+		 * compressed, as defined in RFC 5480 section 2.2.
+		 */
+		wpabuf_put_u8(buf, wpabuf_len(pubkey) + 1);
+		wpabuf_put_u8(buf, compressed ? WPA_PASN_PUBKEY_COMPRESSED_0 :
+			      WPA_PASN_PUBKEY_UNCOMPRESSED);
+
+		wpabuf_put_buf(buf, pubkey);
+	}
+}
+
+/*
+ * wpa_pasn_add_wrapped_data - Add a Wrapped Data IE to PASN Authentication
+ * frame. If needed, the Wrapped Data IE would be fragmented.
+ *
+ * @buf: Buffer in which the IE will be added
+ * @wrapped_data_buf: Buffer holding the wrapped data
+ */
+int wpa_pasn_add_wrapped_data(struct wpabuf *buf,
+			      struct wpabuf *wrapped_data_buf)
+{
+	const u8 *data;
+	size_t data_len;
+	u8 len;
+
+	if (!wrapped_data_buf)
+		return 0;
+
+	wpa_printf(MSG_DEBUG, "PASN: Add wrapped data");
+
+	data = wpabuf_head_u8(wrapped_data_buf);
+	data_len = wpabuf_len(wrapped_data_buf);
+
+	/* nothing to add */
+	if (!data_len)
+		return 0;
+
+	if (data_len <= 254)
+		len = 1 + data_len;
+	else
+		len = 255;
+
+	if (wpabuf_tailroom(buf) < 3 + data_len)
+		return -1;
+
+	wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
+	wpabuf_put_u8(buf, len);
+	wpabuf_put_u8(buf, WLAN_EID_EXT_WRAPPED_DATA);
+	wpabuf_put_data(buf, data, len - 1);
+
+	data += len - 1;
+	data_len -= len - 1;
+
+	while (data_len) {
+		if (wpabuf_tailroom(buf) < 1 + data_len)
+			return -1;
+		wpabuf_put_u8(buf, WLAN_EID_FRAGMENT);
+		len = data_len > 255 ? 255 : data_len;
+		wpabuf_put_u8(buf, len);
+		wpabuf_put_data(buf, data, len);
+		data += len;
+		data_len -= len;
+	}
+
+	return 0;
+}
+
+
+/*
+ * wpa_pasn_validate_rsne - Validate PSAN specific data of RSNE
+ * @data: Parsed representation of an RSNE
+ * Returns -1 for invalid data; otherwise 0
+ */
+int wpa_pasn_validate_rsne(const struct wpa_ie_data *data)
+{
+	u16 capab = WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR;
+
+	if (data->proto != WPA_PROTO_RSN)
+		return -1;
+
+	if ((data->capabilities & capab) != capab) {
+		wpa_printf(MSG_DEBUG, "PASN: Invalid RSNE capabilities");
+		return -1;
+	}
+
+	if (!data->has_group || data->group_cipher != WPA_CIPHER_GTK_NOT_USED) {
+		wpa_printf(MSG_DEBUG, "PASN: Invalid group data cipher");
+		return -1;
+	}
+
+	if (!data->has_pairwise || !data->pairwise_cipher ||
+	    (data->pairwise_cipher & (data->pairwise_cipher - 1))) {
+		wpa_printf(MSG_DEBUG, "PASN: No valid pairwise suite");
+		return -1;
+	}
+
+	switch (data->key_mgmt) {
+#ifdef CONFIG_SAE
+	case WPA_KEY_MGMT_SAE:
+	/* fall through */
+#endif /* CONFIG_SAE */
+#ifdef CONFIG_FILS
+	case WPA_KEY_MGMT_FILS_SHA256:
+	case WPA_KEY_MGMT_FILS_SHA384:
+	/* fall through */
+#endif /* CONFIG_FILS */
+#ifdef CONFIG_IEEE80211R
+	case WPA_KEY_MGMT_FT_PSK:
+	case WPA_KEY_MGMT_FT_IEEE8021X:
+	case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
+	/* fall through */
+#endif /* CONFIG_IEEE80211R */
+	case WPA_KEY_MGMT_PASN:
+		break;
+	default:
+		wpa_printf(MSG_ERROR, "PASN: invalid key_mgmt: 0x%0x",
+			   data->key_mgmt);
+		return -1;
+	}
+
+	if (data->mgmt_group_cipher != WPA_CIPHER_GTK_NOT_USED) {
+		wpa_printf(MSG_DEBUG, "PASN: Invalid group mgmt cipher");
+		return -1;
+	}
+
+	if (data->num_pmkid > 1) {
+		wpa_printf(MSG_DEBUG, "PASN: Invalid number of PMKIDs");
+		return -1;
+	}
+
+	return 0;
+}
+
+
+/*
+ * wpa_pasn_parse_parameter_ie - Validates PASN Parameters IE
+ * @data: Pointer to the PASN Parameters IE (starting with the EID).
+ * @len: Length of the data in the PASN Parameters IE
+ * @from_ap: Whether this was received from an AP
+ * @pasn_params: On successful return would hold the parsed PASN parameters.
+ * Returns: -1 for invalid data; otherwise 0
+ *
+ * Note: On successful return, the pointers in &pasn_params point to the data in
+ * the IE and are not locally allocated (so they should not be freed etc.).
+ */
+int wpa_pasn_parse_parameter_ie(const u8 *data, u8 len, bool from_ap,
+				struct wpa_pasn_params_data *pasn_params)
+{
+	struct pasn_parameter_ie *params = (struct pasn_parameter_ie *) data;
+	const u8 *pos = (const u8 *) (params + 1);
+
+	if (!pasn_params) {
+		wpa_printf(MSG_DEBUG, "PASN: Invalid params");
+		return -1;
+	}
+
+	if (!params || ((size_t) (params->len + 2) < sizeof(*params)) ||
+	    len < sizeof(*params) || params->len + 2 != len) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: Invalid parameters IE. len=(%u, %u)",
+			   params ? params->len : 0, len);
+		return -1;
+	}
+
+	os_memset(pasn_params, 0, sizeof(*pasn_params));
+
+	switch (params->wrapped_data_format) {
+	case WPA_PASN_WRAPPED_DATA_NO:
+	case WPA_PASN_WRAPPED_DATA_SAE:
+	case WPA_PASN_WRAPPED_DATA_FILS_SK:
+	case WPA_PASN_WRAPPED_DATA_FT:
+		break;
+	default:
+		wpa_printf(MSG_DEBUG, "PASN: Invalid wrapped data format");
+		return -1;
+	}
+
+	pasn_params->wrapped_data_format = params->wrapped_data_format;
+
+	len -= sizeof(*params);
+
+	if (params->control & WPA_PASN_CTRL_COMEBACK_INFO_PRESENT) {
+		if (from_ap) {
+			if (len < 2) {
+				wpa_printf(MSG_DEBUG,
+					   "PASN: Invalid Parameters IE: Truncated Comeback After");
+				return -1;
+			}
+			pasn_params->after = WPA_GET_LE16(pos);
+			pos += 2;
+			len -= 2;
+		}
+
+		if (len < 1 || len < 1 + *pos) {
+			wpa_printf(MSG_DEBUG,
+				   "PASN: Invalid Parameters IE: comeback len");
+			return -1;
+		}
+
+		pasn_params->comeback_len = *pos++;
+		len--;
+		pasn_params->comeback = pos;
+		len -=  pasn_params->comeback_len;
+		pos += pasn_params->comeback_len;
+	}
+
+	if (params->control & WPA_PASN_CTRL_GROUP_AND_KEY_PRESENT) {
+		if (len < 3 || len < 3 + pos[2]) {
+			wpa_printf(MSG_DEBUG,
+				   "PASN: Invalid Parameters IE: group and key");
+			return -1;
+		}
+
+		pasn_params->group = WPA_GET_LE16(pos);
+		pos += 2;
+		len -= 2;
+		pasn_params->pubkey_len = *pos++;
+		len--;
+		pasn_params->pubkey = pos;
+		len -= pasn_params->pubkey_len;
+		pos += pasn_params->pubkey_len;
+	}
+
+	if (len) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: Invalid Parameters IE. Bytes left=%u", len);
+		return -1;
+	}
+
+	return 0;
+}
+
+
+void wpa_pasn_add_rsnxe(struct wpabuf *buf, u16 capab)
+{
+	size_t flen;
+
+	flen = (capab & 0xff00) ? 2 : 1;
+	if (!capab)
+		return; /* no supported extended RSN capabilities */
+	if (wpabuf_tailroom(buf) < 2 + flen)
+		return;
+	capab |= flen - 1; /* bit 0-3 = Field length (n - 1) */
+
+	wpabuf_put_u8(buf, WLAN_EID_RSNX);
+	wpabuf_put_u8(buf, flen);
+	wpabuf_put_u8(buf, capab & 0x00ff);
+	capab >>= 8;
+	if (capab)
+		wpabuf_put_u8(buf, capab);
+}
+
+#endif /* CONFIG_PASN */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/wpa_common.h b/src/lynq/packages/thirdpart/lynq-wg870/src/common/wpa_common.h
index 07f8d67..9d83f36 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/wpa_common.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/wpa_common.h
@@ -19,6 +19,9 @@
 #define WPA_KEY_RSC_LEN 8
 #define WPA_GMK_LEN 32
 #define WPA_GTK_MAX_LEN 32
+#define WPA_PASN_PMK_LEN 32
+#define WPA_PASN_MAX_MIC_LEN 24
+#define WPA_MAX_RSNXE_LEN 4
 
 #define OWE_DH_GROUP 19
 
@@ -78,6 +81,9 @@
 #define RSN_AUTH_KEY_MGMT_FT_FILS_SHA256 RSN_SELECTOR(0x00, 0x0f, 0xac, 16)
 #define RSN_AUTH_KEY_MGMT_FT_FILS_SHA384 RSN_SELECTOR(0x00, 0x0f, 0xac, 17)
 #define RSN_AUTH_KEY_MGMT_OWE RSN_SELECTOR(0x00, 0x0f, 0xac, 18)
+
+#define RSN_AUTH_KEY_MGMT_PASN RSN_SELECTOR(0x00, 0x0f, 0xac, 21)
+
 #define RSN_AUTH_KEY_MGMT_CCKM RSN_SELECTOR(0x00, 0x40, 0x96, 0x00)
 #define RSN_AUTH_KEY_MGMT_OSEN RSN_SELECTOR(0x50, 0x6f, 0x9a, 0x01)
 #define RSN_AUTH_KEY_MGMT_DPP RSN_SELECTOR(0x50, 0x6f, 0x9a, 0x02)
@@ -227,8 +233,11 @@
 #define WPA_KCK_MAX_LEN 32
 #define WPA_KEK_MAX_LEN 64
 #define WPA_TK_MAX_LEN 32
+#define WPA_KDK_MAX_LEN 32
 #define FILS_ICK_MAX_LEN 48
 #define FILS_FT_MAX_LEN 48
+#define WPA_PASN_KCK_LEN 32
+#define WPA_PASN_MIC_MAX_LEN 24
 
 /**
  * struct wpa_ptk - WPA Pairwise Transient Key
@@ -240,11 +249,13 @@
 	u8 tk[WPA_TK_MAX_LEN]; /* Temporal Key (TK) */
 	u8 kck2[WPA_KCK_MAX_LEN]; /* FT reasoc Key Confirmation Key (KCK2) */
 	u8 kek2[WPA_KEK_MAX_LEN]; /* FT reassoc Key Encryption Key (KEK2) */
+	u8 kdk[WPA_KDK_MAX_LEN]; /* Key Derivation Key */
 	size_t kck_len;
 	size_t kek_len;
 	size_t tk_len;
 	size_t kck2_len;
 	size_t kek2_len;
+	size_t kdk_len;
 	int installed; /* 1 if key has already been installed to driver */
 };
 
@@ -409,7 +420,7 @@
 		   const u8 *addr1, const u8 *addr2,
 		   const u8 *nonce1, const u8 *nonce2,
 		   struct wpa_ptk *ptk, int akmp, int cipher,
-		   const u8 *z, size_t z_len);
+		   const u8 *z, size_t z_len, size_t kdk_len);
 int fils_rmsk_to_pmk(int akmp, const u8 *rmsk, size_t rmsk_len,
 		     const u8 *snonce, const u8 *anonce, const u8 *dh_ss,
 		     size_t dh_ss_len, u8 *pmk, size_t *pmk_len);
@@ -419,7 +430,7 @@
 		    const u8 *snonce, const u8 *anonce, const u8 *dhss,
 		    size_t dhss_len, struct wpa_ptk *ptk,
 		    u8 *ick, size_t *ick_len, int akmp, int cipher,
-		    u8 *fils_ft, size_t *fils_ft_len);
+		    u8 *fils_ft, size_t *fils_ft_len, size_t kdk_len);
 int fils_key_auth_sk(const u8 *ick, size_t ick_len, const u8 *snonce,
 		     const u8 *anonce, const u8 *sta_addr, const u8 *bssid,
 		     const u8 *g_sta, size_t g_sta_len,
@@ -450,7 +461,8 @@
 int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, size_t pmk_r1_len, const u8 *snonce,
 		      const u8 *anonce, const u8 *sta_addr, const u8 *bssid,
 		      const u8 *pmk_r1_name,
-		      struct wpa_ptk *ptk, u8 *ptk_name, int akmp, int cipher);
+		      struct wpa_ptk *ptk, u8 *ptk_name, int akmp, int cipher,
+		      size_t kdk_len);
 #endif /* CONFIG_IEEE80211R */
 
 struct wpa_ie_data {
@@ -538,6 +550,38 @@
 	size_t rsnxe_len;
 };
 
+/* IEEE P802.11az/D2.6 - 9.4.2.303 PASN Parameters element */
+#define WPA_PASN_CTRL_COMEBACK_INFO_PRESENT BIT(0)
+#define WPA_PASN_CTRL_GROUP_AND_KEY_PRESENT BIT(1)
+
+#define WPA_PASN_WRAPPED_DATA_NO      0
+#define WPA_PASN_WRAPPED_DATA_FT      1
+#define WPA_PASN_WRAPPED_DATA_FILS_SK 2
+#define WPA_PASN_WRAPPED_DATA_SAE     3
+
+struct pasn_parameter_ie {
+	u8 id;
+	u8 len;
+	u8 id_ext;
+	u8 control; /* WPA_PASN_CTRL_* */
+	u8 wrapped_data_format; /* WPA_PASN_WRAPPED_DATA_* */
+} STRUCT_PACKED;
+
+struct wpa_pasn_params_data {
+	u8 wrapped_data_format;
+	u16 after;
+	u8 comeback_len;
+	const u8 *comeback;
+	u16 group;
+	u8 pubkey_len;
+	const u8 *pubkey;
+};
+
+/* See RFC 5480 section 2.2 */
+#define WPA_PASN_PUBKEY_COMPRESSED_0 0x02
+#define WPA_PASN_PUBKEY_COMPRESSED_1 0x03
+#define WPA_PASN_PUBKEY_UNCOMPRESSED 0x04
+
 int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse,
 		     int use_sha384);
 
@@ -584,6 +628,9 @@
 	size_t ext_supp_rates_len;
 	const u8 *ht_capabilities;
 	const u8 *vht_capabilities;
+	const u8 *he_capabilities;
+	size_t he_capab_len;
+	const u8 *he_6ghz_capabilities;
 	const u8 *supp_channels;
 	size_t supp_channels_len;
 	const u8 *supp_oper_classes;
@@ -625,4 +672,41 @@
 int wpa_use_aes_key_wrap(int akmp);
 int fils_domain_name_hash(const char *domain, u8 *hash);
 
+int pasn_pmk_to_ptk(const u8 *pmk, size_t pmk_len,
+		    const u8 *spa, const u8 *bssid,
+		    const u8 *dhss, size_t dhss_len,
+		    struct wpa_ptk *ptk, int akmp, int cipher,
+		    size_t kdk_len);
+
+u8 pasn_mic_len(int akmp, int cipher);
+
+int pasn_mic(const u8 *kck, int akmp, int cipher,
+	     const u8 *addr1, const u8 *addr2,
+	     const u8 *data, size_t data_len,
+	     const u8 *frame, size_t frame_len, u8 *mic);
+
+int pasn_auth_frame_hash(int akmp, int cipher, const u8 *data, size_t len,
+			 u8 *hash);
+
+void wpa_pasn_build_auth_header(struct wpabuf *buf, const u8 *bssid,
+				const u8 *src, const u8 *dst,
+				u8 trans_seq, u16 status);
+
+int wpa_pasn_add_rsne(struct wpabuf *buf, const u8 *pmkid,
+		      int akmp, int cipher);
+
+void wpa_pasn_add_parameter_ie(struct wpabuf *buf, u16 pasn_group,
+			       u8 wrapped_data_format,
+			       const struct wpabuf *pubkey, bool compressed,
+			       const struct wpabuf *comeback, int after);
+
+int wpa_pasn_add_wrapped_data(struct wpabuf *buf,
+			      struct wpabuf *wrapped_data_buf);
+
+int wpa_pasn_validate_rsne(const struct wpa_ie_data *data);
+int wpa_pasn_parse_parameter_ie(const u8 *data, u8 len, bool from_ap,
+				struct wpa_pasn_params_data *pasn_params);
+
+void wpa_pasn_add_rsnxe(struct wpabuf *buf, u16 capab);
+
 #endif /* WPA_COMMON_H */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/common/wpa_ctrl.h b/src/lynq/packages/thirdpart/lynq-wg870/src/common/wpa_ctrl.h
index acc2d6c..2c7ec04 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/common/wpa_ctrl.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/common/wpa_ctrl.h
@@ -126,6 +126,10 @@
 #define WPA_EVENT_FREQ_CONFLICT "CTRL-EVENT-FREQ-CONFLICT "
 /** Frequency ranges that the driver recommends to avoid */
 #define WPA_EVENT_AVOID_FREQ "CTRL-EVENT-AVOID-FREQ "
+/** A new network profile was added (followed by network entry id) */
+#define WPA_EVENT_NETWORK_ADDED "CTRL-EVENT-NETWORK-ADDED "
+/** A network profile was removed (followed by prior network entry id) */
+#define WPA_EVENT_NETWORK_REMOVED "CTRL-EVENT-NETWORK-REMOVED "
 /** Result of MSCS setup */
 #define WPA_EVENT_MSCS_RESULT "CTRL-EVENT-MSCS-RESULT "
 /** WPS overlap detected in PBC mode */
@@ -157,6 +161,10 @@
 #define WPS_EVENT_ENROLLEE_SEEN "WPS-ENROLLEE-SEEN "
 
 #define WPS_EVENT_OPEN_NETWORK "WPS-OPEN-NETWORK "
+/** Result of SCS setup */
+#define WPA_EVENT_SCS_RESULT "CTRL-EVENT-SCS-RESULT "
+/* Event indicating DSCP policy */
+#define WPA_EVENT_DSCP_POLICY "CTRL-EVENT-DSCP-POLICY "
 
 /* WPS ER events */
 #define WPS_EVENT_ER_AP_ADD "WPS-ER-AP-ADD "
@@ -271,7 +279,7 @@
 #define P2P_EVENT_P2PS_PROVISION_DONE "P2PS-PROV-DONE "
 
 #define INTERWORKING_AP "INTERWORKING-AP "
-#define INTERWORKING_BLACKLISTED "INTERWORKING-BLACKLISTED "
+#define INTERWORKING_EXCLUDED "INTERWORKING-BLACKLISTED "
 #define INTERWORKING_NO_MATCH "INTERWORKING-NO-MATCH "
 #define INTERWORKING_ALREADY_CONNECTED "INTERWORKING-ALREADY-CONNECTED "
 #define INTERWORKING_SELECTED "INTERWORKING-SELECTED "
@@ -404,10 +412,16 @@
  * frame=<saqueryreq/saqueryresp> error=<error string> */
 #define OCV_FAILURE "OCV-FAILURE "
 
+/* Event triggered for received management frame */
+#define AP_MGMT_FRAME_RECEIVED "AP-MGMT-FRAME-RECEIVED "
+
 #ifndef BIT
 #define BIT(x) (1U << (x))
 #endif
 
+/* PASN authentication status */
+#define PASN_AUTH_STATUS "PASN-AUTH-STATUS "
+
 /* BSS command information masks */
 
 #define WPA_BSS_MASK_ALL		0xFFFDFFFF
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/crypto.h b/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/crypto.h
index 7d2ebd6..e6150b0 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/crypto.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/crypto.h
@@ -495,6 +495,13 @@
  */
 int crypto_get_random(void *buf, size_t len);
 
+/**
+ * crypto_pkcs7_get_certificates - Extract X.509 certificates from PKCS#7 data
+ * @pkcs7: DER encoded PKCS#7 data
+ * Returns: Buffer of the extracted PEM X.509 certificates or %NULL on failure
+ */
+struct wpabuf * crypto_pkcs7_get_certificates(const struct wpabuf *pkcs7);
+
 
 /**
  * struct crypto_bignum - bignum
@@ -714,6 +721,14 @@
 struct crypto_ec;
 
 /**
+ * struct crypto_ec_point - Elliptic curve point
+ *
+ * Internal data structure for EC implementation to represent a point. The
+ * contents is specific to the used crypto library.
+ */
+struct crypto_ec_point;
+
+/**
  * crypto_ec_init - Initialize elliptic curve context
  * @group: Identifying number for the ECC group (IANA "Group Description"
  *	attribute registrty for RFC 2409)
@@ -762,16 +777,26 @@
  */
 const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e);
 
+/**
+ * crypto_ec_get_a - Get 'a' coefficient of an EC group's curve
+ * @e: EC context from crypto_ec_init()
+ * Returns: 'a' coefficient (bignum) of the group
+ */
 const struct crypto_bignum * crypto_ec_get_a(struct crypto_ec *e);
+
+/**
+ * crypto_ec_get_b - Get 'b' coeffiecient of an EC group's curve
+ * @e: EC context from crypto_ec_init()
+ * Returns: 'b' coefficient (bignum) of the group
+ */
 const struct crypto_bignum * crypto_ec_get_b(struct crypto_ec *e);
 
 /**
- * struct crypto_ec_point - Elliptic curve point
- *
- * Internal data structure for EC implementation to represent a point. The
- * contents is specific to the used crypto library.
+ * crypto_ec_get_generator - Get generator point of the EC group's curve
+ * @e: EC context from crypto_ec_init()
+ * Returns: Pointer to generator point
  */
-struct crypto_ec_point;
+const struct crypto_ec_point * crypto_ec_get_generator(struct crypto_ec *e);
 
 /**
  * crypto_ec_point_init - Initialize data for an EC point
@@ -858,18 +883,6 @@
 int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p);
 
 /**
- * crypto_ec_point_solve_y_coord - Solve y coordinate for an x coordinate
- * @e: EC context from crypto_ec_init()
- * @p: EC point to use for the returning the result
- * @x: x coordinate
- * @y_bit: y-bit (0 or 1) for selecting the y value to use
- * Returns: 0 on success, -1 on failure
- */
-int crypto_ec_point_solve_y_coord(struct crypto_ec *e,
-				  struct crypto_ec_point *p,
-				  const struct crypto_bignum *x, int y_bit);
-
-/**
  * crypto_ec_point_compute_y_sqr - Compute y^2 = x^3 + ax + b
  * @e: EC context from crypto_ec_init()
  * @x: x coordinate
@@ -909,25 +922,357 @@
 			const struct crypto_ec_point *a,
 			const struct crypto_ec_point *b);
 
-struct crypto_ecdh;
+/**
+ * crypto_ec_point_debug_print - Dump EC point to debug log
+ * @e: EC context from crypto_ec_init()
+ * @p: EC point
+ * @title: Name of the EC point in the trace
+ */
+void crypto_ec_point_debug_print(const struct crypto_ec *e,
+				 const struct crypto_ec_point *p,
+				 const char *title);
 
-struct crypto_ecdh * crypto_ecdh_init(int group);
-struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y);
-struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y,
-					const u8 *key, size_t len);
-void crypto_ecdh_deinit(struct crypto_ecdh *ecdh);
-size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh);
-
+/**
+ * struct crypto_ec_key - Elliptic curve key pair
+ *
+ * Internal data structure for EC key pair. The contents is specific to the used
+ * crypto library.
+ */
 struct crypto_ec_key;
 
+/**
+ * struct crypto_ecdh - Elliptic Curve Diffie–Hellman context
+ *
+ * Internal data structure for ECDH. The contents is specific to the used
+ * crypto library.
+ */
+struct crypto_ecdh;
+
+/**
+ * crypto_ecdh_init - Initialize elliptic curve Diffie–Hellman context
+ * @group: Identifying number for the ECC group (IANA "Group Description"
+ *	attribute registry for RFC 2409)
+ * This function generates an ephemeral key pair.
+ * Returns: Pointer to ECDH context or %NULL on failure
+ */
+struct crypto_ecdh * crypto_ecdh_init(int group);
+
+/**
+ * crypto_ecdh_init2 - Initialize elliptic curve Diffie–Hellman context with a
+ * given EC key
+ * @group: Identifying number for the ECC group (IANA "Group Description"
+ *	attribute registry for RFC 2409)
+ * @own_key: Our own EC Key
+ * Returns: Pointer to ECDH context or %NULL on failure
+ */
+struct crypto_ecdh * crypto_ecdh_init2(int group,
+				       struct crypto_ec_key *own_key);
+
+/**
+ * crypto_ecdh_get_pubkey - Retrieve public key from ECDH context
+ * @ecdh: ECDH context from crypto_ecdh_init() or crypto_ecdh_init2()
+ * @inc_y: Whether public key should include y coordinate (explicit form)
+ * or not (compressed form)
+ * Returns: Binary data f the public key or %NULL on failure
+ */
+struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y);
+
+/**
+ * crypto_ecdh_set_peerkey - Compute ECDH secret
+ * @ecdh: ECDH context from crypto_ecdh_init() or crypto_ecdh_init2()
+ * @inc_y: Whether peer's public key includes y coordinate (explicit form)
+ * or not (compressed form)
+ * @key: Binary data of the peer's public key
+ * @len: Length of the @key buffer
+ * Returns: Binary data with the EDCH secret or %NULL on failure
+ */
+struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y,
+					const u8 *key, size_t len);
+
+/**
+ * crypto_ecdh_deinit - Free ECDH context
+ * @ecdh: ECDH context from crypto_ecdh_init() or crypto_ecdh_init2()
+ */
+void crypto_ecdh_deinit(struct crypto_ecdh *ecdh);
+
+/**
+ * crypto_ecdh_prime_len - Get length of the prime in octets
+ * @e: ECDH context from crypto_ecdh_init()
+ * Returns: Length of the prime defining the group
+ */
+size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh);
+
+/**
+ * crypto_ec_key_parse_priv - Initialize EC key pair from ECPrivateKey ASN.1
+ * @der: DER encoding of ASN.1 ECPrivateKey
+ * @der_len: Length of @der buffer
+ * Returns: EC key or %NULL on failure
+ */
 struct crypto_ec_key * crypto_ec_key_parse_priv(const u8 *der, size_t der_len);
+
+/**
+ * crypto_ec_key_parse_pub - Initialize EC key pair from SubjectPublicKeyInfo ASN.1
+ * @der: DER encoding of ASN.1 SubjectPublicKeyInfo
+ * @der_len: Length of @der buffer
+ * Returns: EC key or %NULL on failure
+ */
 struct crypto_ec_key * crypto_ec_key_parse_pub(const u8 *der, size_t der_len);
+
+/**
+ * crypto_ec_key_set_pub - Initialize an EC public key from EC point coordinates
+ * @group: Identifying number for the ECC group
+ * @x: X coordinate of the public key
+ * @y: Y coordinate of the public key
+ * @len: Length of @x and @y buffer
+ * Returns: EC key or %NULL on failure
+ *
+ * This function initialize an EC key from public key coordinates, in big endian
+ * byte order padded to the length of the prime defining the group.
+ */
+struct crypto_ec_key * crypto_ec_key_set_pub(int group, const u8 *x,
+					     const u8 *y, size_t len);
+
+/**
+ * crypto_ec_key_set_pub_point - Initialize an EC public key from EC point
+ * @e: EC context from crypto_ec_init()
+ * @pub: Public key point
+ * Returns: EC key or %NULL on failure
+ */
+struct crypto_ec_key *
+crypto_ec_key_set_pub_point(struct crypto_ec *e,
+			    const struct crypto_ec_point *pub);
+
+/**
+ * crypto_ec_key_gen - Generate EC key pair
+ * @group: Identifying number for the ECC group
+ * Returns: EC key or %NULL on failure
+ */
+struct crypto_ec_key * crypto_ec_key_gen(int group);
+
+/**
+ * crypto_ec_key_deinit - Free EC key
+ * @key: EC key from crypto_ec_key_parse_pub/priv() or crypto_ec_key_gen()
+ */
 void crypto_ec_key_deinit(struct crypto_ec_key *key);
+
+/**
+ * crypto_ec_key_get_subject_public_key - Get SubjectPublicKeyInfo ASN.1 for an EC key
+ * @key: EC key from crypto_ec_key_parse/set_pub/priv() or crypto_ec_key_gen()
+ * Returns: Buffer with DER encoding of ASN.1 SubjectPublicKeyInfo or %NULL on failure
+ */
 struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key);
+
+/**
+ * crypto_ec_key_get_ecprivate_key - Get ECPrivateKey ASN.1 for a EC key
+ * @key: EC key from crypto_ec_key_parse_priv() or crypto_ec_key_gen()
+ * @include_pub: Whether to include public key in the ASN.1 sequence
+ * Returns: Buffer with DER encoding of ASN.1 ECPrivateKey or %NULL on failure
+ */
+struct wpabuf * crypto_ec_key_get_ecprivate_key(struct crypto_ec_key *key,
+						bool include_pub);
+
+/**
+ * crypto_ec_key_get_pubkey_point - Get public key point coordinates
+ * @key: EC key from crypto_ec_key_parse/set_pub() or crypto_ec_key_parse_priv()
+ * @prefix: Whether output buffer should include the octet to indicate
+ * coordinate form (as defined for SubjectPublicKeyInfo)
+ * Returns: Buffer with coordinates of public key in uncompressed form or %NULL
+ * on failure
+ */
+struct wpabuf * crypto_ec_key_get_pubkey_point(struct crypto_ec_key *key,
+					       int prefix);
+
+/**
+ * crypto_ec_key_get_public_key - Get EC public key as an EC point
+ * @key: EC key from crypto_ec_key_parse/set_pub() or crypto_ec_key_parse_priv()
+ * Returns: Public key as an EC point or %NULL on failure
+ */
+const struct crypto_ec_point *
+crypto_ec_key_get_public_key(struct crypto_ec_key *key);
+
+/**
+ * crypto_ec_key_get_private_key - Get EC private key as a bignum
+ * @key: EC key from crypto_ec_key_parse/set_pub() or crypto_ec_key_parse_priv()
+ * Returns: Private key as a bignum or %NULL on failure
+ */
+const struct crypto_bignum *
+crypto_ec_key_get_private_key(struct crypto_ec_key *key);
+
+/**
+ * crypto_ec_key_sign - Sign a buffer with an EC key
+ * @key: EC key from crypto_ec_key_parse_priv() or crypto_ec_key_gen()
+ * @data: Data to sign
+ * @len: Length of @data buffer
+ * Returns: Buffer with DER encoding of ASN.1 Ecdsa-Sig-Value or %NULL on failure
+ */
 struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data,
 				   size_t len);
+
+/**
+ * crypto_ec_key_sign_r_s - Sign a buffer with an EC key
+ * @key: EC key from crypto_ec_key_parse_priv() or crypto_ec_key_gen()
+ * @data: Data to sign
+ * @len: Length of @data buffer
+ * Returns: Buffer with the concatenated r and s values. Each value is in big
+ * endian byte order padded to the length of the prime defining the group of
+ * the key.
+ */
+struct wpabuf * crypto_ec_key_sign_r_s(struct crypto_ec_key *key,
+				       const u8 *data, size_t len);
+
+/**
+ * crypto_ec_key_verify_signature - Verify ECDSA signature
+ * @key: EC key from crypto_ec_key_parse/set_pub() or crypto_ec_key_gen()
+ * @data: Data to be signed
+ * @len: Length of @data buffer
+ * @sig: DER encoding of ASN.1 Ecdsa-Sig-Value
+ * @sig_len: Length of @sig buffer
+ * Returns: 1 if signature is valid, 0 if signature is invalid and -1 on failure
+ */
 int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data,
 				   size_t len, const u8 *sig, size_t sig_len);
+
+/**
+ * crypto_ec_key_verify_signature_r_s - Verify signature
+ * @key: EC key from crypto_ec_key_parse/set_pub() or crypto_ec_key_gen()
+ * @data: Data to signed
+ * @len: Length of @data buffer
+ * @r: Binary data, in big endian byte order, of the 'r' field of the ECDSA
+ * signature.
+ * @s: Binary data, in big endian byte order, of the 's' field of the ECDSA
+ * signature.
+ * @r_len: Length of @r buffer
+ * @s_len: Length of @s buffer
+ * Returns: 1 if signature is valid, 0 if signature is invalid, or -1 on failure
+ */
+int crypto_ec_key_verify_signature_r_s(struct crypto_ec_key *key,
+				       const u8 *data, size_t len,
+				       const u8 *r, size_t r_len,
+				       const u8 *s, size_t s_len);
+
+/**
+ * crypto_ec_key_group - Get IANA group identifier for an EC key
+ * @key: EC key from crypto_ec_key_parse/set_pub/priv() or crypto_ec_key_gen()
+ * Returns: IANA group identifier and -1 on failure
+ */
 int crypto_ec_key_group(struct crypto_ec_key *key);
 
+/**
+ * crypto_ec_key_cmp - Compare two EC public keys
+ * @key1: Key 1
+ * @key2: Key 2
+ * Returns: 0 if public keys are identical, -1 otherwise
+ */
+int crypto_ec_key_cmp(struct crypto_ec_key *key1, struct crypto_ec_key *key2);
+
+/**
+ * crypto_ec_key_debug_print - Dump EC key to debug log
+ * @key:  EC key from crypto_ec_key_parse/set_pub/priv() or crypto_ec_key_gen()
+ * @title: Name of the EC point in the trace
+ */
+void crypto_ec_key_debug_print(const struct crypto_ec_key *key,
+			       const char *title);
+
+/**
+ * struct crypto_csr - Certification Signing Request
+ *
+ * Internal data structure for CSR. The contents is specific to the used
+ * crypto library.
+ * For now it is assumed that only an EC public key can be used
+ */
+struct crypto_csr;
+
+/**
+ * enum crypto_csr_name - CSR name type
+ */
+enum crypto_csr_name {
+	CSR_NAME_CN,
+	CSR_NAME_SN,
+	CSR_NAME_C,
+	CSR_NAME_O,
+	CSR_NAME_OU,
+};
+
+/**
+ * enum crypto_csr_attr - CSR attribute
+ */
+enum crypto_csr_attr {
+	CSR_ATTR_CHALLENGE_PASSWORD,
+};
+
+/**
+ * crypto_csr_init - Initialize empty CSR
+ * Returns: Pointer to CSR data or %NULL on failure
+ */
+struct crypto_csr * crypto_csr_init(void);
+
+/**
+ * crypto_csr_verify - Initialize CSR from CertificationRequest
+ * @req: DER encoding of ASN.1 CertificationRequest
+ *
+ * Returns: Pointer to CSR data or %NULL on failure or if signature is invalid
+ */
+struct crypto_csr * crypto_csr_verify(const struct wpabuf *req);
+
+/**
+ * crypto_csr_deinit - Free CSR structure
+ * @csr: CSR structure from @crypto_csr_init() or crypto_csr_verify()
+ */
+void crypto_csr_deinit(struct crypto_csr *csr);
+
+/**
+ * crypto_csr_set_ec_public_key - Set public key in CSR
+ * @csr: CSR structure from @crypto_csr_init()
+ * @key: EC public key to set as public key in the CSR
+ * Returns: 0 on success, -1 on failure
+ */
+int crypto_csr_set_ec_public_key(struct crypto_csr *csr,
+				 struct crypto_ec_key *key);
+
+/**
+ * crypto_csr_set_name - Set name entry in CSR SubjectName
+ * @csr: CSR structure from @crypto_csr_init()
+ * @type: Name type  to add into the CSR SubjectName
+ * @name: UTF-8 string to write in the CSR SubjectName
+ * Returns: 0 on success, -1 on failure
+ */
+int crypto_csr_set_name(struct crypto_csr *csr, enum crypto_csr_name type,
+			const char *name);
+
+/**
+ * crypto_csr_set_attribute - Set attribute in CSR
+ * @csr: CSR structure from @crypto_csr_init()
+ * @attr: Attribute identifier
+ * @attr_type: ASN.1 type of @value buffer
+ * @value: Attribute value
+ * @len: length of @value buffer
+ * Returns: 0 on success, -1 on failure
+ */
+int crypto_csr_set_attribute(struct crypto_csr *csr, enum crypto_csr_attr attr,
+			     int attr_type, const u8 *value, size_t len);
+
+/**
+ * crypto_csr_get_attribute - Get attribute from CSR
+ * @csr: CSR structure from @crypto_csr_verify()
+ * @attr: Updated with atribute identifier
+ * @len: Updated with length of returned buffer
+ * @type: ASN.1 type of the attribute buffer
+ * Returns: Type, length, and pointer on attribute value or %NULL on failure
+ */
+const u8 * crypto_csr_get_attribute(struct crypto_csr *csr,
+				    enum crypto_csr_attr attr,
+				    size_t *len, int *type);
+
+/**
+ * crypto_csr_sign - Sign CSR and return ASN.1 CertificationRequest
+ * @csr: CSR structure from @crypto_csr_init()
+ * @key: Private key to sign the CSR (for now ony EC key are supported)
+ * @algo: Hash algorithm to use for the signature
+ * Returns: DER encoding of ASN.1 CertificationRequest for the CSR or %NULL on
+ * failure
+ */
+struct wpabuf * crypto_csr_sign(struct crypto_csr *csr,
+				struct crypto_ec_key *key,
+				enum crypto_hash_alg algo);
+
 #endif /* CRYPTO_H */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/crypto_internal-rsa.c b/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/crypto_internal-rsa.c
index dc7f350..0c5cead 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/crypto_internal-rsa.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/crypto_internal-rsa.c
@@ -14,7 +14,7 @@
 #include "tls/pkcs1.h"
 #include "tls/pkcs8.h"
 
-/* Dummy structures; these are just typecast to struct crypto_rsa_key */
+/* Stub structures; these are just typecast to struct crypto_rsa_key */
 struct crypto_public_key;
 struct crypto_private_key;
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/crypto_openssl.c b/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/crypto_openssl.c
index ce75002..432c4ad 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/crypto_openssl.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/crypto_openssl.c
@@ -22,7 +22,11 @@
 #ifdef CONFIG_ECC
 #include <openssl/ec.h>
 #include <openssl/x509.h>
+#include <openssl/pem.h>
 #endif /* CONFIG_ECC */
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#include <openssl/provider.h>
+#endif /* OpenSSL version >= 3.0 */
 
 #include "common.h"
 #include "utils/const_time.h"
@@ -81,16 +85,62 @@
 
 
 #ifndef ABOVE_8_1
+#ifdef CONFIG_ECC
 static EC_KEY * EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
 {
 	if (pkey->type != EVP_PKEY_EC)
 		return NULL;
 	return pkey->pkey.ec;
 }
+#endif /* CONFIG_ECC */
 #endif /* ABOVE_8_1 */
 
+#ifdef CONFIG_ECC
+static int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
+{
+	sig->r = r;
+	sig->s = s;
+	return 1;
+}
+
+
+static void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr,
+			   const BIGNUM **ps)
+{
+	if (pr)
+		*pr = sig->r;
+	if (ps)
+		*ps = sig->s;
+}
+
+#endif /* CONFIG_ECC */
+
+static const unsigned char * ASN1_STRING_get0_data(const ASN1_STRING *x)
+{
+	return ASN1_STRING_data((ASN1_STRING *) x);
+}
 #endif /* OpenSSL version < 1.1.0 */
 
+
+void openssl_load_legacy_provider(void)
+{
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+	static bool loaded = false;
+	OSSL_PROVIDER *legacy;
+
+	if (loaded)
+		return;
+
+	legacy = OSSL_PROVIDER_load(NULL, "legacy");
+
+	if (legacy) {
+		OSSL_PROVIDER_load(NULL, "default");
+		loaded = true;
+	}
+#endif /* OpenSSL version >= 3.0 */
+}
+
+
 static BIGNUM * get_group5_prime(void)
 {
 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !(defined(LIBRESSL_VERSION_NUMBER) && \
@@ -196,6 +246,7 @@
 #ifndef CONFIG_FIPS
 int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 {
+	openssl_load_legacy_provider();
 	return openssl_digest_vector(EVP_md4(), num_elem, addr, len, mac);
 }
 #endif /* CONFIG_FIPS */
@@ -204,8 +255,10 @@
 int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
 {
 	u8 pkey[8], next, tmp;
-	int i;
-	DES_key_schedule ks;
+	int i, plen, ret = -1;
+	EVP_CIPHER_CTX *ctx;
+
+	openssl_load_legacy_provider();
 
 	/* Add parity bits to the key */
 	next = 0;
@@ -216,10 +269,19 @@
 	}
 	pkey[i] = next | 1;
 
-	DES_set_key((DES_cblock *) &pkey, &ks);
-	DES_ecb_encrypt((DES_cblock *) clear, (DES_cblock *) cypher, &ks,
-			DES_ENCRYPT);
-	return 0;
+	ctx = EVP_CIPHER_CTX_new();
+	if (ctx &&
+	    EVP_EncryptInit_ex(ctx, EVP_des_ecb(), NULL, pkey, NULL) == 1 &&
+	    EVP_CIPHER_CTX_set_padding(ctx, 0) == 1 &&
+	    EVP_EncryptUpdate(ctx, cypher, &plen, clear, 8) == 1 &&
+	    EVP_EncryptFinal_ex(ctx, &cypher[plen], &plen) == 1)
+		ret = 0;
+	else
+		wpa_printf(MSG_ERROR, "OpenSSL: DES encrypt failed");
+
+	if (ctx)
+		EVP_CIPHER_CTX_free(ctx);
+	return ret;
 }
 
 
@@ -235,10 +297,12 @@
 	int res = -1;
 	unsigned char skip_buf[16];
 
+	openssl_load_legacy_provider();
+
 	ctx = EVP_CIPHER_CTX_new();
 	if (!ctx ||
-	    !EVP_CIPHER_CTX_set_padding(ctx, 0) ||
 	    !EVP_CipherInit_ex(ctx, EVP_rc4(), NULL, NULL, NULL, 1) ||
+	    !EVP_CIPHER_CTX_set_padding(ctx, 0) ||
 	    !EVP_CIPHER_CTX_set_key_length(ctx, keylen) ||
 	    !EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, 1))
 		goto out;
@@ -698,8 +762,8 @@
 	}
 
 	if (!(ctx->enc = EVP_CIPHER_CTX_new()) ||
-	    !EVP_CIPHER_CTX_set_padding(ctx->enc, 0) ||
 	    !EVP_EncryptInit_ex(ctx->enc, cipher, NULL, NULL, NULL) ||
+	    !EVP_CIPHER_CTX_set_padding(ctx->enc, 0) ||
 	    !EVP_CIPHER_CTX_set_key_length(ctx->enc, key_len) ||
 	    !EVP_EncryptInit_ex(ctx->enc, NULL, NULL, key, iv)) {
 		if (ctx->enc)
@@ -709,8 +773,8 @@
 	}
 
 	if (!(ctx->dec = EVP_CIPHER_CTX_new()) ||
-	    !EVP_CIPHER_CTX_set_padding(ctx->dec, 0) ||
 	    !EVP_DecryptInit_ex(ctx->dec, cipher, NULL, NULL, NULL) ||
+	    !EVP_CIPHER_CTX_set_padding(ctx->dec, 0) ||
 	    !EVP_CIPHER_CTX_set_key_length(ctx->dec, key_len) ||
 	    !EVP_DecryptInit_ex(ctx->dec, NULL, NULL, key, iv)) {
 		EVP_CIPHER_CTX_free(ctx->enc);
@@ -1627,51 +1691,51 @@
 	BIGNUM *b;
 };
 
+
+static int crypto_ec_group_2_nid(int group)
+{
+	/* Map from IANA registry for IKE D-H groups to OpenSSL NID */
+	switch (group) {
+	case 19:
+		return NID_X9_62_prime256v1;
+	case 20:
+		return NID_secp384r1;
+	case 21:
+		return NID_secp521r1;
+	case 25:
+		return NID_X9_62_prime192v1;
+	case 26:
+		return NID_secp224r1;
+#ifdef NID_brainpoolP224r1
+	case 27:
+		return NID_brainpoolP224r1;
+#endif /* NID_brainpoolP224r1 */
+#ifdef NID_brainpoolP256r1
+	case 28:
+		return NID_brainpoolP256r1;
+#endif /* NID_brainpoolP256r1 */
+#ifdef NID_brainpoolP384r1
+	case 29:
+		return NID_brainpoolP384r1;
+#endif /* NID_brainpoolP384r1 */
+#ifdef NID_brainpoolP512r1
+	case 30:
+		return NID_brainpoolP512r1;
+#endif /* NID_brainpoolP512r1 */
+	default:
+		return -1;
+	}
+}
+
+
 struct crypto_ec * crypto_ec_init(int group)
 {
 	struct crypto_ec *e;
 	int nid;
 
-	/* Map from IANA registry for IKE D-H groups to OpenSSL NID */
-	switch (group) {
-	case 19:
-		nid = NID_X9_62_prime256v1;
-		break;
-	case 20:
-		nid = NID_secp384r1;
-		break;
-	case 21:
-		nid = NID_secp521r1;
-		break;
-	case 25:
-		nid = NID_X9_62_prime192v1;
-		break;
-	case 26:
-		nid = NID_secp224r1;
-		break;
-#ifdef NID_brainpoolP224r1
-	case 27:
-		nid = NID_brainpoolP224r1;
-		break;
-#endif /* NID_brainpoolP224r1 */
-#ifdef NID_brainpoolP256r1
-	case 28:
-		nid = NID_brainpoolP256r1;
-		break;
-#endif /* NID_brainpoolP256r1 */
-#ifdef NID_brainpoolP384r1
-	case 29:
-		nid = NID_brainpoolP384r1;
-		break;
-#endif /* NID_brainpoolP384r1 */
-#ifdef NID_brainpoolP512r1
-	case 30:
-		nid = NID_brainpoolP512r1;
-		break;
-#endif /* NID_brainpoolP512r1 */
-	default:
+	nid = crypto_ec_group_2_nid(group);
+	if (nid < 0)
 		return NULL;
-	}
 
 	e = os_zalloc(sizeof(*e));
 	if (e == NULL)
@@ -1762,6 +1826,13 @@
 }
 
 
+const struct crypto_ec_point * crypto_ec_get_generator(struct crypto_ec *e)
+{
+	return (const struct crypto_ec_point *)
+		EC_GROUP_get0_generator(e->group);
+}
+
+
 void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
 {
 	if (clear)
@@ -1878,48 +1949,27 @@
 }
 
 
-int crypto_ec_point_solve_y_coord(struct crypto_ec *e,
-				  struct crypto_ec_point *p,
-				  const struct crypto_bignum *x, int y_bit)
-{
-	if (TEST_FAIL())
-		return -1;
-	if (!EC_POINT_set_compressed_coordinates_GFp(e->group, (EC_POINT *) p,
-						     (const BIGNUM *) x, y_bit,
-						     e->bnctx) ||
-	    !EC_POINT_is_on_curve(e->group, (EC_POINT *) p, e->bnctx))
-		return -1;
-	return 0;
-}
-
-
 struct crypto_bignum *
 crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
 			      const struct crypto_bignum *x)
 {
-	BIGNUM *tmp, *tmp2, *y_sqr = NULL;
+	BIGNUM *tmp;
 
 	if (TEST_FAIL())
 		return NULL;
 
 	tmp = BN_new();
-	tmp2 = BN_new();
 
-	/* y^2 = x^3 + ax + b */
-	if (tmp && tmp2 &&
+	/* y^2 = x^3 + ax + b = (x^2 + a)x + b */
+	if (tmp &&
 	    BN_mod_sqr(tmp, (const BIGNUM *) x, e->prime, e->bnctx) &&
+	    BN_mod_add_quick(tmp, e->a, tmp, e->prime) &&
 	    BN_mod_mul(tmp, tmp, (const BIGNUM *) x, e->prime, e->bnctx) &&
-	    BN_mod_mul(tmp2, e->a, (const BIGNUM *) x, e->prime, e->bnctx) &&
-	    BN_mod_add_quick(tmp2, tmp2, tmp, e->prime) &&
-	    BN_mod_add_quick(tmp2, tmp2, e->b, e->prime)) {
-		y_sqr = tmp2;
-		tmp2 = NULL;
-	}
+	    BN_mod_add_quick(tmp, tmp, e->b, e->prime))
+		return (struct crypto_bignum *) tmp;
 
 	BN_clear_free(tmp);
-	BN_clear_free(tmp2);
-
-	return (struct crypto_bignum *) y_sqr;
+	return NULL;
 }
 
 
@@ -1947,6 +1997,35 @@
 }
 
 
+void crypto_ec_point_debug_print(const struct crypto_ec *e,
+				 const struct crypto_ec_point *p,
+				 const char *title)
+{
+	BIGNUM *x, *y;
+	char *x_str = NULL, *y_str = NULL;
+
+	x = BN_new();
+	y = BN_new();
+	if (!x || !y ||
+	    EC_POINT_get_affine_coordinates_GFp(e->group, (const EC_POINT *) p,
+						x, y, e->bnctx) != 1)
+		goto fail;
+
+	x_str = BN_bn2hex(x);
+	y_str = BN_bn2hex(y);
+	if (!x_str || !y_str)
+		goto fail;
+
+	wpa_printf(MSG_DEBUG, "%s (%s,%s)", title, x_str, y_str);
+
+fail:
+	OPENSSL_free(x_str);
+	OPENSSL_free(y_str);
+	BN_free(x);
+	BN_free(y);
+}
+
+
 struct crypto_ecdh {
 	struct crypto_ec *ec;
 	EVP_PKEY *pkey;
@@ -2011,6 +2090,32 @@
 }
 
 
+struct crypto_ecdh * crypto_ecdh_init2(int group, struct crypto_ec_key *own_key)
+{
+	struct crypto_ecdh *ecdh;
+
+	ecdh = os_zalloc(sizeof(*ecdh));
+	if (!ecdh)
+		goto fail;
+
+	ecdh->ec = crypto_ec_init(group);
+	if (!ecdh->ec)
+		goto fail;
+
+	ecdh->pkey = EVP_PKEY_new();
+	if (!ecdh->pkey ||
+	    EVP_PKEY_assign_EC_KEY(ecdh->pkey,
+				   EVP_PKEY_get1_EC_KEY((EVP_PKEY *) own_key))
+	    != 1)
+		goto fail;
+
+	return ecdh;
+fail:
+	crypto_ecdh_deinit(ecdh);
+	return NULL;
+}
+
+
 struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y)
 {
 	struct wpabuf *buf = NULL;
@@ -2182,83 +2287,348 @@
 }
 
 
-struct crypto_ec_key {
-	EVP_PKEY *pkey;
-	EC_KEY *eckey;
-};
-
-
 struct crypto_ec_key * crypto_ec_key_parse_priv(const u8 *der, size_t der_len)
 {
-	struct crypto_ec_key *key;
+	EVP_PKEY *pkey = NULL;
+	EC_KEY *eckey;
 
-	key = os_zalloc(sizeof(*key));
-	if (!key)
-		return NULL;
-
-	key->eckey = d2i_ECPrivateKey(NULL, &der, der_len);
-	if (!key->eckey) {
+	eckey = d2i_ECPrivateKey(NULL, &der, der_len);
+	if (!eckey) {
 		wpa_printf(MSG_INFO, "OpenSSL: d2i_ECPrivateKey() failed: %s",
 			   ERR_error_string(ERR_get_error(), NULL));
 		goto fail;
 	}
-	EC_KEY_set_conv_form(key->eckey, POINT_CONVERSION_COMPRESSED);
+	EC_KEY_set_conv_form(eckey, POINT_CONVERSION_COMPRESSED);
 
-	key->pkey = EVP_PKEY_new();
-	if (!key->pkey || EVP_PKEY_assign_EC_KEY(key->pkey, key->eckey) != 1) {
-		EC_KEY_free(key->eckey);
-		key->eckey = NULL;
+	pkey = EVP_PKEY_new();
+	if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, eckey) != 1) {
+		EC_KEY_free(eckey);
 		goto fail;
 	}
 
-	return key;
+	return (struct crypto_ec_key *) pkey;
 fail:
-	crypto_ec_key_deinit(key);
+	crypto_ec_key_deinit((struct crypto_ec_key *) pkey);
 	return NULL;
 }
 
 
 struct crypto_ec_key * crypto_ec_key_parse_pub(const u8 *der, size_t der_len)
 {
-	struct crypto_ec_key *key;
+	EVP_PKEY *pkey;
 
-	key = os_zalloc(sizeof(*key));
-	if (!key)
-		return NULL;
-
-	key->pkey = d2i_PUBKEY(NULL, &der, der_len);
-	if (!key->pkey) {
+	pkey = d2i_PUBKEY(NULL, &der, der_len);
+	if (!pkey) {
 		wpa_printf(MSG_INFO, "OpenSSL: d2i_PUBKEY() failed: %s",
 			   ERR_error_string(ERR_get_error(), NULL));
 		goto fail;
 	}
 
-	key->eckey = EVP_PKEY_get0_EC_KEY(key->pkey);
-	if (!key->eckey)
+	/* Ensure this is an EC key */
+	if (!EVP_PKEY_get0_EC_KEY(pkey))
 		goto fail;
-	return key;
+	return (struct crypto_ec_key *) pkey;
 fail:
-	crypto_ec_key_deinit(key);
+	crypto_ec_key_deinit((struct crypto_ec_key *) pkey);
 	return NULL;
 }
 
 
+struct crypto_ec_key * crypto_ec_key_set_pub(int group, const u8 *buf_x,
+					     const u8 *buf_y, size_t len)
+{
+	EC_KEY *eckey = NULL;
+	EVP_PKEY *pkey = NULL;
+	EC_GROUP *ec_group = NULL;
+	BN_CTX *ctx;
+	EC_POINT *point = NULL;
+	BIGNUM *x = NULL, *y = NULL;
+	int nid;
+
+	if (!buf_x || !buf_y)
+		return NULL;
+
+	nid = crypto_ec_group_2_nid(group);
+	if (nid < 0) {
+		wpa_printf(MSG_ERROR, "OpenSSL: Unsupported group %d", group);
+		return NULL;
+	}
+
+	ctx = BN_CTX_new();
+	if (!ctx)
+		goto fail;
+
+	ec_group = EC_GROUP_new_by_curve_name(nid);
+	if (!ec_group)
+		goto fail;
+
+	x = BN_bin2bn(buf_x, len, NULL);
+	y = BN_bin2bn(buf_y, len, NULL);
+	point = EC_POINT_new(ec_group);
+	if (!x || !y || !point)
+		goto fail;
+
+	if (!EC_POINT_set_affine_coordinates_GFp(ec_group, point, x, y, ctx)) {
+		wpa_printf(MSG_ERROR,
+			   "OpenSSL: EC_POINT_set_affine_coordinates_GFp failed: %s",
+			   ERR_error_string(ERR_get_error(), NULL));
+		goto fail;
+	}
+
+	if (!EC_POINT_is_on_curve(ec_group, point, ctx) ||
+	    EC_POINT_is_at_infinity(ec_group, point)) {
+		wpa_printf(MSG_ERROR, "OpenSSL: Invalid point");
+		goto fail;
+	}
+
+	eckey = EC_KEY_new();
+	if (!eckey ||
+	    EC_KEY_set_group(eckey, ec_group) != 1 ||
+	    EC_KEY_set_public_key(eckey, point) != 1) {
+		wpa_printf(MSG_ERROR,
+			   "OpenSSL: Failed to set EC_KEY: %s",
+			   ERR_error_string(ERR_get_error(), NULL));
+		goto fail;
+	}
+	EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE);
+
+	pkey = EVP_PKEY_new();
+	if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, eckey) != 1) {
+		wpa_printf(MSG_ERROR, "OpenSSL: Could not create EVP_PKEY");
+		goto fail;
+	}
+
+out:
+	EC_GROUP_free(ec_group);
+	BN_free(x);
+	BN_free(y);
+	EC_POINT_free(point);
+	BN_CTX_free(ctx);
+	return (struct crypto_ec_key *) pkey;
+
+fail:
+	EC_KEY_free(eckey);
+	EVP_PKEY_free(pkey);
+	pkey = NULL;
+	goto out;
+}
+
+
+struct crypto_ec_key *
+crypto_ec_key_set_pub_point(struct crypto_ec *ec,
+			    const struct crypto_ec_point *pub)
+{
+	EC_KEY *eckey;
+	EVP_PKEY *pkey = NULL;
+
+	eckey = EC_KEY_new();
+	if (!eckey ||
+	    EC_KEY_set_group(eckey, ec->group) != 1 ||
+	    EC_KEY_set_public_key(eckey, (const EC_POINT *) pub) != 1) {
+		wpa_printf(MSG_ERROR,
+			   "OpenSSL: Failed to set EC_KEY: %s",
+			   ERR_error_string(ERR_get_error(), NULL));
+		goto fail;
+	}
+	EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE);
+
+	pkey = EVP_PKEY_new();
+	if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, eckey) != 1) {
+		wpa_printf(MSG_ERROR, "OpenSSL: Could not create EVP_PKEY");
+		goto fail;
+	}
+
+out:
+	return (struct crypto_ec_key *) pkey;
+
+fail:
+	EVP_PKEY_free(pkey);
+	EC_KEY_free(eckey);
+	pkey = NULL;
+	goto out;
+}
+
+
+struct crypto_ec_key * crypto_ec_key_gen(int group)
+{
+	EVP_PKEY_CTX *kctx = NULL;
+	EC_KEY *ec_params = NULL, *eckey;
+	EVP_PKEY *params = NULL, *key = NULL;
+	int nid;
+
+	nid = crypto_ec_group_2_nid(group);
+	if (nid < 0) {
+		wpa_printf(MSG_ERROR, "OpenSSL: Unsupported group %d", group);
+		return NULL;
+	}
+
+	ec_params = EC_KEY_new_by_curve_name(nid);
+	if (!ec_params) {
+		wpa_printf(MSG_ERROR,
+			   "OpenSSL: Failed to generate EC_KEY parameters");
+		goto fail;
+	}
+	EC_KEY_set_asn1_flag(ec_params, OPENSSL_EC_NAMED_CURVE);
+	params = EVP_PKEY_new();
+	if (!params || EVP_PKEY_set1_EC_KEY(params, ec_params) != 1) {
+		wpa_printf(MSG_ERROR,
+			   "OpenSSL: Failed to generate EVP_PKEY parameters");
+		goto fail;
+	}
+
+	kctx = EVP_PKEY_CTX_new(params, NULL);
+	if (!kctx ||
+	    EVP_PKEY_keygen_init(kctx) != 1 ||
+	    EVP_PKEY_keygen(kctx, &key) != 1) {
+		wpa_printf(MSG_ERROR, "OpenSSL: Failed to generate EC key");
+		key = NULL;
+		goto fail;
+	}
+
+	eckey = EVP_PKEY_get1_EC_KEY(key);
+	if (!eckey) {
+		key = NULL;
+		goto fail;
+	}
+	EC_KEY_set_conv_form(eckey, POINT_CONVERSION_COMPRESSED);
+	EC_KEY_free(eckey);
+
+fail:
+	EC_KEY_free(ec_params);
+	EVP_PKEY_free(params);
+	EVP_PKEY_CTX_free(kctx);
+	return (struct crypto_ec_key *) key;
+}
+
+
 void crypto_ec_key_deinit(struct crypto_ec_key *key)
 {
-	if (key) {
-		EVP_PKEY_free(key->pkey);
-		os_free(key);
-	}
+	EVP_PKEY_free((EVP_PKEY *) key);
 }
 
 
+#ifdef OPENSSL_IS_BORINGSSL
+
+/* BoringSSL version of i2d_PUBKEY() always outputs public EC key using
+ * uncompressed form so define a custom function to export EC pubkey using
+ * the compressed format that is explicitly required for some protocols. */
+
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+
+typedef struct {
+	/* AlgorithmIdentifier ecPublicKey with optional parameters present
+	 * as an OID identifying the curve */
+	X509_ALGOR *alg;
+	/* Compressed format public key per ANSI X9.63 */
+	ASN1_BIT_STRING *pub_key;
+} EC_COMP_PUBKEY;
+
+ASN1_SEQUENCE(EC_COMP_PUBKEY) = {
+	ASN1_SIMPLE(EC_COMP_PUBKEY, alg, X509_ALGOR),
+	ASN1_SIMPLE(EC_COMP_PUBKEY, pub_key, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END(EC_COMP_PUBKEY);
+
+IMPLEMENT_ASN1_FUNCTIONS(EC_COMP_PUBKEY);
+
+#endif /* OPENSSL_IS_BORINGSSL */
+
+
 struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key)
 {
+#ifdef OPENSSL_IS_BORINGSSL
+	unsigned char *der = NULL;
+	int der_len;
+	const EC_KEY *eckey;
+	struct wpabuf *ret = NULL;
+	size_t len;
+	const EC_GROUP *group;
+	const EC_POINT *point;
+	BN_CTX *ctx;
+	EC_COMP_PUBKEY *pubkey = NULL;
+	int nid;
+
+	ctx = BN_CTX_new();
+	eckey = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) key);
+	if (!ctx || !eckey)
+		goto fail;
+
+	group = EC_KEY_get0_group(eckey);
+	point = EC_KEY_get0_public_key(eckey);
+	if (!group || !point)
+		goto fail;
+	nid = EC_GROUP_get_curve_name(group);
+
+	pubkey = EC_COMP_PUBKEY_new();
+	if (!pubkey ||
+	    X509_ALGOR_set0(pubkey->alg, OBJ_nid2obj(EVP_PKEY_EC),
+			    V_ASN1_OBJECT, (void *) OBJ_nid2obj(nid)) != 1)
+		goto fail;
+
+	len = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED,
+				 NULL, 0, ctx);
+	if (len == 0)
+		goto fail;
+
+	der = OPENSSL_malloc(len);
+	if (!der)
+		goto fail;
+	len = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED,
+				 der, len, ctx);
+
+	OPENSSL_free(pubkey->pub_key->data);
+	pubkey->pub_key->data = der;
+	der = NULL;
+	pubkey->pub_key->length = len;
+	/* No unused bits */
+	pubkey->pub_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+	pubkey->pub_key->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+
+	der_len = i2d_EC_COMP_PUBKEY(pubkey, &der);
+	if (der_len <= 0) {
+		wpa_printf(MSG_ERROR,
+			   "BoringSSL: Failed to build DER encoded public key");
+		goto fail;
+	}
+
+	ret = wpabuf_alloc_copy(der, der_len);
+fail:
+	EC_COMP_PUBKEY_free(pubkey);
+	OPENSSL_free(der);
+	BN_CTX_free(ctx);
+	return ret;
+#else /* OPENSSL_IS_BORINGSSL */
 	unsigned char *der = NULL;
 	int der_len;
 	struct wpabuf *buf;
+	EC_KEY *eckey;
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+	EVP_PKEY *tmp;
+#endif /* OpenSSL version >= 3.0 */
 
-	der_len = i2d_PUBKEY(key->pkey, &der);
+	eckey = EVP_PKEY_get1_EC_KEY((EVP_PKEY *) key);
+	if (!eckey)
+		return NULL;
+
+	/* For now, all users expect COMPRESSED form */
+	EC_KEY_set_conv_form(eckey, POINT_CONVERSION_COMPRESSED);
+
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+	tmp = EVP_PKEY_new();
+	if (!tmp)
+		return NULL;
+	if (EVP_PKEY_set1_EC_KEY(tmp, eckey) != 1) {
+		EVP_PKEY_free(tmp);
+		return NULL;
+	}
+	key = (struct crypto_ec_key *) tmp;
+#endif /* OpenSSL version >= 3.0 */
+
+	der_len = i2d_PUBKEY((EVP_PKEY *) key, &der);
+	EC_KEY_free(eckey);
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+	EVP_PKEY_free(tmp);
+#endif /* OpenSSL version >= 3.0 */
 	if (der_len <= 0) {
 		wpa_printf(MSG_INFO, "OpenSSL: i2d_PUBKEY() failed: %s",
 			   ERR_error_string(ERR_get_error(), NULL));
@@ -2268,6 +2638,112 @@
 	buf = wpabuf_alloc_copy(der, der_len);
 	OPENSSL_free(der);
 	return buf;
+#endif /* OPENSSL_IS_BORINGSSL */
+}
+
+
+struct wpabuf * crypto_ec_key_get_ecprivate_key(struct crypto_ec_key *key,
+						bool include_pub)
+{
+	EC_KEY *eckey;
+	unsigned char *der = NULL;
+	int der_len;
+	struct wpabuf *buf;
+	unsigned int key_flags;
+
+	eckey = EVP_PKEY_get1_EC_KEY((EVP_PKEY *) key);
+	if (!eckey)
+		return NULL;
+
+	key_flags = EC_KEY_get_enc_flags(eckey);
+	if (include_pub)
+		key_flags &= ~EC_PKEY_NO_PUBKEY;
+	else
+		key_flags |= EC_PKEY_NO_PUBKEY;
+	EC_KEY_set_enc_flags(eckey, key_flags);
+
+	EC_KEY_set_conv_form(eckey, POINT_CONVERSION_UNCOMPRESSED);
+
+	der_len = i2d_ECPrivateKey(eckey, &der);
+	EC_KEY_free(eckey);
+	if (der_len <= 0)
+		return NULL;
+	buf = wpabuf_alloc_copy(der, der_len);
+	OPENSSL_free(der);
+
+	return buf;
+}
+
+
+struct wpabuf * crypto_ec_key_get_pubkey_point(struct crypto_ec_key *key,
+					       int prefix)
+{
+	int len, res;
+	EC_KEY *eckey;
+	struct wpabuf *buf;
+	unsigned char *pos;
+
+	eckey = EVP_PKEY_get1_EC_KEY((EVP_PKEY *) key);
+	if (!eckey)
+		return NULL;
+	EC_KEY_set_conv_form(eckey, POINT_CONVERSION_UNCOMPRESSED);
+	len = i2o_ECPublicKey(eckey, NULL);
+	if (len <= 0) {
+		wpa_printf(MSG_ERROR,
+			   "OpenSSL: Failed to determine public key encoding length");
+		EC_KEY_free(eckey);
+		return NULL;
+	}
+
+	buf = wpabuf_alloc(len);
+	if (!buf) {
+		EC_KEY_free(eckey);
+		return NULL;
+	}
+
+	pos = wpabuf_put(buf, len);
+	res = i2o_ECPublicKey(eckey, &pos);
+	EC_KEY_free(eckey);
+	if (res != len) {
+		wpa_printf(MSG_ERROR,
+			   "OpenSSL: Failed to encode public key (res=%d/%d)",
+			   res, len);
+		wpabuf_free(buf);
+		return NULL;
+	}
+
+	if (!prefix) {
+		/* Remove 0x04 prefix if requested */
+		pos = wpabuf_mhead(buf);
+		os_memmove(pos, pos + 1, len - 1);
+		buf->used--;
+	}
+
+	return buf;
+}
+
+
+const struct crypto_ec_point *
+crypto_ec_key_get_public_key(struct crypto_ec_key *key)
+{
+	const EC_KEY *eckey;
+
+	eckey = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) key);
+	if (!eckey)
+		return NULL;
+	return (const struct crypto_ec_point *) EC_KEY_get0_public_key(eckey);
+}
+
+
+const struct crypto_bignum *
+crypto_ec_key_get_private_key(struct crypto_ec_key *key)
+{
+	const EC_KEY *eckey;
+
+	eckey = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) key);
+	if (!eckey)
+		return NULL;
+	return (const struct crypto_bignum *) EC_KEY_get0_private_key(eckey);
 }
 
 
@@ -2278,12 +2754,12 @@
 	struct wpabuf *sig_der;
 	size_t sig_len;
 
-	sig_len = EVP_PKEY_size(key->pkey);
+	sig_len = EVP_PKEY_size((EVP_PKEY *) key);
 	sig_der = wpabuf_alloc(sig_len);
 	if (!sig_der)
 		return NULL;
 
-	pkctx = EVP_PKEY_CTX_new(key->pkey, NULL);
+	pkctx = EVP_PKEY_CTX_new((EVP_PKEY *) key, NULL);
 	if (!pkctx ||
 	    EVP_PKEY_sign_init(pkctx) <= 0 ||
 	    EVP_PKEY_sign(pkctx, wpabuf_put(sig_der, 0), &sig_len,
@@ -2299,13 +2775,68 @@
 }
 
 
+struct wpabuf * crypto_ec_key_sign_r_s(struct crypto_ec_key *key,
+				       const u8 *data, size_t len)
+{
+	const EC_GROUP *group;
+	const EC_KEY *eckey;
+	BIGNUM *prime = NULL;
+	ECDSA_SIG *sig = NULL;
+	const BIGNUM *r, *s;
+	u8 *r_buf, *s_buf;
+	struct wpabuf *buf;
+	const unsigned char *p;
+	int prime_len;
+
+	buf = crypto_ec_key_sign(key, data, len);
+	if (!buf)
+		return NULL;
+
+	/* Extract (r,s) from Ecdsa-Sig-Value */
+	eckey = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) key);
+	if (!eckey)
+		goto fail;
+	group = EC_KEY_get0_group(eckey);
+	prime = BN_new();
+	if (!prime || !group ||
+	    !EC_GROUP_get_curve_GFp(group, prime, NULL, NULL, NULL))
+		goto fail;
+	prime_len = BN_num_bytes(prime);
+
+	p = wpabuf_head(buf);
+	sig = d2i_ECDSA_SIG(NULL, &p, wpabuf_len(buf));
+	if (!sig)
+		goto fail;
+	ECDSA_SIG_get0(sig, &r, &s);
+
+	/* Re-use wpabuf returned by crypto_ec_key_sign() */
+	buf->used = 0;
+	r_buf = wpabuf_put(buf, prime_len);
+	s_buf = wpabuf_put(buf, prime_len);
+	if (crypto_bignum_to_bin((const struct crypto_bignum *) r, r_buf,
+				 prime_len, prime_len) < 0 ||
+	    crypto_bignum_to_bin((const struct crypto_bignum *) s, s_buf,
+				 prime_len, prime_len) < 0)
+		goto fail;
+
+out:
+	BN_free(prime);
+	ECDSA_SIG_free(sig);
+	return buf;
+fail:
+	wpabuf_clear_free(buf);
+	buf = NULL;
+	goto out;
+}
+
+
 int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data,
 				   size_t len, const u8 *sig, size_t sig_len)
 {
 	EVP_PKEY_CTX *pkctx;
 	int ret;
 
-	pkctx = EVP_PKEY_CTX_new(key->pkey, NULL);
+	pkctx = EVP_PKEY_CTX_new((EVP_PKEY *) key, NULL);
 	if (!pkctx || EVP_PKEY_verify_init(pkctx) <= 0) {
 		EVP_PKEY_CTX_free(pkctx);
 		return -1;
@@ -2321,12 +2852,53 @@
 }
 
 
+int crypto_ec_key_verify_signature_r_s(struct crypto_ec_key *key,
+				       const u8 *data, size_t len,
+				       const u8 *r, size_t r_len,
+				       const u8 *s, size_t s_len)
+{
+	ECDSA_SIG *sig;
+	BIGNUM *r_bn, *s_bn;
+	unsigned char *der = NULL;
+	int der_len;
+	int ret = -1;
+
+	r_bn = BN_bin2bn(r, r_len, NULL);
+	s_bn = BN_bin2bn(s, s_len, NULL);
+	sig = ECDSA_SIG_new();
+	if (!r_bn || !s_bn || !sig || ECDSA_SIG_set0(sig, r_bn, s_bn) != 1)
+		goto fail;
+	r_bn = NULL;
+	s_bn = NULL;
+
+	der_len = i2d_ECDSA_SIG(sig, &der);
+	if (der_len <= 0) {
+		wpa_printf(MSG_DEBUG,
+			   "OpenSSL: Could not DER encode signature");
+		goto fail;
+	}
+
+	ret = crypto_ec_key_verify_signature(key, data, len, der, der_len);
+
+fail:
+	OPENSSL_free(der);
+	BN_free(r_bn);
+	BN_free(s_bn);
+	ECDSA_SIG_free(sig);
+	return ret;
+}
+
+
 int crypto_ec_key_group(struct crypto_ec_key *key)
 {
+	const EC_KEY *eckey;
 	const EC_GROUP *group;
 	int nid;
 
-	group = EC_KEY_get0_group(key->eckey);
+	eckey = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) key);
+	if (!eckey)
+		return -1;
+	group = EC_KEY_get0_group(eckey);
 	if (!group)
 		return -1;
 	nid = EC_GROUP_get_curve_name(group);
@@ -2337,8 +2909,334 @@
 		return 20;
 	case NID_secp521r1:
 		return 21;
+#ifdef NID_brainpoolP256r1
+	case NID_brainpoolP256r1:
+		return 28;
+#endif /* NID_brainpoolP256r1 */
+#ifdef NID_brainpoolP384r1
+	case NID_brainpoolP384r1:
+		return 29;
+#endif /* NID_brainpoolP384r1 */
+#ifdef NID_brainpoolP512r1
+	case NID_brainpoolP512r1:
+		return 30;
+#endif /* NID_brainpoolP512r1 */
 	}
+	wpa_printf(MSG_ERROR, "OpenSSL: Unsupported curve (nid=%d) in EC key",
+		   nid);
 	return -1;
 }
 
+
+int crypto_ec_key_cmp(struct crypto_ec_key *key1, struct crypto_ec_key *key2)
+{
+	if (EVP_PKEY_cmp((EVP_PKEY *) key1, (EVP_PKEY *) key2) != 1)
+		return -1;
+	return 0;
+}
+
+
+void crypto_ec_key_debug_print(const struct crypto_ec_key *key,
+			       const char *title)
+{
+	BIO *out;
+	size_t rlen;
+	char *txt;
+	int res;
+
+	out = BIO_new(BIO_s_mem());
+	if (!out)
+		return;
+
+	EVP_PKEY_print_private(out, (EVP_PKEY *) key, 0, NULL);
+	rlen = BIO_ctrl_pending(out);
+	txt = os_malloc(rlen + 1);
+	if (txt) {
+		res = BIO_read(out, txt, rlen);
+		if (res > 0) {
+			txt[res] = '\0';
+			wpa_printf(MSG_DEBUG, "%s: %s", title, txt);
+		}
+		os_free(txt);
+	}
+	BIO_free(out);
+}
+
+
+struct wpabuf * crypto_pkcs7_get_certificates(const struct wpabuf *pkcs7)
+{
+#ifdef OPENSSL_IS_BORINGSSL
+	CBS pkcs7_cbs;
+#else /* OPENSSL_IS_BORINGSSL */
+	PKCS7 *p7 = NULL;
+	const unsigned char *p = wpabuf_head(pkcs7);
+#endif /* OPENSSL_IS_BORINGSSL */
+	STACK_OF(X509) *certs;
+	int i, num;
+	BIO *out = NULL;
+	size_t rlen;
+	struct wpabuf *pem = NULL;
+	int res;
+
+#ifdef OPENSSL_IS_BORINGSSL
+	certs = sk_X509_new_null();
+	if (!certs)
+		goto fail;
+	CBS_init(&pkcs7_cbs, wpabuf_head(pkcs7), wpabuf_len(pkcs7));
+	if (!PKCS7_get_certificates(certs, &pkcs7_cbs)) {
+		wpa_printf(MSG_INFO,
+			   "OpenSSL: Could not parse PKCS#7 object: %s",
+			   ERR_error_string(ERR_get_error(), NULL));
+		goto fail;
+	}
+#else /* OPENSSL_IS_BORINGSSL */
+	p7 = d2i_PKCS7(NULL, &p, wpabuf_len(pkcs7));
+	if (!p7) {
+		wpa_printf(MSG_INFO,
+			   "OpenSSL: Could not parse PKCS#7 object: %s",
+			   ERR_error_string(ERR_get_error(), NULL));
+		goto fail;
+	}
+
+	switch (OBJ_obj2nid(p7->type)) {
+	case NID_pkcs7_signed:
+		certs = p7->d.sign->cert;
+		break;
+	case NID_pkcs7_signedAndEnveloped:
+		certs = p7->d.signed_and_enveloped->cert;
+		break;
+	default:
+		certs = NULL;
+		break;
+	}
+#endif /* OPENSSL_IS_BORINGSSL */
+
+	if (!certs || ((num = sk_X509_num(certs)) == 0)) {
+		wpa_printf(MSG_INFO,
+			   "OpenSSL: No certificates found in PKCS#7 object");
+		goto fail;
+	}
+
+	out = BIO_new(BIO_s_mem());
+	if (!out)
+		goto fail;
+
+	for (i = 0; i < num; i++) {
+		X509 *cert = sk_X509_value(certs, i);
+
+		PEM_write_bio_X509(out, cert);
+	}
+
+	rlen = BIO_ctrl_pending(out);
+	pem = wpabuf_alloc(rlen);
+	if (!pem)
+		goto fail;
+	res = BIO_read(out, wpabuf_put(pem, 0), rlen);
+	if (res <= 0) {
+		wpabuf_free(pem);
+		pem = NULL;
+		goto fail;
+	}
+	wpabuf_put(pem, res);
+
+fail:
+#ifdef OPENSSL_IS_BORINGSSL
+	if (certs)
+		sk_X509_pop_free(certs, X509_free);
+#else /* OPENSSL_IS_BORINGSSL */
+	PKCS7_free(p7);
+#endif /* OPENSSL_IS_BORINGSSL */
+	if (out)
+		BIO_free_all(out);
+
+	return pem;
+}
+
+
+struct crypto_csr * crypto_csr_init()
+{
+	return (struct crypto_csr *)X509_REQ_new();
+}
+
+
+struct crypto_csr * crypto_csr_verify(const struct wpabuf *req)
+{
+	X509_REQ *csr;
+	EVP_PKEY *pkey = NULL;
+	const u8 *der = wpabuf_head(req);
+
+	csr = d2i_X509_REQ(NULL, &der, wpabuf_len(req));
+	if (!csr)
+		return NULL;
+
+	pkey = X509_REQ_get_pubkey((X509_REQ *)csr);
+	if (!pkey)
+		goto fail;
+
+	if (X509_REQ_verify((X509_REQ *)csr, pkey) != 1)
+		goto fail;
+
+	return (struct crypto_csr *)csr;
+fail:
+	X509_REQ_free(csr);
+	return NULL;
+}
+
+
+void crypto_csr_deinit(struct crypto_csr *csr)
+{
+	X509_REQ_free((X509_REQ *)csr);
+}
+
+
+int crypto_csr_set_ec_public_key(struct crypto_csr *csr, struct crypto_ec_key *key)
+{
+	if (!X509_REQ_set_pubkey((X509_REQ *)csr, (EVP_PKEY *)key))
+		return -1;
+
+	return 0;
+}
+
+
+int crypto_csr_set_name(struct crypto_csr *csr, enum crypto_csr_name type,
+			const char *name)
+{
+	X509_NAME *n;
+	int nid;
+
+	switch (type) {
+	case CSR_NAME_CN:
+		nid = NID_commonName;
+		break;
+	case CSR_NAME_SN:
+		nid = NID_surname;
+		break;
+	case CSR_NAME_C:
+		nid = NID_countryName;
+		break;
+	case CSR_NAME_O:
+		nid = NID_organizationName;
+		break;
+	case CSR_NAME_OU:
+		nid = NID_organizationalUnitName;
+		break;
+	default:
+		return -1;
+	}
+
+	n = X509_REQ_get_subject_name((X509_REQ *) csr);
+	if (!n)
+		return -1;
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+	if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_UTF8,
+					(unsigned char *) name,
+					os_strlen(name), -1, 0))
+		return -1;
+#else
+	if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_UTF8,
+					(unsigned char *) name,
+					os_strlen(name), -1, 0))
+		return -1;
+#endif
+
+	return 0;
+}
+
+
+int crypto_csr_set_attribute(struct crypto_csr *csr, enum crypto_csr_attr attr,
+			     int attr_type, const u8 *value, size_t len)
+{
+	int nid;
+
+	switch (attr) {
+	case CSR_ATTR_CHALLENGE_PASSWORD:
+		nid = NID_pkcs9_challengePassword;
+		break;
+	default:
+		return -1;
+	}
+
+	if (!X509_REQ_add1_attr_by_NID((X509_REQ *) csr, nid, attr_type, value,
+				       len))
+		return -1;
+
+	return 0;
+}
+
+
+const u8 * crypto_csr_get_attribute(struct crypto_csr *csr,
+				    enum crypto_csr_attr attr,
+				    size_t *len, int *type)
+{
+	X509_ATTRIBUTE *attrib;
+	ASN1_TYPE *attrib_type;
+	ASN1_STRING *data;
+	int loc;
+	int nid;
+
+	switch (attr) {
+	case CSR_ATTR_CHALLENGE_PASSWORD:
+		nid = NID_pkcs9_challengePassword;
+		break;
+	default:
+		return NULL;
+	}
+
+	loc = X509_REQ_get_attr_by_NID((X509_REQ *) csr, nid, -1);
+	if (loc < 0)
+		return NULL;
+
+	attrib = X509_REQ_get_attr((X509_REQ *) csr, loc);
+	if (!attrib)
+		return NULL;
+
+	attrib_type = X509_ATTRIBUTE_get0_type(attrib, 0);
+	if (!attrib_type)
+		return NULL;
+	*type = ASN1_TYPE_get(attrib_type);
+	data = X509_ATTRIBUTE_get0_data(attrib, 0, *type, NULL);
+	if (!data)
+		return NULL;
+	*len = ASN1_STRING_length(data);
+	return ASN1_STRING_get0_data(data);
+}
+
+
+struct wpabuf * crypto_csr_sign(struct crypto_csr *csr,
+				struct crypto_ec_key *key,
+				enum crypto_hash_alg algo)
+{
+	const EVP_MD *sign_md;
+	struct wpabuf *buf;
+	unsigned char *der = NULL;
+	int der_len;
+
+	switch (algo) {
+	case CRYPTO_HASH_ALG_SHA256:
+		sign_md = EVP_sha256();
+		break;
+	case CRYPTO_HASH_ALG_SHA384:
+		sign_md = EVP_sha384();
+		break;
+	case CRYPTO_HASH_ALG_SHA512:
+		sign_md = EVP_sha512();
+		break;
+	default:
+		return NULL;
+	}
+
+	if (!X509_REQ_sign((X509_REQ *) csr, (EVP_PKEY *) key, sign_md))
+		return NULL;
+
+	der_len = i2d_X509_REQ((X509_REQ *) csr, &der);
+	if (der_len < 0)
+		return NULL;
+
+	buf = wpabuf_alloc_copy(der, der_len);
+	OPENSSL_free(der);
+
+	return buf;
+}
+
 #endif /* CONFIG_ECC */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/crypto_wolfssl.c b/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/crypto_wolfssl.c
index 8ddea57..814842e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/crypto_wolfssl.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/crypto_wolfssl.c
@@ -608,7 +608,7 @@
 #endif
 
 
-#ifdef CONFIG_WPS_NFC
+#ifdef CONFIG_WPS
 
 static const unsigned char RFC3526_PRIME_1536[] = {
 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
@@ -694,6 +694,8 @@
 }
 
 
+#ifdef CONFIG_WPS_NFC
+
 void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ)
 {
 	DhKey *ret = NULL;
@@ -735,6 +737,8 @@
 	return ret;
 }
 
+#endif /* CONFIG_WPS_NFC */
+
 
 struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public,
 				  const struct wpabuf *own_private)
@@ -771,7 +775,7 @@
 	XFREE(ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 }
 
-#endif /* CONFIG_WPS_NFC */
+#endif /* CONFIG_WPS */
 
 
 int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey,
@@ -1625,30 +1629,6 @@
 }
 
 
-int crypto_ec_point_solve_y_coord(struct crypto_ec *e,
-				  struct crypto_ec_point *p,
-				  const struct crypto_bignum *x, int y_bit)
-{
-	byte buf[1 + 2 * MAX_ECC_BYTES];
-	int ret;
-	int prime_len = crypto_ec_prime_len(e);
-
-	if (TEST_FAIL())
-		return -1;
-
-	buf[0] = y_bit ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN;
-	ret = crypto_bignum_to_bin(x, buf + 1, prime_len, prime_len);
-	if (ret <= 0)
-		return -1;
-	ret = wc_ecc_import_point_der(buf, 1 + 2 * ret, e->key.idx,
-				      (ecc_point *) p);
-	if (ret != 0)
-		return -1;
-
-	return 0;
-}
-
-
 struct crypto_bignum *
 crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
 			      const struct crypto_bignum *x)
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/random.c b/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/random.c
index 0b15432..7026f4e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/random.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/random.c
@@ -49,9 +49,9 @@
 static u32 pool[POOL_WORDS];
 static unsigned int input_rotate = 0;
 static unsigned int pool_pos = 0;
-static u8 dummy_key[20];
+static u8 stub_key[20];
 #ifdef __linux__
-static size_t dummy_key_avail = 0;
+static size_t stub_key_avail = 0;
 static int random_fd = -1;
 #endif /* __linux__ */
 static unsigned int own_pool_ready = 0;
@@ -109,13 +109,13 @@
 	u32 buf[POOL_WORDS / 2];
 
 	/* First, add hash back to pool to make backtracking more difficult. */
-	hmac_sha1(dummy_key, sizeof(dummy_key), (const u8 *) pool,
+	hmac_sha1(stub_key, sizeof(stub_key), (const u8 *) pool,
 		  sizeof(pool), hash);
 	random_mix_pool(hash, sizeof(hash));
 	/* Hash half the pool to extra data */
 	for (i = 0; i < POOL_WORDS / 2; i++)
 		buf[i] = pool[(pool_pos - i) & POOL_WORDS_MASK];
-	hmac_sha1(dummy_key, sizeof(dummy_key), (const u8 *) buf,
+	hmac_sha1(stub_key, sizeof(stub_key), (const u8 *) buf,
 		  sizeof(buf), hash);
 	/*
 	 * Fold the hash to further reduce any potential output pattern.
@@ -234,7 +234,7 @@
 	 * some key derivation operations to proceed.
 	 */
 
-	if (dummy_key_avail == sizeof(dummy_key))
+	if (stub_key_avail == sizeof(stub_key))
 		return 1; /* Already initialized - good to continue */
 
 	/*
@@ -245,8 +245,8 @@
 	 */
 
 #ifdef CONFIG_GETRANDOM
-	res = getrandom(dummy_key + dummy_key_avail,
-			sizeof(dummy_key) - dummy_key_avail, GRND_NONBLOCK);
+	res = getrandom(stub_key + stub_key_avail,
+			sizeof(stub_key) - stub_key_avail, GRND_NONBLOCK);
 	if (res < 0) {
 		if (errno == ENOSYS) {
 			wpa_printf(MSG_DEBUG,
@@ -270,8 +270,8 @@
 			return -1;
 		}
 
-		res = read(fd, dummy_key + dummy_key_avail,
-			   sizeof(dummy_key) - dummy_key_avail);
+		res = read(fd, stub_key + stub_key_avail,
+			   sizeof(stub_key) - stub_key_avail);
 		if (res < 0) {
 			wpa_printf(MSG_ERROR,
 				   "random: Cannot read from /dev/random: %s",
@@ -282,10 +282,10 @@
 	}
 
 	wpa_printf(MSG_DEBUG, "random: Got %u/%u random bytes", (unsigned) res,
-		   (unsigned) (sizeof(dummy_key) - dummy_key_avail));
-	dummy_key_avail += res;
+		   (unsigned) (sizeof(stub_key) - stub_key_avail));
+	stub_key_avail += res;
 
-	if (dummy_key_avail == sizeof(dummy_key)) {
+	if (stub_key_avail == sizeof(stub_key)) {
 		if (own_pool_ready < MIN_READY_MARK)
 			own_pool_ready = MIN_READY_MARK;
 		random_write_entropy();
@@ -294,7 +294,7 @@
 
 	wpa_printf(MSG_INFO, "random: Only %u/%u bytes of strong "
 		   "random data available",
-		   (unsigned) dummy_key_avail, (unsigned) sizeof(dummy_key));
+		   (unsigned) stub_key_avail, (unsigned) sizeof(stub_key));
 
 	if (own_pool_ready >= MIN_READY_MARK ||
 	    total_collected + 10 * own_pool_ready > MIN_COLLECT_ENTROPY) {
@@ -338,13 +338,13 @@
 {
 	ssize_t res;
 
-	if (dummy_key_avail == sizeof(dummy_key)) {
+	if (stub_key_avail == sizeof(stub_key)) {
 		random_close_fd();
 		return;
 	}
 
-	res = read(sock, dummy_key + dummy_key_avail,
-		   sizeof(dummy_key) - dummy_key_avail);
+	res = read(sock, stub_key + stub_key_avail,
+		   sizeof(stub_key) - stub_key_avail);
 	if (res < 0) {
 		wpa_printf(MSG_ERROR, "random: Cannot read from /dev/random: "
 			   "%s", strerror(errno));
@@ -353,10 +353,10 @@
 
 	wpa_printf(MSG_DEBUG, "random: Got %u/%u bytes from /dev/random",
 		   (unsigned) res,
-		   (unsigned) (sizeof(dummy_key) - dummy_key_avail));
-	dummy_key_avail += res;
+		   (unsigned) (sizeof(stub_key) - stub_key_avail));
+	stub_key_avail += res;
 
-	if (dummy_key_avail == sizeof(dummy_key)) {
+	if (stub_key_avail == sizeof(stub_key)) {
 		random_close_fd();
 		if (own_pool_ready < MIN_READY_MARK)
 			own_pool_ready = MIN_READY_MARK;
@@ -447,9 +447,9 @@
 
 #ifdef CONFIG_GETRANDOM
 	{
-		u8 dummy;
+		u8 stub;
 
-		if (getrandom(&dummy, 0, GRND_NONBLOCK) == 0 ||
+		if (getrandom(&stub, 0, GRND_NONBLOCK) == 0 ||
 		    errno != ENOSYS) {
 			wpa_printf(MSG_DEBUG,
 				   "random: getrandom() support available");
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/tls_openssl.c b/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/tls_openssl.c
index e74f38e..fc3ecde 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/tls_openssl.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/tls_openssl.c
@@ -952,6 +952,10 @@
 	const char *ciphers;
 
 	if (tls_openssl_ref_count == 0) {
+		void openssl_load_legacy_provider(void);
+
+		openssl_load_legacy_provider();
+
 		tls_global = context = tls_context_new(conf);
 		if (context == NULL)
 			return NULL;
@@ -1039,6 +1043,8 @@
 	SSL_CTX_set_options(ssl, SSL_OP_NO_SSLv2);
 	SSL_CTX_set_options(ssl, SSL_OP_NO_SSLv3);
 
+	SSL_CTX_set_mode(ssl, SSL_MODE_AUTO_RETRY);
+
 #ifdef SSL_MODE_NO_AUTO_CHAIN
 	/* Number of deployed use cases assume the default OpenSSL behavior of
 	 * auto chaining the local certificate is in use. BoringSSL removed this
@@ -3009,13 +3015,23 @@
 #endif /* >= 1.1.0 */
 #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) && \
 	!defined(OPENSSL_IS_BORINGSSL)
-	if ((flags & (TLS_CONN_ENABLE_TLSv1_0 | TLS_CONN_ENABLE_TLSv1_1)) &&
-	    SSL_get_security_level(ssl) >= 2) {
-		/*
-		 * Need to drop to security level 1 to allow TLS versions older
-		 * than 1.2 to be used when explicitly enabled in configuration.
-		 */
-		SSL_set_security_level(conn->ssl, 1);
+	{
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+		int need_level = 0;
+#else
+		int need_level = 1;
+#endif
+
+		if ((flags &
+		     (TLS_CONN_ENABLE_TLSv1_0 | TLS_CONN_ENABLE_TLSv1_1)) &&
+		    SSL_get_security_level(ssl) > need_level) {
+			/*
+			 * Need to drop to security level 1 (or 0  with OpenSSL
+			 * 3.0) to allow TLS versions older than 1.2 to be used
+			 * when explicitly enabled in configuration.
+			 */
+			SSL_set_security_level(conn->ssl, need_level);
+		}
 	}
 #endif
 
@@ -3766,6 +3782,7 @@
 				      const u8 *private_key_blob,
 				      size_t private_key_blob_len)
 {
+	BIO *bio;
 	int ok;
 
 	if (private_key == NULL && private_key_blob == NULL)
@@ -3811,6 +3828,28 @@
 			break;
 		}
 
+		bio = BIO_new_mem_buf((u8 *) private_key_blob,
+				      private_key_blob_len);
+		if (bio) {
+			EVP_PKEY *pkey;
+
+			pkey = PEM_read_bio_PrivateKey(
+				bio, NULL, tls_passwd_cb,
+				(void *) private_key_passwd);
+			if (pkey) {
+				if (SSL_use_PrivateKey(conn->ssl, pkey) == 1) {
+					wpa_printf(MSG_DEBUG,
+						   "OpenSSL: SSL_use_PrivateKey --> OK");
+					ok = 1;
+					EVP_PKEY_free(pkey);
+					BIO_free(bio);
+					break;
+				}
+				EVP_PKEY_free(pkey);
+			}
+			BIO_free(bio);
+		}
+
 		if (tls_read_pkcs12_blob(data, conn->ssl, private_key_blob,
 					 private_key_blob_len,
 					 private_key_passwd) == 0) {
@@ -4537,10 +4576,18 @@
 		return NULL;
 	res = SSL_read(conn->ssl, wpabuf_mhead(buf), wpabuf_size(buf));
 	if (res < 0) {
-		tls_show_errors(MSG_INFO, __func__,
-				"Decryption failed - SSL_read");
-		wpabuf_free(buf);
-		return NULL;
+		int err = SSL_get_error(conn->ssl, res);
+
+		if (err == SSL_ERROR_WANT_READ) {
+			wpa_printf(MSG_DEBUG,
+				   "SSL: SSL_connect - want more data");
+			res = 0;
+		} else {
+			tls_show_errors(MSG_INFO, __func__,
+					"Decryption failed - SSL_read");
+			wpabuf_free(buf);
+			return NULL;
+		}
 	}
 	wpabuf_put(buf, res);
 
@@ -5356,6 +5403,7 @@
 
 static void openssl_debug_dump_certificate_chains(SSL_CTX *ssl_ctx)
 {
+	/* OpenSSL: Fix build with OpenSSL 1.0.1 */
 #if !defined(LIBRESSL_VERSION_NUMBER) && !defined(BORINGSSL_API_VERSION) && \
 	OPENSSL_VERSION_NUMBER >= 0x10002000L
 	int res;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/tls_openssl_ocsp.c b/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/tls_openssl_ocsp.c
index 8b37b34..cb75058 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/tls_openssl_ocsp.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/tls_openssl_ocsp.c
@@ -15,6 +15,9 @@
 #include <openssl/asn1.h>
 #include <openssl/asn1t.h>
 #endif /* OPENSSL_IS_BORINGSSL */
+#ifdef ABOVE_13
+#include <x509/internal.h>
+#endif
 
 #include "common.h"
 #include "tls_openssl.h"
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/tls_wolfssl.c b/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/tls_wolfssl.c
index 8090957..6d14f6e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/tls_wolfssl.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/crypto/tls_wolfssl.c
@@ -458,7 +458,7 @@
 	if (client_cert_blob) {
 		if (wolfSSL_use_certificate_chain_buffer_format(
 			    conn->ssl, client_cert_blob, blob_len,
-			    SSL_FILETYPE_ASN1) < 0) {
+			    SSL_FILETYPE_ASN1) != SSL_SUCCESS) {
 			wpa_printf(MSG_INFO,
 				   "SSL: use client cert DER blob failed");
 			return -1;
@@ -468,13 +468,13 @@
 	}
 
 	if (client_cert) {
-		if (wolfSSL_use_certificate_chain_file(conn->ssl,
-						       client_cert) < 0) {
+		if (wolfSSL_use_certificate_chain_file(
+			    conn->ssl, client_cert) != SSL_SUCCESS) {
 			wpa_printf(MSG_INFO,
 				   "SSL: use client cert PEM file failed");
 			if (wolfSSL_use_certificate_chain_file_format(
 				    conn->ssl, client_cert,
-				    SSL_FILETYPE_ASN1) < 0) {
+				    SSL_FILETYPE_ASN1) != SSL_SUCCESS) {
 				wpa_printf(MSG_INFO,
 					   "SSL: use client cert DER file failed");
 				return -1;
@@ -523,7 +523,7 @@
 	if (private_key_blob) {
 		if (wolfSSL_use_PrivateKey_buffer(conn->ssl,
 						  private_key_blob, blob_len,
-						  SSL_FILETYPE_ASN1) < 0) {
+						  SSL_FILETYPE_ASN1) <= 0) {
 			wpa_printf(MSG_INFO,
 				   "SSL: use private DER blob failed");
 		} else {
@@ -534,11 +534,11 @@
 
 	if (!ok && private_key) {
 		if (wolfSSL_use_PrivateKey_file(conn->ssl, private_key,
-						SSL_FILETYPE_PEM) < 0) {
+						SSL_FILETYPE_PEM) <= 0) {
 			wpa_printf(MSG_INFO,
 				   "SSL: use private key PEM file failed");
 			if (wolfSSL_use_PrivateKey_file(conn->ssl, private_key,
-							SSL_FILETYPE_ASN1) < 0)
+							SSL_FILETYPE_ASN1) <= 0)
 			{
 				wpa_printf(MSG_INFO,
 					   "SSL: use private key DER file failed");
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver.h b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver.h
index 727c836..0ee0135 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver.h
@@ -26,6 +26,7 @@
 #include "pae/ieee802_1x_kay.h"
 #endif /* CONFIG_MACSEC */
 #include "utils/list.h"
+#include "common/ifx_vendor.h"
 
 #define HOSTAPD_CHAN_DISABLED 0x00000001
 #define HOSTAPD_CHAN_NO_IR 0x00000002
@@ -316,6 +317,9 @@
 #define IEEE80211_CAP_DMG_PBSS	0x0002 /* Tx by: PCP */
 #define IEEE80211_CAP_DMG_AP	0x0003 /* Tx by: AP */
 
+#if defined(WAPI_ANDROID)
+#define SSID_MAX_WAPI_IE_LEN 100
+#endif 
 #define WPA_SCAN_QUAL_INVALID		BIT(0)
 #define WPA_SCAN_NOISE_INVALID		BIT(1)
 #define WPA_SCAN_LEVEL_INVALID		BIT(2)
@@ -374,6 +378,10 @@
 	u64 parent_tsf;
 	u8 tsf_bssid[ETH_ALEN];
 	size_t ie_len;
+#if defined(WAPI_ANDROID)
+        u8 wapi_ie[SSID_MAX_WAPI_IE_LEN];
+        size_t wapi_ie_len;
+#endif 
 	size_t beacon_ie_len;
 	/* Followed by ie_len + beacon_ie_len octets of IE data */
 };
@@ -648,6 +656,22 @@
 	 */
 	unsigned int oce_scan:1;
 
+	/**
+	 * p2p_include_6ghz - Include 6 GHz channels for P2P full scan
+	 *
+	 */
+	unsigned int p2p_include_6ghz:1;
+
+	/**
+	 * non_coloc_6ghz - Force scanning of non-PSC 6 GHz channels
+	 *
+	 * If this is set, the driver should scan non-PSC channels from the
+	 * scan request even if neighbor reports from 2.4/5 GHz APs did not
+	 * report a co-located AP on these channels. The default is to scan
+	 * non-PSC channels only if a co-located AP was reported on the channel.
+	 */
+	unsigned int non_coloc_6ghz:1;
+
 	/*
 	 * NOTE: Whenever adding new parameters here, please make sure
 	 * wpa_scan_clone_params() and wpa_scan_free_params() get updated with
@@ -1011,7 +1035,9 @@
 	 */
 	const u8 *psk;
 
-	/**
+	/* Refer commit 828b06743f: SAE: Pass SAE password on connect if
+	 * driver advertises SAE authentication offload support.
+	 *
 	 * sae_password - Password for SAE authentication
 	 *
 	 * This value is made available only for WPA3-Personal (SAE) and only
@@ -1057,6 +1083,10 @@
 	 * STA mode: bits 0..3 UAPSD enabled for VO,VI,BK,BE
 	 */
 	int uapsd;
+#if defined(WAPI_ANDROID)
+        const u8 *ap_wapi_ie;
+        size_t ap_wapi_ie_len;
+#endif 
 
 	/**
 	 * fixed_bssid - Whether to force this BSSID in IBSS mode
@@ -1275,14 +1305,14 @@
 	 *
 	 * This parameter can be used to set a specific Beacon frame data rate
 	 * for the BSS. The interpretation of this value depends on the
-	 * rate_type (legacy: in 100 kbps units, HT: HT-MCS, VHT: VHT-MCS). If
-	 * beacon_rate == 0 and rate_type == 0 (BEACON_RATE_LEGACY), the default
-	 * Beacon frame data rate is used.
+	 * rate_type (legacy: in 100 kbps units, HT: HT-MCS, VHT: VHT-MCS,
+	 * HE: HE-MCS). If beacon_rate == 0 and rate_type == 0
+	 * (BEACON_RATE_LEGACY), the default Beacon frame data rate is used.
 	 */
 	unsigned int beacon_rate;
 
 	/**
-	 * beacon_rate_type: Beacon data rate type (legacy/HT/VHT)
+	 * beacon_rate_type: Beacon data rate type (legacy/HT/VHT/HE)
 	 */
 	enum beacon_rate_type rate_type;
 
@@ -1494,19 +1524,36 @@
 	const struct wpabuf *civic;
 
 	/**
-	 * he_spr - Whether Spatial Reuse is enabled
+	 * he_spr_ctrl - Spatial Reuse control field of SPR element
 	 */
-	 int he_spr;
+	u8 he_spr_ctrl;
+
+	/**
+	 * he_spr_non_srg_obss_pd_max_offset - Non-SRG Maximum TX power offset
+	 */
+	u8 he_spr_non_srg_obss_pd_max_offset;
 
 	/**
 	 * he_spr_srg_obss_pd_min_offset - Minimum TX power offset
 	 */
-	 int he_spr_srg_obss_pd_min_offset;
+	u8 he_spr_srg_obss_pd_min_offset;
 
 	/**
 	 * he_spr_srg_obss_pd_max_offset - Maximum TX power offset
 	 */
-	 int he_spr_srg_obss_pd_max_offset;
+	u8 he_spr_srg_obss_pd_max_offset;
+
+	/**
+	 * he_spr_bss_color_bitmap - BSS color values used by members of the
+	 * SRG.
+	 */
+	u8 he_spr_bss_color_bitmap[8];
+
+	/**
+	 * he_spr_partial_bssid_bitmap - Partial BSSID values used by members
+	 * of the SRG.
+	 */
+	u8 he_spr_partial_bssid_bitmap[8];
 
 	/**
 	 * he_bss_color - Whether the BSS Color is disabled
@@ -1535,42 +1582,46 @@
 	 * 2 = both hunting-and-pecking loop and hash-to-element enabled
 	 */
 	int sae_pwe;
+
+	/**
+	 * FILS Discovery frame minimum interval in TUs
+	 */
+	u32 fd_min_int;
+
+	/**
+	 * FILS Discovery frame maximum interval in TUs (0 = FD frame disabled)
+	 */
+	u32 fd_max_int;
+
+	/**
+	 * FILS Discovery frame template data
+	 */
+	u8 *fd_frame_tmpl;
+
+	/**
+	 * FILS Discovery frame template length
+	 */
+	size_t fd_frame_tmpl_len;
+
+	/**
+	 * Unsolicited broadcast Probe Response interval in TUs
+	 */
+	unsigned int unsol_bcast_probe_resp_interval;
+
+	/**
+	 * Unsolicited broadcast Probe Response template data
+	 */
+	u8 *unsol_bcast_probe_resp_tmpl;
+
+	/**
+	 * Unsolicited broadcast Probe Response template length
+	 */
+	size_t unsol_bcast_probe_resp_tmpl_len;
+
 #ifdef CONFIG_BRCM_SAE
         u8 sae_passphrase[MAX_PASSPHRASE_LEN];
         u8 sae_passphrase_len;
 #endif /* CONFIG_BRCM_SAE */
-
-	/* Support for 4-way handshake offload to internal supplicant
-	 * for WPA/WPA2-PSK
-	 */
-	/**
-	 * passphrase - RSN passphrase for PSK
-	 *
-	 * This value is made available only for WPA/WPA2-Personal (PSK) and
-	 * only for drivers that set WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK.
-	 * This is the 8..63 character ASCII passphrase, if available. Please
-	 * note that this can be %NULL if passphrase was not used to generate
-	 * the PSK. In that case, the psk field must be used to fetch the PSK.
-	 */
-	const char *passphrase;
-
-	/**
-	 * psk - RSN PSK (alternative for passphrase for PSK)
-	 *
-	 * This value is made available only for WPA/WPA2-Personal (PSK) and
-	 * only for drivers that set WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK.
-	 * This is the 32-octet (256-bit) PSK, if available. The driver wrapper
-	 * should be prepared to handle %NULL value as an error.
-	 */
-	const u8 *psk;
-
-	/**
-	 * sae_password - Password for SAE authentication
-	 *
-	 * This value is made available only for WPA3-Personal (SAE) and only
-	 * for drivers that set WPA_DRIVER_FLAGS2_SAE_OFFLOAD_AP.
-	 */
-	const char *sae_password;
 };
 
 struct wpa_driver_mesh_bss_params {
@@ -1579,6 +1630,7 @@
 #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
+#define WPA_DRIVER_MESH_CONF_FLAG_FORWARDING		0x00000020
 	/*
 	 * TODO: Other mesh configuration parameters would go here.
 	 * See NL80211_MESHCONF_* for all the mesh config parameters.
@@ -1588,6 +1640,7 @@
 	int peer_link_timeout;
 	int max_peer_links;
 	int rssi_threshold;
+	int forwarding;
 	u16 ht_opmode;
 };
 
@@ -1606,6 +1659,7 @@
 #define WPA_DRIVER_MESH_FLAG_SAE_AUTH	0x00000004
 #define WPA_DRIVER_MESH_FLAG_AMPE	0x00000008
 	unsigned int flags;
+	bool handle_dfs;
 };
 
 struct wpa_driver_set_key_params {
@@ -1883,11 +1937,11 @@
  */
 #define WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P		0x00002000
 /**
- * Driver is known to use sane error codes, i.e., when it indicates that
+ * Driver is known to use valid error codes, i.e., when it indicates that
  * something (e.g., association) fails, there was indeed a failure and the
  * operation does not end up getting completed successfully later.
  */
-#define WPA_DRIVER_FLAGS_SANE_ERROR_CODES		0x00004000
+#define WPA_DRIVER_FLAGS_VALID_ERROR_CODES		0x00004000
 /** Driver supports off-channel TX */
 #define WPA_DRIVER_FLAGS_OFFCHANNEL_TX			0x00008000
 /** Driver indicates TX status events for EAPOL Data frames */
@@ -1997,15 +2051,25 @@
 #define WPA_DRIVER_FLAGS2_CONTROL_PORT_RX	0x0000000000000001ULL
 /** Driver supports TX status reports for EAPOL frames through control port */
 #define WPA_DRIVER_FLAGS2_CONTROL_PORT_TX_STATUS 0x0000000000000002ULL
-/** Driver supports SAE authentication offload in station mode */
-#define WPA_DRIVER_FLAGS2_SAE_OFFLOAD		0x0000000000000004ULL
-/* Support for 4-way handshake offload to internal supplicant
- * for WPA/WPA2-PSK
+/** Driver supports secure LTF */
+#define WPA_DRIVER_FLAGS2_SEC_LTF		0x0000000000000004ULL
+/** Driver supports secure RTT measurement exchange */
+#define WPA_DRIVER_FLAGS2_SEC_RTT		0x0000000000000008ULL
+/**
+ * Driver supports protection of range negotiation and measurement management
+ * frames
  */
-/** Driver supports 4-way handshake offload for WPA-Personal in AP mode */
-#define WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK	0x0000000000000008ULL
-/** Driver supports SAE authentication offload in AP mode */
-#define WPA_DRIVER_FLAGS2_SAE_OFFLOAD_AP	0x0000000000000010ULL
+#define WPA_DRIVER_FLAGS2_PROT_RANGE_NEG	0x0000000000000010ULL
+/** Driver supports Beacon frame TX rate configuration (HE rates) */
+#define WPA_DRIVER_FLAGS2_BEACON_RATE_HE	0x0000000000000020ULL
+/** Driver supports Beacon protection only in client mode */
+#define WPA_DRIVER_FLAGS2_BEACON_PROTECTION_CLIENT 0x0000000000000040ULL
+/** Driver supports Operating Channel Validation */
+#define WPA_DRIVER_FLAGS2_OCV			0x0000000000000080ULL
+/** Driver expects user space implementation of SME in AP mode */
+#define WPA_DRIVER_FLAGS2_AP_SME		0x0000000000000100ULL
+/** Driver supports SAE authentication offload in station mode */
+#define WPA_DRIVER_FLAGS2_SAE_OFFLOAD		0x0000000000000200ULL
 	u64 flags2;
 
 #define FULL_AP_CLIENT_STATE_SUPP(drv_flags) \
@@ -2132,6 +2196,7 @@
 #define STA_DRV_DATA_TX_SHORT_GI BIT(6)
 #define STA_DRV_DATA_RX_SHORT_GI BIT(7)
 #define STA_DRV_DATA_LAST_ACK_RSSI BIT(8)
+#define STA_DRV_DATA_CONN_TIME BIT(9)
 
 struct hostap_sta_driver_data {
 	unsigned long rx_packets, tx_packets;
@@ -2141,6 +2206,7 @@
 	unsigned long current_tx_rate;
 	unsigned long current_rx_rate;
 	unsigned long inactive_msec;
+	unsigned long connected_sec;
 	unsigned long flags; /* bitfield of STA_DRV_DATA_* */
 	unsigned long num_ps_buf_frames;
 	unsigned long tx_retry_failed;
@@ -2379,6 +2445,7 @@
 	TDLS_PEER_HT = BIT(0),
 	TDLS_PEER_VHT = BIT(1),
 	TDLS_PEER_WMM = BIT(2),
+	TDLS_PEER_HE = BIT(3),
 };
 
 /* valid info in the wmm_params struct */
@@ -2439,6 +2506,37 @@
 	int edmg_enabled;
 };
 
+#ifdef CONFIG_TWT_OFFLOAD_IFX
+struct drv_setup_twt_params {
+	u8 dtok;
+	u64 twt;
+	u64 twt_offset;
+	u8 min_twt;
+	u8 exponent;
+	u16 mantissa;
+	enum ifx_twt_oper_setup_cmd_type setup_cmd;
+	u8 requestor;
+	u8 trigger;
+	u8 implicit;
+	u8 flow_type;
+	u8 flow_id;
+	u8 bcast_twt_id;
+	u8 protection;
+	u8 twt_channel;
+	u8 control;
+	enum ifx_twt_param_nego_type negotiation_type;
+	u8 twt_info_frame_disabled;
+	u8 min_twt_unit;	/* true - in TUs, false - in 256us */
+};
+
+struct drv_teardown_twt_params {
+	u8 negotiation_type;
+	u8 flow_id;
+	u8 bcast_twt_id;
+	u8 teardown_all_twt;
+};
+#endif /* CONFIG_TWT_OFFLOAD_IFX */
+
 struct wpa_bss_trans_info {
 	u8 mbo_transition_reason;
 	u8 n_candidates;
@@ -2554,6 +2652,24 @@
 	 * string.
 	 */
 	int (*get_ssid)(void *priv, u8 *ssid);
+#if defined(WAPI_ANDROID)
+        int (*set_wpa_ie)(void *priv, const u8 *wpa_ie, size_t wpa_ie_len);
+        int (*set_wapi)(void *priv, int enabled);
+#endif 
+
+#ifdef CONFIG_TWT_OFFLOAD_IFX
+	/**
+	 * setup_twt - Setup a TWT session
+	 * @params: Setup TWT params
+	 */
+	int (*setup_twt)(void *priv, struct drv_setup_twt_params *params);
+
+	/**
+	 * teardown_twt - Teardown the already negotiated TWT session
+	 * @params: Teardown TWT params
+	 */
+	int (*teardown_twt)(void *priv, struct drv_teardown_twt_params *params);
+#endif /* CONFIG_TWT_OFFLOAD_IFX */
 
 	/**
 	 * set_key - Configure encryption key
@@ -4310,12 +4426,12 @@
 	int (*do_acs)(void *priv, struct drv_acs_params *params);
 
 	/**
-	 * set_band - Notify driver of band selection
+	 * set_band - Notify driver of band(s) selection
 	 * @priv: Private driver interface data
-	 * @band: The selected band(s)
+	 * @band_mask: The selected band(s) bit mask (from enum set_band)
 	 * Returns 0 on success, -1 on failure
 	 */
-	int (*set_band)(void *priv, enum set_band band);
+	int (*set_band)(void *priv, u32 band_mask);
 
 	/**
 	 * get_pref_freq_list - Get preferred frequency list for an interface
@@ -4517,6 +4633,12 @@
 	 * explicitly allow reception of broadcast Public Action frames.
 	 */
 	int (*dpp_listen)(void *priv, bool enable);
+
+#ifdef CONFIG_TESTING_OPTIONS
+	int (*register_frame)(void *priv, u16 type,
+			      const u8 *match, size_t match_len,
+			      bool multicast);
+#endif /* CONFIG_TESTING_OPTIONS */
 };
 
 /**
@@ -4977,6 +5099,9 @@
 	 */
 	EVENT_AVOID_FREQUENCIES,
 
+#if defined(WAPI_ANDROID)
+        EVENT_AUTH_WAPI_ENABLE,
+#endif 
 	/**
 	 * EVENT_NEW_PEER_CANDIDATE - new (unknown) mesh peer notification
 	 */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_bsd.c b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_bsd.c
index 4123941..1ae86c9 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_bsd.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_bsd.c
@@ -16,7 +16,9 @@
 #include "common/ieee802_11_defs.h"
 #include "common/wpa_common.h"
 
+#include <ifaddrs.h>
 #include <net/if.h>
+#include <net/if_dl.h>
 #include <net/if_media.h>
 
 #ifdef __NetBSD__
@@ -614,6 +616,108 @@
 	return 0;
 }
 
+#ifdef SO_RERROR
+static void
+bsd_route_overflow(int sock, void *ctx, struct bsd_driver_global *global)
+{
+	char event_buf[2048]; /* max size of a single route(4) msg */
+	int n;
+	struct ifaddrs *ifaddrs, *ifa;
+	struct bsd_driver_data *drv;
+	struct sockaddr_dl *sdl;
+	union wpa_event_data event;
+
+	/* We need to match the system state, so drain the route
+	 * socket to avoid stale messages. */
+	do {
+		n = read(sock, event_buf, sizeof(event_buf));
+	} while (n != -1 || errno == ENOBUFS);
+
+	if (getifaddrs(&ifaddrs) == -1) {
+		wpa_printf(MSG_ERROR, "%s getifaddrs() failed: %s",
+			   __func__, strerror(errno));
+		return;
+	}
+
+	/* add or update existing interfaces */
+	for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
+		if (ifa->ifa_addr == NULL ||
+		    ifa->ifa_addr->sa_family != AF_LINK)
+			continue;
+		sdl = (struct sockaddr_dl *) (void *) ifa->ifa_addr;
+		drv = bsd_get_drvname(global, ifa->ifa_name);
+		if (drv != NULL &&
+		    (drv->ifindex != sdl->sdl_index || drv->if_removed)) {
+			wpa_printf(MSG_DEBUG,
+				   "RTM_IFANNOUNCE: Interface '%s' added",
+				   drv->ifname);
+			drv->ifindex = sdl->sdl_index;
+			drv->if_removed = 0;
+			event.interface_status.ievent = EVENT_INTERFACE_ADDED;
+			os_strlcpy(event.interface_status.ifname, ifa->ifa_name,
+				   sizeof(event.interface_status.ifname));
+			wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS,
+					     &event);
+		}
+		if (!drv &&
+		    (drv = bsd_get_drvindex(global, sdl->sdl_index)) != NULL) {
+			/* Driver name is invalid */
+			wpa_printf(MSG_DEBUG,
+				   "RTM_IFANNOUNCE: Interface '%s' removed",
+				   drv->ifname);
+			drv->if_removed = 1;
+			event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
+			os_strlcpy(event.interface_status.ifname, drv->ifname,
+				   sizeof(event.interface_status.ifname));
+			wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS,
+					     &event);
+		}
+	}
+
+	/* punt missing interfaces and update flags */
+	dl_list_for_each(drv, &global->ifaces, struct bsd_driver_data, list) {
+		for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
+			if (ifa->ifa_addr == NULL ||
+			    ifa->ifa_addr->sa_family != AF_LINK)
+				continue;
+			sdl = (struct sockaddr_dl *) (void *) ifa->ifa_addr;
+			if (os_strcmp(drv->ifname, ifa->ifa_name) == 0)
+				break;
+		}
+		if (ifa == NULL && !drv->if_removed) {
+			wpa_printf(MSG_DEBUG,
+				   "RTM_IFANNOUNCE: Interface '%s' removed",
+				   drv->ifname);
+			drv->if_removed = 1;
+			event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
+			os_strlcpy(event.interface_status.ifname, drv->ifname,
+				   sizeof(event.interface_status.ifname));
+			wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS,
+					     &event);
+		}
+		if (!ifa)
+			continue;
+
+		if ((ifa->ifa_flags & IFF_UP) == 0 &&
+		    (drv->flags & IFF_UP) != 0) {
+			wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' DOWN",
+				   drv->ifname);
+			wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_DISABLED,
+					     NULL);
+		} else if ((ifa->ifa_flags & IFF_UP) != 0 &&
+			   (drv->flags & IFF_UP) == 0) {
+			wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' UP",
+				   drv->ifname);
+			wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED,
+					     NULL);
+		}
+		drv->flags = ifa->ifa_flags;
+	}
+
+	freeifaddrs(ifaddrs);
+}
+#endif /* SO_RERROR */
+
 static void
 bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx)
 {
@@ -634,6 +738,10 @@
 		if (errno != EINTR && errno != EAGAIN)
 			wpa_printf(MSG_ERROR, "%s read() failed: %s",
 				   __func__, strerror(errno));
+#ifdef SO_RERROR
+		if (errno == ENOBUFS)
+			bsd_route_overflow(sock, ctx, sock_ctx);
+#endif /* SO_RERROR */
 		return;
 	}
 
@@ -1560,14 +1668,15 @@
 	global->ctx = ctx;
 	dl_list_init(&global->ifaces);
 
-	global->sock = socket(PF_INET, SOCK_DGRAM, 0);
+	global->sock = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
 	if (global->sock < 0) {
 		wpa_printf(MSG_ERROR, "socket[PF_INET,SOCK_DGRAM]: %s",
 			   strerror(errno));
 		goto fail1;
 	}
 
-	global->route = socket(PF_ROUTE, SOCK_RAW, 0);
+	global->route = socket(PF_ROUTE,
+			       SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
 	if (global->route < 0) {
 		wpa_printf(MSG_ERROR, "socket[PF_ROUTE,SOCK_RAW]: %s",
 			   strerror(errno));
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_common.c b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_common.c
index e761f83..34aa69c 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_common.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_common.c
@@ -80,6 +80,9 @@
 	E2S(SURVEY);
 	E2S(SCAN_STARTED);
 	E2S(AVOID_FREQUENCIES);
+#if defined(WAPI_ANDROID)
+	E2S(AUTH_WAPI_ENABLE);
+#endif 
 	E2S(NEW_PEER_CANDIDATE);
 	E2S(ACS_CHANNEL_SELECTED);
 	E2S(DFS_CAC_STARTED);
@@ -271,7 +274,7 @@
 	DF2S(P2P_CAPABLE);
 	DF2S(AP_TEARDOWN_SUPPORT);
 	DF2S(P2P_MGMT_AND_NON_P2P);
-	DF2S(SANE_ERROR_CODES);
+	DF2S(VALID_ERROR_CODES);
 	DF2S(OFFCHANNEL_TX);
 	DF2S(EAPOL_TX_STATUS);
 	DF2S(DEAUTH_TX_STATUS);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_hostap.h b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_hostap.h
index 4c1e6d6..ac0b83a 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_hostap.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_hostap.h
@@ -55,8 +55,6 @@
 	PRISM2_PARAM_MONITOR_ALLOW_FCSERR = 16,
 	PRISM2_PARAM_HOST_ENCRYPT = 17,
 	PRISM2_PARAM_HOST_DECRYPT = 18,
-	PRISM2_PARAM_BUS_MASTER_THRESHOLD_RX = 19,
-	PRISM2_PARAM_BUS_MASTER_THRESHOLD_TX = 20,
 	PRISM2_PARAM_HOST_ROAMING = 21,
 	PRISM2_PARAM_BCRX_STA_KEY = 22,
 	PRISM2_PARAM_IEEE_802_1X = 23,
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_macsec_qca.c b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_macsec_qca.c
index 928f024..54964f3 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_macsec_qca.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_macsec_qca.c
@@ -257,6 +257,33 @@
 }
 
 
+static int macsec_qca_secy_id_get(const char *ifname, u32 *secy_id)
+{
+#ifdef NSS_MACSEC_SECY_ID_GET_FUNC
+	/* Get secy id from nss macsec driver */
+	return nss_macsec_secy_id_get((u8 *) ifname, secy_id);
+#else /* NSS_MACSEC_SECY_ID_GET_FUNC */
+	/* Board specific settings */
+	if (os_strcmp(ifname, "eth2") == 0) {
+		*secy_id = 1;
+	} else if (os_strcmp(ifname, "eth3") == 0) {
+		*secy_id = 2;
+	} else if (os_strcmp(ifname, "eth4") == 0 ||
+		   os_strcmp(ifname, "eth0") == 0) {
+		*secy_id = 0;
+	} else if (os_strcmp(ifname, "eth5") == 0 ||
+		   os_strcmp(ifname, "eth1") == 0) {
+		*secy_id = 1;
+	} else {
+		*secy_id = -1;
+		return -1;
+	}
+
+	return 0;
+#endif /* NSS_MACSEC_SECY_ID_GET_FUNC */
+}
+
+
 static void * macsec_qca_init(void *ctx, const char *ifname)
 {
 	struct macsec_qca_data *drv;
@@ -265,13 +292,12 @@
 	if (drv == NULL)
 		return NULL;
 
-	/* Board specific settings */
-	if (os_memcmp("eth2", ifname, 4) == 0)
-		drv->secy_id = 1;
-	else if (os_memcmp("eth3", ifname, 4) == 0)
-		drv->secy_id = 2;
-	else
-		drv->secy_id = -1;
+	if (macsec_qca_secy_id_get(ifname, &drv->secy_id)) {
+		wpa_printf(MSG_ERROR,
+			   "macsec_qca: Failed to get secy_id for %s", ifname);
+		os_free(drv);
+		return NULL;
+	}
 
 	if (driver_wired_init_common(&drv->common, ifname, ctx) < 0) {
 		os_free(drv);
@@ -303,17 +329,13 @@
 		return NULL;
 	}
 
-	/* Board specific settings */
-	if (os_memcmp("eth2", params->ifname, 4) == 0)
-		drv->secy_id = 1;
-	else if (os_memcmp("eth3", params->ifname, 4) == 0)
-		drv->secy_id = 2;
-	else if (os_memcmp("eth4", params->ifname, 4) == 0)
-		drv->secy_id = 0;
-	else if (os_memcmp("eth5", params->ifname, 4) == 0)
-		drv->secy_id = 1;
-	else
-		drv->secy_id = -1;
+	if (macsec_qca_secy_id_get(params->ifname, &drv->secy_id)) {
+		wpa_printf(MSG_ERROR,
+			   "macsec_qca: Failed to get secy_id for %s",
+			   params->ifname);
+		os_free(drv);
+		return NULL;
+	}
 
 	drv->common.ctx = hapd;
 	os_strlcpy(drv->common.ifname, params->ifname,
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_ndis.c b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_ndis.c
index 082ad05..a07fffb 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_ndis.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_ndis.c
@@ -1107,20 +1107,14 @@
 		auth_mode = Ndis802_11AuthModeOpen;
 		priv_mode = Ndis802_11PrivFilterAcceptAll;
 		if (params->wps == WPS_MODE_PRIVACY) {
-			u8 dummy_key[5] = { 0x11, 0x22, 0x33, 0x44, 0x55 };
-			/*
-			 * Some NDIS drivers refuse to associate in open mode
-			 * configuration due to Privacy field mismatch, so use
-			 * a workaround to make the configuration look like
-			 * matching one for WPS provisioning.
-			 */
-			wpa_printf(MSG_DEBUG, "NDIS: Set dummy WEP key as a "
+			u8 stub_key[5] = { 0x11, 0x22, 0x33, 0x44, 0x55 };
+			wpa_printf(MSG_DEBUG, "NDIS: Set stub WEP key as a "
 				   "workaround to allow driver to associate "
 				   "for WPS");
 			wpa_driver_ndis_set_key(drv->ifname, drv, WPA_ALG_WEP,
 						bcast, 0, 1,
-						NULL, 0, dummy_key,
-						sizeof(dummy_key));
+						NULL, 0, stub_key,
+						sizeof(stub_key));
 		}
 #endif /* CONFIG_WPS */
 	} else {
@@ -2227,12 +2221,8 @@
 		}
 	}
 
-	/*
-	 * Windows 98 with Packet.dll 3.0 alpha3 does not include adapter
-	 * descriptions. Fill in dummy descriptors to work around this.
-	 */
 	while (num_desc < num_name)
-		desc[num_desc++] = "dummy description";
+		desc[num_desc++] = "stub description";
 
 	if (num_name != num_desc) {
 		wpa_printf(MSG_DEBUG, "NDIS: mismatch in adapter name and "
@@ -3158,12 +3148,8 @@
 		}
 	}
 
-	/*
-	 * Windows 98 with Packet.dll 3.0 alpha3 does not include adapter
-	 * descriptions. Fill in dummy descriptors to work around this.
-	 */
 	while (num_desc < num_name)
-		desc[num_desc++] = "dummy description";
+		desc[num_desc++] = "stub description";
 
 	if (num_name != num_desc) {
 		wpa_printf(MSG_DEBUG, "NDIS: mismatch in adapter name and "
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_nl80211.c b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_nl80211.c
index ed11723..9434891 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_nl80211.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_nl80211.c
@@ -30,6 +30,7 @@
 #ifdef ANDROID_P2P
 #include "common/brcm_vendor.h"
 #endif /* ANDROID_P2P */
+#include "common/ifx_vendor.h"
 #include "common/ieee802_11_defs.h"
 #include "common/ieee802_11_common.h"
 #include "common/wpa_common.h"
@@ -41,6 +42,15 @@
 #include "rfkill.h"
 #include "driver_nl80211.h"
 
+#if defined(WAPI_ANDROID)
+#include "../../wpa_supplicant/wpa_supplicant_i.h"
+#endif 
+#if defined(WAPI_ANDROID)
+#include "wapi_asue.h"
+#include "wapi.h"
+#define IW_ENCODE_ALG_SM4   0x20
+#define IW_ENCODE_SEQ_MAX_SIZE    8
+#endif 
 #if defined(ANDROID) || defined(BCM_LINUX_BUILD)
 #include "android_drv.h"
 #endif /* ANDROID || BCM_LINUX_BUILD */
@@ -489,8 +499,8 @@
 	}
  out:
 	nl_cb_put(cb);
-	if (!valid_handler && valid_data == (void *) -1)
-		nl80211_nlmsg_clear(msg);
+	/* Always clear the message as it can potentially contain keys */
+	nl80211_nlmsg_clear(msg);
 	nlmsg_free(msg);
 	return err;
 }
@@ -552,6 +562,22 @@
 }
 
 
+static int
+send_and_recv_msgs_connect_handle(struct wpa_driver_nl80211_data *drv,
+				  struct nl_msg *msg, struct i802_bss *bss,
+				  int set_owner)
+{
+	struct nl_sock *nl_connect = get_connect_handle(bss);
+
+	if (nl_connect)
+		return send_and_recv_msgs_owner(drv, msg, nl_connect, set_owner,
+						process_bss_event, bss, NULL,
+						NULL);
+	else
+		return send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
+}
+
+
 struct nl_sock * get_connect_handle(struct i802_bss *bss)
 {
 	if ((bss->drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) ||
@@ -605,13 +631,13 @@
 			       const char *family, const char *group)
 {
 	struct nl_msg *msg;
-	int ret;
+	int ret=0;
 	struct family_data res = { group, -ENOENT };
 
 	msg = nlmsg_alloc();
 	if (!msg)
 		return -ENOMEM;
-	if (!genlmsg_put(msg, 0, 0, genl_ctrl_resolve(global->nl, "nlctrl"),
+	if (!genlmsg_put(msg, 0, 0, global->nlctrl_id,
 			 0, 0, CTRL_CMD_GETFAMILY, 0) ||
 	    nla_put_string(msg, CTRL_ATTR_FAMILY_NAME, family)) {
 		nlmsg_free(msg);
@@ -663,12 +689,10 @@
 
 
 static struct nl_msg *
-nl80211_ifindex_msg(struct wpa_driver_nl80211_data *drv, int ifindex,
-		    int flags, uint8_t cmd)
+nl80211_ifindex_msg_build(struct wpa_driver_nl80211_data *drv,
+			  struct nl_msg *msg, int ifindex, int flags,
+			  uint8_t cmd)
 {
-	struct nl_msg *msg;
-
-	msg = nlmsg_alloc();
 	if (!msg)
 		return NULL;
 
@@ -682,6 +706,15 @@
 }
 
 
+static struct nl_msg *
+nl80211_ifindex_msg(struct wpa_driver_nl80211_data *drv, int ifindex,
+		    int flags, uint8_t cmd)
+{
+	return nl80211_ifindex_msg_build(drv, nlmsg_alloc(), ifindex, flags,
+					 cmd);
+}
+
+
 struct nl_msg * nl80211_drv_msg(struct wpa_driver_nl80211_data *drv, int flags,
 				uint8_t cmd)
 {
@@ -699,6 +732,7 @@
 	int wiphy_idx;
 	enum nl80211_iftype nlmode;
 	u8 *macaddr;
+	u8 use_4addr;
 };
 
 
@@ -721,6 +755,9 @@
 		os_memcpy(info->macaddr, nla_data(tb[NL80211_ATTR_MAC]),
 			  ETH_ALEN);
 
+	if (tb[NL80211_ATTR_4ADDR])
+		info->use_4addr = nla_get_u8(tb[NL80211_ATTR_4ADDR]);
+
 	return NL_SKIP;
 }
 
@@ -776,6 +813,21 @@
 }
 
 
+static int nl80211_get_4addr(struct i802_bss *bss)
+{
+	struct nl_msg *msg;
+	struct wiphy_idx_data data = {
+		.use_4addr = 0,
+	};
+
+	if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_GET_INTERFACE)) ||
+	    send_and_recv_msgs(bss->drv, msg, netdev_info_handler, &data,
+			       NULL, NULL))
+		return -1;
+	return data.use_4addr;
+}
+
+
 static int nl80211_register_beacons(struct wpa_driver_nl80211_data *drv,
 				    struct nl80211_wiphy_data *w)
 {
@@ -1864,6 +1916,13 @@
 		goto err;
 	}
 
+	global->nlctrl_id = genl_ctrl_resolve(global->nl, "nlctrl");
+	if (global->nlctrl_id < 0) {
+		wpa_printf(MSG_ERROR,
+			   "nl80211: 'nlctrl' generic netlink not found");
+		goto err;
+	}
+
 	global->nl_event = nl_create_handle(global->nl_cb, "event");
 	if (global->nl_event == NULL)
 		goto err;
@@ -2188,6 +2247,9 @@
 	bss->ctx = ctx;
 
 	os_strlcpy(bss->ifname, ifname, sizeof(bss->ifname));
+#if defined(WAPI_ANDROID)
+	os_strlcpy(drv->ifname, ifname, sizeof(bss->ifname));
+#endif 
 	drv->monitor_ifidx = -1;
 	drv->monitor_sock = -1;
 	drv->eapol_tx_sock = -1;
@@ -2350,6 +2412,14 @@
 				       (u8 *) "\x03\x00", 2, false);
 	}
 
+#ifdef CONFIG_PASN
+	/* register for PASN Authentication frames */
+	if ((drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
+	    nl80211_register_frame(bss, bss->nl_mgmt, type,
+				   (u8 *) "\x07\x00", 2, false))
+		ret = -1;
+#endif /* CONFIG_PASN */
+
 #ifdef CONFIG_INTERWORKING
 	/* QoS Map Configure */
 	if (nl80211_register_action_frame(bss, (u8 *) "\x01\x04", 2) < 0)
@@ -2478,10 +2548,19 @@
 	    (nl80211_register_action_frame(bss, (u8 *) "\x05\x02", 2) < 0))
 		ret = -1;
 
+	/* Robust AV SCS Response */
+	if (nl80211_register_action_frame(bss, (u8 *) "\x13\x01", 2) < 0)
+		ret = -1;
+
 	/* Robust AV MSCS Response */
 	if (nl80211_register_action_frame(bss, (u8 *) "\x13\x05", 2) < 0)
 		ret = -1;
 
+	/* Protected QoS Management Action frame */
+	if (nl80211_register_action_frame(bss, (u8 *) "\x7e\x50\x6f\x9a\x1a",
+					  5) < 0)
+		ret = -1;
+
 	nl80211_mgmt_handle_register_eloop(bss);
 
 	return ret;
@@ -2650,7 +2729,7 @@
 				   "nl80211: Failed to subscribe to handle Authentication frames - SAE offload may not work");
 #ifdef CONFIG_CY_AP_RX_MGMT_DISCONNECT
 		type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_DISASSOC << 4);
-		if (nl80211_register_frame(bss, bss->nl_mgmt, type, NULL, 0)
+		if (nl80211_register_frame(bss, bss->nl_mgmt, type, NULL, 0, false)
 		    < 0)
 			wpa_printf(MSG_DEBUG,
 				   "nl80211: Failed to subscribe to handle Disassociation frames");
@@ -2826,8 +2905,8 @@
 				set_addr)))
 		return -1;
 
-	if (first && nl80211_get_ifmode(bss) == NL80211_IFTYPE_AP)
-		drv->start_mode_ap = 1;
+	if (first && nl80211_get_ifmode(bss) == NL80211_IFTYPE_STATION)
+		drv->start_mode_sta = 1;
 
 	if (drv->hostapd || bss->static_ap)
 		nlmode = NL80211_IFTYPE_AP;
@@ -2992,7 +3071,7 @@
 	}
 
 	if (drv->nlmode != NL80211_IFTYPE_P2P_DEVICE) {
-		if (!drv->hostapd || !drv->start_mode_ap)
+		if (drv->start_mode_sta)
 			wpa_driver_nl80211_set_mode(bss,
 						    NL80211_IFTYPE_STATION);
 		nl80211_mgmt_unsubscribe(bss, "deinit");
@@ -3006,6 +3085,7 @@
 	os_free(drv->filter_ssids);
 
 	os_free(drv->auth_ie);
+	os_free(drv->auth_data);
 
 	if (drv->in_interface_list)
 		dl_list_del(&drv->list);
@@ -3017,6 +3097,9 @@
 		os_free(drv->iface_ext_capa[i].ext_capa_mask);
 	}
 	os_free(drv->first_bss);
+#ifdef CONFIG_DRIVER_NL80211_QCA
+	os_free(drv->pending_roam_data);
+#endif /* CONFIG_DRIVER_NL80211_QCA */
 	os_free(drv);
 }
 
@@ -3048,6 +3131,11 @@
 		return RSN_CIPHER_SUITE_BIP_CMAC_256;
 	case WPA_ALG_SMS4:
 		return RSN_CIPHER_SUITE_SMS4;
+#if defined(WAPI_ANDROID)
+	case WAPI_ALG_SMS4:
+		wpa_printf(MSG_DEBUG, "%s: WAPI_ALG_SMS4\n", __func__);
+		return RSN_CIPHER_SUITE_SMS4;
+#endif 
 	case WPA_ALG_KRK:
 		return RSN_CIPHER_SUITE_KRK;
 	case WPA_ALG_NONE:
@@ -3171,7 +3259,7 @@
 		nlmsg_free(msg);
 		return -1;
 	}
-	ret = send_and_recv_msgs(drv, msg, NULL, (void *) -1, NULL, NULL);
+	ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
 	if (ret) {
 		wpa_printf(MSG_DEBUG,
 			   "nl80211: Key management set key failed: ret=%d (%s)",
@@ -3195,7 +3283,7 @@
 	if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
 	    nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_BRCM) ||
 	    nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
-				BRCM_VENDOR_SUBCMD_SET_PSK) ||
+				BRCM_VENDOR_SCMD_BCM_PSK) ||
 	    nla_put(msg, NL80211_ATTR_VENDOR_DATA, key_len, key)) {
 		nl80211_nlmsg_clear(msg);
 		nlmsg_free(msg);
@@ -3295,7 +3383,7 @@
 		return -ENOBUFS;
 	}
 
-	ret = send_and_recv_msgs(drv, msg, NULL, (void *) -1, NULL, NULL);
+	ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
 	if (ret) {
 		wpa_printf(MSG_DEBUG, "nl80211: Set PMK failed: ret=%d (%s)",
 			   ret, strerror(-ret));
@@ -3341,6 +3429,17 @@
 		return -EINVAL;
 	}
 
+#if defined(WAPI_ANDROID)
+	if ( (alg == WAPI_ALG_SMS4) && (seq_len > IW_ENCODE_SEQ_MAX_SIZE * 2) ) {
+		wpa_printf(MSG_ERROR, "%s: Invalid seq_len for WAPI_ALG_SMS4 %lu",
+			   __FUNCTION__, (unsigned long) seq_len);
+		return -1;
+	} else if ( (alg != WAPI_ALG_SMS4) && (seq_len > IW_ENCODE_SEQ_MAX_SIZE) ) {
+		wpa_printf(MSG_ERROR, "%s: Invalid seq_len %lu",
+			   __FUNCTION__, (unsigned long) seq_len);
+		return -1;
+	}
+#endif 
 
 #ifdef CONFIG_DRIVER_NL80211_BRCM
 	if (key_flag == KEY_FLAG_PMK &&
@@ -3483,8 +3582,7 @@
 			goto fail;
 	}
 
-	ret = send_and_recv_msgs(drv, msg, NULL, key ? (void *) -1 : NULL,
-				 NULL, NULL);
+	ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
 	if ((ret == -ENOENT || ret == -ENOLINK) && alg == WPA_ALG_NONE)
 		ret = 0;
 	if (ret)
@@ -3655,10 +3753,11 @@
 int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
 			    const u8 *addr, int cmd, u16 reason_code,
 			    int local_state_change,
-			    struct nl_sock *nl_connect)
+			    struct i802_bss *bss)
 {
 	int ret;
 	struct nl_msg *msg;
+	struct nl_sock *nl_connect = get_connect_handle(bss);
 
 	if (!(msg = nl80211_drv_msg(drv, 0, cmd)) ||
 	    nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code) ||
@@ -3670,8 +3769,8 @@
 	}
 
 	if (nl_connect)
-		ret = send_and_recv(drv->global, nl_connect, msg, NULL, NULL,
-				    NULL, NULL);
+		ret = send_and_recv(drv->global, nl_connect, msg,
+				    process_bss_event, bss, NULL, NULL);
 	else
 		ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
 	if (ret) {
@@ -3685,7 +3784,7 @@
 
 static int wpa_driver_nl80211_disconnect(struct wpa_driver_nl80211_data *drv,
 					 u16 reason_code,
-					 struct nl_sock *nl_connect)
+					 struct i802_bss *bss)
 {
 	int ret;
 	int drv_associated = drv->associated;
@@ -3694,7 +3793,7 @@
 	nl80211_mark_disconnected(drv);
 	/* Disconnect command doesn't need BSSID - it uses cached value */
 	ret = wpa_driver_nl80211_mlme(drv, NULL, NL80211_CMD_DISCONNECT,
-				      reason_code, 0, nl_connect);
+				      reason_code, 0, bss);
 	/*
 	 * For locally generated disconnect, supplicant already generates a
 	 * DEAUTH event, so ignore the event from NL80211.
@@ -3717,14 +3816,13 @@
 		return nl80211_leave_ibss(drv, 1);
 	}
 	if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) {
-		return wpa_driver_nl80211_disconnect(drv, reason_code,
-						     get_connect_handle(bss));
+		return wpa_driver_nl80211_disconnect(drv, reason_code, bss);
 	}
 	wpa_printf(MSG_DEBUG, "%s(addr=" MACSTR " reason_code=%d)",
 		   __func__, MAC2STR(addr), reason_code);
 	nl80211_mark_disconnected(drv);
 	ret = wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DEAUTHENTICATE,
-				      reason_code, 0, get_connect_handle(bss));
+				      reason_code, 0, bss);
 	/*
 	 * For locally generated deauthenticate, supplicant already generates a
 	 * DEAUTH event, so ignore the event from NL80211.
@@ -3769,6 +3867,16 @@
 		}
 	}
 
+	os_free(drv->auth_data);
+	drv->auth_data = NULL;
+	drv->auth_data_len = 0;
+	if (params->auth_data) {
+		drv->auth_data = os_memdup(params->auth_data,
+					   params->auth_data_len);
+		if (drv->auth_data)
+			drv->auth_data_len = params->auth_data_len;
+	}
+
 	for (i = 0; i < 4; i++) {
 		if (params->wep_key[i] && params->wep_key_len[i] &&
 		    params->wep_key_len[i] <= 16) {
@@ -4017,6 +4125,8 @@
 
 	params.ie = drv->auth_ie;
 	params.ie_len = drv->auth_ie_len;
+	params.auth_data = drv->auth_data;
+	params.auth_data_len = drv->auth_data_len;
 
 	for (i = 0; i < 4; i++) {
 		if (drv->auth_wep_key_len[i]) {
@@ -4098,17 +4208,41 @@
 			encrypt = 0;
 	}
 
-	if (freq == 0 && drv->nlmode == NL80211_IFTYPE_STATION &&
-	    (drv->capa.flags & WPA_DRIVER_FLAGS_SAE) &&
-	    !(drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
+	if (is_sta_interface(drv->nlmode) &&
 	    WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
 	    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_AUTH) {
-		freq = nl80211_get_assoc_freq(drv);
-		wpa_printf(MSG_DEBUG,
-			   "nl80211: send_mlme - Use assoc_freq=%u for external auth",
-			   freq);
+		if (freq == 0 &&
+		    (drv->capa.flags & WPA_DRIVER_FLAGS_SAE) &&
+		    !(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) {
+			freq = nl80211_get_assoc_freq(drv);
+			wpa_printf(MSG_DEBUG,
+				   "nl80211: send_mlme - Use assoc_freq=%u for external auth",
+				   freq);
+		}
+
+		/* Allow off channel for PASN authentication */
+		if (data_len >= IEEE80211_HDRLEN + 2 &&
+		    WPA_GET_LE16(data + IEEE80211_HDRLEN) == WLAN_AUTH_PASN &&
+		    !offchanok) {
+			wpa_printf(MSG_DEBUG,
+				   "nl80211: send_mlme: allow off channel for PASN");
+			offchanok = 1;
+		}
 	}
 
+#ifdef CONFIG_PASN
+	if (is_sta_interface(drv->nlmode) &&
+	    WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
+	     WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_DEAUTH) {
+		wpa_printf(MSG_DEBUG,
+			   "nl80211: send_mlme: allow Deauthentication frame for PASN");
+
+		use_cookie = 0;
+		offchanok = 1;
+		goto send_frame_cmd;
+	}
+#endif /* CONFIG_PASN */
+
 	if (freq == 0 && drv->nlmode == NL80211_IFTYPE_ADHOC) {
 		freq = nl80211_get_assoc_freq(drv);
 		wpa_printf(MSG_DEBUG,
@@ -4121,7 +4255,7 @@
 		freq = bss->freq;
 	}
 
-	if (drv->use_monitor) {
+	if (drv->use_monitor && is_ap_interface(drv->nlmode)) {
 		wpa_printf(MSG_DEBUG,
 			   "nl80211: send_frame(freq=%u bss->freq=%u) -> send_monitor",
 			   freq, bss->freq);
@@ -4207,6 +4341,7 @@
 	struct nl_msg *acl;
 	unsigned int i;
 	int ret;
+	size_t acl_nla_sz, acl_nlmsg_sz, nla_sz, nlmsg_sz;
 
 	if (!(drv->capa.max_acl_mac_addrs))
 		return -ENOTSUP;
@@ -4217,7 +4352,9 @@
 	wpa_printf(MSG_DEBUG, "nl80211: Set %s ACL (num_mac_acl=%u)",
 		   params->acl_policy ? "Accept" : "Deny", params->num_mac_acl);
 
-	acl = nlmsg_alloc();
+	acl_nla_sz = nla_total_size(ETH_ALEN) * params->num_mac_acl;
+	acl_nlmsg_sz = nlmsg_total_size(acl_nla_sz);
+	acl = nlmsg_alloc_size(acl_nlmsg_sz);
 	if (!acl)
 		return -ENOMEM;
 	for (i = 0; i < params->num_mac_acl; i++) {
@@ -4227,7 +4364,19 @@
 		}
 	}
 
-	if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_MAC_ACL)) ||
+	/*
+	 * genetlink message header (Length of user header is 0) +
+	 * u32 attr: NL80211_ATTR_IFINDEX +
+	 * u32 attr: NL80211_ATTR_ACL_POLICY +
+	 * nested acl attr
+	 */
+	nla_sz = GENL_HDRLEN +
+		nla_total_size(4) * 2 +
+		nla_total_size(acl_nla_sz);
+	nlmsg_sz = nlmsg_total_size(nla_sz);
+	if (!(msg = nl80211_ifindex_msg_build(drv, nlmsg_alloc_size(nlmsg_sz),
+					      drv->ifindex, 0,
+					      NL80211_CMD_SET_MAC_ACL)) ||
 	    nla_put_u32(msg, NL80211_ATTR_ACL_POLICY, params->acl_policy ?
 			NL80211_ACL_POLICY_DENY_UNLESS_LISTED :
 			NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED) ||
@@ -4302,11 +4451,12 @@
 #endif /* CONFIG_MESH */
 
 
-static int nl80211_put_beacon_rate(struct nl_msg *msg, const u64 flags,
+static int nl80211_put_beacon_rate(struct nl_msg *msg, u64 flags, u64 flags2,
 				   struct wpa_driver_ap_params *params)
 {
 	struct nlattr *bands, *band;
 	struct nl80211_txrate_vht vht_rate;
+	struct nl80211_txrate_he he_rate;
 
 	if (!params->freq ||
 	    (params->beacon_rate == 0 &&
@@ -4323,7 +4473,10 @@
 		band = nla_nest_start(msg, NL80211_BAND_2GHZ);
 		break;
 	case HOSTAPD_MODE_IEEE80211A:
-		band = nla_nest_start(msg, NL80211_BAND_5GHZ);
+		if (is_6ghz_freq(params->freq->freq))
+			band = nla_nest_start(msg, NL80211_BAND_6GHZ);
+		else
+			band = nla_nest_start(msg, NL80211_BAND_5GHZ);
 		break;
 	case HOSTAPD_MODE_IEEE80211AD:
 		band = nla_nest_start(msg, NL80211_BAND_60GHZ);
@@ -4336,6 +4489,7 @@
 		return -1;
 
 	os_memset(&vht_rate, 0, sizeof(vht_rate));
+	os_memset(&he_rate, 0, sizeof(he_rate));
 
 	switch (params->rate_type) {
 	case BEACON_RATE_LEGACY:
@@ -4388,6 +4542,22 @@
 		wpa_printf(MSG_DEBUG, " * beacon_rate = VHT-MCS %u",
 			   params->beacon_rate);
 		break;
+	case BEACON_RATE_HE:
+		if (!(flags2 & WPA_DRIVER_FLAGS2_BEACON_RATE_HE)) {
+			wpa_printf(MSG_INFO,
+				   "nl80211: Driver does not support setting Beacon frame rate (HE)");
+			return -1;
+		}
+		he_rate.mcs[0] = BIT(params->beacon_rate);
+		if (nla_put(msg, NL80211_TXRATE_LEGACY, 0, NULL) ||
+		    nla_put(msg, NL80211_TXRATE_HT, 0, NULL) ||
+		    nla_put(msg, NL80211_TXRATE_VHT, sizeof(vht_rate),
+			    &vht_rate) ||
+		    nla_put(msg, NL80211_TXRATE_HE, sizeof(he_rate), &he_rate))
+			return -1;
+		wpa_printf(MSG_DEBUG, " * beacon_rate = HE-MCS %u",
+			   params->beacon_rate);
+		break;
 	}
 
 	nla_nest_end(msg, band);
@@ -4453,7 +4623,7 @@
 	if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
 	    nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_BRCM) ||
 	    nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
-	                        BRCM_VENDOR_SUBCMD_SET_PSK) ||
+	                        BRCM_VENDOR_SCMD_BCM_PSK) ||
 	    nla_put(msg, NL80211_ATTR_VENDOR_DATA, key_len, key)) {
 	        nl80211_nlmsg_clear(msg);
 	        nlmsg_free(msg);
@@ -4513,6 +4683,69 @@
 #endif /* CONFIG_SAE */
 
 
+#ifdef CONFIG_FILS
+static int nl80211_fils_discovery(struct i802_bss *bss, struct nl_msg *msg,
+				  struct wpa_driver_ap_params *params)
+{
+	struct nlattr *attr;
+
+	if (!bss->drv->fils_discovery) {
+		wpa_printf(MSG_ERROR,
+			   "nl80211: Driver does not support FILS Discovery frame transmission for %s",
+			   bss->ifname);
+		return -1;
+	}
+
+	attr = nla_nest_start(msg, NL80211_ATTR_FILS_DISCOVERY);
+	if (!attr ||
+	    nla_put_u32(msg, NL80211_FILS_DISCOVERY_ATTR_INT_MIN,
+			params->fd_min_int) ||
+	    nla_put_u32(msg, NL80211_FILS_DISCOVERY_ATTR_INT_MAX,
+			params->fd_max_int) ||
+	    (params->fd_frame_tmpl &&
+	     nla_put(msg, NL80211_FILS_DISCOVERY_ATTR_TMPL,
+		     params->fd_frame_tmpl_len, params->fd_frame_tmpl)))
+		return -1;
+
+	nla_nest_end(msg, attr);
+	return 0;
+}
+#endif /* CONFIG_FILS */
+
+
+#ifdef CONFIG_IEEE80211AX
+static int nl80211_unsol_bcast_probe_resp(struct i802_bss *bss,
+					  struct nl_msg *msg,
+					  struct wpa_driver_ap_params *params)
+{
+	struct nlattr *attr;
+
+	if (!bss->drv->unsol_bcast_probe_resp) {
+		wpa_printf(MSG_ERROR,
+			   "nl80211: Driver does not support unsolicited broadcast Probe Response frame transmission for %s",
+			   bss->ifname);
+		return -1;
+	}
+
+	wpa_printf(MSG_DEBUG,
+		   "nl80211: Unsolicited broadcast Probe Response frame interval: %u",
+		   params->unsol_bcast_probe_resp_interval);
+	attr = nla_nest_start(msg, NL80211_ATTR_UNSOL_BCAST_PROBE_RESP);
+	if (!attr ||
+	    nla_put_u32(msg, NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INT,
+			params->unsol_bcast_probe_resp_interval) ||
+	    (params->unsol_bcast_probe_resp_tmpl &&
+	     nla_put(msg, NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL,
+		     params->unsol_bcast_probe_resp_tmpl_len,
+		     params->unsol_bcast_probe_resp_tmpl)))
+		return -1;
+
+	nla_nest_end(msg, attr);
+	return 0;
+}
+#endif /* CONFIG_IEEE80211AX */
+
+
 static int wpa_driver_nl80211_set_ap(void *priv,
 				     struct wpa_driver_ap_params *params)
 {
@@ -4563,7 +4796,8 @@
 	    nla_put(msg, NL80211_ATTR_BEACON_TAIL, params->tail_len,
 		    params->tail) ||
 	    nl80211_put_beacon_int(msg, params->beacon_int) ||
-	    nl80211_put_beacon_rate(msg, drv->capa.flags, params) ||
+	    nl80211_put_beacon_rate(msg, drv->capa.flags, drv->capa.flags2,
+				    params) ||
 	    nl80211_put_dtim_period(msg, params->dtim_period) ||
 	    nla_put(msg, NL80211_ATTR_SSID, params->ssid_len, params->ssid))
 		goto fail;
@@ -4663,36 +4897,6 @@
 	    nla_put_u32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, suite))
 		goto fail;
 
-	/* Support for 4-way handshake offload to internal supplicant
-	 * for WPA/WPA2-PSK. Add PSK in case of 4-way handshake offload
-	 */
-	if (params->psk &&
-	    (drv->capa.flags2 & WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK)) {
-		wpa_hexdump_key(MSG_DEBUG, "nl80211: PSK", params->psk, 32);
-		if (nla_put(msg, NL80211_ATTR_PMK, 32, params->psk))
-			goto fail;
-	}
-
-#ifdef CONFIG_SAE
-	/* Add SAE password in case of SAE authentication offload */
-	if ((params->sae_password || params->passphrase) &&
-	    (params->key_mgmt_suites & WPA_KEY_MGMT_SAE) &&
-	    (drv->capa.flags2 & WPA_DRIVER_FLAGS2_SAE_OFFLOAD_AP)) {
-		const char *password;
-		size_t pwd_len;
-
-		if (params->sae_password)
-			password = params->sae_password;
-		else
-			password = params->passphrase;
-
-		pwd_len = os_strlen(password);
-		wpa_hexdump_ascii_key(MSG_DEBUG, "nl80211: SAE password",
-				      (u8 *) password, pwd_len);
-		if (nla_put(msg, NL80211_ATTR_SAE_PASSWORD, pwd_len, password))
-			goto fail;
-	}
-#endif /* CONFIG_SAE */
 
 	if (params->beacon_ies) {
 		wpa_hexdump_buf(MSG_DEBUG, "nl80211: beacon_ies",
@@ -4772,17 +4976,34 @@
 	}
 
 #ifdef CONFIG_IEEE80211AX
-	if (params->he_spr) {
+	if (params->he_spr_ctrl) {
 		struct nlattr *spr;
 
 		spr = nla_nest_start(msg, NL80211_ATTR_HE_OBSS_PD);
-		wpa_printf(MSG_DEBUG, "nl80211: he_spr=%d", params->he_spr);
+		wpa_printf(MSG_DEBUG, "nl80211: he_spr_ctrl=0x%x",
+			   params->he_spr_ctrl);
 
 		if (!spr ||
-		    nla_put_u8(msg, NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET,
-			       params->he_spr_srg_obss_pd_min_offset) ||
-		    nla_put_u8(msg, NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET,
-			       params->he_spr_srg_obss_pd_max_offset))
+		    nla_put_u8(msg, NL80211_HE_OBSS_PD_ATTR_SR_CTRL,
+			       params->he_spr_ctrl) ||
+		    ((params->he_spr_ctrl &
+		      SPATIAL_REUSE_NON_SRG_OFFSET_PRESENT) &&
+		     nla_put_u8(msg, NL80211_HE_OBSS_PD_ATTR_NON_SRG_MAX_OFFSET,
+				params->he_spr_non_srg_obss_pd_max_offset)))
+			goto fail;
+
+		if ((params->he_spr_ctrl &
+		     SPATIAL_REUSE_SRG_INFORMATION_PRESENT) &&
+		    (nla_put_u8(msg, NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET,
+				params->he_spr_srg_obss_pd_min_offset) ||
+		     nla_put_u8(msg, NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET,
+				params->he_spr_srg_obss_pd_max_offset) ||
+		     nla_put(msg, NL80211_HE_OBSS_PD_ATTR_BSS_COLOR_BITMAP,
+			     sizeof(params->he_spr_bss_color_bitmap),
+			     params->he_spr_bss_color_bitmap) ||
+		     nla_put(msg, NL80211_HE_OBSS_PD_ATTR_PARTIAL_BSSID_BITMAP,
+			     sizeof(params->he_spr_partial_bssid_bitmap),
+			     params->he_spr_partial_bssid_bitmap)))
 			goto fail;
 
 		nla_nest_end(msg, spr);
@@ -4809,6 +5030,10 @@
 		if (nla_put_flag(msg, NL80211_ATTR_TWT_RESPONDER))
 			goto fail;
 	}
+
+	if (params->unsol_bcast_probe_resp_interval &&
+	    nl80211_unsol_bcast_probe_resp(bss, msg, params) < 0)
+		goto fail;
 #endif /* CONFIG_IEEE80211AX */
 
 #ifdef CONFIG_SAE
@@ -4818,8 +5043,12 @@
 		goto fail;
 #endif /* CONFIG_SAE */
 
-	ret = send_and_recv_msgs_owner(drv, msg, get_connect_handle(bss), 1,
-				       NULL, NULL, NULL, NULL);
+#ifdef CONFIG_FILS
+	if (params->fd_max_int && nl80211_fils_discovery(bss, msg, params) < 0)
+		goto fail;
+#endif /* CONFIG_FILS */
+
+	ret = send_and_recv_msgs_connect_handle(drv, msg, bss, 1);
 	if (ret) {
 		wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)",
 			   ret, strerror(-ret));
@@ -5170,6 +5399,16 @@
 				goto fail;
 		}
 
+		if (params->he_6ghz_capab) {
+			wpa_hexdump(MSG_DEBUG, "  * he_6ghz_capab",
+				    params->he_6ghz_capab,
+				    sizeof(*params->he_6ghz_capab));
+			if (nla_put(msg, NL80211_ATTR_HE_6GHZ_CAPABILITY,
+				    sizeof(*params->he_6ghz_capab),
+				    params->he_6ghz_capab))
+				goto fail;
+		}
+
 		if (params->ext_capab) {
 			wpa_hexdump(MSG_DEBUG, "  * ext_capab",
 				    params->ext_capab, params->ext_capab_len);
@@ -5194,7 +5433,7 @@
 			/*
 			 * cfg80211 validates that AID is non-zero, so we have
 			 * to make this a non-zero value for the TDLS case where
-			 * a dummy STA entry is used for now and for a station
+			 * a stub STA entry is used for now and for a station
 			 * that is still not associated.
 			 */
 			wpa_printf(MSG_DEBUG, "  * aid=1 (%s workaround)",
@@ -5501,6 +5740,10 @@
 	if (nla_put_flag(msg, NL80211_ATTR_IFACE_SOCKET_OWNER))
 		goto fail;
 
+	if ((addr && iftype == NL80211_IFTYPE_P2P_DEVICE) &&
+	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
+		goto fail;
+
 	ret = send_and_recv_msgs(drv, msg, handler, arg, NULL, NULL);
 	msg = NULL;
 	if (ret) {
@@ -5857,6 +6100,7 @@
 {
 	struct i802_bss *bss = priv;
 	struct nl_msg *msg;
+	int ret;
 
 	wpa_printf(MSG_DEBUG,
 		   "nl80211: Set STA airtime weight - ifname=%s addr=" MACSTR
@@ -5867,7 +6111,13 @@
 	    nla_put_u16(msg, NL80211_ATTR_AIRTIME_WEIGHT, weight))
 		goto fail;
 
-	return send_and_recv_msgs(bss->drv, msg, NULL, NULL, NULL, NULL);
+	ret = send_and_recv_msgs(bss->drv, msg, NULL, NULL, NULL, NULL);
+	if (ret) {
+		wpa_printf(MSG_DEBUG,
+			   "nl80211: SET_STATION[AIRTIME_WEIGHT] failed: ret=%d (%s)",
+			   ret, strerror(-ret));
+	}
+	return ret;
 fail:
 	nlmsg_free(msg);
 	return -ENOBUFS;
@@ -5911,9 +6161,7 @@
 	int ret;
 
 	msg = nl80211_drv_msg(drv, 0, NL80211_CMD_LEAVE_IBSS);
-	ret = send_and_recv_msgs_owner(drv, msg,
-				       get_connect_handle(drv->first_bss), 1,
-				       NULL, NULL, NULL, NULL);
+	ret = send_and_recv_msgs_connect_handle(drv, msg, drv->first_bss, 1);
 	if (ret) {
 		wpa_printf(MSG_DEBUG, "nl80211: Leave IBSS failed: ret=%d "
 			   "(%s)", ret, strerror(-ret));
@@ -5971,6 +6219,14 @@
 	}
 #endif /* CONFIG_VHT_OVERRIDES */
 
+#ifdef CONFIG_HE_OVERRIDES
+	if (params->disable_he) {
+		wpa_printf(MSG_DEBUG, "  * HE disabled");
+		if (nla_put_flag(msg, NL80211_ATTR_DISABLE_HE))
+			return -1;
+	}
+#endif /* CONFIG_HE_OVERRIDES */
+
 	return 0;
 }
 
@@ -6045,9 +6301,7 @@
 	if (ret < 0)
 		goto fail;
 
-	ret = send_and_recv_msgs_owner(drv, msg,
-				       get_connect_handle(drv->first_bss), 1,
-				       NULL, NULL, NULL, NULL);
+	ret = send_and_recv_msgs_connect_handle(drv, msg, drv->first_bss, 1);
 	msg = NULL;
 	if (ret) {
 		wpa_printf(MSG_DEBUG, "nl80211: Join IBSS failed: ret=%d (%s)",
@@ -6118,6 +6372,21 @@
 {
 	if (nla_put_flag(msg, NL80211_ATTR_IFACE_SOCKET_OWNER))
 		return -1;
+#if defined(WAPI_ANDROID)
+	struct wpa_supplicant *wpa_s = drv->ctx;
+	int wapi_ie_present = 0;
+    if(drv->ap_wapi_ie_len && drv->ap_wapi_ie) {
+		wpa_printf(MSG_ERROR, "%s : Set wpa_s->ap_wapi_ie and "
+			"wpa_s->ap_wapi_ie_len\n",__func__);
+		memcpy(wpa_s->ap_wapi_ie, drv->ap_wapi_ie, drv->ap_wapi_ie_len);
+		wpa_s->ap_wapi_ie_len = drv->ap_wapi_ie_len;
+	}
+
+	if (params->wpa_ie_len && params->wpa_ie && (params->wpa_ie[0] == WLAN_EID_WAPI)) {
+		wapi_ie_present = 1;
+		wpa_printf(MSG_ERROR, " * ## WAPI element ID present in IE\n");
+	}
+#endif 
 
 	if (params->bssid) {
 		wpa_printf(MSG_DEBUG, "  * bssid=" MACSTR,
@@ -6183,6 +6452,16 @@
 	}
 
 	wpa_hexdump(MSG_DEBUG, "  * IEs", params->wpa_ie, params->wpa_ie_len);
+#if defined(WAPI_ANDROID)
+    wpa_printf(MSG_DEBUG, "%s: params->wpa_ie_len=%d\n", __FUNCTION__, (int)params->wpa_ie_len);
+	if (wapi_ie_present) {
+		wpa_printf(MSG_DEBUG, "%s: params->wpa_ie: [%02x][%02x][%02x][%02x]\n",
+				   __FUNCTION__, params->wpa_ie[0], params->wpa_ie[1], params->wpa_ie[2], params->wpa_ie[3]);
+		wpa_printf(MSG_DEBUG, "params->wpa_ie[0] == WLAN_EID_WAPI\n");
+		drv->ap_wapi_ie = params->ap_wapi_ie ;
+		drv->ap_wapi_ie_len = params->ap_wapi_ie_len ;
+	}
+#endif 
 	if (params->wpa_ie &&
 	    nla_put(msg, NL80211_ATTR_IE, params->wpa_ie_len, params->wpa_ie))
 		return -1;
@@ -6193,7 +6472,15 @@
 		if (params->wpa_proto & WPA_PROTO_WPA)
 			ver |= NL80211_WPA_VERSION_1;
 		if (params->wpa_proto & WPA_PROTO_RSN) {
-			if ((params->key_mgmt_suite == WPA_KEY_MGMT_SAE) &&
+			/* Refer commit 828b06743f: SAE: Pass SAE password on
+			 * connect if driver advertises SAE authentication
+			 * offload support.
+			 */
+			/* Refer commit 8ced7f3596: SAE: Set the right WPA
+			 * Versions for FT-SAE key management
+			 */
+			if ((params->key_mgmt_suite == WPA_KEY_MGMT_SAE ||
+				params->key_mgmt_suite == WPA_KEY_MGMT_FT_SAE) &&
 				(drv->capa.flags2 & WPA_DRIVER_FLAGS2_SAE_OFFLOAD))
 				ver |= NL80211_WPA_VERSION_3;
 			else
@@ -6204,15 +6491,44 @@
 		if (nla_put_u32(msg, NL80211_ATTR_WPA_VERSIONS, ver))
 			return -1;
 	}
+#if defined(WAPI_ANDROID)
+        else if (params->wpa_ie && params->wpa_ie[0] == WLAN_EID_WAPI) {
+                wpa_printf(MSG_ERROR, "## its EID_WAPI\n");
+                wpa_printf(MSG_DEBUG, " * NO params->wpa_ie && params->wpa_ie_len");
+        }
+#endif 
 
 	if (params->pairwise_suite != WPA_CIPHER_NONE) {
 		u32 cipher = wpa_cipher_to_cipher_suite(params->pairwise_suite);
 		wpa_printf(MSG_DEBUG, "  * pairwise=0x%x", cipher);
+#if defined(WAPI_ANDROID)
+		if (wapi_ie_present) { /* wapi */
+			wpa_printf(MSG_DEBUG, " * Set SUITES_PAIRWISE to RSN_CIPHER_SUITE_SMS4");
+			cipher = RSN_CIPHER_SUITE_SMS4;
+		}
+#endif 
 		if (nla_put_u32(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
 				cipher))
 			return -1;
 	}
 
+#if defined(WAPI_ANDROID)
+        else {
+
+                if (params->wpa_ie && params->wpa_ie[0] == WLAN_EID_WAPI) { /* wapi */
+                        int cipher;
+                        wpa_printf(MSG_DEBUG, " * Set SUITES_PAIRWISE to RSN_CIPHER_SUITE_SMS4");
+                        cipher = RSN_CIPHER_SUITE_SMS4;
+
+                        params->pairwise_suite = RSN_CIPHER_SUITE_SMS4;
+
+                        nla_put_u32(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE, cipher);
+
+                }
+                wpa_printf(MSG_DEBUG, " * Set 22222222222222222\n");
+	}
+#else /* WAPI */
+#endif 
 	if (params->group_suite == WPA_CIPHER_GTK_NOT_USED &&
 	    !(drv->capa.enc & WPA_DRIVER_CAPA_ENC_GTK_NOT_USED)) {
 		/*
@@ -6223,12 +6539,22 @@
 	} else if (params->group_suite != WPA_CIPHER_NONE) {
 		u32 cipher = wpa_cipher_to_cipher_suite(params->group_suite);
 		wpa_printf(MSG_DEBUG, "  * group=0x%x", cipher);
+#if defined(WAPI_ANDROID)
+		if (wapi_ie_present) { /* wapi */
+			wpa_printf(MSG_DEBUG, " * Set SUITE_GROUP to RSN_CIPHER_SUITE_SMS4");
+			cipher = RSN_CIPHER_SUITE_SMS4;
+		}
+#endif 
 		if (nla_put_u32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, cipher))
 			return -1;
 	}
 
 	if (params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
 	    params->key_mgmt_suite == WPA_KEY_MGMT_PSK ||
+#if defined(WAPI_ANDROID)
+	    params->key_mgmt_suite == WPA_KEY_MGMT_WAPI_PSK ||
+	    params->key_mgmt_suite == WPA_KEY_MGMT_WAPI_CERT ||
+#endif 
 
 	    params->key_mgmt_suite == WPA_KEY_MGMT_FT_IEEE8021X ||
 	    params->key_mgmt_suite == WPA_KEY_MGMT_FT_PSK ||
@@ -6256,6 +6582,14 @@
 		case WPA_KEY_MGMT_IEEE8021X:
 			mgmt = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
 			break;
+#if defined(WAPI_ANDROID)
+		case WPA_KEY_MGMT_WAPI_PSK:
+			mgmt = WLAN_AKM_SUITE_WAPI_PSK;
+			break;
+		case WPA_KEY_MGMT_WAPI_CERT:
+			mgmt = WLAN_AKM_SUITE_WAPI_CERT;
+			break;
+#endif 
 		case WPA_KEY_MGMT_FT_IEEE8021X:
 			mgmt = RSN_AUTH_KEY_MGMT_FT_802_1X;
 			break;
@@ -6329,7 +6663,9 @@
 			return -1;
 	}
 
-	/* add SAE password in case of SAE authentication offload */
+	/* Refer commit 828b06743f: add SAE password in case of SAE
+	 * authentication offload
+	 */
 	if ((params->sae_password || params->passphrase) &&
 	    (drv->capa.flags2 & WPA_DRIVER_FLAGS2_SAE_OFFLOAD)) {
 		const char *password;
@@ -6425,7 +6761,7 @@
 static int wpa_driver_nl80211_try_connect(
 	struct wpa_driver_nl80211_data *drv,
 	struct wpa_driver_associate_params *params,
-	struct nl_sock *nl_connect)
+	struct i802_bss *bss)
 {
 	struct nl_msg *msg;
 	enum nl80211_auth_type type;
@@ -6492,6 +6828,9 @@
 		algs++;
 	if (params->auth_alg & WPA_AUTH_ALG_FT)
 		algs++;
+	/* Refer commit 828b06743f: SAE: Pass SAE password on connect
+	 * if driver advertises SAE authentication offload support.
+	 */
 	if (params->auth_alg & WPA_AUTH_ALG_SAE)
 		algs++;
 	if (algs > 1) {
@@ -6501,6 +6840,12 @@
 	}
 
 	type = get_nl_auth_type(params->auth_alg);
+#if defined(WAPI_ANDROID)
+	if (params->wpa_ie && params->wpa_ie[0] == WLAN_EID_WAPI) {
+		wpa_printf(MSG_DEBUG, "params->wpa_ie[0] == WLAN_EID_WAPI, Set type = NL80211_AUTHTYPE_OPEN_SYSTEM\n");
+		type = NL80211_AUTHTYPE_OPEN_SYSTEM;
+	}
+#endif 
 	wpa_printf(MSG_DEBUG, "  * Auth Type %d", type);
 	if (type == NL80211_AUTHTYPE_MAX ||
 	    nla_put_u32(msg, NL80211_ATTR_AUTH_TYPE, type))
@@ -6520,13 +6865,16 @@
 		}
 	}
 #endif /* CONFIG_BRCM_SAE */
-	ret = send_and_recv_msgs_owner(drv, msg, nl_connect, 1, NULL,
-				       (void *) -1, NULL, NULL);
+
+	ret = send_and_recv_msgs_connect_handle(drv, msg, bss, 1);
 	msg = NULL;
 	if (ret) {
 		wpa_printf(MSG_DEBUG, "nl80211: MLME connect failed: ret=%d "
 			   "(%s)", ret, strerror(-ret));
 	} else {
+#ifdef CONFIG_DRIVER_NL80211_QCA
+		drv->roam_indication_done = false;
+#endif /* CONFIG_DRIVER_NL80211_QCA */
 		wpa_printf(MSG_DEBUG,
 			   "nl80211: Connect request send successfully");
 	}
@@ -6542,7 +6890,7 @@
 static int wpa_driver_nl80211_connect(
 	struct wpa_driver_nl80211_data *drv,
 	struct wpa_driver_associate_params *params,
-	struct nl_sock *nl_connect)
+	struct i802_bss *bss)
 {
 	int ret;
 
@@ -6552,15 +6900,15 @@
 	else
 		os_memset(drv->auth_attempt_bssid, 0, ETH_ALEN);
 
-	ret = wpa_driver_nl80211_try_connect(drv, params, nl_connect);
+	ret = wpa_driver_nl80211_try_connect(drv, params, bss);
 	if (ret == -EALREADY) {
 		wpa_printf(MSG_DEBUG, "nl80211: Explicitly "
 			   "disconnecting before reassociation "
 			   "attempt");
 		if (wpa_driver_nl80211_disconnect(
-			    drv, WLAN_REASON_PREV_AUTH_NOT_VALID, nl_connect))
+			    drv, WLAN_REASON_PREV_AUTH_NOT_VALID, bss))
 			return -1;
-		ret = wpa_driver_nl80211_try_connect(drv, params, nl_connect);
+		ret = wpa_driver_nl80211_try_connect(drv, params, bss);
 	}
 	return ret;
 }
@@ -6594,8 +6942,7 @@
 		else
 			bss->use_nl_connect = 0;
 
-		return wpa_driver_nl80211_connect(drv, params,
-						  get_connect_handle(bss));
+		return wpa_driver_nl80211_connect(drv, params, bss);
 	}
 
 	nl80211_mark_disconnected(drv);
@@ -6630,9 +6977,7 @@
 			goto fail;
 	}
 
-	ret = send_and_recv_msgs_owner(drv, msg,
-				       get_connect_handle(drv->first_bss), 1,
-				       NULL, NULL, NULL, NULL);
+	ret = send_and_recv_msgs_connect_handle(drv, msg, drv->first_bss, 1);
 	msg = NULL;
 	if (ret) {
 		wpa_dbg(drv->ctx, MSG_DEBUG,
@@ -7123,6 +7468,7 @@
 		[NL80211_STA_INFO_ACK_SIGNAL] = { .type = NLA_U8 },
 		[NL80211_STA_INFO_RX_DURATION] = { .type = NLA_U64 },
 		[NL80211_STA_INFO_TX_DURATION] = { .type = NLA_U64 },
+		[NL80211_STA_INFO_CONNECTED_TIME] = { .type = NLA_U32 },
 	};
 	struct nlattr *rate[NL80211_RATE_INFO_MAX + 1];
 	static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
@@ -7197,6 +7543,12 @@
 		data->flags |= STA_DRV_DATA_LAST_ACK_RSSI;
 	}
 
+	if (stats[NL80211_STA_INFO_CONNECTED_TIME]) {
+		data->connected_sec =
+			nla_get_u32(stats[NL80211_STA_INFO_CONNECTED_TIME]);
+		data->flags |= STA_DRV_DATA_CONN_TIME;
+	}
+
 	if (stats[NL80211_STA_INFO_TX_BITRATE] &&
 	    nla_parse_nested(rate, NL80211_RATE_INFO_MAX,
 			     stats[NL80211_STA_INFO_TX_BITRATE],
@@ -7967,8 +8319,10 @@
 
 		drv->global->if_add_wdevid = p2pdev_info.wdev_id;
 		drv->global->if_add_wdevid_set = p2pdev_info.wdev_id_set;
-		if (!is_zero_ether_addr(p2pdev_info.macaddr))
+		if (!is_zero_ether_addr(p2pdev_info.macaddr)){
 			os_memcpy(if_addr, p2pdev_info.macaddr, ETH_ALEN);
+                        os_memcpy(drv->global->p2p_perm_addr, p2pdev_info.macaddr, ETH_ALEN);
+                }
 		wpa_printf(MSG_DEBUG, "nl80211: New P2P Device interface %s (0x%llx) created",
 			   ifname,
 			   (long long unsigned int) p2pdev_info.wdev_id);
@@ -8285,6 +8639,28 @@
 		os_memset(bss->rand_addr, 0, ETH_ALEN);
 	}
 
+#ifdef CONFIG_MESH
+	if (is_mesh_interface(drv->nlmode)) {
+		struct hostapd_hw_modes *modes;
+		u16 num_modes, flags;
+		u8 dfs_domain;
+		int i;
+
+		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);
+		}
+	}
+#endif /* CONFIG_MESH */
+
 	if (is_ap_interface(drv->nlmode) &&
 	    (!(drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) ||
 	     (int) freq == bss->freq || drv->device_ap_sme ||
@@ -8854,7 +9230,7 @@
 		return -ENOBUFS;
 	}
 
-	return send_and_recv_msgs(bss->drv, msg, NULL, (void *) -1, NULL, NULL);
+	return send_and_recv_msgs(bss->drv, msg, NULL, NULL, NULL, NULL);
 }
 
 
@@ -9124,7 +9500,7 @@
 
 	nla_nest_end(msg, replay_nested);
 
-	ret = send_and_recv_msgs(drv, msg, NULL, (void *) -1, NULL, NULL);
+	ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
 	if (ret == -EOPNOTSUPP) {
 		wpa_printf(MSG_DEBUG,
 			   "nl80211: Driver does not support rekey offload");
@@ -9204,6 +9580,200 @@
 	}
 }
 
+#if defined(WAPI_ANDROID)
+static int wpa_driver_nl80211_set_wapi(void *priv, int enabled)
+{
+	wpa_printf(MSG_DEBUG, "CFG80211:  wpa_driver_nl80211_set_wapi");
+	return 1;
+}
+#endif 
+
+#ifdef CONFIG_TWT_OFFLOAD_IFX
+static int wpa_driver_nl80211_setup_twt(void *priv, struct drv_setup_twt_params *params)
+{
+	struct i802_bss *bss = priv;
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+	struct nl_msg *msg = NULL;
+	struct nlattr *data, *twt_param_attrs;
+	int ret = -1;
+
+	if (!drv->ifx_twt_offload)
+		goto fail;
+
+	if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
+	    nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_IFX) ||
+	    nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, IFX_VENDOR_SCMD_TWT))
+		goto fail;
+
+	data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
+	if (!data)
+		goto fail;
+
+	if (nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_OPER, IFX_TWT_OPER_SETUP))
+		goto fail;
+
+	twt_param_attrs = nla_nest_start(msg, IFX_VENDOR_ATTR_TWT_PARAMS);
+	if (!twt_param_attrs)
+		goto fail;
+
+	if (nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_NEGO_TYPE,
+		       params->negotiation_type) ||
+
+	    nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_SETUP_CMD_TYPE,
+		       params->setup_cmd) ||
+
+	    nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_DIALOG_TOKEN,
+		       params->dtok) ||
+
+	    (params->twt &&
+	     nla_put_u64(msg, IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME,
+			 params->twt)) ||
+
+	    (params->twt_offset &&
+	     nla_put_u64(msg, IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME_OFFSET,
+			 params->twt_offset)) ||
+
+	    nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION,
+		       params->min_twt) ||
+
+	    nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_EXPONENT,
+		       params->exponent) ||
+
+	    nla_put_u16(msg, IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_MANTISSA,
+			params->mantissa) ||
+
+	    nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_REQUESTOR,
+		       params->requestor) ||
+
+	    nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_TRIGGER,
+		       params->trigger) ||
+
+	    nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_IMPLICIT,
+		       params->implicit) ||
+
+	    nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_FLOW_TYPE,
+		       params->flow_type) ||
+
+	    (params->flow_id &&
+	     nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_FLOW_ID,
+			params->flow_id)) ||
+
+	    (params->bcast_twt_id &&
+	     nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_BCAST_TWT_ID,
+			params->bcast_twt_id)) ||
+
+	    nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_PROTECTION,
+		       params->protection) ||
+
+	    nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_CHANNEL,
+		       params->twt_channel) ||
+
+	    nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_TWT_INFO_FRAME_DISABLED,
+		       params->twt_info_frame_disabled) ||
+
+	    nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION_UNIT,
+		       params->min_twt_unit))
+		goto fail;
+
+	nla_nest_end(msg, twt_param_attrs);
+	nla_nest_end(msg, data);
+
+	wpa_printf(MSG_DEBUG,
+		   "nl80211: TWT Setup: Neg Type: %d REQ Type: %d TWT: %lu min_twt: %d "
+		   "exponent: %d mantissa: %d requestor: %d trigger: %d implicit: %d "
+		   "flow_type: %d flow_id: %d bcast_twt_id: %d protection: %d "
+		   "twt_channel: %d twt_info_frame_disabled: %d min_twt_unit: %d",
+		   params->negotiation_type, params->setup_cmd, params->twt,
+		   params->min_twt, params->exponent, params->mantissa,
+		   params->requestor, params->trigger, params->implicit,
+		   params->flow_type, params->flow_id, params->bcast_twt_id,
+		   params->protection, params->twt_channel,
+		   params->twt_info_frame_disabled, params->min_twt_unit);
+
+	ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
+	if (ret < 0) {
+		wpa_printf(MSG_DEBUG,
+			   "nl80211: TWT Setup: Failed to invoke driver "
+			   "TWT setup function: %s",
+			   strerror(-ret));
+	}
+
+	return ret;
+fail:
+	nl80211_nlmsg_clear(msg);
+	nlmsg_free(msg);
+	return ret;
+}
+
+static int wpa_driver_nl80211_teardown_twt(void *priv, struct drv_teardown_twt_params *params)
+{
+	struct i802_bss *bss = priv;
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+	struct nl_msg *msg = NULL;
+	struct nlattr *data, *twt_param_attrs;
+	int ret = -1;
+
+	if (!drv->ifx_twt_offload)
+		goto fail;
+
+	if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
+	    nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_IFX) ||
+	    nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, IFX_VENDOR_SCMD_TWT))
+		goto fail;
+
+	data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
+	if (!data)
+		goto fail;
+
+	if (nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_OPER, IFX_TWT_OPER_TEARDOWN))
+		goto fail;
+
+	twt_param_attrs = nla_nest_start(msg, IFX_VENDOR_ATTR_TWT_PARAMS);
+	if (!twt_param_attrs)
+		goto fail;
+
+	if (nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_NEGO_TYPE,
+		       params->negotiation_type))
+		goto fail;
+
+	if (params->teardown_all_twt) {
+	    if (nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_TEARDOWN_ALL_TWT,
+			   params->teardown_all_twt))
+		goto fail;
+	} else if (params->flow_id &&
+		   nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_FLOW_ID,
+			      params->flow_id)) {
+		goto fail;
+	} else if (params->bcast_twt_id &&
+		   nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_BCAST_TWT_ID,
+			      params->bcast_twt_id)) {
+		goto fail;
+	}
+
+	nla_nest_end(msg, twt_param_attrs);
+	nla_nest_end(msg, data);
+
+	wpa_printf(MSG_DEBUG,
+		   "nl80211: TWT Teardown: Neg Type: %d teardown_all_twt: %d "
+		   "flow_id: %d bcast_twt_id: %d",
+		   params->negotiation_type, params->teardown_all_twt,
+		   params->flow_id, params->bcast_twt_id);
+
+	ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
+	if (ret) {
+		wpa_printf(MSG_DEBUG,
+			   "nl80211: TWT Teardown: Failed to invoke driver "
+			   "TWT teardown function: %s",
+			   strerror(-ret));
+	}
+
+	return ret;
+fail:
+	nl80211_nlmsg_clear(msg);
+	nlmsg_free(msg);
+	return ret;
+}
+#endif /* CONFIG_TWT_OFFLOAD_IFX */
 
 static int nl80211_set_power_save(struct i802_bss *bss, int enabled)
 {
@@ -9287,6 +9857,28 @@
 
 #ifdef CONFIG_TDLS
 
+static int nl80211_add_peer_capab(struct nl_msg *msg,
+				  enum tdls_peer_capability capa)
+{
+	u32 peer_capab = 0;
+
+	if (!capa)
+		return 0;
+
+	if (capa & TDLS_PEER_HT)
+		peer_capab |= NL80211_TDLS_PEER_HT;
+	if (capa & TDLS_PEER_VHT)
+		peer_capab |= NL80211_TDLS_PEER_VHT;
+	if (capa & TDLS_PEER_WMM)
+		peer_capab |= NL80211_TDLS_PEER_WMM;
+	if (capa & TDLS_PEER_HE)
+		peer_capab |= NL80211_TDLS_PEER_HE;
+
+	return nla_put_u32(msg, NL80211_ATTR_TDLS_PEER_CAPABILITY,
+			   peer_capab);
+}
+
+
 static int nl80211_send_tdls_mgmt(void *priv, const u8 *dst, u8 action_code,
 				  u8 dialog_token, u16 status_code,
 				  u32 peer_capab, int initiator, const u8 *buf,
@@ -9306,21 +9898,9 @@
 	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dst) ||
 	    nla_put_u8(msg, NL80211_ATTR_TDLS_ACTION, action_code) ||
 	    nla_put_u8(msg, NL80211_ATTR_TDLS_DIALOG_TOKEN, dialog_token) ||
-	    nla_put_u16(msg, NL80211_ATTR_STATUS_CODE, status_code))
-		goto fail;
-	if (peer_capab) {
-		/*
-		 * The internal enum tdls_peer_capability definition is
-		 * currently identical with the nl80211 enum
-		 * nl80211_tdls_peer_capability, so no conversion is needed
-		 * here.
-		 */
-		if (nla_put_u32(msg, NL80211_ATTR_TDLS_PEER_CAPABILITY,
-				peer_capab))
-			goto fail;
-	}
-	if ((initiator &&
-	     nla_put_flag(msg, NL80211_ATTR_TDLS_INITIATOR)) ||
+	    nla_put_u16(msg, NL80211_ATTR_STATUS_CODE, status_code) ||
+	    nl80211_add_peer_capab(msg, peer_capab) ||
+	    (initiator && nla_put_flag(msg, NL80211_ATTR_TDLS_INITIATOR)) ||
 	    nla_put(msg, NL80211_ATTR_IE, len, buf))
 		goto fail;
 
@@ -9862,11 +10442,18 @@
 	int csa_off_len = 0;
 	int i;
 
-	wpa_printf(MSG_DEBUG, "nl80211: Channel switch request (cs_count=%u block_tx=%u freq=%d width=%d cf1=%d cf2=%d)",
+	wpa_printf(MSG_DEBUG,
+		   "nl80211: Channel switch request (cs_count=%u block_tx=%u freq=%d channel=%d sec_channel_offset=%d width=%d cf1=%d cf2=%d%s%s%s)",
 		   settings->cs_count, settings->block_tx,
-		   settings->freq_params.freq, settings->freq_params.bandwidth,
+		   settings->freq_params.freq,
+		   settings->freq_params.channel,
+		   settings->freq_params.sec_channel_offset,
+		   settings->freq_params.bandwidth,
 		   settings->freq_params.center_freq1,
-		   settings->freq_params.center_freq2);
+		   settings->freq_params.center_freq2,
+		   settings->freq_params.ht_enabled ? " ht" : "",
+		   settings->freq_params.vht_enabled ? " vht" : "",
+		   settings->freq_params.he_enabled ? " he" : "");
 
 	if (!(drv->capa.flags & WPA_DRIVER_FLAGS_AP_CSA)) {
 		wpa_printf(MSG_DEBUG, "nl80211: Driver does not support channel switch command");
@@ -10447,12 +11034,41 @@
 	struct wpa_driver_nl80211_data *drv = bss->drv;
 	int new_addr = addr != NULL;
 
+	struct nl_msg *msg = NULL;
+	struct nlattr *params;
+	int ret = -1;
+
 	if (TEST_FAIL())
 		return -1;
+        if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE) {
 
-	if (!addr)
-		addr = drv->perm_addr;
+            if (!addr)
+	        addr = drv->global->p2p_perm_addr;
+            if(!ETHER_IS_LOCALADDR(addr)) {
+                wpa_printf(MSG_ERROR, "nl80211: locally administered not set" MACSTR, MAC2STR(addr));
+                return -1;
+            }
+            if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_VENDOR)) ||
+                nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_IFX) ||
+                nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+                IFX_VENDOR_SCMD_SET_P2P_RAND_MAC) ||
+                !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
+                nla_put(msg, IFX_VENDOR_ATTR_MAC_ADDR, ETH_ALEN, addr)) {
+                    wpa_printf(MSG_ERROR, "failed to put p2p randmac");
+                    nl80211_nlmsg_clear(msg);
+                    nlmsg_free(msg);
+                    return -ENOBUFS;
+            }
+            nla_nest_end(msg, params);
 
+            ret = send_and_recv_msgs(drv, msg, NULL, (void *) -1, NULL, NULL);
+            if (ret) {
+                wpa_printf(MSG_ERROR, "nl80211: p2p set macaddr failed: ret=%d (%s)",
+	                ret, strerror(-ret));
+            }
+            memcpy(bss->addr, addr, ETH_ALEN);
+            return ret;
+        }
 	if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0) < 0)
 		return -1;
 
@@ -10522,6 +11138,9 @@
 	if (((params->flags & WPA_DRIVER_MESH_CONF_FLAG_AUTO_PLINKS) &&
 	     nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
 			params->auto_plinks)) ||
+	    ((params->flags & WPA_DRIVER_MESH_CONF_FLAG_FORWARDING) &&
+	     nla_put_u8(msg, NL80211_MESHCONF_FORWARDING,
+			params->forwarding)) ||
 	    ((params->flags & WPA_DRIVER_MESH_CONF_FLAG_MAX_PEER_LINKS) &&
 	     nla_put_u16(msg, NL80211_MESHCONF_MAX_PEER_LINKS,
 			 params->max_peer_links)) ||
@@ -10573,6 +11192,9 @@
 
 	wpa_printf(MSG_DEBUG, "  * flags=%08X", params->flags);
 
+	if (params->handle_dfs && nla_put_flag(msg, NL80211_ATTR_HANDLE_DFS))
+		goto fail;
+
 	container = nla_nest_start(msg, NL80211_ATTR_MESH_SETUP);
 	if (!container)
 		goto fail;
@@ -10603,8 +11225,7 @@
 	if (nl80211_put_mesh_config(msg, &params->conf) < 0)
 		goto fail;
 
-	ret = send_and_recv_msgs_owner(drv, msg, get_connect_handle(bss), 1,
-				       NULL, NULL, NULL, NULL);
+	ret = send_and_recv_msgs_connect_handle(drv, msg, bss, 1);
 	msg = NULL;
 	if (ret) {
 		wpa_printf(MSG_DEBUG, "nl80211: mesh join failed: ret=%d (%s)",
@@ -10661,8 +11282,7 @@
 
 	wpa_printf(MSG_DEBUG, "nl80211: mesh leave (ifindex=%d)", drv->ifindex);
 	msg = nl80211_drv_msg(drv, 0, NL80211_CMD_LEAVE_MESH);
-	ret = send_and_recv_msgs_owner(drv, msg, get_connect_handle(bss), 0,
-				       NULL, NULL, NULL, NULL);
+	ret = send_and_recv_msgs_connect_handle(drv, msg, bss, 0);
 	if (ret) {
 		wpa_printf(MSG_DEBUG, "nl80211: mesh leave failed: ret=%d (%s)",
 			   ret, strerror(-ret));
@@ -10671,7 +11291,8 @@
 			   "nl80211: mesh leave request send successfully");
 	}
 
-	if (wpa_driver_nl80211_set_mode(drv->first_bss,
+	if (drv->start_mode_sta &&
+	    wpa_driver_nl80211_set_mode(drv->first_bss,
 					NL80211_IFTYPE_STATION)) {
 		wpa_printf(MSG_INFO,
 			   "nl80211: Failed to set interface into station mode");
@@ -11031,7 +11652,8 @@
 		 * compatibility.
 		 */
 		if (!(freq >= 2412 && freq <= 2484) &&
-		    !(freq >= 5180 && freq <= 5900))
+		    !(freq >= 5180 && freq <= 5900) &&
+		    !(freq >= 5945 && freq <= 7115))
 			continue;
 		hw_mode = ieee80211_freq_to_chan(freq, &ch_list[num_channels]);
 		if (hw_mode != NUM_HOSTAPD_MODES)
@@ -11067,10 +11689,9 @@
 }
 
 
-static int wpa_driver_do_acs(void *priv, struct drv_acs_params *params)
+static int nl80211_qca_do_acs(struct wpa_driver_nl80211_data *drv,
+			      struct drv_acs_params *params)
 {
-	struct i802_bss *bss = priv;
-	struct wpa_driver_nl80211_data *drv = bss->drv;
 	struct nl_msg *msg;
 	struct nlattr *data;
 	int ret;
@@ -11118,38 +11739,49 @@
 }
 
 
-static int nl80211_set_band(void *priv, enum set_band band)
+static int nl80211_set_band(void *priv, u32 band_mask)
 {
 	struct i802_bss *bss = priv;
 	struct wpa_driver_nl80211_data *drv = bss->drv;
 	struct nl_msg *msg;
 	struct nlattr *data;
 	int ret;
-	enum qca_set_band qca_band;
+	enum qca_set_band qca_band_value;
+	u32 qca_band_mask = QCA_SETBAND_AUTO;
 
-	if (!drv->setband_vendor_cmd_avail)
+	if (!drv->setband_vendor_cmd_avail ||
+	    (band_mask > (WPA_SETBAND_2G | WPA_SETBAND_5G | WPA_SETBAND_6G)))
 		return -1;
 
-	switch (band) {
-	case WPA_SETBAND_AUTO:
-		qca_band = QCA_SETBAND_AUTO;
-		break;
-	case WPA_SETBAND_5G:
-		qca_band = QCA_SETBAND_5G;
-		break;
-	case WPA_SETBAND_2G:
-		qca_band = QCA_SETBAND_2G;
-		break;
-	default:
-		return -1;
-	}
+	if (band_mask & WPA_SETBAND_5G)
+		qca_band_mask |= QCA_SETBAND_5G;
+	if (band_mask & WPA_SETBAND_2G)
+		qca_band_mask |= QCA_SETBAND_2G;
+	if (band_mask & WPA_SETBAND_6G)
+		qca_band_mask |= QCA_SETBAND_6G;
+
+	/*
+	 * QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE is a legacy interface hence make
+	 * it suite to its values (AUTO/5G/2G) for backwards compatibility.
+	 */
+	qca_band_value = ((qca_band_mask & QCA_SETBAND_5G) &&
+			  (qca_band_mask & QCA_SETBAND_2G)) ?
+				QCA_SETBAND_AUTO :
+				qca_band_mask & ~QCA_SETBAND_6G;
+
+	wpa_printf(MSG_DEBUG,
+		   "nl80211: QCA_BAND_MASK = 0x%x, QCA_BAND_VALUE = %d",
+		   qca_band_mask, qca_band_value);
 
 	if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
 	    nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
 	    nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
 			QCA_NL80211_VENDOR_SUBCMD_SETBAND) ||
 	    !(data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
-	    nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE, qca_band)) {
+	    nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE,
+			qca_band_value) ||
+	    nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_SETBAND_MASK,
+			qca_band_mask)) {
 		nlmsg_free(msg);
 		return -ENOBUFS;
 	}
@@ -11837,6 +12469,80 @@
 }
 #endif /* CONFIG_BRCM_DEBUG */
 
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+static int wpa_driver_do_broadcom_acs(struct wpa_driver_nl80211_data *drv,
+				      struct drv_acs_params *params)
+{
+	struct nl_msg *msg;
+	struct nlattr *data;
+	int freq_list_len;
+	int ret = -1;
+
+	freq_list_len = int_array_len(params->freq_list);
+	wpa_printf(MSG_DEBUG, "%s: freq_list_len=%d",
+		   __func__, freq_list_len);
+
+	msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
+	if (!msg ||
+	    nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_BRCM) ||
+	    nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+			BRCM_VENDOR_SCMD_ACS) ||
+	    !(data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
+	    nla_put_u8(msg, BRCM_VENDOR_ATTR_ACS_HW_MODE, params->hw_mode) ||
+	    nla_put_u8(msg, BRCM_VENDOR_ATTR_ACS_HT_ENABLED,
+		       params->ht_enabled) ||
+	    nla_put_u8(msg, BRCM_VENDOR_ATTR_ACS_HT40_ENABLED,
+		       params->ht40_enabled) ||
+	    nla_put_u8(msg, BRCM_VENDOR_ATTR_ACS_VHT_ENABLED,
+		       params->vht_enabled) ||
+	    nla_put_u16(msg, BRCM_VENDOR_ATTR_ACS_CHWIDTH, params->ch_width) ||
+	    (freq_list_len > 0 &&
+	     nla_put(msg, BRCM_VENDOR_ATTR_ACS_FREQ_LIST,
+		     sizeof(int) * freq_list_len, params->freq_list)))
+		goto fail;
+	nla_nest_end(msg, data);
+
+	wpa_printf(MSG_DEBUG,
+		   "nl80211: ACS Params: HW_MODE: %d HT: %d HT40: %d VHT: %d BW: %d",
+		   params->hw_mode, params->ht_enabled, params->ht40_enabled,
+		   params->vht_enabled, params->ch_width);
+
+	ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
+	if (ret) {
+		wpa_printf(MSG_ERROR,
+			   "nl80211: BRCM Failed to invoke driver ACS function: %s",
+			   strerror(errno));
+	}
+
+	msg = NULL;
+fail:
+	nlmsg_free(msg);
+	return ret;
+}
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
+
+
+static int nl80211_do_acs(void *priv, struct drv_acs_params *params)
+{
+#if defined(CONFIG_DRIVER_NL80211_QCA) || defined(CONFIG_DRIVER_NL80211_BRCM)
+	struct i802_bss *bss = priv;
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+#endif /* CONFIG_DRIVER_NL80211_QCA || CONFIG_DRIVER_NL80211_BRCM */
+
+#ifdef CONFIG_DRIVER_NL80211_QCA
+	if (drv->qca_do_acs)
+		return nl80211_qca_do_acs(drv, params);
+#endif /* CONFIG_DRIVER_NL80211_QCA */
+
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+	if (drv->brcm_do_acs)
+		return wpa_driver_do_broadcom_acs(drv, params);
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
+
+	return -1;
+}
+
+
 static int nl80211_write_to_file(const char *name, unsigned int val)
 {
 	int fd, len;
@@ -11881,6 +12587,10 @@
 	char path[128];
 	int ret;
 
+	/* P2P-Device has no netdev that can (or should) be configured here */
+	if (nl80211_get_ifmode(bss) == NL80211_IFTYPE_P2P_DEVICE)
+		return 0;
+
 	wpa_printf(MSG_DEBUG, "nl80211: Data frame filter flags=0x%x",
 		   filter_flags);
 
@@ -12150,6 +12860,11 @@
 
 	ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
 	msg = NULL;
+	if (ret && val && nl80211_get_4addr(bss) == 1) {
+		wpa_printf(MSG_DEBUG,
+			   "nl80211: 4addr mode was already enabled");
+		ret = 0;
+	}
 	if (!ret) {
 		if (bridge_ifname[0] && val &&
 		    i802_check_bridge(drv, bss, bridge_ifname, bss->ifname) < 0)
@@ -12187,6 +12902,23 @@
 #endif /* CONFIG_DPP */
 
 
+#ifdef CONFIG_TESTING_OPTIONS
+static int testing_nl80211_register_frame(void *priv, u16 type,
+					  const u8 *match, size_t match_len,
+					  bool multicast)
+{
+	struct i802_bss *bss = priv;
+	struct nl_sock *handle;
+
+	if (!bss->nl_mgmt)
+		return -1;
+	handle = (void *) (((intptr_t) bss->nl_mgmt) ^ ELOOP_SOCKET_INVALID);
+	return nl80211_register_frame(bss, handle, type, match, match_len,
+				      multicast);
+}
+#endif /* CONFIG_TESTING_OPTIONS */
+
+
 const struct wpa_driver_ops wpa_driver_nl80211_ops = {
 	.name = "nl80211",
 	.desc = "Linux nl80211/cfg80211",
@@ -12286,6 +13018,13 @@
 	.get_wowlan = nl80211_get_wowlan,
 	.set_wowlan = nl80211_set_wowlan,
 	.set_mac_addr = nl80211_set_mac_addr,
+#if defined(WAPI_ANDROID)
+	.set_wapi = wpa_driver_nl80211_set_wapi,
+#endif 
+#ifdef CONFIG_TWT_OFFLOAD_IFX
+	.setup_twt = wpa_driver_nl80211_setup_twt,
+	.teardown_twt = wpa_driver_nl80211_teardown_twt,
+#endif /* CONFIG_TWT_OFFLOAD_IFX */
 #ifdef CONFIG_MESH
 	.init_mesh = wpa_driver_nl80211_init_mesh,
 	.join_mesh = wpa_driver_nl80211_join_mesh,
@@ -12302,7 +13041,6 @@
 #ifdef CONFIG_DRIVER_NL80211_QCA
 	.roaming = nl80211_roaming,
 	.disable_fils = nl80211_disable_fils,
-	.do_acs = wpa_driver_do_acs,
 	.set_band = nl80211_set_band,
 	.get_pref_freq_list = nl80211_get_pref_freq_list,
 	.set_prob_oper_freq = nl80211_set_prob_oper_freq,
@@ -12317,6 +13055,7 @@
 	.set_bssid_tmp_disallow = nl80211_set_bssid_tmp_disallow,
 	.add_sta_node = nl80211_add_sta_node,
 #endif /* CONFIG_DRIVER_NL80211_QCA */
+	.do_acs = nl80211_do_acs,
 	.configure_data_frame_filters = nl80211_configure_data_frame_filters,
 	.get_ext_capab = nl80211_get_ext_capab,
 	.update_connect_params = nl80211_update_connection_params,
@@ -12325,4 +13064,7 @@
 #ifdef CONFIG_DPP
 	.dpp_listen = nl80211_dpp_listen,
 #endif /* CONFIG_DPP */
+#ifdef CONFIG_TESTING_OPTIONS
+	.register_frame = testing_nl80211_register_frame,
+#endif /* CONFIG_TESTING_OPTIONS */
 };
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_nl80211.h b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_nl80211.h
index 70d8f68..b7da83d 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_nl80211.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_nl80211.h
@@ -32,7 +32,9 @@
 	struct nl_cb *nl_cb;
 	struct nl_sock *nl;
 	int nl80211_id;
+	int nlctrl_id;
 	int ioctl_sock; /* socket for ioctl() use */
+        u8 p2p_perm_addr[ETH_ALEN];
 
 	struct nl_sock *nl_event;
 };
@@ -149,7 +151,7 @@
 	unsigned int ignore_next_local_disconnect:1;
 	unsigned int ignore_next_local_deauth:1;
 	unsigned int hostapd:1;
-	unsigned int start_mode_ap:1;
+	unsigned int start_mode_sta:1;
 	unsigned int start_iface_up:1;
 	unsigned int test_use_roc_tx:1;
 	unsigned int ignore_deauth_event:1;
@@ -175,6 +177,11 @@
 	unsigned int multicast_registrations:1;
 	unsigned int no_rrm:1;
 	unsigned int get_sta_info_vendor_cmd_avail:1;
+	unsigned int fils_discovery:1;
+	unsigned int unsol_bcast_probe_resp:1;
+	unsigned int qca_do_acs:1;
+	unsigned int brcm_do_acs:1;
+	unsigned int ifx_twt_offload:1;
 
 	u64 vendor_scan_cookie;
 	u64 remain_on_chan_cookie;
@@ -191,6 +198,11 @@
 
 	struct i802_bss *first_bss;
 
+#if defined(WAPI_ANDROID)
+        char ifname[IFNAMSIZ + 1];
+        size_t ap_wapi_ie_len;
+        const u8 *ap_wapi_ie;
+#endif 
 	int eapol_tx_sock;
 
 	int eapol_sock; /* socket for EAPOL frames */
@@ -209,6 +221,8 @@
 	int auth_alg;
 	u8 *auth_ie;
 	size_t auth_ie_len;
+	u8 *auth_data;
+	size_t auth_data_len;
 	u8 auth_wep_key[4][16];
 	size_t auth_wep_key_len[4];
 	int auth_wep_tx_keyidx;
@@ -221,6 +235,12 @@
 	 * (NL80211_CMD_VENDOR). 0 if no pending scan request.
 	 */
 	int last_scan_cmd;
+#ifdef CONFIG_DRIVER_NL80211_QCA
+	bool roam_indication_done;
+	u8 *pending_roam_data;
+	size_t pending_roam_data_len;
+	struct os_reltime pending_roam_ind_time;
+#endif /* CONFIG_DRIVER_NL80211_QCA */
 };
 
 #ifdef CONFIG_BRCM_DEBUG
@@ -291,7 +311,7 @@
 int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
 			    const u8 *addr, int cmd, u16 reason_code,
 			    int local_state_change,
-			    struct nl_sock *nl_connect);
+			    struct i802_bss *bss);
 
 int nl80211_create_monitor_interface(struct wpa_driver_nl80211_data *drv);
 void nl80211_remove_monitor_interface(struct wpa_driver_nl80211_data *drv);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_nl80211_capa.c b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_nl80211_capa.c
index 7f03b62..5e9c277 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_nl80211_capa.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_nl80211_capa.c
@@ -16,6 +16,8 @@
 #include "common/wpa_common.h"
 #include "common/qca-vendor.h"
 #include "common/qca-vendor-attr.h"
+#include "common/brcm_vendor.h"
+#include "common/ifx_vendor.h"
 #include "driver_nl80211.h"
 
 
@@ -559,6 +561,10 @@
 		capa->flags |= WPA_DRIVER_FLAGS_BEACON_RATE_VHT;
 
 	if (ext_feature_isset(ext_features, len,
+			      NL80211_EXT_FEATURE_BEACON_RATE_HE))
+		capa->flags2 |= WPA_DRIVER_FLAGS2_BEACON_RATE_HE;
+
+	if (ext_feature_isset(ext_features, len,
 			      NL80211_EXT_FEATURE_SET_SCAN_DWELL))
 		capa->rrm_flags |= WPA_DRIVER_FLAGS_SUPPORT_SET_SCAN_DWELL;
 
@@ -589,22 +595,11 @@
 			      NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
 		capa->flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X;
 
-	/* Support for 4-way handshake offload to internal supplicant
-	 * for WPA/WPA2-PSK
-	 */
-	if (ext_feature_isset(ext_features, len,
-			      NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK))
-		capa->flags2 |= WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK;
-
 	if (ext_feature_isset(ext_features, len,
 			      NL80211_EXT_FEATURE_SAE_OFFLOAD))
 		capa->flags2 |= WPA_DRIVER_FLAGS2_SAE_OFFLOAD;
 
 	if (ext_feature_isset(ext_features, len,
-			      NL80211_EXT_FEATURE_SAE_OFFLOAD_AP))
-		capa->flags2 |= WPA_DRIVER_FLAGS2_SAE_OFFLOAD_AP;
-
-	if (ext_feature_isset(ext_features, len,
 			      NL80211_EXT_FEATURE_MFP_OPTIONAL))
 		capa->flags |= WPA_DRIVER_FLAGS_MFP_OPTIONAL;
 
@@ -659,6 +654,22 @@
 	if (ext_feature_isset(ext_features, len,
 			      NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS))
 		info->drv->multicast_registrations = 1;
+
+	if (ext_feature_isset(ext_features, len,
+			      NL80211_EXT_FEATURE_FILS_DISCOVERY))
+		info->drv->fils_discovery = 1;
+
+	if (ext_feature_isset(ext_features, len,
+			      NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP))
+		info->drv->unsol_bcast_probe_resp = 1;
+
+	if (ext_feature_isset(ext_features, len,
+			      NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT))
+		capa->flags2 |= WPA_DRIVER_FLAGS2_BEACON_PROTECTION_CLIENT;
+
+	if (ext_feature_isset(ext_features, len,
+			      NL80211_EXT_FEATURE_OPERATING_CHANNEL_VALIDATION))
+		capa->flags2 |= WPA_DRIVER_FLAGS2_OCV;
 }
 
 
@@ -885,7 +896,7 @@
 
 	if (tb[NL80211_ATTR_MAC_ACL_MAX])
 		capa->max_acl_mac_addrs =
-			nla_get_u8(tb[NL80211_ATTR_MAC_ACL_MAX]);
+			nla_get_u32(tb[NL80211_ATTR_MAC_ACL_MAX]);
 
 	wiphy_info_supported_iftypes(info, tb[NL80211_ATTR_SUPPORTED_IFTYPES]);
 	wiphy_info_iface_comb(info, tb[NL80211_ATTR_INTERFACE_COMBINATIONS]);
@@ -990,6 +1001,7 @@
 				case QCA_NL80211_VENDOR_SUBCMD_DO_ACS:
 					drv->capa.flags |=
 						WPA_DRIVER_FLAGS_ACS_OFFLOAD;
+					drv->qca_do_acs = 1;
 					break;
 				case QCA_NL80211_VENDOR_SUBCMD_SETBAND:
 					drv->setband_vendor_cmd_avail = 1;
@@ -1014,6 +1026,25 @@
 					break;
 #endif /* CONFIG_DRIVER_NL80211_QCA */
 				}
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+			} else if (vinfo->vendor_id == OUI_BRCM) {
+				switch (vinfo->subcmd) {
+				case BRCM_VENDOR_SCMD_ACS:
+					drv->capa.flags |=
+						WPA_DRIVER_FLAGS_ACS_OFFLOAD;
+					wpa_printf(MSG_DEBUG,
+						   "Enabled BRCM ACS");
+					drv->brcm_do_acs = 1;
+					break;
+				}
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
+
+			} else if (vinfo->vendor_id == OUI_IFX) {
+				switch (vinfo->subcmd) {
+				case IFX_VENDOR_SCMD_TWT:
+					drv->ifx_twt_offload = 1;
+					break;
+				}
 			}
 
 			wpa_printf(MSG_DEBUG, "nl80211: Supported vendor command: vendor_id=0x%x subcmd=%u",
@@ -1376,7 +1407,8 @@
             WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK;
 #endif /* CONFIG_IEEE80211R && BRCM_VE */
 
-	drv->capa.flags |= WPA_DRIVER_FLAGS_SANE_ERROR_CODES;
+
+	drv->capa.flags |= WPA_DRIVER_FLAGS_VALID_ERROR_CODES;
 	drv->capa.flags |= WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE;
 	drv->capa.flags |= WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
 
@@ -1391,6 +1423,7 @@
 
 	if (!info.device_ap_sme) {
 		drv->capa.flags |= WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS;
+		drv->capa.flags2 |= WPA_DRIVER_FLAGS2_AP_SME;
 
 		/*
 		 * No AP SME is currently assumed to also indicate no AP MLME
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_nl80211_event.c b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_nl80211_event.c
index 2edab84..3929226 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_nl80211_event.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_nl80211_event.c
@@ -15,12 +15,16 @@
 #include "utils/eloop.h"
 #include "common/qca-vendor.h"
 #include "common/qca-vendor-attr.h"
+#include "common/brcm_vendor.h"
 #include "common/ieee802_11_defs.h"
 #include "common/ieee802_11_common.h"
 #include "driver_nl80211.h"
 #ifdef ANDROID_P2P
 #include "common/brcm_vendor.h"
 #endif /* ANDROID_P2P */
+#if defined(WAPI_ANDROID)
+#include "../../wpa_supplicant/wpa_supplicant_i.h"
+#endif 
 #ifdef WL_SAE
 static void nl80211_external_auth(struct wpa_driver_nl80211_data *drv,
 				  struct nlattr **tb);
@@ -144,19 +148,45 @@
 	C2S(NL80211_CMD_SET_QOS_MAP)
 	C2S(NL80211_CMD_ADD_TX_TS)
 	C2S(NL80211_CMD_DEL_TX_TS)
+	C2S(NL80211_CMD_GET_MPP)
+	C2S(NL80211_CMD_JOIN_OCB)
+	C2S(NL80211_CMD_LEAVE_OCB)
+	C2S(NL80211_CMD_CH_SWITCH_STARTED_NOTIFY)
+	C2S(NL80211_CMD_TDLS_CHANNEL_SWITCH)
+	C2S(NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH)
 	C2S(NL80211_CMD_WIPHY_REG_CHANGE)
+	C2S(NL80211_CMD_ABORT_SCAN)
+	C2S(NL80211_CMD_START_NAN)
+	C2S(NL80211_CMD_STOP_NAN)
+	C2S(NL80211_CMD_ADD_NAN_FUNCTION)
+	C2S(NL80211_CMD_DEL_NAN_FUNCTION)
+	C2S(NL80211_CMD_CHANGE_NAN_CONFIG)
+	C2S(NL80211_CMD_NAN_MATCH)
+	C2S(NL80211_CMD_SET_MULTICAST_TO_UNICAST)
+	C2S(NL80211_CMD_UPDATE_CONNECT_PARAMS)
+	C2S(NL80211_CMD_SET_PMK)
+	C2S(NL80211_CMD_DEL_PMK)
 	C2S(NL80211_CMD_PORT_AUTHORIZED)
+	C2S(NL80211_CMD_RELOAD_REGDB)
 	C2S(NL80211_CMD_EXTERNAL_AUTH)
 	C2S(NL80211_CMD_STA_OPMODE_CHANGED)
 	C2S(NL80211_CMD_CONTROL_PORT_FRAME)
+	C2S(NL80211_CMD_GET_FTM_RESPONDER_STATS)
+	C2S(NL80211_CMD_PEER_MEASUREMENT_START)
+	C2S(NL80211_CMD_PEER_MEASUREMENT_RESULT)
+	C2S(NL80211_CMD_PEER_MEASUREMENT_COMPLETE)
+	C2S(NL80211_CMD_NOTIFY_RADAR)
 	C2S(NL80211_CMD_UPDATE_OWE_INFO)
+	C2S(NL80211_CMD_PROBE_MESH_LINK)
+	C2S(NL80211_CMD_SET_TID_CONFIG)
 	C2S(NL80211_CMD_UNPROT_BEACON)
 	C2S(NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS)
-
-	default:
-		return "NL80211_CMD_UNKNOWN";
+	C2S(NL80211_CMD_SET_SAR_SPECS)
+	C2S(__NL80211_CMD_AFTER_LAST)
 	}
 #undef C2S
+
+	return "NL80211_CMD_UNKNOWN";
 }
 
 
@@ -408,6 +438,15 @@
 {
 	union wpa_event_data event;
 	const u8 *ssid = NULL;
+#if defined(WAPI_ANDROID)
+		struct wpa_supplicant *wpa_s = drv->ctx;
+		if(drv->ap_wapi_ie_len && drv->ap_wapi_ie) {
+			wpa_printf(MSG_ERROR, "%s : Set wpa_s->ap_wapi_ie and "
+				"wpa_s->ap_wapi_ie_len\n",__func__);
+			memcpy(wpa_s->ap_wapi_ie, drv->ap_wapi_ie, drv->ap_wapi_ie_len);
+			wpa_s->ap_wapi_ie_len = drv->ap_wapi_ie_len;
+		}
+#endif 
 	u16 status_code;
 	int ssid_len;
 
@@ -578,6 +617,13 @@
 		event.assoc_info.fils_pmkid = nla_data(fils_pmkid);
 
 	wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
+
+	/* Avoid a race condition by stopping to ignore any following
+	 * disconnection events now that the driver has indicated it is
+	 * connected since that connection could have been triggered by a roam
+	 * operation that happened in parallel with the disconnection request.
+	 */
+	drv->ignore_next_local_disconnect = 0;
 }
 
 
@@ -637,8 +683,10 @@
 	case CHAN_WIDTH_160:
 		freq1 = cf1 - 70;
 		break;
-	case CHAN_WIDTH_UNKNOWN:
 	case CHAN_WIDTH_80P80:
+		freq1 = cf1 - 30;
+		break;
+	case CHAN_WIDTH_UNKNOWN:
 	case CHAN_WIDTH_2160:
 	case CHAN_WIDTH_4320:
 	case CHAN_WIDTH_6480:
@@ -699,6 +747,8 @@
 						    nla_get_u32(freq),
 						    nla_get_u32(cf1),
 						    cf2 ? nla_get_u32(cf2) : 0);
+		wpa_printf(MSG_DEBUG, "nl80211: Calculated channel offset: %d",
+			   chan_offset);
 	} else {
 		wpa_printf(MSG_WARNING, "nl80211: Unknown secondary channel information - following channel definition calculations may fail");
 	}
@@ -1297,7 +1347,7 @@
 	struct nlattr *nl;
 	int rem;
 	struct scan_info *info;
-#define MAX_REPORT_FREQS 50
+#define MAX_REPORT_FREQS 100
 	int freqs[MAX_REPORT_FREQS];
 	int num_freqs = 0;
 
@@ -1329,7 +1379,7 @@
 		}
 	}
 	if (tb[NL80211_ATTR_SCAN_FREQUENCIES]) {
-		char msg[300], *pos, *end;
+		char msg[500], *pos, *end;
 		int res;
 
 		pos = msg;
@@ -1382,7 +1432,6 @@
 	struct nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
 	enum nl80211_cqm_rssi_threshold_event event;
 	union wpa_event_data ed;
-	struct wpa_signal_info sig;
 	int res;
 
 	if (tb[NL80211_ATTR_CQM] == NULL ||
@@ -1449,19 +1498,27 @@
 		return;
 	}
 
-	res = nl80211_get_link_signal(drv, &sig);
+	/*
+	 * nl80211_get_link_signal() and nl80211_get_link_noise() set default
+	 * values in case querying the driver fails.
+	 */
+	res = nl80211_get_link_signal(drv, &ed.signal_change);
 	if (res == 0) {
-		ed.signal_change.current_signal = sig.current_signal;
-		ed.signal_change.current_txrate = sig.current_txrate;
 		wpa_printf(MSG_DEBUG, "nl80211: Signal: %d dBm  txrate: %d",
-			   sig.current_signal, sig.current_txrate);
+			   ed.signal_change.current_signal,
+			   ed.signal_change.current_txrate);
+	} else {
+		wpa_printf(MSG_DEBUG,
+			   "nl80211: Querying the driver for signal info failed");
 	}
 
-	res = nl80211_get_link_noise(drv, &sig);
+	res = nl80211_get_link_noise(drv, &ed.signal_change);
 	if (res == 0) {
-		ed.signal_change.current_noise = sig.current_noise;
 		wpa_printf(MSG_DEBUG, "nl80211: Noise: %d dBm",
-			   sig.current_noise);
+			   ed.signal_change.current_noise);
+	} else {
+		wpa_printf(MSG_DEBUG,
+			   "nl80211: Querying the driver for noise info failed");
 	}
 
 	wpa_supplicant_event(drv->ctx, EVENT_SIGNAL_CHANGE, &ed);
@@ -1876,96 +1933,6 @@
 	}
 	return;
 }
-
-static void nl80211_vendor_event_brcm( struct wpa_driver_nl80211_data *drv,
-	                             u32 subcmd, u8 *data, size_t len)
-{
-	union wpa_event_data event;
-        const struct nlattr *iter;
-        int rem = len;
-
-	wpa_printf(MSG_DEBUG, "got vendor event %d", subcmd);
-	memset(&event, 0, sizeof(event));
-	switch (subcmd) {
-	case BRCM_VENDOR_EVENT_PRIV_STR:
-		wpa_msg_global(drv->ctx, MSG_INFO, "%s", data);
-		break;
-	case BRCM_VENDOR_EVENT_HANGED:
-	       /* Dump the event on to the console */
-		wpa_msg(NULL, MSG_INFO, "%s", data);
-	break;
-#ifdef CONFIG_BRCM_SAE
-	case BRCM_VENDOR_EVENT_SAE_KEY: {
-		u16 pmkid_len = 0;
-                nla_for_each_attr(iter, (const struct nlattr *)data, len, rem) {
-	                wpa_printf(MSG_DEBUG, "attr type is %d", nla_type(iter));
-	                wpa_printf(MSG_DEBUG, "attr length is %d", nla_len(iter));
-	                if (nla_type(iter) == BRCM_SAE_KEY_ATTR_PEER_MAC)
-	                        memcpy(event.sae_key_info.peer_mac, nla_data(iter), nla_len(iter));
-	                if (nla_type(iter) == BRCM_SAE_KEY_ATTR_PMK) {
-	                        memcpy(event.sae_key_info.psk, nla_data(iter), nla_len(iter));
-	                        event.sae_key_info.psk_len = nla_len(iter);
-	                }
-	                if (nla_type(iter) == BRCM_SAE_KEY_ATTR_PMKID) {
-	                        memcpy(event.sae_key_info.pmkid, nla_data(iter), nla_len(iter));
-				pmkid_len = nla_len(iter);
-			}
-		}
-		if (event.sae_key_info.psk_len && pmkid_len && !is_zero_ether_addr(event.sae_key_info.peer_mac)) {
-			wpa_supplicant_event(drv->ctx, EVENT_SAE_KEY, &event);
-		} else {
-			wpa_printf(MSG_ERROR, "PMK data missing");
-		}
-	}
-	break;
-#endif /* CONFIG_BRCM_SAE */
-	case BRCM_VENDOR_EVENT_BEACON_RECV:
-		/* Fake ap beacon results in console */
-		nl80211_beacon_info_fakeap(drv, data, len);
-		break;
-#ifdef WL_SAE
-	case BRCM_VENDOR_EVENT_EXTERNAL_AUTH: {
-		struct nlattr *tb[NL80211_ATTR_MAX + 1];
-
-		nla_for_each_attr(iter, (const struct nlattr *)data, len, rem) {
-			wpa_printf(MSG_DEBUG, "attr type is %d. len is %d.\n",
-				nla_type(iter), nla_len(iter));
-
-			if (nla_type(iter) == NL80211_ATTR_AKM_SUITES) {
-				wpa_printf(MSG_DEBUG, "attr type is NL80211_ATTR_AKM_SUITES");
-				tb[NL80211_ATTR_AKM_SUITES] = (struct nlattr *)iter;
-			}
-			if (nla_type(iter) == NL80211_ATTR_EXTERNAL_AUTH_ACTION) {
-				wpa_printf(MSG_DEBUG, "attr type is "
-						"NL80211_ATTR_EXTERNAL_AUTH_ACTION");
-				tb[NL80211_ATTR_EXTERNAL_AUTH_ACTION] = (struct nlattr *)iter;
-			}
-			if (nla_type(iter) == NL80211_ATTR_BSSID) {
-				wpa_printf(MSG_DEBUG, "attr type is NL80211_ATTR_BSSID");
-				tb[NL80211_ATTR_BSSID] = (struct nlattr *)iter;
-			}
-			if (nla_type(iter) == NL80211_ATTR_SSID) {
-				wpa_printf(MSG_DEBUG, "attr type is NL80211_ATTR_SSID");
-				tb[NL80211_ATTR_SSID] = (struct nlattr *)iter;
-			}
-		}
-		wpa_printf(MSG_DEBUG, "nl80211: BRCM vendor event(%u): "
-				"BRCM_VENDOR_EVENT_EXTERNAL_AUTH", subcmd);
-		nl80211_external_auth(drv, tb);
-	}
-	break;
-#endif /* WL_SAE */
-	case BRCM_VENDOR_EVENT_OVERTEMP:
-		wpa_printf(MSG_DEBUG, "nl80211: BRCM vendor event(%u): "
-				"BRCM_VENDOR_EVENT_OVERTEMP\n", subcmd);
-		wpa_msg_global(drv->ctx, MSG_INFO, "overtemp event");
-		break;
-	default:
-		wpa_printf(MSG_DEBUG, "nl80211: Ignore unsupported BRCM vendor event %u", subcmd);
-		break;
-	}
-
-}
 #endif /* ANDROID_P2P */
 
 #ifdef CONFIG_DRIVER_NL80211_QCA
@@ -2075,7 +2042,7 @@
 		return 2407 + 5 * chan;
 	if (chan == 14)
 		return 2484;
-	if (chan >= 36 && chan <= 169)
+	if (chan >= 36 && chan <= 177)
 		return 5000 + 5 * chan;
 
 	return 0;
@@ -2203,6 +2170,27 @@
 }
 
 
+static void
+qca_nl80211_key_mgmt_auth_handler(struct wpa_driver_nl80211_data *drv,
+				  const u8 *data, size_t len)
+{
+	if (!drv->roam_indication_done) {
+		wpa_printf(MSG_DEBUG,
+			   "nl80211: Pending roam indication, delay processing roam+auth vendor event");
+		os_get_reltime(&drv->pending_roam_ind_time);
+
+		os_free(drv->pending_roam_data);
+		drv->pending_roam_data = os_memdup(data, len);
+		if (!drv->pending_roam_data)
+			return;
+		drv->pending_roam_data_len = len;
+		return;
+	}
+	drv->roam_indication_done = false;
+	qca_nl80211_key_mgmt_auth(drv, data, len);
+}
+
+
 static void qca_nl80211_dfs_offload_radar_event(
 	struct wpa_driver_nl80211_data *drv, u32 subcmd, u8 *msg, int length)
 {
@@ -2352,7 +2340,7 @@
 	}
 
 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES]) {
-		char msg[300], *pos, *end;
+		char msg[500], *pos, *end;
 		int res;
 
 		pos = msg;
@@ -2460,7 +2448,7 @@
 		qca_nl80211_avoid_freq(drv, data, len);
 		break;
 	case QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH:
-		qca_nl80211_key_mgmt_auth(drv, data, len);
+		qca_nl80211_key_mgmt_auth_handler(drv, data, len);
 		break;
 	case QCA_NL80211_VENDOR_SUBCMD_DO_ACS:
 		qca_nl80211_acs_select_ch(drv, data, len);
@@ -2491,6 +2479,157 @@
 }
 
 
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+
+static void brcm_nl80211_acs_select_ch(struct wpa_driver_nl80211_data *drv,
+				       const u8 *data, size_t len)
+{
+	struct nlattr *tb[BRCM_VENDOR_ATTR_ACS_LAST + 1];
+	union wpa_event_data event;
+
+	wpa_printf(MSG_DEBUG,
+		   "nl80211: BRCM ACS channel selection vendor event received");
+
+	if (nla_parse(tb, BRCM_VENDOR_ATTR_ACS_LAST, (struct nlattr *) data,
+		      len, NULL) ||
+	    !tb[BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ] ||
+	    !tb[BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ])
+		return;
+
+	os_memset(&event, 0, sizeof(event));
+	if (tb[BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ])
+		event.acs_selected_channels.pri_freq =
+			nla_get_u32(tb[BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ]);
+	if (tb[BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ])
+		event.acs_selected_channels.sec_freq =
+			nla_get_u32(tb[BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ]);
+	if (tb[BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL])
+		event.acs_selected_channels.vht_seg0_center_ch =
+			nla_get_u8(tb[BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL]);
+	if (tb[BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL])
+		event.acs_selected_channels.vht_seg1_center_ch =
+			nla_get_u8(tb[BRCM_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL]);
+	if (tb[BRCM_VENDOR_ATTR_ACS_CHWIDTH])
+		event.acs_selected_channels.ch_width =
+			nla_get_u16(tb[BRCM_VENDOR_ATTR_ACS_CHWIDTH]);
+	if (tb[BRCM_VENDOR_ATTR_ACS_HW_MODE]) {
+		event.acs_selected_channels.hw_mode = nla_get_u8(tb[BRCM_VENDOR_ATTR_ACS_HW_MODE]);
+		if (event.acs_selected_channels.hw_mode == NUM_HOSTAPD_MODES ||
+		    event.acs_selected_channels.hw_mode ==
+		    HOSTAPD_MODE_IEEE80211ANY) {
+			wpa_printf(MSG_DEBUG,
+				   "nl80211: Invalid hw_mode %d in ACS selection event",
+				   event.acs_selected_channels.hw_mode);
+			return;
+		}
+	}
+
+	wpa_printf(MSG_DEBUG,
+		   "nl80211: ACS Results: PCH: %d SCH: %d BW: %d VHT0: %d VHT1: %d HW_MODE: %d",
+		   event.acs_selected_channels.pri_freq,
+		   event.acs_selected_channels.sec_freq,
+		   event.acs_selected_channels.ch_width,
+		   event.acs_selected_channels.vht_seg0_center_ch,
+		   event.acs_selected_channels.vht_seg1_center_ch,
+		   event.acs_selected_channels.hw_mode);
+	wpa_supplicant_event(drv->ctx, EVENT_ACS_CHANNEL_SELECTED, &event);
+}
+
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
+
+#ifdef ANDROID_P2P
+static void nl80211_vendor_event_brcm(struct wpa_driver_nl80211_data *drv,
+				      u32 subcmd, u8 *data, size_t len)
+{
+	union wpa_event_data event;
+	const struct nlattr *iter;
+	int rem = len;
+
+	wpa_printf(MSG_DEBUG, "nl80211: Got BRCM vendor event %u", subcmd);
+	memset(&event, 0, sizeof(event));
+	switch (subcmd) {
+	case BRCM_VENDOR_EVENT_PRIV_STR:
+	case BRCM_VENDOR_EVENT_HANGED:
+		/* Dump the event on to the console */
+		wpa_msg(NULL, MSG_INFO, "%s", data);
+		break;
+#ifdef CONFIG_BRCM_SAE
+	case BRCM_VENDOR_EVENT_SAE_KEY: {
+		u16 pmkid_len = 0;
+		nla_for_each_attr(iter, (const struct nlattr *)data, len, rem) {
+			wpa_printf(MSG_DEBUG, "attr type is %d", nla_type(iter));
+			wpa_printf(MSG_DEBUG, "attr length is %d", nla_len(iter));
+			if (nla_type(iter) == BRCM_SAE_KEY_ATTR_PEER_MAC)
+				memcpy(event.sae_key_info.peer_mac, nla_data(iter), nla_len(iter));
+			if (nla_type(iter) == BRCM_SAE_KEY_ATTR_PMK) {
+				memcpy(event.sae_key_info.psk, nla_data(iter), nla_len(iter));
+				event.sae_key_info.psk_len = nla_len(iter);
+			}
+			if (nla_type(iter) == BRCM_SAE_KEY_ATTR_PMKID) {
+				memcpy(event.sae_key_info.pmkid, nla_data(iter), nla_len(iter));
+				pmkid_len = nla_len(iter);
+			}
+		}
+		if (event.sae_key_info.psk_len && pmkid_len && !is_zero_ether_addr(event.sae_key_info.peer_mac)) {
+			wpa_supplicant_event(drv->ctx, EVENT_SAE_KEY, &event);
+		} else {
+			wpa_printf(MSG_ERROR, "PMK data missing");
+		}
+	}
+	break;
+#endif /* CONFIG_BRCM_SAE */
+	case BRCM_VENDOR_EVENT_BEACON_RECV:
+		/* Fake ap beacon results in console */
+		nl80211_beacon_info_fakeap(drv, data, len);
+	break;
+#ifdef WL_SAE
+	case BRCM_VENDOR_EVENT_EXTERNAL_AUTH: {
+		struct nlattr *tb[NL80211_ATTR_MAX + 1];
+
+		nla_for_each_attr(iter, (const struct nlattr *)data, len, rem) {
+			wpa_printf(MSG_DEBUG, "attr type is %d. len is %d.\n",
+				nla_type(iter), nla_len(iter));
+
+			if (nla_type(iter) == NL80211_ATTR_AKM_SUITES) {
+				wpa_printf(MSG_DEBUG, "attr type is NL80211_ATTR_AKM_SUITES");
+				tb[NL80211_ATTR_AKM_SUITES] = (struct nlattr *)iter;
+			}
+			if (nla_type(iter) == NL80211_ATTR_EXTERNAL_AUTH_ACTION) {
+				wpa_printf(MSG_DEBUG, "attr type is "
+						"NL80211_ATTR_EXTERNAL_AUTH_ACTION");
+				tb[NL80211_ATTR_EXTERNAL_AUTH_ACTION] = (struct nlattr *)iter;
+			}
+			if (nla_type(iter) == NL80211_ATTR_BSSID) {
+				wpa_printf(MSG_DEBUG, "attr type is NL80211_ATTR_BSSID");
+				tb[NL80211_ATTR_BSSID] = (struct nlattr *)iter;
+			}
+			if (nla_type(iter) == NL80211_ATTR_SSID) {
+				wpa_printf(MSG_DEBUG, "attr type is NL80211_ATTR_SSID");
+				tb[NL80211_ATTR_SSID] = (struct nlattr *)iter;
+			}
+		}
+		wpa_printf(MSG_DEBUG, "nl80211: BRCM vendor event(%u): "
+				"BRCM_VENDOR_EVENT_EXTERNAL_AUTH", subcmd);
+		nl80211_external_auth(drv, tb);
+	}
+	break;
+#endif /* WL_SAE */
+	case BRCM_VENDOR_EVENT_OVERTEMP:
+		wpa_printf(MSG_DEBUG, "nl80211: BRCM vendor event(%u): "
+				"BRCM_VENDOR_EVENT_OVERTEMP\n", subcmd);
+		wpa_msg_global(drv->ctx, MSG_INFO, "overtemp event");
+	break;
+
+	default:
+		wpa_printf(MSG_DEBUG,
+			   "%s: Ignore unsupported BRCM vendor event %u",
+			   __func__, subcmd);
+		break;
+	}
+}
+#endif /* ANDROID_P2P */
+
+
 static void nl80211_vendor_event(struct wpa_driver_nl80211_data *drv,
 				 struct nlattr **tb)
 {
@@ -2525,6 +2664,12 @@
 		return;
 	}
 
+#ifdef ANDROID
+#ifdef ANDROID_LIB_EVENT
+       wpa_driver_nl80211_driver_event(drv, vendor_id, subcmd, data, len);
+#endif /* ANDROID_LIB_EVENT */
+#endif /* ANDROID */
+
 	switch (vendor_id) {
 	case OUI_QCA:
 		nl80211_vendor_event_qca(drv, subcmd, data, len);
@@ -2857,17 +3002,36 @@
 	wpa_printf(MSG_DEBUG, "nl80211: Drv Event %d (%s) received for %s",
 		   cmd, nl80211_command_to_string(cmd), bss->ifname);
 
+#ifdef CONFIG_DRIVER_NL80211_QCA
 	if (cmd == NL80211_CMD_ROAM &&
 	    (drv->capa.flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD)) {
+		if (drv->pending_roam_data) {
+			struct os_reltime now, age;
+
+			os_get_reltime(&now);
+			os_reltime_sub(&now, &drv->pending_roam_ind_time, &age);
+			if (age.sec == 0 && age.usec < 100000) {
+				wpa_printf(MSG_DEBUG,
+					   "nl80211: Process pending roam+auth vendor event");
+				qca_nl80211_key_mgmt_auth(
+					drv, drv->pending_roam_data,
+					drv->pending_roam_data_len);
+			}
+			os_free(drv->pending_roam_data);
+			drv->pending_roam_data = NULL;
+			return;
+		}
 		/*
 		 * Device will use roam+auth vendor event to indicate
 		 * roaming, so ignore the regular roam event.
 		 */
+		drv->roam_indication_done = true;
 		wpa_printf(MSG_DEBUG,
 			   "nl80211: Ignore roam event (cmd=%d), device will use vendor event roam+auth",
 			   cmd);
 		return;
 	}
+#endif /* CONFIG_DRIVER_NL80211_QCA */
 
 	if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED &&
 	    (cmd == NL80211_CMD_NEW_SCAN_RESULTS ||
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_nl80211_scan.c b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_nl80211_scan.c
index 233175d..1cd1546 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_nl80211_scan.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_nl80211_scan.c
@@ -203,6 +203,21 @@
 				goto fail;
 		}
 		nla_nest_end(msg, ssids);
+
+		/*
+		 * If allowed, scan for 6 GHz APs that are reported by other
+		 * APs. Note that if the flag is not set and 6 GHz channels are
+		 * to be scanned, it is highly likely that non-PSC channels
+		 * would be scanned passively (due to the Probe Request frame
+		 * transmission restrictions mandated in IEEE Std 802.11ax-2021,
+		 * 26.17.2.3 (Scanning in the 6 GHz band). Passive scanning of
+		 * all non-PSC channels would take a significant amount of time.
+		 */
+		if (!params->non_coloc_6ghz) {
+			wpa_printf(MSG_DEBUG,
+				   "nl80211: Scan co-located APs on 6 GHz");
+			scan_flags |= NL80211_SCAN_FLAG_COLOCATED_6GHZ;
+		}
 	} else {
 		wpa_printf(MSG_DEBUG, "nl80211: Passive scan requested");
 	}
@@ -870,7 +885,7 @@
 		wpa_driver_nl80211_mlme(drv, addr,
 					NL80211_CMD_DEAUTHENTICATE,
 					WLAN_REASON_PREV_AUTH_NOT_VALID, 1,
-					get_connect_handle(drv->first_bss));
+					drv->first_bss);
 	}
 }
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_wext.c b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_wext.c
index 691097c..e9e9849 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_wext.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/driver_wext.c
@@ -31,6 +31,10 @@
 #include "rfkill.h"
 #include "driver.h"
 #include "driver_wext.h"
+#if defined(WAPI_ANDROID)
+#include "wapi_asue.h"
+#include "wapi.h"
+#endif 
 
 static int wpa_driver_wext_flush_pmkid(void *priv);
 static int wpa_driver_wext_get_range(void *priv);
@@ -1208,6 +1212,9 @@
 	u8 ssid[SSID_MAX_LEN];
 	size_t ssid_len;
 	int maxrate;
+#if defined(WAPI_ANDROID)
+	size_t wapi_ie_len;
+#endif 
 };
 
 
@@ -1425,6 +1432,33 @@
 		}
 		res->res.tsf += WPA_GET_BE64(bin);
 	}
+#if defined(WAPI_ANDROID)
+	else if (clen > 8 && os_strncmp(custom, "wapi_ie=", 8) == 0) {
+		char *spos;
+		int bytes;
+		spos = custom + 8;
+		bytes = custom + clen - spos;
+		wpa_printf(MSG_DEBUG, "Got WAPI IE (%d)\n", bytes);
+		if (bytes & 1) {
+			wpa_printf(MSG_ERROR, "%s: === ALARM: bytes & 1 ===\n", __FUNCTION__);
+			return;
+		}
+		bytes /= 2;
+		if (bytes > SSID_MAX_WAPI_IE_LEN) {
+			wpa_printf(MSG_ERROR, "Too long WAPI IE (%d)", bytes);
+			return;
+		}
+		tmp = os_realloc(res->ie, res->ie_len + bytes);
+		if (tmp == NULL)
+			return;
+		hexstr2bin(spos, tmp + res->ie_len, bytes);
+		res->ie = tmp;
+		res->ie_len += bytes;
+		res->wapi_ie_len = bytes;
+		wpa_printf(MSG_DEBUG, "wapi ie, len=%d\n", res->wapi_ie_len);
+		wpa_hexdump_ascii(MSG_DEBUG, "wapi ie", (u8 *)res->ie, res->wapi_ie_len);
+	}
+#endif 
 }
 
 
@@ -1470,6 +1504,10 @@
 		return;
 	os_memcpy(r, &data->res, sizeof(*r));
 	r->ie_len = extra_len + data->ie_len;
+#if defined(WAPI_ANDROID)
+	r->wapi_ie_len = data->wapi_ie_len;
+	wpa_printf(MSG_DEBUG, "%s: wapi_ie_len=%d\n", __FUNCTION__, r->wapi_ie_len);
+#endif 
 	pos = (u8 *) (r + 1);
 	if (ssid_ie == NULL) {
 		/*
@@ -1683,6 +1721,15 @@
 	return 0;
 }
 
+#if defined(WAPI_ANDROID)
+static int wpa_driver_wext_set_wapi(void *priv, int enabled)
+{
+	struct wpa_driver_wext_data *drv = priv;
+	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
+	return wpa_driver_wext_set_auth_param(drv, IW_AUTH_WAPI_ENABLED, enabled);
+}
+#define IW_ENCODE_ALG_SM4   0x20
+#endif 
 
 static int wpa_driver_wext_set_psk(struct wpa_driver_wext_data *drv,
 				   const u8 *psk)
@@ -1782,6 +1829,11 @@
 		case WPA_ALG_CCMP:
 			ext->alg = IW_ENCODE_ALG_CCMP;
 			break;
+#if defined(WAPI_ANDROID)
+		case WAPI_ALG_SMS4:
+			ext->alg = IW_ENCODE_ALG_SM4;
+			break;
+#endif 
 		case WPA_ALG_BIP_CMAC_128:
 			ext->alg = IW_ENCODE_ALG_AES_CMAC;
 			break;
@@ -1794,8 +1846,17 @@
 	}
 
 	if (seq && seq_len) {
+#if defined(WAPI_ANDROID)
+		if (alg == WAPI_ALG_SMS4) {
+			os_memcpy(ext->tx_seq, seq, seq_len);
+			wpa_hexdump(MSG_DEBUG, "seq", seq, seq_len);
+		} else {
+#endif 
 		ext->ext_flags |= IW_ENCODE_EXT_RX_SEQ_VALID;
 		os_memcpy(ext->rx_seq, seq, seq_len);
+#if defined(WAPI_ANDROID)
+		}
+#endif 
 	}
 
 	if (ioctl(drv->ioctl_sock, SIOCSIWENCODEEXT, &iwr) < 0) {
@@ -2169,6 +2230,10 @@
 		ret = -1;
 	if (params->wpa_proto & WPA_PROTO_RSN)
 		value = IW_AUTH_WPA_VERSION_WPA2;
+#if defined(WAPI_ANDROID)
+	else if (params->wpa_ie[0] == WLAN_EID_WAPI) /* wapi */
+		value = IW_AUTH_WAPI_VERSION_1;
+#endif 
 	else if (params->wpa_proto & WPA_PROTO_WPA)
 		value = IW_AUTH_WPA_VERSION_WPA;
 	else
@@ -2177,14 +2242,32 @@
 					   IW_AUTH_WPA_VERSION, value) < 0)
 		ret = -1;
 	value = wpa_driver_wext_cipher2wext(params->pairwise_suite);
+#if defined(WAPI_ANDROID)
+	if (params->wpa_ie[0] == WLAN_EID_WAPI) /* wapi */
+		value |= IW_AUTH_CIPHER_SMS4;
+#endif 
 	if (wpa_driver_wext_set_auth_param(drv,
 					   IW_AUTH_CIPHER_PAIRWISE, value) < 0)
 		ret = -1;
 	value = wpa_driver_wext_cipher2wext(params->group_suite);
+#if defined(WAPI_ANDROID)
+	if (params->wpa_ie[0] == WLAN_EID_WAPI) /* wapi */
+		value |= IW_AUTH_CIPHER_SMS4;
+#endif 
 	if (wpa_driver_wext_set_auth_param(drv,
 					   IW_AUTH_CIPHER_GROUP, value) < 0)
 		ret = -1;
 	value = wpa_driver_wext_keymgmt2wext(params->key_mgmt_suite);
+#if defined(WAPI_ANDROID)
+	if (params->wpa_ie[0] == WLAN_EID_WAPI) { /* wapi */
+		if (params->wpa_ie[9] == 2) /* wapi psk */
+			value = IW_AUTH_KEY_MGMT_WAPI_PSK;
+		else if (params->wpa_ie[9] == 1) /* wapi cert */
+			value = IW_AUTH_KEY_MGMT_WAPI_CERT;
+		else 
+			wpa_printf(MSG_DEBUG, "Unknown WAPI key management value 0x%x\n", params->wpa_ie[9]);
+	}
+#endif 
 	if (wpa_driver_wext_set_auth_param(drv,
 					   IW_AUTH_KEY_MGMT, value) < 0)
 		ret = -1;
@@ -2495,6 +2578,9 @@
 	.desc = "Linux wireless extensions (generic)",
 	.get_bssid = wpa_driver_wext_get_bssid,
 	.get_ssid = wpa_driver_wext_get_ssid,
+#if defined(WAPI_ANDROID)
+	.set_wapi = wpa_driver_wext_set_wapi,
+#endif 
 	.set_key = wpa_driver_wext_set_key,
 	.set_countermeasures = wpa_driver_wext_set_countermeasures,
 	.scan2 = wpa_driver_wext_scan,
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/drivers.mak b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/drivers.mak
index 55a98ef..a03d4a0 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/drivers.mak
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/drivers.mak
@@ -26,6 +26,10 @@
 CONFIG_LIBNL3_ROUTE=y
 endif
 
+ifdef CONFIG_DRIVER_NL80211_BRCM
+DRV_CFLAGS += -DCONFIG_DRIVER_NL80211_BRCM
+endif
+
 ifdef CONFIG_DRIVER_MACSEC_QCA
 DRV_CFLAGS += -DCONFIG_DRIVER_MACSEC_QCA
 DRV_OBJS += ../src/drivers/driver_macsec_qca.o
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/drivers.mk b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/drivers.mk
index 5a32a24..10eab6a 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/drivers.mk
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/drivers.mk
@@ -41,6 +41,9 @@
 ifdef CONFIG_DRIVER_NL80211_QCA
 DRV_CFLAGS += -DCONFIG_DRIVER_NL80211_QCA
 endif
+ifdef CONFIG_DRIVER_NL80211_BRCM
+DRV_CFLAGS += -DCONFIG_DRIVER_NL80211_BRCM
+endif
 NEED_SME=y
 NEED_AP_MLME=y
 NEED_NETLINK=y
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/nl80211_copy.h b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/nl80211_copy.h
index 5ac681b..bdc409a 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/nl80211_copy.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/nl80211_copy.h
@@ -655,6 +655,9 @@
  *	When a security association was established on an 802.1X network using
  *	fast transition, this event should be followed by an
  *	%NL80211_CMD_PORT_AUTHORIZED event.
+ *	Following a %NL80211_CMD_ROAM event userspace can issue
+ *	%NL80211_CMD_GET_SCAN in order to obtain the scan information for the
+ *	new BSS the card/driver roamed to.
  * @NL80211_CMD_DISCONNECT: drop a given connection; also used to notify
  *	userspace that a connection was dropped by the AP or due to other
  *	reasons, for this the %NL80211_ATTR_DISCONNECTED_BY_AP and
@@ -1178,6 +1181,10 @@
  *	includes the contents of the frame. %NL80211_ATTR_ACK flag is included
  *	if the recipient acknowledged the frame.
  *
+ * @NL80211_CMD_SET_SAR_SPECS: SAR power limitation configuration is
+ *	passed using %NL80211_ATTR_SAR_SPEC. %NL80211_ATTR_WIPHY is used to
+ *	specify the wiphy index to be applied to.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -1364,6 +1371,9 @@
 
 	NL80211_CMD_WIPHY_REG_CHANGE,
 
+#if defined(WAPI_ANDROID)
+        NL80211_CMD_AUTH_WAPI_ENABLE,
+#endif
 	NL80211_CMD_ABORT_SCAN,
 
 	NL80211_CMD_START_NAN,
@@ -1408,6 +1418,8 @@
 
 	NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS,
 
+	NL80211_CMD_SET_SAR_SPECS,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
@@ -1957,8 +1969,15 @@
  * @NL80211_ATTR_PROBE_RESP: Probe Response template data. Contains the entire
  *	probe-response frame. The DA field in the 802.11 header is zero-ed out,
  *	to be filled by the FW.
- * @NL80211_ATTR_DISABLE_HT:  Force HT capable interfaces to disable
- *      this feature.  Currently, only supported in mac80211 drivers.
+ * @NL80211_ATTR_DISABLE_HT: Force HT capable interfaces to disable
+ *      this feature during association. This is a flag attribute.
+ *	Currently only supported in mac80211 drivers.
+ * @NL80211_ATTR_DISABLE_VHT: Force VHT capable interfaces to disable
+ *      this feature during association. This is a flag attribute.
+ *	Currently only supported in mac80211 drivers.
+ * @NL80211_ATTR_DISABLE_HE: Force HE capable interfaces to disable
+ *      this feature during association. This is a flag attribute.
+ *	Currently only supported in mac80211 drivers.
  * @NL80211_ATTR_HT_CAPABILITY_MASK: Specify which bits of the
  *      ATTR_HT_CAPABILITY to which attention should be paid.
  *      Currently, only mac80211 NICs support this feature.
@@ -2079,7 +2098,8 @@
  *	until the channel switch event.
  * @NL80211_ATTR_CH_SWITCH_BLOCK_TX: flag attribute specifying that transmission
  *	must be blocked on the current channel (before the channel switch
- *	operation).
+ *	operation). Also included in the channel switch started event if quiet
+ *	was requested by the AP.
  * @NL80211_ATTR_CSA_IES: Nested set of attributes containing the IE information
  *	for the time while performing a channel switch.
  * @NL80211_ATTR_CNTDWN_OFFS_BEACON: An array of offsets (u16) to the channel
@@ -2534,6 +2554,15 @@
  *	This is a u8 attribute that encapsulates one of the values from
  *	&enum nl80211_sae_pwe_mechanism.
  *
+ * @NL80211_ATTR_SAR_SPEC: SAR power limitation specification when
+ *	used with %NL80211_CMD_SET_SAR_SPECS. The message contains fields
+ *	of %nl80211_sar_attrs which specifies the sar type and related
+ *	sar specs. Sar specs contains array of %nl80211_sar_specs_attrs.
+ *
+ * @NL80211_ATTR_RECONNECT_REQUESTED: flag attribute, used with deauth and
+ *	disassoc events to indicate that an immediate reconnect to the AP
+ *	is desired.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2903,6 +2932,11 @@
 
 	NL80211_ATTR_REG_INDOOR,
 
+#if defined(WAPI_ANDROID)
+	NL80211_ATTR_WAPI,
+	NL80211_ATTR_WAPI_PSK,
+	NL80211_ATTR_WAPI_CERT,
+#endif 
 	NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS,
 	NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL,
 	NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS,
@@ -3025,6 +3059,12 @@
 
 	NL80211_ATTR_SAE_PWE,
 
+	NL80211_ATTR_RECONNECT_REQUESTED,
+
+	NL80211_ATTR_SAR_SPEC,
+
+	NL80211_ATTR_DISABLE_HE,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -4631,6 +4671,9 @@
 	NL80211_BSS_CHAN_WIDTH,
 	NL80211_BSS_BEACON_TSF,
 	NL80211_BSS_PRESP_DATA,
+#if defined(WAPI_ANDROID)
+ 	NL80211_BSS_WAPI_IES,
+#endif 
 	NL80211_BSS_LAST_SEEN_BOOTTIME,
 	NL80211_BSS_PAD,
 	NL80211_BSS_PARENT_TSF,
@@ -4684,6 +4727,9 @@
 	NL80211_AUTHTYPE_FT,
 	NL80211_AUTHTYPE_NETWORK_EAP,
 	NL80211_AUTHTYPE_SAE,
+#if defined(WAPI_ANDROID)
+	NL80211_AUTHTYPE_WAPI,
+#endif 
 	NL80211_AUTHTYPE_FILS_SK,
 	NL80211_AUTHTYPE_FILS_SK_PFS,
 	NL80211_AUTHTYPE_FILS_PK,
@@ -4725,6 +4771,9 @@
 	NL80211_WPA_VERSION_1 = 1 << 0,
 	NL80211_WPA_VERSION_2 = 1 << 1,
 	NL80211_WPA_VERSION_3 = 1 << 2,
+#if defined(WAPI_ANDROID)
+	NL80211_WAPI_VERSION_1 = 1 << 3,
+#endif 
 };
 
 /**
@@ -5917,6 +5966,16 @@
  * @NL80211_EXT_FEATURE_BEACON_RATE_HE: Driver supports beacon rate
  *	configuration (AP/mesh) with HE rates.
  *
+ * @NL80211_EXT_FEATURE_SECURE_LTF: Device supports secure LTF measurement
+ *      exchange protocol.
+ *
+ * @NL80211_EXT_FEATURE_SECURE_RTT: Device supports secure RTT measurement
+ *      exchange protocol.
+ *
+ * @NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE: Device supports management
+ *      frame protection for all management frames exchanged during the
+ *      negotiation and range measurement procedure.
+ *
  * @NUM_NL80211_EXT_FEATURES: number of extended features.
  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
  */
@@ -5978,6 +6037,9 @@
 	NL80211_EXT_FEATURE_FILS_DISCOVERY,
 	NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP,
 	NL80211_EXT_FEATURE_BEACON_RATE_HE,
+	NL80211_EXT_FEATURE_SECURE_LTF,
+	NL80211_EXT_FEATURE_SECURE_RTT,
+	NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE,
 
 	/* add new features before the definition below */
 	NUM_NL80211_EXT_FEATURES,
@@ -6275,11 +6337,13 @@
  * @NL80211_TDLS_PEER_HT: TDLS peer is HT capable.
  * @NL80211_TDLS_PEER_VHT: TDLS peer is VHT capable.
  * @NL80211_TDLS_PEER_WMM: TDLS peer is WMM capable.
+ * @NL80211_TDLS_PEER_HE: TDLS peer is HE capable.
  */
 enum nl80211_tdls_peer_capability {
 	NL80211_TDLS_PEER_HT = 1<<0,
 	NL80211_TDLS_PEER_VHT = 1<<1,
 	NL80211_TDLS_PEER_WMM = 1<<2,
+	NL80211_TDLS_PEER_HE = 1<<3,
 };
 
 /**
@@ -6871,6 +6935,9 @@
  *      if neither %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED nor
  *	%NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED is set, EDCA based
  *	ranging will be used.
+ * @NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK: negotiate for LMR feedback. Only
+ *	valid if either %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED or
+ *	%NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED is set.
  *
  * @NUM_NL80211_PMSR_FTM_REQ_ATTR: internal
  * @NL80211_PMSR_FTM_REQ_ATTR_MAX: highest attribute number
@@ -6889,6 +6956,7 @@
 	NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC,
 	NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED,
 	NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED,
+	NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK,
 
 	/* keep last */
 	NUM_NL80211_PMSR_FTM_REQ_ATTR,
@@ -7165,4 +7233,96 @@
 	NL80211_SAE_PWE_HASH_TO_ELEMENT,
 	NL80211_SAE_PWE_BOTH,
 };
+
+/**
+ * enum nl80211_sar_type - type of SAR specs
+ *
+ * @NL80211_SAR_TYPE_POWER: power limitation specified in 0.25dBm unit
+ *
+ */
+enum nl80211_sar_type {
+	NL80211_SAR_TYPE_POWER,
+
+	/* add new type here */
+
+	/* Keep last */
+	NUM_NL80211_SAR_TYPE,
+};
+
+/**
+ * enum nl80211_sar_attrs - Attributes for SAR spec
+ *
+ * @NL80211_SAR_ATTR_TYPE: the SAR type as defined in &enum nl80211_sar_type.
+ *
+ * @NL80211_SAR_ATTR_SPECS: Nested array of SAR power
+ *	limit specifications. Each specification contains a set
+ *	of %nl80211_sar_specs_attrs.
+ *
+ *	For SET operation, it contains array of %NL80211_SAR_ATTR_SPECS_POWER
+ *	and %NL80211_SAR_ATTR_SPECS_RANGE_INDEX.
+ *
+ *	For sar_capa dump, it contains array of
+ *	%NL80211_SAR_ATTR_SPECS_START_FREQ
+ *	and %NL80211_SAR_ATTR_SPECS_END_FREQ.
+ *
+ * @__NL80211_SAR_ATTR_LAST: Internal
+ * @NL80211_SAR_ATTR_MAX: highest sar attribute
+ *
+ * These attributes are used with %NL80211_CMD_SET_SAR_SPEC
+ */
+enum nl80211_sar_attrs {
+	__NL80211_SAR_ATTR_INVALID,
+
+	NL80211_SAR_ATTR_TYPE,
+	NL80211_SAR_ATTR_SPECS,
+
+	__NL80211_SAR_ATTR_LAST,
+	NL80211_SAR_ATTR_MAX = __NL80211_SAR_ATTR_LAST - 1,
+};
+
+/**
+ * enum nl80211_sar_specs_attrs - Attributes for SAR power limit specs
+ *
+ * @NL80211_SAR_ATTR_SPECS_POWER: Required (s32)value to specify the actual
+ *	power limit value in units of 0.25 dBm if type is
+ *	NL80211_SAR_TYPE_POWER. (i.e., a value of 44 represents 11 dBm).
+ *	0 means userspace doesn't have SAR limitation on this associated range.
+ *
+ * @NL80211_SAR_ATTR_SPECS_RANGE_INDEX: Required (u32) value to specify the
+ *	index of exported freq range table and the associated power limitation
+ *	is applied to this range.
+ *
+ *	Userspace isn't required to set all the ranges advertised by WLAN driver,
+ *	and userspace can skip some certain ranges. These skipped ranges don't
+ *	have SAR limitations, and they are same as setting the
+ *	%NL80211_SAR_ATTR_SPECS_POWER to any unreasonable high value because any
+ *	value higher than regulatory allowed value just means SAR power
+ *	limitation is removed, but it's required to set at least one range.
+ *	It's not allowed to set duplicated range in one SET operation.
+ *
+ *	Every SET operation overwrites previous SET operation.
+ *
+ * @NL80211_SAR_ATTR_SPECS_START_FREQ: Required (u32) value to specify the start
+ *	frequency of this range edge when registering SAR capability to wiphy.
+ *	It's not a channel center frequency. The unit is kHz.
+ *
+ * @NL80211_SAR_ATTR_SPECS_END_FREQ: Required (u32) value to specify the end
+ *	frequency of this range edge when registering SAR capability to wiphy.
+ *	It's not a channel center frequency. The unit is kHz.
+ *
+ * @__NL80211_SAR_ATTR_SPECS_LAST: Internal
+ * @NL80211_SAR_ATTR_SPECS_MAX: highest sar specs attribute
+ */
+enum nl80211_sar_specs_attrs {
+	__NL80211_SAR_ATTR_SPECS_INVALID,
+
+	NL80211_SAR_ATTR_SPECS_POWER,
+	NL80211_SAR_ATTR_SPECS_RANGE_INDEX,
+	NL80211_SAR_ATTR_SPECS_START_FREQ,
+	NL80211_SAR_ATTR_SPECS_END_FREQ,
+
+	__NL80211_SAR_ATTR_SPECS_LAST,
+	NL80211_SAR_ATTR_SPECS_MAX = __NL80211_SAR_ATTR_SPECS_LAST - 1,
+};
+
 #endif /* __LINUX_NL80211_H */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/wireless_copy.h b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/wireless_copy.h
index 3f99a63..b0ecae7 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/wireless_copy.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/drivers/wireless_copy.h
@@ -598,10 +598,16 @@
 #define IW_AUTH_PRIVACY_INVOKED		10
 #define IW_AUTH_CIPHER_GROUP_MGMT	11
 #define IW_AUTH_MFP			12
+#if defined(WAPI_ANDROID)
+#define IW_AUTH_WAPI_ENABLED		0x20
+#endif 
 /* IW_AUTH_WPA_VERSION values (bit field) */
 #define IW_AUTH_WPA_VERSION_DISABLED	0x00000001
 #define IW_AUTH_WPA_VERSION_WPA		0x00000002
 #define IW_AUTH_WPA_VERSION_WPA2	0x00000004
+#if defined(WAPI_ANDROID)
+#define IW_AUTH_WAPI_VERSION_1		0x00000008
+#endif 
 
 /* IW_AUTH_PAIRWISE_CIPHER, IW_AUTH_GROUP_CIPHER, and IW_AUTH_CIPHER_GROUP_MGMT
  * values (bit field) */
@@ -610,11 +616,18 @@
 #define IW_AUTH_CIPHER_TKIP	0x00000004
 #define IW_AUTH_CIPHER_CCMP	0x00000008
 #define IW_AUTH_CIPHER_WEP104	0x00000010
+#if defined(WAPI_ANDROID)
+#define IW_AUTH_CIPHER_SMS4	0x00000020
+#endif 
 #define IW_AUTH_CIPHER_AES_CMAC	0x00000020
 
 /* IW_AUTH_KEY_MGMT values (bit field) */
 #define IW_AUTH_KEY_MGMT_802_1X	1
 #define IW_AUTH_KEY_MGMT_PSK	2
+#if defined(WAPI_ANDROID)
+#define IW_AUTH_KEY_MGMT_WAPI_PSK	4
+#define IW_AUTH_KEY_MGMT_WAPI_CERT	8
+#endif 
 #ifdef BRCM_VE
 #define IW_AUTH_KEY_MGMT_FT_8021X	4
 #define IW_AUTH_KEY_MGMT_FT_PSK		8
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_common/eap_sim_common.c b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_common/eap_sim_common.c
index 4a93244..ab9bd86 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_common/eap_sim_common.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_common/eap_sim_common.c
@@ -1210,9 +1210,24 @@
 }
 
 
+static const u8 * get_last_char(const u8 *val, size_t len, char c)
+{
+	while (len > 0) {
+		const u8 *pos = &val[len - 1];
+
+		if (*pos == (u8) c)
+			return pos;
+		len--;
+	}
+
+	return NULL;
+}
+
+
 int eap_sim_anonymous_username(const u8 *id, size_t id_len)
 {
 	static const char *anonymous_id_prefix = "anonymous@";
+	const u8 *decorated;
 	size_t anonymous_id_len = os_strlen(anonymous_id_prefix);
 
 	if (id_len > anonymous_id_len &&
@@ -1226,5 +1241,14 @@
 	if (id_len > 1 && id[0] == '@')
 		return 1; /* '@realm' */
 
+	/* RFC 7542 decorated username, for example:
+	 * homerealm.example.org!anonymous@otherrealm.example.net */
+	decorated = get_last_char(id, id_len, '!');
+	if (decorated) {
+		decorated++;
+		return eap_sim_anonymous_username(decorated,
+						  id + id_len - decorated);
+	}
+
 	return 0;
 }
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/Makefile b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/Makefile
index bdbead6..076d8c0 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/Makefile
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/Makefile
@@ -5,9 +5,3 @@
 	eap_methods.o
 
 include ../lib.rules
-
-install:
-	if ls *.so >/dev/null 2>&1; then \
-		install -d $(DESTDIR)$(LIBDIR)/wpa_supplicant && \
-		cp *.so $(DESTDIR)$(LIBDIR)/wpa_supplicant \
-	; fi
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap.c b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap.c
index 74c2ad3..d209334 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap.c
@@ -242,14 +242,6 @@
 	eapol_set_bool(sm, EAPOL_eapRestart, false);
 	sm->lastId = -1; /* new session - make sure this does not match with
 			  * the first EAP-Packet */
-	/*
-	 * RFC 4137 does not reset eapResp and eapNoResp here. However, this
-	 * seemed to be able to trigger cases where both were set and if EAPOL
-	 * state machine uses eapNoResp first, it may end up not sending a real
-	 * reply correctly. This occurred when the workaround in FAIL state set
-	 * eapNoResp = true.. Maybe that workaround needs to be fixed to do
-	 * something else(?)
-	 */
 	eapol_set_bool(sm, EAPOL_eapResp, false);
 	eapol_set_bool(sm, EAPOL_eapNoResp, false);
 	/*
@@ -1069,6 +1061,20 @@
 	wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS
 		"EAP authentication completed successfully");
 
+	if (!config || !sm->m) {
+		/*
+		 * This should not happen under normal conditions, but be more
+		 * careful here since there was an earlier case where
+		 * EAP-Success could end up getting delivered to the state
+		 * machine for processing after the state had been cleaned with
+		 * a call to eap_invalidate_cached_session() (and also
+		 * eapol_sm_notify_config() having been used to clear EAP
+		 * configuration in the EAPOL state machine).
+		 */
+		wpa_printf(MSG_DEBUG,
+			   "EAP: State machine not configured - cannot initialize ERP");
+		return;
+	}
 	if (config->erp && sm->m->get_emsk && sm->eapSessionId &&
 	    sm->m->isKeyAvailable &&
 	    sm->m->isKeyAvailable(sm, sm->eap_method_priv))
@@ -1175,14 +1181,6 @@
 	duplicate = (sm->reqId == sm->lastId) && sm->rxReq;
 	if (sm->workaround && duplicate &&
 	    os_memcmp(sm->req_sha1, sm->last_sha1, 20) != 0) {
-		/*
-		 * RFC 4137 uses (reqId == lastId) as the only verification for
-		 * duplicate EAP requests. However, this misses cases where the
-		 * AS is incorrectly using the same id again; and
-		 * unfortunately, such implementations exist. Use SHA1 hash as
-		 * an extra verification for the packets being duplicate to
-		 * workaround these issues.
-		 */
 		wpa_printf(MSG_DEBUG, "EAP: AS used the same Id again, but "
 			   "EAP packets were not identical");
 		wpa_printf(MSG_DEBUG, "EAP: workaround - assume this is not a "
@@ -1207,11 +1205,6 @@
 {
 	int duplicate = eap_peer_req_is_duplicate(sm);
 
-	/*
-	 * Two special cases below for LEAP are local additions to work around
-	 * odd LEAP behavior (EAP-Success in the middle of authentication and
-	 * then swapped roles). Other transitions are based on RFC 4137.
-	 */
 	if (sm->rxSuccess && sm->decision != DECISION_FAIL &&
 	    (sm->reqId == sm->lastId ||
 	     eap_success_workaround(sm, sm->reqId, sm->lastId)))
@@ -2711,11 +2704,6 @@
 }
 
 
-/**
- * eap_set_workaround - Update EAP workarounds setting
- * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
- * @workaround: 1 = Enable EAP workarounds, 0 = Disable EAP workarounds
- */
 void eap_set_workaround(struct eap_sm *sm, unsigned int workaround)
 {
 	sm->workaround = workaround;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_aka.c b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_aka.c
index 730aa68..88f6929 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_aka.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_aka.c
@@ -432,19 +432,28 @@
 
 
 static int eap_aka_add_id_msg(struct eap_aka_data *data,
-			      const struct wpabuf *msg)
+			      const struct wpabuf *msg1,
+			      const struct wpabuf *msg2)
 {
-	if (msg == NULL)
-		return -1;
+	size_t len;
 
-	if (data->id_msgs == NULL) {
-		data->id_msgs = wpabuf_dup(msg);
-		return data->id_msgs == NULL ? -1 : 0;
+	if (!msg1)
+		return -1;
+	len = wpabuf_len(msg1);
+	if (msg2)
+		len += wpabuf_len(msg2);
+
+	if (!data->id_msgs) {
+		data->id_msgs = wpabuf_alloc(len);
+		if (!data->id_msgs)
+			return -1;
+	} else if (wpabuf_resize(&data->id_msgs, len) < 0) {
+		return -1;
 	}
 
-	if (wpabuf_resize(&data->id_msgs, wpabuf_len(msg)) < 0)
-		return -1;
-	wpabuf_put_buf(data->id_msgs, msg);
+	wpabuf_put_buf(data->id_msgs, msg1);
+	if (msg2)
+		wpabuf_put_buf(data->id_msgs, msg2);
 
 	return 0;
 }
@@ -789,8 +798,13 @@
 	buf = eap_aka_response_identity(sm, data, id, attr->id_req);
 
 	if (data->prev_id != id) {
-		eap_aka_add_id_msg(data, reqData);
-		eap_aka_add_id_msg(data, buf);
+		if (eap_aka_add_id_msg(data, reqData, buf) < 0) {
+			wpa_printf(MSG_INFO,
+				   "EAP-AKA: Failed to store ID messages");
+			wpabuf_free(buf);
+			return eap_aka_client_error(
+				data, id, EAP_AKA_UNABLE_TO_PROCESS_PACKET);
+		}
 		data->prev_id = id;
 	}
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_peap.c b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_peap.c
index 7c37043..12e30df 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_peap.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_peap.c
@@ -803,6 +803,10 @@
 	res = eap_peer_tls_decrypt(sm, &data->ssl, in_data, &in_decrypted);
 	if (res)
 		return res;
+	if (wpabuf_len(in_decrypted) == 0) {
+		wpabuf_free(in_decrypted);
+		return 1;
+	}
 
 continue_req:
 	wpa_hexdump_buf(MSG_DEBUG, "EAP-PEAP: Decrypted Phase 2 EAP",
@@ -1081,7 +1085,11 @@
 		}
 
 		if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
-			char *label;
+			const char *label;
+			const u8 eap_tls13_context[1] = { EAP_TYPE_PEAP };
+			const u8 *context = NULL;
+			size_t context_len = 0;
+
 			wpa_printf(MSG_DEBUG,
 				   "EAP-PEAP: TLS done, proceed to Phase 2");
 			eap_peap_free_key(data);
@@ -1091,16 +1099,25 @@
 			 * PEAPv1 implementations seem to be using the old
 			 * label, "client EAP encryption", instead. Use the old
 			 * label by default, but allow it to be configured with
-			 * phase1 parameter peaplabel=1. */
-			if (data->force_new_label)
+			 * phase1 parameter peaplabel=1.
+			 *
+			 * When using TLS 1.3, draft-ietf-emu-tls-eap-types
+			 * defines a new set of label and context parameters.
+			 */
+			if (data->ssl.tls_v13) {
+				label = "EXPORTER_EAP_TLS_Key_Material";
+				context = eap_tls13_context;
+				context_len = sizeof(eap_tls13_context);
+			} else if (data->force_new_label) {
 				label = "client PEAP encryption";
-			else
+			} else {
 				label = "client EAP encryption";
+			}
 			wpa_printf(MSG_DEBUG, "EAP-PEAP: using label '%s' in "
 				   "key derivation", label);
 			data->key_data =
 				eap_peer_tls_derive_key(sm, &data->ssl, label,
-							NULL, 0,
+							context, context_len,
 							EAP_TLS_KEY_LEN +
 							EAP_EMSK_LEN);
 			if (data->key_data) {
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_proxy_dummy.c b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_proxy_dummy.c
index 2cc05c9..181e8cc 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_proxy_dummy.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_proxy_dummy.c
@@ -1,5 +1,5 @@
 /*
- * EAP proxy - dummy implementation for build testing
+ * EAP proxy - stub implementation for build testing
  * Copyright (c) 2013 Qualcomm Atheros, Inc.
  *
  * This software may be distributed under the terms of the BSD license.
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_teap.c b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_teap.c
index e1570a9..28621a8 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_teap.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_teap.c
@@ -1760,8 +1760,8 @@
 
 
 #ifdef CONFIG_TESTING_OPTIONS
-static struct wpabuf * eap_teap_add_dummy_outer_tlvs(struct eap_teap_data *data,
-						     struct wpabuf *resp)
+static struct wpabuf * eap_teap_add_stub_outer_tlvs(struct eap_teap_data *data,
+						    struct wpabuf *resp)
 {
 	struct wpabuf *resp2;
 	u16 len;
@@ -1775,11 +1775,11 @@
 		return NULL;
 	}
 
-	/* Outer TLVs (dummy Vendor-Specific TLV for testing) */
+	/* Outer TLVs (stub Vendor-Specific TLV for testing) */
 	wpabuf_put_be16(data->peer_outer_tlvs, TEAP_TLV_VENDOR_SPECIFIC);
 	wpabuf_put_be16(data->peer_outer_tlvs, 4);
 	wpabuf_put_be32(data->peer_outer_tlvs, EAP_VENDOR_HOSTAP);
-	wpa_hexdump_buf(MSG_DEBUG, "EAP-TEAP: TESTING - Add dummy Outer TLVs",
+	wpa_hexdump_buf(MSG_DEBUG, "EAP-TEAP: TESTING - Add stub Outer TLVs",
 			data->peer_outer_tlvs);
 
 	wpa_hexdump_buf(MSG_DEBUG,
@@ -1986,7 +1986,7 @@
 #ifdef CONFIG_TESTING_OPTIONS
 	if (data->test_outer_tlvs && res == 0 && resp &&
 	    (flags & EAP_TLS_FLAGS_START) && wpabuf_len(resp) >= 6)
-		resp = eap_teap_add_dummy_outer_tlvs(data, resp);
+		resp = eap_teap_add_stub_outer_tlvs(data, resp);
 #endif /* CONFIG_TESTING_OPTIONS */
 
 	return resp;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_tls.c b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_tls.c
index ad079a7..0d479f1 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_tls.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_tls.c
@@ -302,15 +302,11 @@
 		return NULL;
 	}
 
-	if (res == 2) {
-		/* Application data included in the handshake message (used by
-		 * EAP-TLS 1.3 to indicate conclusion of the exchange). */
-		wpa_hexdump_buf(MSG_DEBUG, "EAP-TLS: Received Application Data",
-				resp);
-		wpa_hexdump_buf(MSG_DEBUG, "EAP-TLS: Remaining tls_out data",
-				data->ssl.tls_out);
+	/* draft-ietf-emu-eap-tls13-13 Section 2.5 */
+	if (res == 2 && data->ssl.tls_v13 && wpabuf_len(resp) == 1 &&
+	    *wpabuf_head_u8(resp) == 0) {
+		wpa_printf(MSG_DEBUG, "EAP-TLS: ACKing Commitment Message");
 		eap_peer_tls_reset_output(&data->ssl);
-		/* Send an ACK to allow the server to complete exchange */
 		res = 1;
 	}
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_tls_common.c b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_tls_common.c
index 298f374..dfe9215 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_tls_common.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_tls_common.c
@@ -404,9 +404,9 @@
 	struct tls_random keys;
 	u8 *out;
 
-	if (eap_type == EAP_TYPE_TLS && data->tls_v13) {
+	if (data->tls_v13) {
 		u8 *id, *method_id;
-		const u8 context[] = { EAP_TYPE_TLS };
+		const u8 context[] = { eap_type };
 
 		/* Session-Id = <EAP-Type> || Method-Id
 		 * Method-Id = TLS-Exporter("EXPORTER_EAP_TLS_Method-Id",
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_tls_common.h b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_tls_common.h
index 183b7de..9ac0012 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_tls_common.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_tls_common.h
@@ -92,7 +92,7 @@
  /* could be up to 128 bytes, but only the first 64 bytes are used */
 #define EAP_TLS_KEY_LEN 64
 
-/* dummy type used as a flag for UNAUTH-TLS */
+/* stub type used as a flag for UNAUTH-TLS */
 #define EAP_UNAUTH_TLS_TYPE 255
 #define EAP_WFA_UNAUTH_TLS_TYPE 254
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_ttls.c b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_ttls.c
index 642d179..c401915 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_ttls.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_peer/eap_ttls.c
@@ -268,10 +268,22 @@
 static int eap_ttls_v0_derive_key(struct eap_sm *sm,
 				  struct eap_ttls_data *data)
 {
+	const char *label;
+	const u8 eap_tls13_context[1] = { EAP_TYPE_TTLS };
+	const u8 *context = NULL;
+	size_t context_len = 0;
+
+	if (data->ssl.tls_v13) {
+		label = "EXPORTER_EAP_TLS_Key_Material";
+		context = eap_tls13_context;
+		context_len = sizeof(eap_tls13_context);
+	} else {
+		label = "ttls keying material";
+	}
+
 	eap_ttls_free_key(data);
-	data->key_data = eap_peer_tls_derive_key(sm, &data->ssl,
-						 "ttls keying material",
-						 NULL, 0,
+	data->key_data = eap_peer_tls_derive_key(sm, &data->ssl, label,
+						 context, context_len,
 						 EAP_TLS_KEY_LEN +
 						 EAP_EMSK_LEN);
 	if (!data->key_data) {
@@ -1441,6 +1453,7 @@
 
 	if ((in_data == NULL || wpabuf_len(in_data) == 0) &&
 	    data->phase2_start) {
+start:
 		return eap_ttls_phase2_start(sm, data, ret, identifier,
 					     out_data);
 	}
@@ -1455,6 +1468,20 @@
 	retval = eap_peer_tls_decrypt(sm, &data->ssl, in_data, &in_decrypted);
 	if (retval)
 		goto done;
+	if (wpabuf_len(in_decrypted) == 0) {
+		wpabuf_free(in_decrypted);
+		goto start;
+	}
+
+	/* draft-ietf-emu-eap-tls13-13 Section 2.5 */
+	if (data->ssl.tls_v13 && wpabuf_len(in_decrypted) == 1 &&
+	    *wpabuf_head_u8(in_decrypted) == 0) {
+		wpa_printf(MSG_DEBUG,
+			   "EAP-TTLS: ACKing EAP-TLS Commitment Message");
+		eap_peer_tls_reset_output(&data->ssl);
+		wpabuf_free(in_decrypted);
+		return 1;
+	}
 
 continue_req:
 	data->phase2_start = 0;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_server/eap_server_peap.c b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_server/eap_server_peap.c
index f234f6f..f526e8b 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_server/eap_server_peap.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_server/eap_server_peap.c
@@ -325,13 +325,27 @@
 	u8 *tk;
 	u8 isk[32], imck[60];
 	int res;
+	const char *label;
+	const u8 eap_tls13_context[1] = { EAP_TYPE_PEAP };
+	const u8 *context = NULL;
+	size_t context_len = 0;
+
+	if (data->ssl.tls_v13) {
+		label = "EXPORTER_EAP_TLS_Key_Material";
+		context = eap_tls13_context;
+		context_len = sizeof(eap_tls13_context);
+	} else {
+		/* TODO: PEAPv1 - different label in some cases */
+		label = "client EAP encryption";
+	}
 
 	/*
 	 * Tunnel key (TK) is the first 60 octets of the key generated by
 	 * phase 1 of PEAP (based on TLS).
 	 */
-	tk = eap_server_tls_derive_key(sm, &data->ssl, "client EAP encryption",
-				       NULL, 0, EAP_TLS_KEY_LEN);
+	tk = eap_server_tls_derive_key(sm, &data->ssl, label,
+				       context, context_len,
+				       EAP_TLS_KEY_LEN);
 	if (tk == NULL)
 		return -1;
 	wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: TK", tk, 60);
@@ -498,7 +512,25 @@
 	encr_req = eap_server_tls_encrypt(sm, &data->ssl, &msgbuf);
 	os_free(hdr);
 
-	return encr_req;
+	if (!data->ssl.tls_v13 ||
+	    !tls_connection_resumed(sm->cfg->ssl_ctx, data->ssl.conn)) {
+		wpabuf_free(data->ssl.tls_out);
+		data->ssl.tls_out_pos = 0;
+		return encr_req;
+	}
+
+	if (wpabuf_resize(&data->ssl.tls_out, wpabuf_len(encr_req)) < 0) {
+		wpa_printf(MSG_INFO,
+			   "EAP-PEAP: Failed to resize output buffer");
+		wpabuf_free(encr_req);
+		return NULL;
+	}
+	wpabuf_put_buf(data->ssl.tls_out, encr_req);
+	wpa_hexdump_buf(MSG_DEBUG,
+			"EAP-PEAP: Data appended to the message", encr_req);
+	os_free(encr_req);
+
+	return data->ssl.tls_out;
 }
 
 
@@ -547,8 +579,6 @@
 		data->ssl.tls_out = eap_peap_build_phase2_tlv(sm, data, id);
 		break;
 	case SUCCESS_REQ:
-		wpabuf_free(data->ssl.tls_out);
-		data->ssl.tls_out_pos = 0;
 		data->ssl.tls_out = eap_peap_build_phase2_term(sm, data, id,
 							       1);
 		break;
@@ -1300,6 +1330,10 @@
 {
 	struct eap_peap_data *data = priv;
 	u8 *eapKeyData;
+	const char *label;
+	const u8 eap_tls13_context[1] = { EAP_TYPE_PEAP };
+	const u8 *context = NULL;
+	size_t context_len = 0;
 
 	if (data->state != SUCCESS)
 		return NULL;
@@ -1332,9 +1366,17 @@
 		return eapKeyData;
 	}
 
-	/* TODO: PEAPv1 - different label in some cases */
+	if (data->ssl.tls_v13) {
+		label = "EXPORTER_EAP_TLS_Key_Material";
+		context = eap_tls13_context;
+		context_len = sizeof(eap_tls13_context);
+	} else {
+		/* TODO: PEAPv1 - different label in some cases */
+		label = "client EAP encryption";
+	}
+
 	eapKeyData = eap_server_tls_derive_key(sm, &data->ssl,
-					       "client EAP encryption", NULL, 0,
+					       label, context, context_len,
 					       EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
 	if (eapKeyData) {
 		os_memset(eapKeyData + EAP_TLS_KEY_LEN, 0, EAP_EMSK_LEN);
@@ -1353,6 +1395,10 @@
 {
 	struct eap_peap_data *data = priv;
 	u8 *eapKeyData, *emsk;
+	const char *label;
+	const u8 eap_tls13_context[1] = { EAP_TYPE_PEAP };
+	const u8 *context = NULL;
+	size_t context_len = 0;
 
 	if (data->state != SUCCESS)
 		return NULL;
@@ -1362,9 +1408,17 @@
 		return NULL;
 	}
 
-	/* TODO: PEAPv1 - different label in some cases */
+	if (data->ssl.tls_v13) {
+		label = "EXPORTER_EAP_TLS_Key_Material";
+		context = eap_tls13_context;
+		context_len = sizeof(eap_tls13_context);
+	} else {
+		/* TODO: PEAPv1 - different label in some cases */
+		label = "client EAP encryption";
+	}
+
 	eapKeyData = eap_server_tls_derive_key(sm, &data->ssl,
-					       "client EAP encryption", NULL, 0,
+					       label, context, context_len,
 					       EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
 	if (eapKeyData) {
 		emsk = os_memdup(eapKeyData + EAP_TLS_KEY_LEN, EAP_EMSK_LEN);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_server/eap_server_tls.c b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_server/eap_server_tls.c
index 1dd208e..00a496f 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_server/eap_server_tls.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_server/eap_server_tls.c
@@ -266,32 +266,6 @@
 		eap_tls_state(data, FAILURE);
 		return;
 	}
-
-	if (data->ssl.tls_v13 &&
-	    tls_connection_established(sm->cfg->ssl_ctx, data->ssl.conn)) {
-		struct wpabuf *plain, *encr;
-
-		wpa_printf(MSG_DEBUG,
-			   "EAP-TLS: Send empty application data to indicate end of exchange");
-		plain = wpabuf_alloc(1);
-		if (!plain)
-			return;
-		wpabuf_put_u8(plain, 0);
-		encr = eap_server_tls_encrypt(sm, &data->ssl, plain);
-		wpabuf_free(plain);
-		if (!encr)
-			return;
-		if (wpabuf_resize(&data->ssl.tls_out, wpabuf_len(encr)) < 0) {
-			wpa_printf(MSG_INFO,
-				   "EAP-TLS: Failed to resize output buffer");
-			wpabuf_free(encr);
-			return;
-		}
-		wpabuf_put_buf(data->ssl.tls_out, encr);
-		wpa_hexdump_buf(MSG_DEBUG,
-				"EAP-TLS: Data appended to the message", encr);
-		wpabuf_free(encr);
-	}
 }
 
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_server/eap_server_tls_common.c b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_server/eap_server_tls_common.c
index b38f1e0..a9b53b1 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_server/eap_server_tls_common.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_server/eap_server_tls_common.c
@@ -146,10 +146,10 @@
 {
 	struct tls_random keys;
 	u8 *out;
-	const u8 context[] = { EAP_TYPE_TLS };
 
-	if (eap_type == EAP_TYPE_TLS && data->tls_v13) {
+	if (data->tls_v13) {
 		u8 *id, *method_id;
+		const u8 context[] = { eap_type };
 
 		/* Session-Id = <EAP-Type> || Method-Id
 		 * Method-Id = TLS-Exporter("EXPORTER_EAP_TLS_Method-Id",
@@ -366,6 +366,56 @@
 		sm->serial_num = tls_connection_peer_serial_num(
 			sm->cfg->ssl_ctx, data->conn);
 
+	/*
+	 * https://tools.ietf.org/html/draft-ietf-emu-eap-tls13#section-2.5
+	 *
+	 * We need to signal the other end that TLS negotiation is done. We
+	 * can't send a zero-length application data message, so we send
+	 * application data which is one byte of zero.
+	 *
+	 * Note this is only done for when there is no application data to be
+	 * sent. So this is done always for EAP-TLS but notibly not for PEAP
+	 * even on resumption.
+	 */
+	if (data->tls_v13 &&
+	    tls_connection_established(sm->cfg->ssl_ctx, data->conn)) {
+		struct wpabuf *plain, *encr;
+
+		switch (sm->currentMethod) {
+		case EAP_TYPE_PEAP:
+			break;
+		default:
+			if (!tls_connection_resumed(sm->cfg->ssl_ctx,
+						    data->conn))
+				break;
+			/* fallthrough */
+		case EAP_TYPE_TLS:
+			wpa_printf(MSG_DEBUG,
+				   "EAP-TLS: Send Commitment Message");
+
+			plain = wpabuf_alloc(1);
+			if (!plain)
+				return -1;
+			wpabuf_put_u8(plain, 0);
+			encr = eap_server_tls_encrypt(sm, data, plain);
+			wpabuf_free(plain);
+			if (!encr)
+				return -1;
+			if (wpabuf_resize(&data->tls_out, wpabuf_len(encr)) < 0)
+			{
+				wpa_printf(MSG_INFO,
+					   "EAP-TLS: Failed to resize output buffer");
+				wpabuf_free(encr);
+				return -1;
+			}
+			wpabuf_put_buf(data->tls_out, encr);
+			wpa_hexdump_buf(MSG_DEBUG,
+					"EAP-TLS: Data appended to the message",
+					encr);
+			wpabuf_free(encr);
+		}
+	}
+
 	return 0;
 }
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_server/eap_server_ttls.c b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_server/eap_server_ttls.c
index 2f0c041..b893522 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_server/eap_server_ttls.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_server/eap_server_ttls.c
@@ -1271,13 +1271,25 @@
 {
 	struct eap_ttls_data *data = priv;
 	u8 *eapKeyData;
+	const char *label;
+	const u8 eap_tls13_context[1] = { EAP_TYPE_TTLS };
+	const u8 *context = NULL;
+	size_t context_len = 0;
 
 	if (data->state != SUCCESS)
 		return NULL;
 
+	if (data->ssl.tls_v13) {
+		label = "EXPORTER_EAP_TLS_Key_Material";
+		context = eap_tls13_context;
+		context_len = sizeof(eap_tls13_context);
+	} else {
+		label = "ttls keying material";
+	}
+
 	eapKeyData = eap_server_tls_derive_key(sm, &data->ssl,
-					       "ttls keying material", NULL, 0,
-					       EAP_TLS_KEY_LEN);
+					       label, context, context_len,
+					       EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
 	if (eapKeyData) {
 		*len = EAP_TLS_KEY_LEN;
 		wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived key",
@@ -1313,12 +1325,24 @@
 {
 	struct eap_ttls_data *data = priv;
 	u8 *eapKeyData, *emsk;
+	const char *label;
+	const u8 eap_tls13_context[1] = { EAP_TYPE_TTLS };
+	const u8 *context = NULL;
+	size_t context_len = 0;
 
 	if (data->state != SUCCESS)
 		return NULL;
 
+	if (data->ssl.tls_v13) {
+		label = "EXPORTER_EAP_TLS_Key_Material";
+		context = eap_tls13_context;
+		context_len = sizeof(eap_tls13_context);
+	} else {
+		label = "ttls keying material";
+	}
+
 	eapKeyData = eap_server_tls_derive_key(sm, &data->ssl,
-					       "ttls keying material", NULL, 0,
+					       label, context, context_len,
 					       EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
 	if (eapKeyData) {
 		emsk = os_malloc(EAP_EMSK_LEN);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_server/eap_server_wsc.c b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_server/eap_server_wsc.c
index fc70cf1..a162deb 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_server/eap_server_wsc.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_server/eap_server_wsc.c
@@ -132,9 +132,11 @@
 	cfg.peer_addr = sm->peer_addr;
 #ifdef CONFIG_P2P
 	if (sm->assoc_p2p_ie) {
-		wpa_printf(MSG_DEBUG, "EAP-WSC: Prefer PSK format for P2P "
-			   "client");
-		cfg.use_psk_key = 1;
+		if (!sm->cfg->wps->use_passphrase) {
+			wpa_printf(MSG_DEBUG,
+				   "EAP-WSC: Prefer PSK format for non-6 GHz P2P client");
+			cfg.use_psk_key = 1;
+		}
 		cfg.p2p_dev_addr = p2p_get_go_dev_addr(sm->assoc_p2p_ie);
 	}
 #endif /* CONFIG_P2P */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_server/eap_tls_common.h b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_server/eap_tls_common.h
index b0b7361..b0723a1 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/eap_server/eap_tls_common.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/eap_server/eap_tls_common.h
@@ -68,7 +68,7 @@
  /* could be up to 128 bytes, but only the first 64 bytes are used */
 #define EAP_TLS_KEY_LEN 64
 
-/* dummy type used as a flag for UNAUTH-TLS */
+/* stub type used as a flag for UNAUTH-TLS */
 #define EAP_UNAUTH_TLS_TYPE 255
 #define EAP_WFA_UNAUTH_TLS_TYPE 254
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/eapol_supp/eapol_supp_sm.h b/src/lynq/packages/thirdpart/lynq-wg870/src/eapol_supp/eapol_supp_sm.h
index 753b947..71559ea 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/eapol_supp/eapol_supp_sm.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/eapol_supp/eapol_supp_sm.h
@@ -46,9 +46,6 @@
 	 */
 	int fast_reauth;
 
-	/**
-	 * workaround - Whether EAP workarounds are enabled
-	 */
 	unsigned int workaround;
 
 	/**
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/l2_packet/l2_packet_linux.c b/src/lynq/packages/thirdpart/lynq-wg870/src/l2_packet/l2_packet_linux.c
index 9c01b3a..528721a 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/l2_packet/l2_packet_linux.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/l2_packet/l2_packet_linux.c
@@ -173,11 +173,6 @@
 		size_t len[1];
 		const struct l2_ethhdr *eth = (const struct l2_ethhdr *) buf;
 
-		/*
-		 * Close the workaround socket if the kernel version seems to be
-		 * able to deliver packets through the packet socket before
-		 * authorization has been completed (in dormant state).
-		 */
 		if (l2->num_rx_br <= 1 &&
 		    (os_memcmp(eth->h_dest, l2->own_addr, ETH_ALEN) == 0 ||
 		     is_multicast_ether_addr(eth->h_dest))) {
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/l2_packet/l2_packet_none.c b/src/lynq/packages/thirdpart/lynq-wg870/src/l2_packet/l2_packet_none.c
index bc7a4e8..6783d73 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/l2_packet/l2_packet_none.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/l2_packet/l2_packet_none.c
@@ -1,5 +1,5 @@
 /*
- * WPA Supplicant - Layer2 packet handling example with dummy functions
+ * WPA Supplicant - Layer2 packet handling example with stub functions
  * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/l2_packet/l2_packet_pcap.c b/src/lynq/packages/thirdpart/lynq-wg870/src/l2_packet/l2_packet_pcap.c
index c2b17fc..eba24b2 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/l2_packet/l2_packet_pcap.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/l2_packet/l2_packet_pcap.c
@@ -259,7 +259,6 @@
 			fprintf(stderr, "%s: cannot enable immediate mode on "
 				"interface %s: %s\n",
 				__func__, l2->ifname, strerror(errno));
-			/* XXX should we fail? */
 		}
 	}
 #endif /* BIOCIMMEDIATE */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p.c b/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p.c
index c32884e..3434601 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p.c
@@ -428,7 +428,9 @@
 			oldest = dev;
 	}
 	if (count + 1 > p2p->cfg->max_peers && oldest) {
-		p2p_dbg(p2p, "Remove oldest peer entry to make room for a new peer");
+		p2p_dbg(p2p,
+			"Remove oldest peer entry to make room for a new peer "
+			MACSTR, MAC2STR(oldest->info.p2p_device_addr));
 		dl_list_del(&oldest->list);
 		p2p_device_free(p2p, oldest);
 	}
@@ -665,6 +667,8 @@
 		if (wpabuf_resize(&dev->info.vendor_elems, 2 + len) < 0)
 			break;
 		wpabuf_put_data(dev->info.vendor_elems, pos - 2, 2 + len);
+		if (wpabuf_size(dev->info.vendor_elems) > 2000)
+			break;
 	}
 }
 
@@ -1126,7 +1130,7 @@
 
 	res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, type, freq,
 				 p2p->num_req_dev_types, p2p->req_dev_types,
-				 p2p->find_dev_id, pw_id);
+				 p2p->find_dev_id, pw_id, p2p->include_6ghz);
 	if (res < 0) {
 		p2p_dbg(p2p, "Scan request schedule failed");
 		p2p_continue_find(p2p);
@@ -1250,7 +1254,7 @@
 	     enum p2p_discovery_type type,
 	     unsigned int num_req_dev_types, const u8 *req_dev_types,
 	     const u8 *dev_id, unsigned int search_delay,
-	     u8 seek_count, const char **seek, int freq)
+	     u8 seek_count, const char **seek, int freq, bool include_6ghz)
 {
 	int res;
 	struct os_reltime start;
@@ -1275,7 +1279,7 @@
 		p2p->find_dev_id = p2p->find_dev_id_buf;
 	} else
 		p2p->find_dev_id = NULL;
-
+	p2p->include_6ghz = p2p_wfd_enabled(p2p) && include_6ghz;
 	if (seek_count == 0 || !seek) {
 		/* Not an ASP search */
 		p2p->p2ps_seek = 0;
@@ -1355,7 +1359,8 @@
 #endif /* CONFIG_DRIVER_NL80211_IFX && CONFIG_BRCM_RSDB */
 						 p2p->num_req_dev_types,
 						 p2p->req_dev_types, dev_id,
-						 DEV_PW_DEFAULT);
+						 DEV_PW_DEFAULT,
+						 p2p->include_6ghz);
 			break;
 		}
 		/* fall through */
@@ -1363,7 +1368,7 @@
 		res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_FULL, 0,
 					 p2p->num_req_dev_types,
 					 p2p->req_dev_types, dev_id,
-					 DEV_PW_DEFAULT);
+					 DEV_PW_DEFAULT, p2p->include_6ghz);
 		break;
 #ifdef CONFIG_BRCM_RSDB
 	case P2P_FIND_FAST_PROGRESSIVE:
@@ -1377,7 +1382,7 @@
 		res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_SOCIAL, 0,
 					 p2p->num_req_dev_types,
 					 p2p->req_dev_types, dev_id,
-					 DEV_PW_DEFAULT);
+					 DEV_PW_DEFAULT, p2p->include_6ghz);
 		break;
 	default:
 		return -1;
@@ -1428,7 +1433,9 @@
 
 void p2p_stop_listen_for_freq(struct p2p_data *p2p, int freq)
 {
-	if (freq > 0 && p2p->drv_in_listen == freq && p2p->in_listen) {
+	if (freq > 0 &&
+	    ((p2p->drv_in_listen == freq && p2p->in_listen) ||
+	     p2p->pending_listen_freq == (unsigned int) freq)) {
 		p2p_dbg(p2p, "Skip stop_listen since we are on correct channel for response");
 		return;
 	}
@@ -1499,8 +1506,8 @@
 		p2p->channels.reg_class[0].reg_class = p2p->op_reg_class;
 		p2p->channels.reg_class[0].channel[0] = p2p->op_channel;
 	} else {
-		os_memcpy(&p2p->channels, &p2p->cfg->channels,
-			  sizeof(struct p2p_channels));
+		p2p_copy_channels(&p2p->channels, &p2p->cfg->channels,
+				  p2p->allow_6ghz);
 	}
 
 	return 0;
@@ -1514,6 +1521,7 @@
 	const int op_classes_ht40[] = { 126, 127, 116, 117, 0 };
 	const int op_classes_vht[] = { 128, 0 };
 	const int op_classes_edmg[] = { 181, 182, 183, 0 };
+	const int op_classes_6ghz[] = { 131, 0 };
 
 	p2p_dbg(p2p, "Prepare channel best");
 
@@ -1550,6 +1558,12 @@
 		   0) {
 		p2p_dbg(p2p, "Select possible EDMG channel (op_class %u channel %u) as operating channel preference",
 			p2p->op_reg_class, p2p->op_channel);
+	} else if (p2p->allow_6ghz &&
+		   (p2p_channel_select(&p2p->cfg->channels, op_classes_6ghz,
+				       &p2p->op_reg_class, &p2p->op_channel) ==
+		    0)) {
+		p2p_dbg(p2p, "Select possible 6 GHz channel (op_class %u channel %u) as operating channel preference",
+			p2p->op_reg_class, p2p->op_channel);
 	} else if (p2p_channel_select(&p2p->cfg->channels, op_classes_vht,
 				      &p2p->op_reg_class, &p2p->op_channel) ==
 		   0) {
@@ -1587,8 +1601,7 @@
 			p2p->op_channel, p2p->op_reg_class);
 	}
 
-	os_memcpy(&p2p->channels, &p2p->cfg->channels,
-		  sizeof(struct p2p_channels));
+	p2p_copy_channels(&p2p->channels, &p2p->cfg->channels, p2p->allow_6ghz);
 }
 
 
@@ -1671,9 +1684,10 @@
 	p2p_dbg(p2p, "Request to start group negotiation - peer=" MACSTR
 		"  GO Intent=%d  Intended Interface Address=" MACSTR
 		" wps_method=%d persistent_group=%d pd_before_go_neg=%d "
-		"oob_pw_id=%u",
+		"oob_pw_id=%u allow_6ghz=%d",
 		MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr),
-		wps_method, persistent_group, pd_before_go_neg, oob_pw_id);
+		wps_method, persistent_group, pd_before_go_neg, oob_pw_id,
+		p2p->allow_6ghz);
 
 	dev = p2p_get_device(p2p, peer_addr);
 	if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) {
@@ -1771,9 +1785,9 @@
 
 	p2p_dbg(p2p, "Request to authorize group negotiation - peer=" MACSTR
 		"  GO Intent=%d  Intended Interface Address=" MACSTR
-		" wps_method=%d  persistent_group=%d oob_pw_id=%u",
+		" wps_method=%d  persistent_group=%d oob_pw_id=%u allow_6ghz=%d",
 		MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr),
-		wps_method, persistent_group, oob_pw_id);
+		wps_method, persistent_group, oob_pw_id, p2p->allow_6ghz);
 
 	dev = p2p_get_device(p2p, peer_addr);
 	if (dev == NULL) {
@@ -3642,12 +3656,17 @@
 }
 
 
-void p2p_scan_res_handled(struct p2p_data *p2p)
+void p2p_scan_res_handled(struct p2p_data *p2p, unsigned int delay)
 {
 	if (!p2p->p2p_scan_running) {
 		p2p_dbg(p2p, "p2p_scan was not running, but scan results received");
 	}
 	p2p->p2p_scan_running = 0;
+
+	/* Use this delay only when p2p_find doesn't set it */
+	if (!p2p->search_delay)
+		p2p->search_delay = delay;
+
 	eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL);
 
 	if (p2p_run_after_scan(p2p))
@@ -4118,6 +4137,10 @@
 
 	p2p_dbg(p2p, "Go to Listen state while waiting for the peer to become ready for GO Negotiation");
 	p2p->cfg->stop_listen(p2p->cfg->cb_ctx);
+	if (p2p->pending_listen_freq) {
+		p2p_dbg(p2p, "Clear pending_listen_freq for %s", __func__);
+		p2p->pending_listen_freq = 0;
+	}
 	p2p_set_state(p2p, P2P_WAIT_PEER_CONNECT);
 	p2p_listen_in_find(p2p, 0);
 }
@@ -5720,6 +5743,73 @@
 
 	return buf;
 }
+
+
+bool p2p_is_peer_6ghz_capab(struct p2p_data *p2p, const u8 *addr)
+{
+	struct p2p_device *dev;
+
+	dev = p2p_get_device(p2p, addr);
+	if (!dev)
+		return false;
+
+	return !!(dev->info.dev_capab & P2P_DEV_CAPAB_6GHZ_BAND_CAPABLE);
+}
+
+
+void p2p_set_6ghz_dev_capab(struct p2p_data *p2p, bool allow_6ghz)
+{
+	p2p->p2p_6ghz_capable = allow_6ghz;
+	p2p->allow_6ghz = allow_6ghz;
+	p2p_dbg(p2p, "Set 6 GHz capability to %d", allow_6ghz);
+
+	if (allow_6ghz)
+		p2p->dev_capab |= P2P_DEV_CAPAB_6GHZ_BAND_CAPABLE;
+	else
+		p2p->dev_capab &= ~P2P_DEV_CAPAB_6GHZ_BAND_CAPABLE;
+}
+
+
+bool is_p2p_6ghz_capable(struct p2p_data *p2p)
+{
+	return p2p->p2p_6ghz_capable;
+}
+
+
+bool p2p_wfd_enabled(struct p2p_data *p2p)
+{
+#ifdef CONFIG_WIFI_DISPLAY
+	return p2p->wfd_ie_probe_req != NULL;
+#else /* CONFIG_WIFI_DISPLAY */
+	return false;
+#endif /* CONFIG_WIFI_DISPLAY */
+}
+
+
+bool p2p_peer_wfd_enabled(struct p2p_data *p2p, const u8 *peer_addr)
+{
+#ifdef CONFIG_WIFI_DISPLAY
+	struct p2p_device *dev;
+
+	dev = p2p_get_device(p2p, peer_addr);
+	return dev && dev->info.wfd_subelems != NULL;
+#else /* CONFIG_WIFI_DISPLAY */
+	return false;
+#endif /* CONFIG_WIFI_DISPLAY */
+}
+
+
+bool is_p2p_allow_6ghz(struct p2p_data *p2p)
+{
+	return p2p->allow_6ghz;
+}
+
+
+void set_p2p_allow_6ghz(struct p2p_data *p2p, bool value)
+{
+	p2p->allow_6ghz = value;
+}
+
 #ifdef CONFIG_BRCM_AUTOMOTIVE
 struct p2p_channels * p2p_get_channels(struct p2p_data *p2p)
 {
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p.h b/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p.h
index f059404..babf41e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p.h
@@ -622,6 +622,7 @@
 	 * @req_dev_types: Array containing requested device types
 	 * @dev_id: Device ID to search for or %NULL to find all devices
 	 * @pw_id: Device Password ID
+	 * @include_6ghz: Include 6 GHz channels in P2P scan
 	 * Returns: 0 on success, -1 on failure
 	 *
 	 * This callback function is used to request a P2P scan or search
@@ -646,11 +647,13 @@
 #if defined(CONFIG_BRCM_RSDB)
 	int (*p2p_scan)(void *ctx, enum p2p_scan_type type, int freq[],
 			unsigned int num_req_dev_types,
-			const u8 *req_dev_types, const u8 *dev_id, u16 pw_id);
+			const u8 *req_dev_types, const u8 *dev_id, u16 pw_id,
+			bool include_6ghz);
 #else
 	int (*p2p_scan)(void *ctx, enum p2p_scan_type type, int freq,
 			unsigned int num_req_dev_types,
-			const u8 *req_dev_types, const u8 *dev_id, u16 pw_id);
+			const u8 *req_dev_types, const u8 *dev_id, u16 pw_id,
+			bool include_6ghz);
 #endif /* CONFIG_DRIVER_NL80211_IFX && CONFIG_BRCM_RSDB */
 
 	/**
@@ -1266,13 +1269,15 @@
  *	P2P_FIND_START_WITH_FULL behavior. 0 = Use normal full scan.
  *	If p2p_find is already in progress, this parameter is ignored and full
  *	scan will be executed.
+ * @include_6ghz: Include 6 GHz channels in P2P find
  * Returns: 0 on success, -1 on failure
  */
 int p2p_find(struct p2p_data *p2p, unsigned int timeout,
 	     enum p2p_discovery_type type,
 	     unsigned int num_req_dev_types, const u8 *req_dev_types,
 	     const u8 *dev_id, unsigned int search_delay,
-	     u8 seek_count, const char **seek_string, int freq);
+	     u8 seek_count, const char **seek_string, int freq,
+	     bool include_6ghz);
 
 /**
  * p2p_notify_scan_trigger_status - Indicate scan trigger status
@@ -1627,6 +1632,7 @@
 /**
  * p2p_scan_res_handled - Indicate end of scan results
  * @p2p: P2P module context from p2p_init()
+ * @delay: Search delay for next scan in ms
  *
  * This function is called to indicate that all P2P scan results from a scan
  * have been reported with zero or more calls to p2p_scan_res_handler(). This
@@ -1634,7 +1640,7 @@
  * struct p2p_config::p2p_scan() call if none of the p2p_scan_res_handler()
  * calls stopped iteration.
  */
-void p2p_scan_res_handled(struct p2p_data *p2p);
+void p2p_scan_res_handled(struct p2p_data *p2p, unsigned int delay);
 
 enum p2p_send_action_result {
 	P2P_SEND_ACTION_SUCCESS /* Frame was send and acknowledged */,
@@ -2423,4 +2429,13 @@
 struct wpabuf * p2p_build_probe_resp_template(struct p2p_data *p2p,
 					      unsigned int freq);
 
+void p2p_set_6ghz_dev_capab(struct p2p_data *p2p, bool allow_6ghz);
+bool is_p2p_6ghz_capable(struct p2p_data *p2p);
+bool p2p_is_peer_6ghz_capab(struct p2p_data *p2p, const u8 *addr);
+bool p2p_peer_wfd_enabled(struct p2p_data *p2p, const u8 *peer_addr);
+bool p2p_wfd_enabled(struct p2p_data *p2p);
+bool is_p2p_allow_6ghz(struct p2p_data *p2p);
+void set_p2p_allow_6ghz(struct p2p_data *p2p, bool value);
+int p2p_remove_6ghz_channels(unsigned int *pref_freq_list, int size);
+
 #endif /* P2P_H */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p_build.c b/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p_build.c
index dc1e8d0..41b1685 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p_build.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p_build.c
@@ -111,7 +111,7 @@
 
 
 void p2p_buf_add_pref_channel_list(struct wpabuf *buf,
-				   const u32 *preferred_freq_list,
+				   const unsigned int *preferred_freq_list,
 				   unsigned int size)
 {
 	unsigned int i, count = 0;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p_go_neg.c b/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p_go_neg.c
index 1133461..1d53d52 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p_go_neg.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p_go_neg.c
@@ -582,8 +582,8 @@
 					&op_channel) < 0)
 			continue; /* cannot happen due to earlier check */
 		for (j = 0; j < msg->channel_list_len; j++) {
-
-			if (op_channel != msg->channel_list[j])
+			if (!msg->channel_list ||
+			    op_channel != msg->channel_list[j])
 				continue;
 
 			p2p->op_reg_class = op_class;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p_i.h b/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p_i.h
index 628f3a5..74e8d33 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p_i.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p_i.h
@@ -566,6 +566,9 @@
 	/* Override option for preferred operating channel in GO Negotiation */
 	u8 override_pref_op_class;
 	u8 override_pref_channel;
+	bool p2p_6ghz_capable;
+	bool include_6ghz;
+	bool allow_6ghz;
 #ifdef CONFIG_BRCM_AUTOMOTIVE
 	int interworking;
 	int access_network_type;
@@ -732,6 +735,8 @@
 			      u8 *op_channel,
 			      struct wpa_freq_range_list *avoid_list,
 			      struct wpa_freq_range_list *disallow_list);
+void p2p_copy_channels(struct p2p_channels *dst, const struct p2p_channels *src,
+		       bool allow_6ghz);
 
 /* p2p_parse.c */
 void p2p_copy_filter_devname(char *dst, size_t dst_len,
@@ -818,7 +823,8 @@
 int p2p_build_wps_ie(struct p2p_data *p2p, struct wpabuf *buf, int pw_id,
 		     int all_attr);
 void p2p_buf_add_pref_channel_list(struct wpabuf *buf,
-				   const u32 *preferred_freq_list, u32 size);
+				   const unsigned int *preferred_freq_list,
+				   unsigned int size);
 
 /* p2p_sd.c */
 struct p2p_sd_query * p2p_pending_sd_req(struct p2p_data *p2p,
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p_invitation.c b/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p_invitation.c
index 77d662a..ab00722 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p_invitation.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p_invitation.c
@@ -653,8 +653,9 @@
 	struct p2p_device *dev;
 
 	p2p_dbg(p2p, "Request to invite peer " MACSTR " role=%d persistent=%d "
-		"force_freq=%u",
-		MAC2STR(peer), role, persistent_group, force_freq);
+		"force_freq=%u allow_6ghz=%d",
+		MAC2STR(peer), role, persistent_group, force_freq,
+		p2p->allow_6ghz);
 	if (bssid)
 		p2p_dbg(p2p, "Invitation for BSSID " MACSTR, MAC2STR(bssid));
 	if (go_dev_addr) {
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p_pd.c b/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p_pd.c
index cc4021b..dec4844 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p_pd.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p_pd.c
@@ -1432,7 +1432,7 @@
 		 * Save the reported channel list and operating frequency.
 		 * Note that the specification mandates that the responder
 		 * should include in the channel list only channels reported by
-		 * the initiator, so this is only a sanity check, and if this
+		 * the initiator, so this is only a validity check, and if this
 		 * fails the flow would continue, although it would probably
 		 * fail. Same is true for the operating channel.
 		 */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p_utils.c b/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p_utils.c
index 1a62a44..7d21f68 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p_utils.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/p2p/p2p_utils.c
@@ -496,3 +496,42 @@
 
 	return idx;
 }
+
+
+void p2p_copy_channels(struct p2p_channels *dst,
+		       const struct p2p_channels *src, bool allow_6ghz)
+{
+	size_t i, j;
+
+	if (allow_6ghz) {
+		os_memcpy(dst, src, sizeof(struct p2p_channels));
+		return;
+	}
+
+	for (i = 0, j = 0; i < P2P_MAX_REG_CLASSES; i++) {
+		if (is_6ghz_op_class(src->reg_class[i].reg_class))
+			continue;
+		os_memcpy(&dst->reg_class[j], &src->reg_class[i],
+			  sizeof(struct p2p_reg_class));
+		j++;
+	}
+	dst->reg_classes = j;
+}
+
+
+int p2p_remove_6ghz_channels(unsigned int *pref_freq_list, int size)
+{
+	int i;
+
+	for (i = 0; i < size; i++) {
+		if (is_6ghz_freq(pref_freq_list[i])) {
+			wpa_printf(MSG_DEBUG, "P2P: Remove 6 GHz channel %d",
+				   pref_freq_list[i]);
+			size--;
+			os_memmove(&pref_freq_list[i], &pref_freq_list[i + 1],
+				   (size - i) * sizeof(pref_freq_list[0]));
+			i--;
+		}
+	}
+	return i;
+}
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/pae/ieee802_1x_kay.c b/src/lynq/packages/thirdpart/lynq-wg870/src/pae/ieee802_1x_kay.c
index a638b8a..cdce6ed 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/pae/ieee802_1x_kay.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/pae/ieee802_1x_kay.c
@@ -3049,12 +3049,12 @@
 
 
 /**
- * ieee802_1x_kay_mkpdu_sanity_check -
- * Sanity checks specified in IEEE Std 802.1X-2010, 11.11.2 (Validation of
+ * ieee802_1x_kay_mkpdu_validity_check -
+ * Validity checks specified in IEEE Std 802.1X-2010, 11.11.2 (Validation of
  * MKPDUs)
  */
-static int ieee802_1x_kay_mkpdu_sanity_check(struct ieee802_1x_kay *kay,
-					     const u8 *buf, size_t len)
+static int ieee802_1x_kay_mkpdu_validity_check(struct ieee802_1x_kay *kay,
+					       const u8 *buf, size_t len)
 {
 	struct ieee8023_hdr *eth_hdr;
 	struct ieee802_1x_hdr *eapol_hdr;
@@ -3207,7 +3207,7 @@
 
 	wpa_printf(MSG_DEBUG, "KaY: Decode received MKPDU (ifname=%s)",
 		   kay->if_name);
-	if (ieee802_1x_kay_mkpdu_sanity_check(kay, buf, len))
+	if (ieee802_1x_kay_mkpdu_validity_check(kay, buf, len))
 		return -1;
 
 	/* handle basic parameter set */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/radius/radius.h b/src/lynq/packages/thirdpart/lynq-wg870/src/radius/radius.h
index 630c0f9..fb81481 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/radius/radius.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/radius/radius.h
@@ -225,6 +225,9 @@
 /* Default size to be allocated for attribute array */
 #define RADIUS_DEFAULT_ATTR_COUNT 16
 
+/* Maximum message length for incoming RADIUS messages, as stated in RFC 2865
+ * Section 3 ("Packet Format").*/
+#define RADIUS_MAX_MSG_LEN 4096
 
 /* MAC address ASCII format for IEEE 802.1X use
  * (draft-congdon-radius-8021x-20.txt) */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/radius/radius_client.c b/src/lynq/packages/thirdpart/lynq-wg870/src/radius/radius_client.c
index 2b7a604..ee9e46d 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/radius/radius_client.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/radius/radius_client.c
@@ -7,6 +7,7 @@
  */
 
 #include "includes.h"
+#include <net/if.h>
 
 #include "common.h"
 #include "radius.h"
@@ -814,9 +815,11 @@
 {
 	struct radius_client_data *radius = eloop_ctx;
 	struct hostapd_radius_servers *conf = radius->conf;
-	RadiusType msg_type = (RadiusType) sock_ctx;
+	RadiusType msg_type = (uintptr_t) sock_ctx;
 	int len, roundtrip;
-	unsigned char buf[3000];
+	unsigned char buf[RADIUS_MAX_MSG_LEN];
+	struct msghdr msghdr = {0};
+	struct iovec iov;
 	struct radius_msg *msg;
 	struct radius_hdr *hdr;
 	struct radius_rx_handler *handlers;
@@ -836,15 +839,22 @@
 		rconf = conf->auth_server;
 	}
 
-	len = recv(sock, buf, sizeof(buf), MSG_DONTWAIT);
+	iov.iov_base = buf;
+	iov.iov_len = RADIUS_MAX_MSG_LEN;
+	msghdr.msg_iov = &iov;
+	msghdr.msg_iovlen = 1;
+	msghdr.msg_flags = 0;
+	len = recvmsg(sock, &msghdr, MSG_DONTWAIT);
 	if (len < 0) {
-		wpa_printf(MSG_INFO, "recv[RADIUS]: %s", strerror(errno));
+		wpa_printf(MSG_INFO, "recvmsg[RADIUS]: %s", strerror(errno));
 		return;
 	}
+
 	hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS,
 		       HOSTAPD_LEVEL_DEBUG, "Received %d bytes from RADIUS "
 		       "server", len);
-	if (len == sizeof(buf)) {
+
+	if (msghdr.msg_flags & MSG_TRUNC) {
 		wpa_printf(MSG_INFO, "RADIUS: Possibly too long UDP frame for our buffer - dropping it");
 		return;
 	}
@@ -1159,6 +1169,29 @@
 		return -1;
 	}
 
+	/* Force a reconnect by disconnecting the socket first */
+	if (connect(sel_sock, (struct sockaddr *) &disconnect_addr,
+		    sizeof(disconnect_addr)) < 0)
+		wpa_printf(MSG_INFO, "disconnect[radius]: %s", strerror(errno));
+
+#ifdef __linux__
+	if (conf->force_client_dev && conf->force_client_dev[0]) {
+		if (setsockopt(sel_sock, SOL_SOCKET, SO_BINDTODEVICE,
+			       conf->force_client_dev,
+			       os_strlen(conf->force_client_dev)) < 0) {
+			wpa_printf(MSG_ERROR,
+				   "RADIUS: setsockopt[SO_BINDTODEVICE]: %s",
+				   strerror(errno));
+			/* Probably not a critical error; continue on and hope
+			 * for the best. */
+		} else {
+			wpa_printf(MSG_DEBUG,
+				   "RADIUS: Bound client socket to device: %s",
+				   conf->force_client_dev);
+		}
+	}
+#endif /* __linux__ */
+
 	if (conf->force_client_addr) {
 		switch (conf->client_addr.af) {
 		case AF_INET:
@@ -1191,11 +1224,6 @@
 		}
 	}
 
-	/* Force a reconnect by disconnecting the socket first */
-	if (connect(sel_sock, (struct sockaddr *) &disconnect_addr,
-		    sizeof(disconnect_addr)) < 0)
-		wpa_printf(MSG_INFO, "disconnect[radius]: %s", strerror(errno));
-
 	if (connect(sel_sock, addr, addrlen) < 0) {
 		wpa_printf(MSG_INFO, "connect[radius]: %s", strerror(errno));
 		return -1;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/radius/radius_client.h b/src/lynq/packages/thirdpart/lynq-wg870/src/radius/radius_client.h
index 8ca0874..687cd81 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/radius/radius_client.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/radius/radius_client.h
@@ -174,6 +174,11 @@
 	 * force_client_addr - Whether to force client (local) address
 	 */
 	int force_client_addr;
+
+	/**
+	 * force_client_dev - Bind the socket to a specified interface, if set
+	 */
+	char *force_client_dev;
 };
 
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/radius/radius_server.c b/src/lynq/packages/thirdpart/lynq-wg870/src/radius/radius_server.c
index 971fe91..e02c215 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/radius/radius_server.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/radius/radius_server.c
@@ -35,11 +35,6 @@
  */
 #define RADIUS_MAX_SESSION 1000
 
-/**
- * RADIUS_MAX_MSG_LEN - Maximum message length for incoming RADIUS messages
- */
-#define RADIUS_MAX_MSG_LEN 3000
-
 static const struct eapol_callbacks radius_server_eapol_cb;
 
 struct radius_client;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/pmksa_cache.c b/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/pmksa_cache.c
index a3ed538..b4ef736 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/pmksa_cache.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/pmksa_cache.c
@@ -31,6 +31,8 @@
 
 	void (*free_cb)(struct rsn_pmksa_cache_entry *entry, void *ctx,
 			enum pmksa_free_reason reason);
+	bool (*is_current_cb)(struct rsn_pmksa_cache_entry *entry,
+			      void *ctx);
 	void *ctx;
 };
 
@@ -62,14 +64,35 @@
 {
 	struct rsn_pmksa_cache *pmksa = eloop_ctx;
 	struct os_reltime now;
+	struct rsn_pmksa_cache_entry *prev = NULL, *tmp;
+	struct rsn_pmksa_cache_entry *entry = pmksa->pmksa;
 
 	os_get_reltime(&now);
-	while (pmksa->pmksa && pmksa->pmksa->expiration <= now.sec) {
-		struct rsn_pmksa_cache_entry *entry = pmksa->pmksa;
-		pmksa->pmksa = entry->next;
+	while (entry && entry->expiration <= now.sec) {
+		if (wpa_key_mgmt_sae(entry->akmp) &&
+		    pmksa->is_current_cb(entry, pmksa->ctx)) {
+			/* Do not expire the currently used PMKSA entry for SAE
+			 * since there is no convenient mechanism for
+			 * reauthenticating during an association with SAE. The
+			 * expired entry will be removed after this association
+			 * has been lost. */
+			wpa_printf(MSG_DEBUG,
+				   "RSN: postpone PMKSA cache entry expiration for SAE with "
+				   MACSTR, MAC2STR(entry->aa));
+			prev = entry;
+			entry = entry->next;
+			continue;
+		}
+
 		wpa_printf(MSG_DEBUG, "RSN: expired PMKSA cache entry for "
 			   MACSTR, MAC2STR(entry->aa));
-		pmksa_cache_free_entry(pmksa, entry, PMKSA_EXPIRE);
+		if (prev)
+			prev->next = entry->next;
+		else
+			pmksa->pmksa = entry->next;
+		tmp = entry;
+		entry = entry->next;
+		pmksa_cache_free_entry(pmksa, tmp, PMKSA_EXPIRE);
 	}
 
 	pmksa_cache_set_expiration(pmksa);
@@ -96,13 +119,32 @@
 		return;
 	os_get_reltime(&now);
 	sec = pmksa->pmksa->expiration - now.sec;
-	if (sec < 0)
+	if (sec < 0) {
 		sec = 0;
+		if (wpa_key_mgmt_sae(pmksa->pmksa->akmp) &&
+		    pmksa->is_current_cb(pmksa->pmksa, pmksa->ctx)) {
+			/* Do not continue polling for the current PMKSA entry
+			 * from SAE to expire every second. Use the expiration
+			 * time to the following entry, if any, and wait at
+			 * maximum 10 minutes to check again.
+			 */
+			entry = pmksa->pmksa->next;
+			if (entry) {
+				sec = entry->expiration - now.sec;
+				if (sec < 0)
+					sec = 0;
+				else if (sec > 600)
+					sec = 600;
+			} else {
+				sec = 600;
+			}
+		}
+	}
 	eloop_register_timeout(sec + 1, 0, pmksa_cache_expire, pmksa, NULL);
 
 	entry = pmksa->sm->cur_pmksa ? pmksa->sm->cur_pmksa :
 		pmksa_cache_get(pmksa, pmksa->sm->bssid, NULL, NULL, 0);
-	if (entry) {
+	if (entry && !wpa_key_mgmt_sae(entry->akmp)) {
 		sec = pmksa->pmksa->reauth_time - now.sec;
 		if (sec < 0)
 			sec = 0;
@@ -217,7 +259,8 @@
 				   "that was based on the old PMK");
 			if (!pos->opportunistic)
 				pmksa_cache_flush(pmksa, entry->network_ctx,
-						  pos->pmk, pos->pmk_len);
+						  pos->pmk, pos->pmk_len,
+						  false);
 			pmksa_cache_free_entry(pmksa, pos, PMKSA_REPLACE);
 			break;
 		}
@@ -291,9 +334,11 @@
  * @network_ctx: Network configuration context or %NULL to flush all entries
  * @pmk: PMK to match for or %NULL to match all PMKs
  * @pmk_len: PMK length
+ * @external_only: Flush only PMKSA cache entries configured by external
+ * applications
  */
 void pmksa_cache_flush(struct rsn_pmksa_cache *pmksa, void *network_ctx,
-		       const u8 *pmk, size_t pmk_len)
+		       const u8 *pmk, size_t pmk_len, bool external_only)
 {
 	struct rsn_pmksa_cache_entry *entry, *prev = NULL, *tmp;
 	int removed = 0;
@@ -304,7 +349,8 @@
 		     network_ctx == NULL) &&
 		    (pmk == NULL ||
 		     (pmk_len == entry->pmk_len &&
-		      os_memcmp(pmk, entry->pmk, pmk_len) == 0))) {
+		      os_memcmp(pmk, entry->pmk, pmk_len) == 0)) &&
+		    (!external_only || entry->external)) {
 			wpa_printf(MSG_DEBUG, "RSN: Flush PMKSA cache entry "
 				   "for " MACSTR, MAC2STR(entry->aa));
 			if (prev)
@@ -383,9 +429,11 @@
 {
 	struct rsn_pmksa_cache_entry *new_entry;
 	os_time_t old_expiration = old_entry->expiration;
+	os_time_t old_reauth_time = old_entry->reauth_time;
 	const u8 *pmkid = NULL;
 
-	if (wpa_key_mgmt_sae(old_entry->akmp))
+	if (wpa_key_mgmt_sae(old_entry->akmp) ||
+	    wpa_key_mgmt_fils(old_entry->akmp))
 		pmkid = old_entry->pmkid;
 	new_entry = pmksa_cache_add(pmksa, old_entry->pmk, old_entry->pmk_len,
 				    pmkid, NULL, 0,
@@ -398,6 +446,7 @@
 
 	/* TODO: reorder entries based on expiration time? */
 	new_entry->expiration = old_expiration;
+	new_entry->reauth_time = old_reauth_time;
 	new_entry->opportunistic = 1;
 
 	return new_entry;
@@ -678,6 +727,8 @@
 struct rsn_pmksa_cache *
 pmksa_cache_init(void (*free_cb)(struct rsn_pmksa_cache_entry *entry,
 				 void *ctx, enum pmksa_free_reason reason),
+		 bool (*is_current_cb)(struct rsn_pmksa_cache_entry *entry,
+				       void *ctx),
 		 void *ctx, struct wpa_sm *sm)
 {
 	struct rsn_pmksa_cache *pmksa;
@@ -685,6 +736,7 @@
 	pmksa = os_zalloc(sizeof(*pmksa));
 	if (pmksa) {
 		pmksa->free_cb = free_cb;
+		pmksa->is_current_cb = is_current_cb;
 		pmksa->ctx = ctx;
 		pmksa->sm = sm;
 	}
@@ -692,4 +744,37 @@
 	return pmksa;
 }
 
+
+void pmksa_cache_reconfig(struct rsn_pmksa_cache *pmksa)
+{
+	struct rsn_pmksa_cache_entry *entry;
+	struct os_reltime now;
+
+	if (!pmksa || !pmksa->pmksa)
+		return;
+
+	os_get_reltime(&now);
+	for (entry = pmksa->pmksa; entry; entry = entry->next) {
+		u32 life_time;
+		u8 reauth_threshold;
+
+		if (entry->expiration - now.sec < 1 ||
+		    entry->reauth_time - now.sec < 1)
+			continue;
+
+		life_time = entry->expiration - now.sec;
+		reauth_threshold = (entry->reauth_time - now.sec) * 100 /
+			life_time;
+		if (!reauth_threshold)
+			continue;
+
+		wpa_sm_add_pmkid(pmksa->sm, entry->network_ctx, entry->aa,
+				 entry->pmkid,
+				 entry->fils_cache_id_set ?
+				 entry->fils_cache_id : NULL,
+				 entry->pmk, entry->pmk_len, life_time,
+				 reauth_threshold, entry->akmp);
+	}
+}
+
 #endif /* IEEE8021X_EAPOL */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/pmksa_cache.h b/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/pmksa_cache.h
index 83faa05..b801268 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/pmksa_cache.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/pmksa_cache.h
@@ -43,6 +43,7 @@
 	 */
 	void *network_ctx;
 	int opportunistic;
+	bool external;
 };
 
 struct rsn_pmksa_cache;
@@ -58,6 +59,8 @@
 struct rsn_pmksa_cache *
 pmksa_cache_init(void (*free_cb)(struct rsn_pmksa_cache_entry *entry,
 				 void *ctx, enum pmksa_free_reason reason),
+		 bool (*is_current_cb)(struct rsn_pmksa_cache_entry *entry,
+				       void *ctx),
 		 void *ctx, struct wpa_sm *sm);
 void pmksa_cache_deinit(struct rsn_pmksa_cache *pmksa);
 struct rsn_pmksa_cache_entry * pmksa_cache_get(struct rsn_pmksa_cache *pmksa,
@@ -84,13 +87,16 @@
 pmksa_cache_get_opportunistic(struct rsn_pmksa_cache *pmksa,
 			      void *network_ctx, const u8 *aa, int akmp);
 void pmksa_cache_flush(struct rsn_pmksa_cache *pmksa, void *network_ctx,
-		       const u8 *pmk, size_t pmk_len);
+		       const u8 *pmk, size_t pmk_len, bool external_only);
+void pmksa_cache_reconfig(struct rsn_pmksa_cache *pmksa);
 
 #else /* IEEE8021X_EAPOL */
 
 static inline struct rsn_pmksa_cache *
 pmksa_cache_init(void (*free_cb)(struct rsn_pmksa_cache_entry *entry,
 				 void *ctx, enum pmksa_free_reason reason),
+		 bool (*is_current_cb)(struct rsn_pmksa_cache_entry *entry,
+				       void *ctx),
 		 void *ctx, struct wpa_sm *sm)
 {
 	return (void *) -1;
@@ -157,7 +163,12 @@
 
 static inline void pmksa_cache_flush(struct rsn_pmksa_cache *pmksa,
 				     void *network_ctx,
-				     const u8 *pmk, size_t pmk_len)
+				     const u8 *pmk, size_t pmk_len,
+				     bool external_only)
+{
+}
+
+static inline void pmksa_cache_reconfig(struct rsn_pmksa_cache *pmksa)
 {
 }
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/tdls.c b/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/tdls.c
index 5bdeae6..02483d0 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/tdls.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/tdls.c
@@ -136,6 +136,9 @@
 
 	struct ieee80211_ht_capabilities *ht_capabilities;
 	struct ieee80211_vht_capabilities *vht_capabilities;
+	struct ieee80211_he_capabilities *he_capabilities;
+	size_t he_capab_len;
+	struct ieee80211_he_6ghz_band_cap *he_6ghz_band_capabilities;
 
 	u8 qos_info;
 
@@ -703,6 +706,10 @@
 	peer->ht_capabilities = NULL;
 	os_free(peer->vht_capabilities);
 	peer->vht_capabilities = NULL;
+	os_free(peer->he_capabilities);
+	peer->he_capabilities = NULL;
+	os_free(peer->he_6ghz_band_capabilities);
+	peer->he_6ghz_band_capabilities = NULL;
 	os_free(peer->ext_capab);
 	peer->ext_capab = NULL;
 	os_free(peer->supp_channels);
@@ -1414,6 +1421,8 @@
 
 skip_ies:
 
+	if (peer->he_capabilities)
+		peer_capab |= TDLS_PEER_HE;
 	if (peer->vht_capabilities)
 		peer_capab |= TDLS_PEER_VHT;
 	if (peer->ht_capabilities)
@@ -1652,6 +1661,56 @@
 }
 
 
+static int copy_peer_he_capab(const struct wpa_eapol_ie_parse *kde,
+			      struct wpa_tdls_peer *peer)
+{
+	if (!kde->he_capabilities) {
+		wpa_printf(MSG_DEBUG, "TDLS: No HE capabilities received");
+		return 0;
+	}
+
+	os_free(peer->he_capabilities);
+	peer->he_capab_len = 0;
+	peer->he_capabilities = os_memdup(kde->he_capabilities,
+					  kde->he_capab_len);
+	if (!peer->he_capabilities)
+		return -1;
+
+	peer->he_capab_len = kde->he_capab_len;
+	wpa_hexdump(MSG_DEBUG, "TDLS: Peer HE capabilities",
+		    peer->he_capabilities, peer->he_capab_len);
+
+	return 0;
+}
+
+
+static int copy_peer_he_6ghz_band_capab(const struct wpa_eapol_ie_parse *kde,
+					struct wpa_tdls_peer *peer)
+{
+	if (!kde->he_6ghz_capabilities) {
+		wpa_printf(MSG_DEBUG,
+			   "TDLS: No HE 6 GHz band capabilities received");
+		return 0;
+	}
+
+	if (!peer->he_6ghz_band_capabilities) {
+		peer->he_6ghz_band_capabilities =
+			os_zalloc(sizeof(struct ieee80211_he_6ghz_band_cap));
+		if (peer->he_6ghz_band_capabilities == NULL)
+			return -1;
+	}
+
+	os_memcpy(peer->he_6ghz_band_capabilities, kde->he_6ghz_capabilities,
+		  sizeof(struct ieee80211_he_6ghz_band_cap));
+
+	wpa_hexdump(MSG_DEBUG, "TDLS: Peer 6 GHz band HE capabilities",
+		    peer->he_6ghz_band_capabilities,
+		    sizeof(struct ieee80211_he_6ghz_band_cap));
+
+	return 0;
+}
+
+
 static int copy_peer_ext_capab(const struct wpa_eapol_ie_parse *kde,
 			       struct wpa_tdls_peer *peer)
 {
@@ -1761,6 +1820,9 @@
 				       peer->supp_rates, peer->supp_rates_len,
 				       peer->ht_capabilities,
 				       peer->vht_capabilities,
+				       peer->he_capabilities,
+				       peer->he_capab_len,
+				       peer->he_6ghz_band_capabilities,
 				       peer->qos_info, peer->wmm_capable,
 				       peer->ext_capab, peer->ext_capab_len,
 				       peer->supp_channels,
@@ -1890,7 +1952,9 @@
 	if (copy_peer_ht_capab(&kde, peer) < 0)
 		goto error;
 
-	if (copy_peer_vht_capab(&kde, peer) < 0)
+	if (copy_peer_vht_capab(&kde, peer) < 0 ||
+	    copy_peer_he_capab(&kde, peer) < 0 ||
+	    copy_peer_he_6ghz_band_capab(&kde, peer) < 0)
 		goto error;
 
 	if (copy_peer_ext_capab(&kde, peer) < 0)
@@ -1919,7 +1983,8 @@
 			   "TDLS setup - send own request");
 		peer->initiator = 1;
 		wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL,
-					NULL, 0, 0, NULL, 0, NULL, 0, NULL, 0);
+					NULL, NULL, 0, NULL, 0, 0, NULL, 0,
+					NULL, 0, NULL, 0);
 		if (wpa_tdls_send_tpk_m1(sm, peer) == -2) {
 			peer = NULL;
 			goto error;
@@ -2260,7 +2325,9 @@
 	if (copy_peer_ht_capab(&kde, peer) < 0)
 		goto error;
 
-	if (copy_peer_vht_capab(&kde, peer) < 0)
+	if (copy_peer_vht_capab(&kde, peer) < 0 ||
+	    copy_peer_he_capab(&kde, peer) < 0 ||
+	    copy_peer_he_6ghz_band_capab(&kde, peer) < 0)
 		goto error;
 
 	if (copy_peer_ext_capab(&kde, peer) < 0)
@@ -2647,7 +2714,8 @@
 
 	/* add the peer to the driver as a "setup in progress" peer */
 	if (wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL,
-				    NULL, 0, 0, NULL, 0, NULL, 0, NULL, 0)) {
+				    NULL, NULL, 0, NULL, 0, 0, NULL, 0, NULL, 0,
+				    NULL, 0)) {
 		wpa_tdls_disable_peer_link(sm, peer);
 		return -1;
 	}
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/wpa.c b/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/wpa.c
index db0d680..eee5149 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/wpa.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/wpa.c
@@ -488,6 +488,10 @@
 		buf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_START,
 					 NULL, 0, &buflen, NULL);
 		if (buf) {
+			/* Set and reset eapFail to allow EAP state machine to
+			 * proceed with new authentication. */
+			eapol_sm_notify_eap_fail(sm->eapol, true);
+			eapol_sm_notify_eap_fail(sm->eapol, false);
 			wpa_sm_ether_send(sm, sm->bssid, ETH_P_EAPOL,
 					  buf, buflen);
 			os_free(buf);
@@ -616,7 +620,7 @@
 			  const struct wpa_eapol_key *key, struct wpa_ptk *ptk)
 {
 	const u8 *z = NULL;
-	size_t z_len = 0;
+	size_t z_len = 0, kdk_len;
 	int akmp;
 
 #ifdef CONFIG_IEEE80211R
@@ -640,10 +644,20 @@
 		akmp |= WPA_KEY_MGMT_PSK_SHA256;
 	}
 #endif /* CONFIG_OWE */
+
+	if (sm->force_kdk_derivation ||
+	    (sm->secure_ltf &&
+	     ieee802_11_rsnx_capab(sm->ap_rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
+		kdk_len = WPA_KDK_MAX_LEN;
+	else
+		kdk_len = 0;
+
+
 	return wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion",
 			      sm->own_addr, sm->bssid, sm->snonce,
 			      key->key_nonce, ptk, akmp,
-			      sm->pairwise_cipher, z, z_len);
+			      sm->pairwise_cipher, z, z_len,
+			      kdk_len);
 }
 
 
@@ -985,6 +999,9 @@
 		return -1;
 	}
 
+	wpa_sm_store_ptk(sm, sm->bssid, sm->pairwise_cipher,
+			 sm->dot11RSNAConfigPMKLifetime, &sm->ptk);
+
 	/* TK is not needed anymore in supplicant */
 	os_memset(sm->ptk.tk, 0, WPA_TK_MAX_LEN);
 	sm->ptk.tk_len = 0;
@@ -1325,7 +1342,8 @@
 {
 	size_t len;
 
-	if (!wpa_cipher_valid_mgmt_group(sm->mgmt_group_cipher))
+	if (!wpa_cipher_valid_mgmt_group(sm->mgmt_group_cipher) ||
+	    sm->mgmt_group_cipher == WPA_CIPHER_GTK_NOT_USED)
 		return 0;
 
 	if (ie->igtk) {
@@ -1578,11 +1596,12 @@
 		return -1;
 	}
 
-	if ((sm->ap_rsnxe && !ie->rsnxe) ||
-	    (!sm->ap_rsnxe && ie->rsnxe) ||
-	    (sm->ap_rsnxe && ie->rsnxe &&
-	     (sm->ap_rsnxe_len != ie->rsnxe_len ||
-	      os_memcmp(sm->ap_rsnxe, ie->rsnxe, sm->ap_rsnxe_len) != 0))) {
+	if (sm->proto == WPA_PROTO_RSN &&
+	    ((sm->ap_rsnxe && !ie->rsnxe) ||
+	     (!sm->ap_rsnxe && ie->rsnxe) ||
+	     (sm->ap_rsnxe && ie->rsnxe &&
+	      (sm->ap_rsnxe_len != ie->rsnxe_len ||
+	       os_memcmp(sm->ap_rsnxe, ie->rsnxe, sm->ap_rsnxe_len) != 0)))) {
 		wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
 			"WPA: RSNXE mismatch between Beacon/ProbeResp and EAPOL-Key msg 3/4");
 		wpa_hexdump(MSG_INFO, "RSNXE in Beacon/ProbeResp",
@@ -1685,6 +1704,7 @@
 	}
 
 	if (ie.igtk &&
+	    sm->mgmt_group_cipher != WPA_CIPHER_GTK_NOT_USED &&
 	    wpa_cipher_valid_mgmt_group(sm->mgmt_group_cipher) &&
 	    ie.igtk_len != WPA_IGTK_KDE_PREFIX_LEN +
 	    (unsigned int) wpa_cipher_key_len(sm->mgmt_group_cipher)) {
@@ -2351,6 +2371,16 @@
 }
 
 
+void wpa_sm_aborted_external_cached(struct wpa_sm *sm)
+{
+	if (sm && sm->cur_pmksa && sm->cur_pmksa->external) {
+		wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
+			"RSN: Cancelling external PMKSA caching attempt");
+		sm->cur_pmksa = NULL;
+	}
+}
+
+
 static void wpa_eapol_key_dump(struct wpa_sm *sm,
 			       const struct wpa_eapol_key *key,
 			       unsigned int key_data_len,
@@ -2920,7 +2950,9 @@
 		sm->pmk_len = 0;
 		os_memset(sm->pmk, 0, sizeof(sm->pmk));
 #ifndef BRCM_OKC
-		/* Refer commit ed56a660: Suppress deauth for PMKSA caching disabled */
+		/* Refer commit 09f46ec2: wpa_supplicant: suppress deauth
+		 * for PMKSA caching disabled
+		 */
 		if (!sm->suppress_deauth_no_pmksa) {
 			wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
 		}
@@ -2929,6 +2961,15 @@
 }
 
 
+static bool wpa_sm_pmksa_is_current_cb(struct rsn_pmksa_cache_entry *entry,
+				       void *ctx)
+{
+	struct wpa_sm *sm = ctx;
+
+	return sm->cur_pmksa == entry;
+}
+
+
 /**
  * wpa_sm_init - Initialize WPA state machine
  * @ctx: Context pointer for callbacks; this needs to be an allocated buffer
@@ -2952,7 +2993,8 @@
 	sm->dot11RSNAConfigPMKReauthThreshold = 70;
 	sm->dot11RSNAConfigSATimeout = 60;
 
-	sm->pmksa = pmksa_cache_init(wpa_sm_pmksa_free_cb, sm, sm);
+	sm->pmksa = pmksa_cache_init(wpa_sm_pmksa_free_cb,
+				     wpa_sm_pmksa_is_current_cb, sm, sm);
 	if (sm->pmksa == NULL) {
 		wpa_msg(sm->ctx->msg_ctx, MSG_ERROR,
 			"RSN: PMKSA cache initialization failed");
@@ -3148,9 +3190,11 @@
 #endif /* CONFIG_IEEE80211R */
 
 	if (bssid) {
-		pmksa_cache_add(sm->pmksa, pmk, pmk_len, pmkid, NULL, 0,
-				bssid, sm->own_addr,
-				sm->network_ctx, sm->key_mgmt, NULL);
+		sm->cur_pmksa = pmksa_cache_add(sm->pmksa, pmk, pmk_len,
+						pmkid, NULL, 0, bssid,
+						sm->own_addr,
+						sm->network_ctx, sm->key_mgmt,
+						NULL);
 	}
 }
 
@@ -3237,6 +3281,7 @@
 		sm->p2p = config->p2p;
 		sm->wpa_rsc_relaxation = config->wpa_rsc_relaxation;
 		sm->owe_ptk_workaround = config->owe_ptk_workaround;
+		sm->force_kdk_derivation = config->force_kdk_derivation;
 #ifdef CONFIG_FILS
 		if (config->fils_cache_id) {
 			sm->fils_cache_id_set = 1;
@@ -3247,7 +3292,9 @@
 		}
 #endif /* CONFIG_FILS */
 		sm->beacon_prot = config->beacon_prot;
-		/* Refer commit ed56a660: Suppress deauth for PMKSA caching disabled */
+		/* Refer commit 09f46ec2: wpa_supplicant: suppress deauth
+		 * for PMKSA caching disabled
+		 */
 		sm->suppress_deauth_no_pmksa = config->suppress_deauth_no_pmksa;
 	} else {
 		sm->network_ctx = NULL;
@@ -3261,6 +3308,7 @@
 		sm->wpa_rsc_relaxation = 0;
 		sm->owe_ptk_workaround = 0;
 		sm->beacon_prot = 0;
+		sm->force_kdk_derivation = false;
 	}
 }
 
@@ -3708,6 +3756,27 @@
 	return 0;
 }
 
+#if defined(WAPI_ANDROID)
+int wpa_sm_set_ap_wapi_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
+{
+        if (sm == NULL)
+                return -1;
+        os_free(sm->ap_wapi_ie);
+        if (ie == NULL || len == 0) {
+                wpa_printf(MSG_DEBUG, " * WPA: clearing AP WAPI IE");
+                sm->ap_wapi_ie = NULL;
+                sm->ap_wapi_ie_len = 0;
+        } else {
+                wpa_hexdump(MSG_DEBUG, " * WPA: set AP WAPI IE", ie, len);
+                sm->ap_wapi_ie = os_malloc(len);
+                if (sm->ap_wapi_ie == NULL)
+                        return -1;
+                os_memcpy(sm->ap_wapi_ie, ie, len);
+                sm->ap_wapi_ie_len = len;
+        }
+        return 0;
+}
+#endif 
 
 /**
  * wpa_sm_set_ap_rsn_ie - Set AP RSN IE from Beacon/ProbeResp
@@ -3838,6 +3907,16 @@
 }
 
 
+struct rsn_pmksa_cache_entry * wpa_sm_pmksa_cache_get(struct wpa_sm *sm,
+						      const u8 *aa,
+						      const u8 *pmkid,
+						      const void *network_ctx,
+						      int akmp)
+{
+	return pmksa_cache_get(sm->pmksa, aa, pmkid, network_ctx, akmp);
+}
+
+
 void wpa_sm_drop_sa(struct wpa_sm *sm)
 {
 	wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Clear old PMK and PTK");
@@ -3858,6 +3937,11 @@
 	sm->pmk_r0_len = 0;
 	os_memset(sm->pmk_r1, 0, sizeof(sm->pmk_r1));
 	sm->pmk_r1_len = 0;
+#ifdef CONFIG_PASN
+	os_free(sm->pasn_r1kh);
+	sm->pasn_r1kh = NULL;
+	sm->n_pasn_r1kh = 0;
+#endif /* CONFIG_PASN */
 #endif /* CONFIG_IEEE80211R */
 }
 
@@ -3886,7 +3970,13 @@
 
 void wpa_sm_pmksa_cache_flush(struct wpa_sm *sm, void *network_ctx)
 {
-	pmksa_cache_flush(sm->pmksa, network_ctx, NULL, 0);
+	pmksa_cache_flush(sm->pmksa, network_ctx, NULL, 0, false);
+}
+
+
+void wpa_sm_external_pmksa_cache_flush(struct wpa_sm *sm, void *network_ctx)
+{
+	pmksa_cache_flush(sm->pmksa, network_ctx, NULL, 0, true);
 }
 
 #ifdef BRCM_VE
@@ -4205,7 +4295,7 @@
 	const u8 *g_sta = NULL;
 	size_t g_sta_len = 0;
 	const u8 *g_ap = NULL;
-	size_t g_ap_len = 0;
+	size_t g_ap_len = 0, kdk_len;
 	struct wpabuf *pub = NULL;
 
 	os_memcpy(sm->bssid, bssid, ETH_ALEN);
@@ -4433,13 +4523,21 @@
 		goto fail;
 	}
 
+	if (sm->force_kdk_derivation ||
+	    (sm->secure_ltf &&
+	     ieee802_11_rsnx_capab(sm->ap_rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
+		kdk_len = WPA_KDK_MAX_LEN;
+	else
+		kdk_len = 0;
+
 	if (fils_pmk_to_ptk(sm->pmk, sm->pmk_len, sm->own_addr, sm->bssid,
 			    sm->fils_nonce, sm->fils_anonce,
 			    dh_ss ? wpabuf_head(dh_ss) : NULL,
 			    dh_ss ? wpabuf_len(dh_ss) : 0,
 			    &sm->ptk, ick, &ick_len,
 			    sm->key_mgmt, sm->pairwise_cipher,
-			    sm->fils_ft, &sm->fils_ft_len) < 0) {
+			    sm->fils_ft, &sm->fils_ft_len,
+			    kdk_len) < 0) {
 		wpa_printf(MSG_DEBUG, "FILS: Failed to derive PTK");
 		goto fail;
 	}
@@ -4989,6 +5087,9 @@
 		goto fail;
 	}
 
+	wpa_sm_store_ptk(sm, sm->bssid, sm->pairwise_cipher,
+			 sm->dot11RSNAConfigPMKLifetime, &sm->ptk);
+
 	/* TODO: TK could be cleared after auth frame exchange now that driver
 	 * takes care of association frame encryption/decryption. */
 	/* TK is not needed anymore in supplicant */
@@ -5261,3 +5362,21 @@
 	}
 }
 #endif /* CONFIG_DPP2 */
+
+
+#ifdef CONFIG_PASN
+void wpa_pasn_pmksa_cache_add(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len,
+			      const u8 *pmkid, const u8 *bssid, int key_mgmt)
+{
+	sm->cur_pmksa = pmksa_cache_add(sm->pmksa, pmk, pmk_len, pmkid, NULL, 0,
+					bssid, sm->own_addr, NULL,
+					key_mgmt, 0);
+}
+#endif /* CONFIG_PASN */
+
+
+void wpa_sm_pmksa_cache_reconfig(struct wpa_sm *sm)
+{
+	if (sm)
+		pmksa_cache_reconfig(sm->pmksa);
+}
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/wpa.h b/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/wpa.h
index a2f02a4..5ee0180 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/wpa.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/wpa.h
@@ -69,6 +69,9 @@
 				size_t supp_rates_len,
 				const struct ieee80211_ht_capabilities *ht_capab,
 				const struct ieee80211_vht_capabilities *vht_capab,
+				const struct ieee80211_he_capabilities *he_capab,
+				size_t he_capab_len,
+				const struct ieee80211_he_6ghz_band_cap *he_6ghz_capab,
 				u8 qosinfo, int wmm, const u8 *ext_capab,
 				size_t ext_capab_len, const u8 *supp_channels,
 				size_t supp_channels_len,
@@ -87,6 +90,8 @@
 			    const u8 *pkt, size_t pkt_len);
 	int (*channel_info)(void *ctx, struct wpa_channel_info *ci);
 	void (*transition_disable)(void *ctx, u8 bitmap);
+	void (*store_ptk)(void *ctx, u8 *addr, int cipher,
+			  u32 life_time, const struct wpa_ptk *ptk);
 };
 
 
@@ -130,7 +135,10 @@
 	int owe_ptk_workaround;
 	const u8 *fils_cache_id;
 	int beacon_prot;
-	/* Refer commit ed56a660: Suppress deauth for PMKSA caching disabled */
+	bool force_kdk_derivation;
+	/* Refer commit 09f46ec2: wpa_supplicant: suppress deauth
+	 * for PMKSA caching disabled
+	 */
 	int suppress_deauth_no_pmksa;
 };
 
@@ -159,6 +167,9 @@
 int wpa_sm_set_ap_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len);
 int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, size_t len);
 int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len);
+#if defined(WAPI_ANDROID)
+int wpa_sm_set_ap_wapi_ie(struct wpa_sm *sm, const u8 *ie, size_t len);
+#endif 
 int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen);
 
 int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
@@ -177,6 +188,7 @@
 		     struct wpa_ie_data *data);
 
 void wpa_sm_aborted_cached(struct wpa_sm *sm);
+void wpa_sm_aborted_external_cached(struct wpa_sm *sm);
 int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
 		    const u8 *buf, size_t len);
 int wpa_sm_parse_own_wpa_ie(struct wpa_sm *sm, struct wpa_ie_data *data);
@@ -191,12 +203,18 @@
 int wpa_sm_pmksa_exists(struct wpa_sm *sm, const u8 *bssid,
 			const void *network_ctx);
 void wpa_sm_drop_sa(struct wpa_sm *sm);
+struct rsn_pmksa_cache_entry * wpa_sm_pmksa_cache_get(struct wpa_sm *sm,
+						      const u8 *aa,
+						      const u8 *pmkid,
+						      const void *network_ctx,
+						      int akmp);
 int wpa_sm_has_ptk(struct wpa_sm *sm);
 int wpa_sm_has_ptk_installed(struct wpa_sm *sm);
 
 void wpa_sm_update_replay_ctr(struct wpa_sm *sm, const u8 *replay_ctr);
 
 void wpa_sm_pmksa_cache_flush(struct wpa_sm *sm, void *network_ctx);
+void wpa_sm_external_pmksa_cache_flush(struct wpa_sm *sm, void *network_ctx);
 
 int wpa_sm_get_p2p_ip_addr(struct wpa_sm *sm, u8 *buf);
 
@@ -209,6 +227,8 @@
 			    const u8 *ptk_kck, size_t ptk_kck_len,
 			    const u8 *ptk_kek, size_t ptk_kek_len);
 int wpa_fils_is_completed(struct wpa_sm *sm);
+void wpa_sm_pmksa_cache_reconfig(struct wpa_sm *sm);
+
 #ifdef BRCM_DHCP_HLP
 void fils_process_hlp_container(struct wpa_sm *sm, const u8 *pos, size_t len);
 #endif /* BRCM_DHCP_HLP */
@@ -352,6 +372,10 @@
 {
 }
 
+static inline void wpa_sm_aborted_external_cached(struct wpa_sm *sm)
+{
+}
+
 static inline int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
 				  const u8 *buf, size_t len)
 {
@@ -374,6 +398,13 @@
 {
 }
 
+static inline struct rsn_pmksa_cache_entry *
+wpa_sm_pmksa_cache_get(struct wpa_sm *sm, const u8 *aa, const u8 *pmkid,
+		       const void *network_ctx, int akmp)
+{
+	return NULL;
+}
+
 static inline int wpa_sm_has_ptk(struct wpa_sm *sm)
 {
 	return 0;
@@ -384,6 +415,11 @@
 {
 }
 
+static inline void wpa_sm_external_pmksa_cache_flush(struct wpa_sm *sm,
+						     void *network_ctx)
+{
+}
+
 static inline void wpa_sm_pmksa_cache_flush(struct wpa_sm *sm,
 					    void *network_ctx)
 {
@@ -410,6 +446,10 @@
 	return 0;
 }
 
+static inline void wpa_sm_pmksa_cache_reconfig(struct wpa_sm *sm)
+{
+}
+
 #endif /* CONFIG_NO_WPA */
 
 #ifdef CONFIG_IEEE80211R
@@ -429,6 +469,13 @@
 int wpa_ft_start_over_ds(struct wpa_sm *sm, const u8 *target_ap,
 			 const u8 *mdie);
 
+#ifdef CONFIG_PASN
+
+int wpa_pasn_ft_derive_pmk_r1(struct wpa_sm *sm, int akmp, const u8 *r1kh_id,
+			      u8 *pmk_r1, size_t *pmk_r1_len, u8 *pmk_r1_name);
+
+#endif /* CONFIG_PASN */
+
 #else /* CONFIG_IEEE80211R */
 
 static inline int
@@ -472,6 +519,16 @@
 	return -1;
 }
 
+#ifdef CONFIG_PASN
+
+int wpa_pasn_ft_derive_pmk_r1(struct wpa_sm *sm, int akmp, const u8 *r1kh_id,
+			      u8 *pmk_r1, size_t *pmk_r1_len, u8 *pmk_r1_name)
+{
+	return -1;
+}
+
+#endif /* CONFIG_PASN */
+
 #endif /* CONFIG_IEEE80211R */
 
 
@@ -520,5 +577,7 @@
 void wpa_sm_set_reset_fils_completed(struct wpa_sm *sm, int set);
 void wpa_sm_set_fils_cache_id(struct wpa_sm *sm, const u8 *fils_cache_id);
 void wpa_sm_set_dpp_z(struct wpa_sm *sm, const struct wpabuf *z);
+void wpa_pasn_pmksa_cache_add(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len,
+			      const u8 *pmkid, const u8 *bssid, int key_mgmt);
 
 #endif /* WPA_H */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/wpa_ft.c b/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/wpa_ft.c
index 7058dfc..929769c 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/wpa_ft.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/wpa_ft.c
@@ -24,6 +24,15 @@
 
 #ifdef CONFIG_IEEE80211R
 
+#ifdef CONFIG_PASN
+static void wpa_ft_pasn_store_r1kh(struct wpa_sm *sm, const u8 *bssid);
+#else /* CONFIG_PASN */
+static void wpa_ft_pasn_store_r1kh(struct wpa_sm *sm, const u8 *bssid)
+{
+}
+#endif /* CONFIG_PASN */
+
+
 int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr,
 		      const struct wpa_eapol_key *key, struct wpa_ptk *ptk)
 {
@@ -31,7 +40,7 @@
 	const u8 *anonce = key->key_nonce;
 	int use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt);
 	const u8 *mpmk;
-	size_t mpmk_len;
+	size_t mpmk_len, kdk_len;
 
 	if (sm->xxkey_len > 0) {
 		mpmk = sm->xxkey;
@@ -56,9 +65,20 @@
 			      sm->r1kh_id, sm->own_addr, sm->pmk_r1,
 			      sm->pmk_r1_name) < 0)
 		return -1;
+
+	wpa_ft_pasn_store_r1kh(sm, src_addr);
+
+	if (sm->force_kdk_derivation ||
+	    (sm->secure_ltf &&
+	     ieee802_11_rsnx_capab(sm->ap_rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
+		kdk_len = WPA_KDK_MAX_LEN;
+	else
+		kdk_len = 0;
+
 	return wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->pmk_r1_len, sm->snonce, anonce,
 				 sm->own_addr, sm->bssid, sm->pmk_r1_name, ptk,
-				 ptk_name, sm->key_mgmt, sm->pairwise_cipher);
+				 ptk_name, sm->key_mgmt, sm->pairwise_cipher,
+				 kdk_len);
 }
 
 
@@ -448,6 +468,8 @@
 		return -1;
 	}
 
+	wpa_sm_store_ptk(sm, sm->bssid, sm->pairwise_cipher,
+			 sm->dot11RSNAConfigPMKLifetime, &sm->ptk);
 	return 0;
 }
 
@@ -524,7 +546,7 @@
 	int ret;
 	const u8 *bssid;
 	const u8 *kck;
-	size_t kck_len;
+	size_t kck_len, kdk_len;
 	int use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt);
 	const u8 *anonce, *snonce;
 
@@ -646,10 +668,21 @@
 	sm->pmk_r1_len = sm->pmk_r0_len;
 
 	bssid = target_ap;
+
+	wpa_ft_pasn_store_r1kh(sm, bssid);
+
+	if (sm->force_kdk_derivation ||
+	    (sm->secure_ltf &&
+	     ieee802_11_rsnx_capab(sm->ap_rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
+		kdk_len = WPA_KDK_MAX_LEN;
+	else
+		kdk_len = 0;
+
 	if (wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->pmk_r1_len, sm->snonce,
 			      anonce, sm->own_addr, bssid,
 			      sm->pmk_r1_name, &sm->ptk, ptk_name, sm->key_mgmt,
-			      sm->pairwise_cipher) < 0)
+			      sm->pairwise_cipher,
+			      kdk_len) < 0)
 		return -1;
 
 	if (wpa_key_mgmt_fils(sm->key_mgmt)) {
@@ -1164,7 +1197,7 @@
 					 ci.seg1_idx) != OCI_SUCCESS) {
 			wpa_msg(sm->ctx->msg_ctx, MSG_INFO, OCV_FAILURE
 				"addr=" MACSTR " frame=ft-assoc error=%s",
-				MAC2STR(sm->bssid), ocv_errorstr);
+				MAC2STR(src_addr), ocv_errorstr);
 			return -1;
 		}
 	}
@@ -1232,4 +1265,88 @@
 	return 0;
 }
 
+
+#ifdef CONFIG_PASN
+
+static struct pasn_ft_r1kh * wpa_ft_pasn_get_r1kh(struct wpa_sm *sm,
+						  const u8 *bssid)
+{
+	size_t i;
+
+	for (i = 0; i < sm->n_pasn_r1kh; i++)
+		if (os_memcmp(sm->pasn_r1kh[i].bssid, bssid, ETH_ALEN) == 0)
+			return &sm->pasn_r1kh[i];
+
+	return NULL;
+}
+
+
+static void wpa_ft_pasn_store_r1kh(struct wpa_sm *sm, const u8 *bssid)
+{
+	struct pasn_ft_r1kh *tmp = wpa_ft_pasn_get_r1kh(sm, bssid);
+
+	if (tmp)
+		return;
+
+	tmp = os_realloc_array(sm->pasn_r1kh, sm->n_pasn_r1kh + 1,
+			       sizeof(*tmp));
+	if (!tmp) {
+		wpa_printf(MSG_DEBUG, "PASN: FT: Failed to store R1KH");
+		return;
+	}
+
+	sm->pasn_r1kh = tmp;
+	tmp = &sm->pasn_r1kh[sm->n_pasn_r1kh];
+
+	wpa_printf(MSG_DEBUG, "PASN: FT: Store R1KH for " MACSTR,
+		   MAC2STR(bssid));
+
+	os_memcpy(tmp->bssid, bssid, ETH_ALEN);
+	os_memcpy(tmp->r1kh_id, sm->r1kh_id, FT_R1KH_ID_LEN);
+
+	sm->n_pasn_r1kh++;
+}
+
+
+int wpa_pasn_ft_derive_pmk_r1(struct wpa_sm *sm, int akmp, const u8 *bssid,
+			      u8 *pmk_r1, size_t *pmk_r1_len, u8 *pmk_r1_name)
+{
+	struct pasn_ft_r1kh *r1kh_entry;
+
+	if (sm->key_mgmt != (unsigned int) akmp) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: FT: Key management mismatch: %u != %u",
+			   sm->key_mgmt, akmp);
+		return -1;
+	}
+
+	r1kh_entry = wpa_ft_pasn_get_r1kh(sm, bssid);
+	if (!r1kh_entry) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: FT: Cannot find R1KH-ID for " MACSTR,
+			   MAC2STR(bssid));
+		return -1;
+	}
+
+	/*
+	 * Note: PMK R0 etc. were already derived and are maintained by the
+	 * state machine, and as the same key hierarchy is used, there is no
+	 * need to derive them again, so only derive PMK R1 etc.
+	 */
+	if (wpa_derive_pmk_r1(sm->pmk_r0, sm->pmk_r0_len, sm->pmk_r0_name,
+			      r1kh_entry->r1kh_id, sm->own_addr, pmk_r1,
+			      pmk_r1_name) < 0)
+		return -1;
+
+	*pmk_r1_len = sm->pmk_r0_len;
+
+	wpa_hexdump_key(MSG_DEBUG, "PASN: FT: PMK-R1", pmk_r1, sm->pmk_r0_len);
+	wpa_hexdump(MSG_DEBUG, "PASN: FT: PMKR1Name", pmk_r1_name,
+		    WPA_PMK_NAME_LEN);
+
+	return 0;
+}
+
+#endif /* CONFIG_PASN */
+
 #endif /* CONFIG_IEEE80211R */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/wpa_i.h b/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/wpa_i.h
index c029626..1b1fee8 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/wpa_i.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/wpa_i.h
@@ -14,6 +14,11 @@
 struct wpa_tdls_peer;
 struct wpa_eapol_key;
 
+struct pasn_ft_r1kh {
+	u8 bssid[ETH_ALEN];
+	u8 r1kh_id[FT_R1KH_ID_LEN];
+};
+
 /**
  * struct wpa_sm - Internal WPA state machine data
  */
@@ -73,6 +78,12 @@
 			     * to be used */
 	int keyidx_active; /* Key ID for the active TK */
 
+	/*
+	 * If set Key Derivation Key should be derived as part of PMK to
+	 * PTK derivation regardless of advertised capabilities.
+	 */
+	bool force_kdk_derivation;
+
 	u8 own_addr[ETH_ALEN];
 	const char *ifname;
 	const char *bridge_ifname;
@@ -95,7 +106,11 @@
 	int mfp; /* 0 = disabled, 1 = optional, 2 = mandatory */
 	int ocv; /* Operating Channel Validation */
 	int sae_pwe; /* SAE PWE generation options */
-	int sae_pk; /* whether SAE-PK is used */
+
+	unsigned int sae_pk:1; /* whether SAE-PK is used */
+	unsigned int secure_ltf:1;
+	unsigned int secure_rtt:1;
+	unsigned int prot_range_neg:1;
 
 	u8 *assoc_wpa_ie; /* Own WPA/RSN IE from (Re)AssocReq */
 	size_t assoc_wpa_ie_len;
@@ -103,6 +118,10 @@
 	size_t assoc_rsnxe_len;
 	u8 *ap_wpa_ie, *ap_rsn_ie, *ap_rsnxe;
 	size_t ap_wpa_ie_len, ap_rsn_ie_len, ap_rsnxe_len;
+#if defined(WAPI_ANDROID)
+        u8 *ap_wapi_ie;
+        size_t ap_wapi_ie_len;
+#endif 
 
 #ifdef CONFIG_TDLS
 	struct wpa_tdls_peer *tdls;
@@ -146,6 +165,17 @@
 	u8 mdie_ft_capab; /* FT Capability and Policy from target AP MDIE */
 	u8 *assoc_resp_ies; /* MDIE and FTIE from (Re)Association Response */
 	size_t assoc_resp_ies_len;
+#ifdef CONFIG_PASN
+	/*
+	 * Currently, the WPA state machine stores the PMK-R1, PMK-R1-Name and
+	 * R1KH-ID only for the current association. As PMK-R1 is required to
+	 * perform PASN authentication with FT, store the R1KH-ID for previous
+	 * associations, which would later be used to derive the PMK-R1 as part
+	 * of the PASN authentication flow.
+	 */
+	struct pasn_ft_r1kh *pasn_r1kh;
+	unsigned int n_pasn_r1kh;
+#endif /* CONFIG_PASN */
 #endif /* CONFIG_IEEE80211R */
 
 #ifdef CONFIG_P2P
@@ -190,7 +220,9 @@
 	struct wpabuf *dpp_z;
 	int dpp_pfs;
 #endif /* CONFIG_DPP2 */
-	/* Refer commit ed56a660: Suppress deauth for PMKSA caching disabled */
+	/* Refer commit 09f46ec2: wpa_supplicant: suppress deauth
+	 * for PMKSA caching disabled
+	 */
 	int suppress_deauth_no_pmksa;
 };
 
@@ -374,6 +406,9 @@
 			size_t supp_rates_len,
 			const struct ieee80211_ht_capabilities *ht_capab,
 			const struct ieee80211_vht_capabilities *vht_capab,
+			const struct ieee80211_he_capabilities *he_capab,
+			size_t he_capab_len,
+			const struct ieee80211_he_6ghz_band_cap *he_6ghz_capab,
 			u8 qosinfo, int wmm, const u8 *ext_capab,
 			size_t ext_capab_len, const u8 *supp_channels,
 			size_t supp_channels_len, const u8 *supp_oper_classes,
@@ -383,7 +418,9 @@
 		return sm->ctx->tdls_peer_addset(sm->ctx->ctx, addr, add,
 						 aid, capability, supp_rates,
 						 supp_rates_len, ht_capab,
-						 vht_capab, qosinfo, wmm,
+						 vht_capab,
+						 he_capab, he_capab_len,
+						 he_6ghz_capab, qosinfo, wmm,
 						 ext_capab, ext_capab_len,
 						 supp_channels,
 						 supp_channels_len,
@@ -443,6 +480,14 @@
 		sm->ctx->transition_disable(sm->ctx->ctx, bitmap);
 }
 
+static inline void wpa_sm_store_ptk(struct wpa_sm *sm,
+				    u8 *addr, int cipher,
+				    u32 life_time, struct wpa_ptk *ptk)
+{
+	if (sm->ctx->store_ptk)
+		sm->ctx->store_ptk(sm->ctx->ctx, addr, cipher, life_time,
+				   ptk);
+}
 
 int wpa_eapol_key_send(struct wpa_sm *sm, struct wpa_ptk *ptk,
 		       int ver, const u8 *dest, u16 proto,
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/wpa_ie.c b/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/wpa_ie.c
index 20fdd69..3ba722f 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/wpa_ie.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/rsn_supp/wpa_ie.c
@@ -354,25 +354,38 @@
 int wpa_gen_rsnxe(struct wpa_sm *sm, u8 *rsnxe, size_t rsnxe_len)
 {
 	u8 *pos = rsnxe;
+	u16 capab = 0;
+	size_t flen;
 
-	if (!wpa_key_mgmt_sae(sm->key_mgmt))
-		return 0; /* SAE not in use */
-	if (sm->sae_pwe != 1 && sm->sae_pwe != 2 && !sm->sae_pk)
+	if (wpa_key_mgmt_sae(sm->key_mgmt) &&
+	    (sm->sae_pwe == 1 || sm->sae_pwe == 2 || sm->sae_pk)) {
+		capab |= BIT(WLAN_RSNX_CAPAB_SAE_H2E);
+#ifdef CONFIG_SAE_PK
+		if (sm->sae_pk)
+			capab |= BIT(WLAN_RSNX_CAPAB_SAE_PK);
+#endif /* CONFIG_SAE_PK */
+	}
+
+	if (sm->secure_ltf)
+		capab |= BIT(WLAN_RSNX_CAPAB_SECURE_LTF);
+	if (sm->secure_rtt)
+		capab |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT);
+	if (sm->prot_range_neg)
+		capab |= BIT(WLAN_RSNX_CAPAB_PROT_RANGE_NEG);
+
+	flen = (capab & 0xff00) ? 2 : 1;
+	if (!capab)
 		return 0; /* no supported extended RSN capabilities */
-
-	if (rsnxe_len < 3)
+	if (rsnxe_len < 2 + flen)
 		return -1;
+	capab |= flen - 1; /* bit 0-3 = Field length (n - 1) */
 
 	*pos++ = WLAN_EID_RSNX;
-	*pos++ = 1;
-	/* bits 0-3 = 0 since only one octet of Extended RSN Capabilities is
-	 * used for now */
-	*pos = BIT(WLAN_RSNX_CAPAB_SAE_H2E);
-#ifdef CONFIG_SAE_PK
-	if (sm->sae_pk)
-		*pos |= BIT(WLAN_RSNX_CAPAB_SAE_PK);
-#endif /* CONFIG_SAE_PK */
-	pos++;
+	*pos++ = flen;
+	*pos++ = capab & 0x00ff;
+	capab >>= 8;
+	if (capab)
+		*pos++ = capab;
 
 	return pos - rsnxe;
 }
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/tls/asn1.c b/src/lynq/packages/thirdpart/lynq-wg870/src/tls/asn1.c
index 2da7b4a..04d5320 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/tls/asn1.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/tls/asn1.c
@@ -129,6 +129,41 @@
 		return 1;
 	if (hdr->tag == ASN1_TAG_BOOLEAN && !asn1_valid_der_boolean(hdr))
 		return 0;
+	if (hdr->tag == ASN1_TAG_NULL && hdr->length != 0)
+		return 0;
+
+	/* Check for allowed primitive/constructed values */
+	if (hdr->constructed &&
+	    (hdr->tag == ASN1_TAG_BOOLEAN ||
+	     hdr->tag == ASN1_TAG_INTEGER ||
+	     hdr->tag == ASN1_TAG_NULL ||
+	     hdr->tag == ASN1_TAG_OID ||
+	     hdr->tag == ANS1_TAG_RELATIVE_OID ||
+	     hdr->tag == ASN1_TAG_REAL ||
+	     hdr->tag == ASN1_TAG_ENUMERATED ||
+	     hdr->tag == ASN1_TAG_BITSTRING ||
+	     hdr->tag == ASN1_TAG_OCTETSTRING ||
+	     hdr->tag == ASN1_TAG_NUMERICSTRING ||
+	     hdr->tag == ASN1_TAG_PRINTABLESTRING ||
+	     hdr->tag == ASN1_TAG_T61STRING ||
+	     hdr->tag == ASN1_TAG_VIDEOTEXSTRING ||
+	     hdr->tag == ASN1_TAG_VISIBLESTRING ||
+	     hdr->tag == ASN1_TAG_IA5STRING ||
+	     hdr->tag == ASN1_TAG_GRAPHICSTRING ||
+	     hdr->tag == ASN1_TAG_GENERALSTRING ||
+	     hdr->tag == ASN1_TAG_UNIVERSALSTRING ||
+	     hdr->tag == ASN1_TAG_UTF8STRING ||
+	     hdr->tag == ASN1_TAG_BMPSTRING ||
+	     hdr->tag == ASN1_TAG_CHARACTERSTRING ||
+	     hdr->tag == ASN1_TAG_UTCTIME ||
+	     hdr->tag == ASN1_TAG_GENERALIZEDTIME ||
+	     hdr->tag == ASN1_TAG_TIME))
+		return 0;
+	if (!hdr->constructed &&
+	    (hdr->tag == ASN1_TAG_SEQUENCE ||
+	     hdr->tag == ASN1_TAG_SET))
+		return 0;
+
 	return 1;
 }
 
@@ -151,18 +186,35 @@
 	hdr->constructed = !!(hdr->identifier & (1 << 5));
 
 	if ((hdr->identifier & 0x1f) == 0x1f) {
+		size_t ext_len = 0;
+
 		hdr->tag = 0;
+		if (pos == end || (*pos & 0x7f) == 0) {
+			wpa_printf(MSG_DEBUG,
+				   "ASN.1: Invalid extended tag (first octet has to be included with at least one nonzero bit for the tag value)");
+			return -1;
+		}
 		do {
 			if (pos >= end) {
 				wpa_printf(MSG_DEBUG, "ASN.1: Identifier "
 					   "underflow");
 				return -1;
 			}
+			ext_len++;
 			tmp = *pos++;
 			wpa_printf(MSG_MSGDUMP, "ASN.1: Extended tag data: "
 				   "0x%02x", tmp);
 			hdr->tag = (hdr->tag << 7) | (tmp & 0x7f);
 		} while (tmp & 0x80);
+		wpa_printf(MSG_MSGDUMP, "ASN.1: Extended Tag: 0x%x (len=%zu)",
+			   hdr->tag, ext_len);
+		if ((hdr->class != ASN1_CLASS_PRIVATE && hdr->tag < 31) ||
+		    ext_len * 7 > sizeof(hdr->tag) * 8) {
+			wpa_printf(MSG_DEBUG,
+				   "ASN.1: Invalid or unsupported (too large) extended Tag: 0x%x (len=%zu)",
+				   hdr->tag, ext_len);
+			return -1;
+		}
 	} else
 		hdr->tag = hdr->identifier & 0x1f;
 
@@ -179,6 +231,11 @@
 		}
 		tmp &= 0x7f; /* number of subsequent octets */
 		hdr->length = 0;
+		if (tmp == 0 || pos == end || *pos == 0) {
+			wpa_printf(MSG_DEBUG,
+				   "ASN.1: Definite long form of the length does not start with a nonzero value");
+			return -1;
+		}
 		if (tmp > 4) {
 			wpa_printf(MSG_DEBUG, "ASN.1: Too long length field");
 			return -1;
@@ -191,6 +248,11 @@
 			}
 			hdr->length = (hdr->length << 8) | *pos++;
 		}
+		if (hdr->length < 128) {
+			wpa_printf(MSG_DEBUG,
+				   "ASN.1: Definite long form of the length used with too short length");
+			return -1;
+		}
 	} else {
 		/* Short form - length 0..127 in one octet */
 		hdr->length = tmp;
@@ -203,7 +265,25 @@
 
 	hdr->payload = pos;
 
-	return asn1_valid_der(hdr) ? 0 : -1;
+	if (!asn1_valid_der(hdr)) {
+		asn1_print_hdr(hdr, "ASN.1: Invalid DER encoding: ");
+		return -1;
+	}
+	return 0;
+}
+
+
+void asn1_print_hdr(const struct asn1_hdr *hdr, const char *title)
+{
+	wpa_printf(MSG_DEBUG, "%sclass %d constructed %d tag 0x%x",
+		   title, hdr->class, hdr->constructed, hdr->tag);
+}
+
+
+void asn1_unexpected(const struct asn1_hdr *hdr, const char *title)
+{
+	wpa_printf(MSG_DEBUG, "%s - found class %d constructed %d tag 0x%x",
+		   title, hdr->class, hdr->constructed, hdr->tag);
 }
 
 
@@ -256,12 +336,9 @@
 {
 	struct asn1_hdr hdr;
 
-	if (asn1_get_next(buf, len, &hdr) < 0 || hdr.length == 0)
-		return -1;
-
-	if (hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_OID) {
-		wpa_printf(MSG_DEBUG, "ASN.1: Expected OID - found class %d "
-			   "tag 0x%x", hdr.class, hdr.tag);
+	if (asn1_get_next(buf, len, &hdr) < 0 || hdr.length == 0 ||
+	    !asn1_is_oid(&hdr)) {
+		asn1_unexpected(&hdr, "ASN.1: Expected OID");
 		return -1;
 	}
 
@@ -360,13 +437,9 @@
 	const u8 *pos;
 	int value;
 
-	if (asn1_get_next(buf, len, &hdr) < 0 || hdr.length == 0)
-		return -1;
-
-	if (hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_INTEGER) {
-		wpa_printf(MSG_DEBUG,
-			   "ASN.1: Expected INTEGER - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(buf, len, &hdr) < 0 || hdr.length == 0 ||
+	    !asn1_is_integer(&hdr)) {
+		asn1_unexpected(&hdr, "ASN.1: Expected INTEGER");
 		return -1;
 	}
 
@@ -393,12 +466,8 @@
 int asn1_get_sequence(const u8 *buf, size_t len, struct asn1_hdr *hdr,
 		      const u8 **next)
 {
-	if (asn1_get_next(buf, len, hdr) < 0 ||
-	    hdr->class != ASN1_CLASS_UNIVERSAL ||
-	    hdr->tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG,
-			   "ASN.1: Expected SEQUENCE - found class %d tag 0x%x",
-			   hdr->class, hdr->tag);
+	if (asn1_get_next(buf, len, hdr) < 0 || !asn1_is_sequence(hdr)) {
+		asn1_unexpected(hdr, "ASN.1: Expected SEQUENCE");
 		return -1;
 	}
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/tls/asn1.h b/src/lynq/packages/thirdpart/lynq-wg870/src/tls/asn1.h
index 6878a4f..a4d1be4 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/tls/asn1.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/tls/asn1.h
@@ -23,11 +23,12 @@
 #define ASN1_TAG_EMBEDDED_PDV	0x0B /* not yet parsed */
 #define ASN1_TAG_UTF8STRING	0x0C /* not yet parsed */
 #define ANS1_TAG_RELATIVE_OID	0x0D
+#define ASN1_TAG_TIME		0x0E
 #define ASN1_TAG_SEQUENCE	0x10 /* shall be constructed */
 #define ASN1_TAG_SET		0x11
 #define ASN1_TAG_NUMERICSTRING	0x12 /* not yet parsed */
 #define ASN1_TAG_PRINTABLESTRING	0x13
-#define ASN1_TAG_TG1STRING	0x14 /* not yet parsed */
+#define ASN1_TAG_T61STRING	0x14 /* not yet parsed */
 #define ASN1_TAG_VIDEOTEXSTRING	0x15 /* not yet parsed */
 #define ASN1_TAG_IA5STRING	0x16
 #define ASN1_TAG_UTCTIME	0x17
@@ -59,6 +60,8 @@
 
 
 int asn1_get_next(const u8 *buf, size_t len, struct asn1_hdr *hdr);
+void asn1_print_hdr(const struct asn1_hdr *hdr, const char *title);
+void asn1_unexpected(const struct asn1_hdr *hdr, const char *title);
 int asn1_parse_oid(const u8 *buf, size_t len, struct asn1_oid *oid);
 int asn1_get_oid(const u8 *buf, size_t len, struct asn1_oid *oid,
 		 const u8 **next);
@@ -82,6 +85,108 @@
 				  const struct wpabuf *params);
 struct wpabuf * asn1_encaps(struct wpabuf *buf, u8 class, u8 tag);
 
+static inline bool asn1_is_oid(const struct asn1_hdr *hdr)
+{
+	return hdr->class == ASN1_CLASS_UNIVERSAL &&
+		hdr->tag == ASN1_TAG_OID;
+}
+
+static inline bool asn1_is_boolean(const struct asn1_hdr *hdr)
+{
+	return hdr->class == ASN1_CLASS_UNIVERSAL &&
+		hdr->tag == ASN1_TAG_BOOLEAN;
+}
+
+static inline bool asn1_is_integer(const struct asn1_hdr *hdr)
+{
+	return hdr->class == ASN1_CLASS_UNIVERSAL &&
+		hdr->tag == ASN1_TAG_INTEGER;
+}
+
+static inline bool asn1_is_enumerated(const struct asn1_hdr *hdr)
+{
+	return hdr->class == ASN1_CLASS_UNIVERSAL &&
+		hdr->tag == ASN1_TAG_ENUMERATED;
+}
+
+static inline bool asn1_is_sequence(const struct asn1_hdr *hdr)
+{
+	return hdr->class == ASN1_CLASS_UNIVERSAL &&
+		hdr->tag == ASN1_TAG_SEQUENCE;
+}
+
+static inline bool asn1_is_set(const struct asn1_hdr *hdr)
+{
+	return hdr->class == ASN1_CLASS_UNIVERSAL &&
+		hdr->tag == ASN1_TAG_SET;
+}
+
+static inline bool asn1_is_octetstring(const struct asn1_hdr *hdr)
+{
+	return hdr->class == ASN1_CLASS_UNIVERSAL &&
+		hdr->tag == ASN1_TAG_OCTETSTRING;
+}
+
+static inline bool asn1_is_bitstring(const struct asn1_hdr *hdr)
+{
+	return hdr->class == ASN1_CLASS_UNIVERSAL &&
+		hdr->tag == ASN1_TAG_BITSTRING;
+}
+
+static inline bool asn1_is_utctime(const struct asn1_hdr *hdr)
+{
+	return hdr->class == ASN1_CLASS_UNIVERSAL &&
+		hdr->tag == ASN1_TAG_UTCTIME;
+}
+
+static inline bool asn1_is_generalizedtime(const struct asn1_hdr *hdr)
+{
+	return hdr->class == ASN1_CLASS_UNIVERSAL &&
+		hdr->tag == ASN1_TAG_GENERALIZEDTIME;
+}
+
+static inline bool asn1_is_string_type(const struct asn1_hdr *hdr)
+{
+	if (hdr->class != ASN1_CLASS_UNIVERSAL || hdr->constructed)
+		return false;
+	return hdr->tag == ASN1_TAG_UTF8STRING ||
+		hdr->tag == ASN1_TAG_NUMERICSTRING ||
+		hdr->tag == ASN1_TAG_PRINTABLESTRING ||
+		hdr->tag == ASN1_TAG_T61STRING ||
+		hdr->tag == ASN1_TAG_VIDEOTEXSTRING ||
+		hdr->tag == ASN1_TAG_IA5STRING ||
+		hdr->tag == ASN1_TAG_GRAPHICSTRING ||
+		hdr->tag == ASN1_TAG_VISIBLESTRING ||
+		hdr->tag == ASN1_TAG_GENERALSTRING ||
+		hdr->tag == ASN1_TAG_UNIVERSALSTRING ||
+		hdr->tag == ASN1_TAG_CHARACTERSTRING ||
+		hdr->tag == ASN1_TAG_BMPSTRING;
+}
+
+static inline bool asn1_is_bmpstring(const struct asn1_hdr *hdr)
+{
+	return hdr->class == ASN1_CLASS_UNIVERSAL &&
+		hdr->tag == ASN1_TAG_BMPSTRING;
+}
+
+static inline bool asn1_is_utf8string(const struct asn1_hdr *hdr)
+{
+	return hdr->class == ASN1_CLASS_UNIVERSAL &&
+		hdr->tag == ASN1_TAG_UTF8STRING;
+}
+
+static inline bool asn1_is_null(const struct asn1_hdr *hdr)
+{
+	return hdr->class == ASN1_CLASS_UNIVERSAL &&
+		hdr->tag == ASN1_TAG_NULL;
+}
+
+static inline bool asn1_is_cs_tag(const struct asn1_hdr *hdr, unsigned int tag)
+{
+	return hdr->class == ASN1_CLASS_CONTEXT_SPECIFIC &&
+		hdr->tag == tag;
+}
+
 extern const struct asn1_oid asn1_sha1_oid;
 extern const struct asn1_oid asn1_sha256_oid;
 extern const struct asn1_oid asn1_ec_public_key_oid;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/tls/pkcs1.c b/src/lynq/packages/thirdpart/lynq-wg870/src/tls/pkcs1.c
index 654c01b..49e439d 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/tls/pkcs1.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/tls/pkcs1.c
@@ -236,14 +236,14 @@
 	 *
 	 */
 	if (asn1_get_next(decrypted, decrypted_len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #1: Expected SEQUENCE (DigestInfo) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #1: Expected SEQUENCE (DigestInfo)");
 		os_free(decrypted);
 		return -1;
 	}
+	wpa_hexdump(MSG_MSGDUMP, "PKCS #1: DigestInfo",
+		    hdr.payload, hdr.length);
 
 	pos = hdr.payload;
 	end = pos + hdr.length;
@@ -257,14 +257,14 @@
 	 */
 
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #1: Expected SEQUENCE (AlgorithmIdentifier) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #1: Expected SEQUENCE (AlgorithmIdentifier)");
 		os_free(decrypted);
 		return -1;
 	}
+	wpa_hexdump(MSG_MSGDUMP, "PKCS #1: DigestAlgorithmIdentifier",
+		    hdr.payload, hdr.length);
 	da_end = hdr.payload + hdr.length;
 
 	if (asn1_get_oid(hdr.payload, hdr.length, &oid, &next)) {
@@ -273,6 +273,23 @@
 		os_free(decrypted);
 		return -1;
 	}
+	wpa_hexdump(MSG_MSGDUMP, "PKCS #1: Digest algorithm parameters",
+		    next, da_end - next);
+
+	/*
+	 * RFC 5754: The correct encoding for the SHA2 algorithms would be to
+	 * omit the parameters, but there are implementation that encode these
+	 * as a NULL element. Allow these two cases and reject anything else.
+	 */
+	if (da_end > next &&
+	    (asn1_get_next(next, da_end - next, &hdr) < 0 ||
+	     !asn1_is_null(&hdr) ||
+	     hdr.payload + hdr.length != da_end)) {
+		wpa_printf(MSG_DEBUG,
+			   "PKCS #1: Unexpected digest algorithm parameters");
+		os_free(decrypted);
+		return -1;
+	}
 
 	if (!asn1_oid_equal(&oid, hash_alg)) {
 		char txt[100], txt2[100];
@@ -287,14 +304,11 @@
 
 	/* Digest ::= OCTET STRING */
 	pos = da_end;
-	end = decrypted + decrypted_len;
 
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_OCTETSTRING) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #1: Expected OCTETSTRING (Digest) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_octetstring(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #1: Expected OCTETSTRING (Digest)");
 		os_free(decrypted);
 		return -1;
 	}
@@ -310,13 +324,14 @@
 
 	os_free(decrypted);
 
-	if (hdr.payload + hdr.length != end) {
+	if (hdr.payload + hdr.length != decrypted + decrypted_len) {
 		wpa_printf(MSG_INFO,
 			   "PKCS #1: Extra data after signature - reject");
 
 		wpa_hexdump(MSG_DEBUG, "PKCS #1: Extra data",
 			    hdr.payload + hdr.length,
-			    end - hdr.payload - hdr.length);
+			    decrypted + decrypted_len - hdr.payload -
+			    hdr.length);
 		return -1;
 	}
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/tls/pkcs5.c b/src/lynq/packages/thirdpart/lynq-wg870/src/tls/pkcs5.c
index a2ad83b..7bef89b 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/tls/pkcs5.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/tls/pkcs5.c
@@ -107,22 +107,18 @@
 	 */
 
 	if (asn1_get_next(pos, enc_alg_end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #5: Expected SEQUENCE (PBES2-params) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #5: Expected SEQUENCE (PBES2-params)");
 		return -1;
 	}
 	pos = hdr.payload;
 	end = hdr.payload + hdr.length;
 
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #5: Expected SEQUENCE (keyDerivationFunc) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #5: Expected SEQUENCE (keyDerivationFunc)");
 		return -1;
 	}
 
@@ -161,11 +157,9 @@
 	 */
 
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #5: Expected SEQUENCE (PBKDF2-params) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #5: Expected SEQUENCE (PBKDF2-params)");
 		return -1;
 	}
 
@@ -174,12 +168,10 @@
 
 	/* For now, only support the salt CHOICE specified (OCTET STRING) */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_OCTETSTRING ||
+	    !asn1_is_octetstring(&hdr) ||
 	    hdr.length > sizeof(params->salt)) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #5: Expected OCTET STRING (salt.specified) - found class %d tag 0x%x size %d",
-			   hdr.class, hdr.tag, hdr.length);
+		asn1_unexpected(&hdr,
+				"PKCS #5: Expected OCTET STRING (salt.specified)");
 		return -1;
 	}
 	pos = hdr.payload + hdr.length;
@@ -188,11 +180,8 @@
 	wpa_hexdump(MSG_DEBUG, "PKCS #5: salt", params->salt, params->salt_len);
 
 	/* iterationCount INTEGER */
-	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_INTEGER) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #5: Expected INTEGER - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !asn1_is_integer(&hdr)) {
+		asn1_unexpected(&hdr, "PKCS #5: Expected INTEGER");
 		return -1;
 	}
 	if (hdr.length == 1) {
@@ -222,11 +211,9 @@
 	/* encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} */
 
 	if (asn1_get_next(pos, enc_alg_end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #5: Expected SEQUENCE (encryptionScheme) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #5: Expected SEQUENCE (encryptionScheme)");
 		return -1;
 	}
 
@@ -258,12 +245,9 @@
 	 * specifying the initialization vector for CBC mode.
 	 */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_OCTETSTRING ||
-	    hdr.length != 8) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #5: Expected OCTET STRING (SIZE(8)) (IV) - found class %d tag 0x%x size %d",
-			   hdr.class, hdr.tag, hdr.length);
+	    !asn1_is_octetstring(&hdr) || hdr.length != 8) {
+		asn1_unexpected(&hdr,
+				"PKCS #5: Expected OCTET STRING (SIZE(8)) (IV)");
 		return -1;
 	}
 	os_memcpy(params->iv, hdr.payload, hdr.length);
@@ -323,11 +307,9 @@
 	 */
 
 	if (asn1_get_next(pos, enc_alg_end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG, "PKCS #5: Expected SEQUENCE "
-			   "(PBEParameter) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #5: Expected SEQUENCE (PBEParameter)");
 		return -1;
 	}
 	pos = hdr.payload;
@@ -335,12 +317,9 @@
 
 	/* salt OCTET STRING SIZE(8) (PKCS #5) or OCTET STRING (PKCS #12) */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_OCTETSTRING ||
-	    hdr.length > sizeof(params->salt)) {
-		wpa_printf(MSG_DEBUG, "PKCS #5: Expected OCTETSTRING SIZE(8) "
-			   "(salt) - found class %d tag 0x%x size %d",
-			   hdr.class, hdr.tag, hdr.length);
+	    !asn1_is_octetstring(&hdr) || hdr.length > sizeof(params->salt)) {
+		asn1_unexpected(&hdr,
+				"PKCS #5: Expected OCTETSTRING SIZE(8) (salt)");
 		return -1;
 	}
 	pos = hdr.payload + hdr.length;
@@ -351,9 +330,8 @@
 
 	/* iterationCount INTEGER */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_INTEGER) {
-		wpa_printf(MSG_DEBUG, "PKCS #5: Expected INTEGER - found "
-			   "class %d tag 0x%x", hdr.class, hdr.tag);
+	    !asn1_is_integer(&hdr)) {
+		asn1_unexpected(&hdr, "PKCS #5: Expected INTEGER");
 		return -1;
 	}
 	if (hdr.length == 1)
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/tls/pkcs8.c b/src/lynq/packages/thirdpart/lynq-wg870/src/tls/pkcs8.c
index 52e43a4..75bbd12 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/tls/pkcs8.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/tls/pkcs8.c
@@ -27,22 +27,17 @@
 	/* PKCS #8, Chapter 6 */
 
 	/* PrivateKeyInfo ::= SEQUENCE */
-	if (asn1_get_next(buf, len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG, "PKCS #8: Does not start with PKCS #8 "
-			   "header (SEQUENCE); assume PKCS #8 not used");
+	if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #8: Does not start with PKCS #8 header (SEQUENCE)");
 		return NULL;
 	}
 	pos = hdr.payload;
 	end = pos + hdr.length;
 
 	/* version Version (Version ::= INTEGER) */
-	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_INTEGER) {
-		wpa_printf(MSG_DEBUG, "PKCS #8: Expected INTEGER - found "
-			   "class %d tag 0x%x; assume PKCS #8 not used",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !asn1_is_integer(&hdr)) {
+		asn1_unexpected(&hdr, "PKCS #8: Expected INTEGER");
 		return NULL;
 	}
 
@@ -68,13 +63,9 @@
 
 	/* privateKeyAlgorithm PrivateKeyAlgorithmIdentifier
 	 * (PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier) */
-	if (asn1_get_next(pos, len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG, "PKCS #8: Expected SEQUENCE "
-			   "(AlgorithmIdentifier) - found class %d tag 0x%x; "
-			   "assume PKCS #8 not used",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #8: Expected SEQUENCE (AlgorithmIdentifier); assume PKCS #8 not used");
 		return NULL;
 	}
 
@@ -104,11 +95,9 @@
 
 	/* privateKey PrivateKey (PrivateKey ::= OCTET STRING) */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_OCTETSTRING) {
-		wpa_printf(MSG_DEBUG, "PKCS #8: Expected OCTETSTRING "
-			   "(privateKey) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_octetstring(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #8: Expected OCTETSTRING (privateKey)");
 		return NULL;
 	}
 	wpa_printf(MSG_DEBUG, "PKCS #8: Try to parse RSAPrivateKey");
@@ -139,12 +128,9 @@
 	 * EncryptedData ::= OCTET STRING
 	 */
 
-	if (asn1_get_next(buf, len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG, "PKCS #8: Does not start with PKCS #8 "
-			   "header (SEQUENCE); assume encrypted PKCS #8 not "
-			   "used");
+	if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #8: Does not start with PKCS #8 header (SEQUENCE); assume encrypted PKCS #8 not used");
 		return NULL;
 	}
 	pos = hdr.payload;
@@ -152,12 +138,9 @@
 
 	/* encryptionAlgorithm EncryptionAlgorithmIdentifier */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG, "PKCS #8: Expected SEQUENCE "
-			   "(AlgorithmIdentifier) - found class %d tag 0x%x; "
-			   "assume encrypted PKCS #8 not used",
-			   hdr.class, hdr.tag);
+	    !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #8: Expected SEQUENCE (AlgorithmIdentifier); assume encrypted PKCS #8 not used");
 		return NULL;
 	}
 	enc_alg = hdr.payload;
@@ -166,11 +149,9 @@
 
 	/* encryptedData EncryptedData */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_OCTETSTRING) {
-		wpa_printf(MSG_DEBUG, "PKCS #8: Expected OCTETSTRING "
-			   "(encryptedData) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_octetstring(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #8: Expected OCTETSTRING (encryptedData)");
 		return NULL;
 	}
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/tls/rsa.c b/src/lynq/packages/thirdpart/lynq-wg870/src/tls/rsa.c
index 1b01f58..56ae7d7 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/tls/rsa.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/tls/rsa.c
@@ -37,9 +37,8 @@
 		return NULL;
 
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_INTEGER) {
-		wpa_printf(MSG_DEBUG, "RSA: Expected INTEGER - found class %d "
-			   "tag 0x%x", hdr.class, hdr.tag);
+	    !asn1_is_integer(&hdr)) {
+		asn1_unexpected(&hdr, "RSA: Expected INTEGER");
 		return NULL;
 	}
 
@@ -84,12 +83,8 @@
 	 * }
 	 */
 
-	if (asn1_get_next(buf, len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG, "RSA: Expected SEQUENCE "
-			   "(public key) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr, "RSA: Expected SEQUENCE (public key)");
 		goto error;
 	}
 	pos = hdr.payload;
@@ -191,12 +186,8 @@
 	 *
 	 * Version ::= INTEGER -- shall be 0 for this version of the standard
 	 */
-	if (asn1_get_next(buf, len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG, "RSA: Expected SEQUENCE "
-			   "(public key) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr, "RSA: Expected SEQUENCE (public key)");
 		goto error;
 	}
 	pos = hdr.payload;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/tls/tlsv1_client.c b/src/lynq/packages/thirdpart/lynq-wg870/src/tls/tlsv1_client.c
index a147a54..4fa14de 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/tls/tlsv1_client.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/tls/tlsv1_client.c
@@ -38,9 +38,33 @@
 }
 
 
-int tls_derive_pre_master_secret(u8 *pre_master_secret)
+u16 tls_client_highest_ver(struct tlsv1_client *conn)
 {
-	WPA_PUT_BE16(pre_master_secret, TLS_VERSION);
+	u16 tls_version = TLS_VERSION;
+
+	/* Pick the highest locally enabled TLS version */
+#ifdef CONFIG_TLSV12
+	if ((conn->flags & TLS_CONN_DISABLE_TLSv1_2) &&
+	    tls_version == TLS_VERSION_1_2)
+		tls_version = TLS_VERSION_1_1;
+#endif /* CONFIG_TLSV12 */
+#ifdef CONFIG_TLSV11
+	if ((conn->flags & TLS_CONN_DISABLE_TLSv1_1) &&
+	    tls_version == TLS_VERSION_1_1)
+		tls_version = TLS_VERSION_1;
+#endif /* CONFIG_TLSV11 */
+	if ((conn->flags & TLS_CONN_DISABLE_TLSv1_0) &&
+	    tls_version == TLS_VERSION_1)
+		return 0;
+
+	return tls_version;
+}
+
+
+int tls_derive_pre_master_secret(struct tlsv1_client *conn,
+				 u8 *pre_master_secret)
+{
+	WPA_PUT_BE16(pre_master_secret, tls_client_highest_ver(conn));
 	if (os_get_random(pre_master_secret + 2,
 			  TLS_PRE_MASTER_SECRET_LEN - 2))
 		return -1;
@@ -800,15 +824,6 @@
 		suites[count++] = TLS_DH_anon_WITH_RC4_128_MD5;
 		suites[count++] = TLS_DH_anon_WITH_DES_CBC_SHA;
 
-		/*
-		 * Cisco AP (at least 350 and 1200 series) local authentication
-		 * server does not know how to search cipher suites from the
-		 * list and seem to require that the last entry in the list is
-		 * the one that it wants to use. However, TLS specification
-		 * requires the list to be in the client preference order. As a
-		 * workaround, add anon-DH AES-128-SHA1 again at the end of the
-		 * list to allow the Cisco code to find it.
-		 */
 		suites[count++] = TLS_DH_anon_WITH_AES_128_CBC_SHA;
 		conn->num_cipher_suites = count;
 	}
@@ -844,6 +859,7 @@
 void tlsv1_client_set_flags(struct tlsv1_client *conn, unsigned int flags)
 {
 	conn->flags = flags;
+	conn->rl.tls_version = tls_client_highest_ver(conn);
 }
 
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/tls/tlsv1_client_i.h b/src/lynq/packages/thirdpart/lynq-wg870/src/tls/tlsv1_client_i.h
index 12ec8df..ccb2e15 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/tls/tlsv1_client_i.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/tls/tlsv1_client_i.h
@@ -78,7 +78,9 @@
 
 void tls_alert(struct tlsv1_client *conn, u8 level, u8 description);
 void tlsv1_client_free_dh(struct tlsv1_client *conn);
-int tls_derive_pre_master_secret(u8 *pre_master_secret);
+u16 tls_client_highest_ver(struct tlsv1_client *conn);
+int tls_derive_pre_master_secret(struct tlsv1_client *conn,
+				 u8 *pre_master_secret);
 int tls_derive_keys(struct tlsv1_client *conn,
 		    const u8 *pre_master_secret, size_t pre_master_secret_len);
 u8 * tls_send_client_hello(struct tlsv1_client *conn, size_t *out_len);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/tls/tlsv1_client_ocsp.c b/src/lynq/packages/thirdpart/lynq-wg870/src/tls/tlsv1_client_ocsp.c
index 1d7b68c..128f4b5 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/tls/tlsv1_client_ocsp.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/tls/tlsv1_client_ocsp.c
@@ -138,12 +138,8 @@
 	 */
 
 	/* CertID ::= SEQUENCE */
-	if (asn1_get_next(resp, len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG,
-			   "OCSP: Expected SEQUENCE (CertID) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(resp, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr, "OCSP: Expected SEQUENCE (CertID)");
 		return -1;
 	}
 	pos = hdr.payload;
@@ -163,11 +159,9 @@
 
 	/* issuerNameHash  OCTET STRING */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_OCTETSTRING) {
-		wpa_printf(MSG_DEBUG,
-			   "OCSP: Expected OCTET STRING (issuerNameHash) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_octetstring(&hdr)) {
+		asn1_unexpected(&hdr,
+				"OCSP: Expected OCTET STRING (issuerNameHash)");
 		return -1;
 	}
 	name_hash = hdr.payload;
@@ -190,11 +184,9 @@
 
 	/* issuerKeyHash  OCTET STRING */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_OCTETSTRING) {
-		wpa_printf(MSG_DEBUG,
-			   "OCSP: Expected OCTET STRING (issuerKeyHash) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_octetstring(&hdr)) {
+		asn1_unexpected(&hdr,
+				"OCSP: Expected OCTET STRING (issuerKeyHash)");
 		return -1;
 	}
 	key_hash = hdr.payload;
@@ -214,11 +206,10 @@
 
 	/* serialNumber CertificateSerialNumber ::= INTEGER */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_INTEGER ||
+	    !asn1_is_integer(&hdr) ||
 	    hdr.length < 1 || hdr.length > X509_MAX_SERIAL_NUM_LEN) {
-		wpa_printf(MSG_DEBUG, "OCSP: No INTEGER tag found for serialNumber; class=%d tag=0x%x length=%u",
-			   hdr.class, hdr.tag, hdr.length);
+		asn1_unexpected(&hdr,
+				"OCSP: No INTEGER tag found for serialNumber");
 		return -1;
 	}
 	serial_number = hdr.payload;
@@ -240,12 +231,16 @@
 	pos = end;
 	end = resp + len;
 
-	/* certStatus CertStatus ::= CHOICE */
+	/* certStatus CertStatus ::= CHOICE
+	 *
+	 * CertStatus ::= CHOICE {
+	 *     good        [0]     IMPLICIT NULL,
+	 *     revoked     [1]     IMPLICIT RevokedInfo,
+	 *     unknown     [2]     IMPLICIT UnknownInfo }
+	 */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
 	    hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
-		wpa_printf(MSG_DEBUG,
-			   "OCSP: Expected CHOICE (CertStatus) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+		asn1_unexpected(&hdr, "OCSP: Expected CHOICE (CertStatus)");
 		return -1;
 	}
 	cert_status = hdr.tag;
@@ -257,8 +252,7 @@
 	os_get_time(&now);
 	/* thisUpdate  GeneralizedTime */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_GENERALIZEDTIME ||
+	    !asn1_is_generalizedtime(&hdr) ||
 	    x509_parse_time(hdr.payload, hdr.length, hdr.tag, &update) < 0) {
 		wpa_printf(MSG_DEBUG, "OCSP: Failed to parse thisUpdate");
 		return -1;
@@ -275,12 +269,11 @@
 	if (pos < end) {
 		if (asn1_get_next(pos, end - pos, &hdr) < 0)
 			return -1;
-		if (hdr.class == ASN1_CLASS_CONTEXT_SPECIFIC && hdr.tag == 0) {
+		if (asn1_is_cs_tag(&hdr, 0) && hdr.constructed) {
 			const u8 *next = hdr.payload + hdr.length;
 
 			if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 ||
-			    hdr.class != ASN1_CLASS_UNIVERSAL ||
-			    hdr.tag != ASN1_TAG_GENERALIZEDTIME ||
+			    !asn1_is_generalizedtime(&hdr) ||
 			    x509_parse_time(hdr.payload, hdr.length, hdr.tag,
 					    &update) < 0) {
 				wpa_printf(MSG_DEBUG,
@@ -329,11 +322,9 @@
 	while (pos < end) {
 		/* SingleResponse ::= SEQUENCE */
 		if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-		    hdr.class != ASN1_CLASS_UNIVERSAL ||
-		    hdr.tag != ASN1_TAG_SEQUENCE) {
-			wpa_printf(MSG_DEBUG,
-				   "OCSP: Expected SEQUENCE (SingleResponse) - found class %d tag 0x%x",
-				   hdr.class, hdr.tag);
+		    !asn1_is_sequence(&hdr)) {
+			asn1_unexpected(&hdr,
+					"OCSP: Expected SEQUENCE (SingleResponse)");
 			return TLS_OCSP_INVALID;
 		}
 		if (tls_process_ocsp_single_response(conn, cert, issuer,
@@ -381,12 +372,9 @@
 	 *    certs            [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
 	 */
 
-	if (asn1_get_next(resp, len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG,
-			   "OCSP: Expected SEQUENCE (BasicOCSPResponse) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(resp, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"OCSP: Expected SEQUENCE (BasicOCSPResponse)");
 		return TLS_OCSP_INVALID;
 	}
 	pos = hdr.payload;
@@ -394,11 +382,9 @@
 
 	/* ResponseData ::= SEQUENCE */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG,
-			   "OCSP: Expected SEQUENCE (ResponseData) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"OCSP: Expected SEQUENCE (ResponseData)");
 		return TLS_OCSP_INVALID;
 	}
 	resp_data = hdr.payload;
@@ -413,11 +399,9 @@
 
 	/* signature  BIT STRING */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_BITSTRING) {
-		wpa_printf(MSG_DEBUG,
-			   "OCSP: Expected BITSTRING (signature) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_bitstring(&hdr)) {
+		asn1_unexpected(&hdr,
+				"OCSP: Expected BITSTRING (signature)");
 		return TLS_OCSP_INVALID;
 	}
 	if (hdr.length < 1)
@@ -439,11 +423,9 @@
 	/* certs  [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL */
 	if (pos < end) {
 		if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-		    hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC ||
-		    hdr.tag != 0) {
-			wpa_printf(MSG_DEBUG,
-				   "OCSP: Expected [0] EXPLICIT (certs) - found class %d tag 0x%x",
-				   hdr.class, hdr.tag);
+		    !hdr.constructed || !asn1_is_cs_tag(&hdr, 0)) {
+			asn1_unexpected(&hdr,
+					"OCSP: Expected [0] EXPLICIT (certs)");
 			return TLS_OCSP_INVALID;
 		}
 		wpa_hexdump(MSG_MSGDUMP, "OCSP: certs",
@@ -454,11 +436,9 @@
 			struct x509_certificate *cert;
 
 			if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-			    hdr.class != ASN1_CLASS_UNIVERSAL ||
-			    hdr.tag != ASN1_TAG_SEQUENCE) {
-				wpa_printf(MSG_DEBUG,
-					   "OCSP: Expected SEQUENCE (Certificate) - found class %d tag 0x%x",
-					   hdr.class, hdr.tag);
+			    !asn1_is_sequence(&hdr)) {
+				asn1_unexpected(&hdr,
+						"OCSP: Expected SEQUENCE (Certificate)");
 				goto fail;
 			}
 
@@ -491,16 +471,12 @@
 	 * version [0] EXPLICIT Version DEFAULT v1
 	 * Version ::= INTEGER { v1(0) }
 	 */
-	if (asn1_get_next(pos, end - pos, &hdr) < 0 &&
-	    hdr.class == ASN1_CLASS_CONTEXT_SPECIFIC &&
-	    hdr.tag == 0) {
+	if (asn1_get_next(pos, end - pos, &hdr) == 0 && hdr.constructed &&
+	    asn1_is_cs_tag(&hdr, 0)) {
 		if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-		    hdr.class != ASN1_CLASS_UNIVERSAL ||
-		    hdr.tag != ASN1_TAG_INTEGER ||
-		    hdr.length != 1) {
-			wpa_printf(MSG_DEBUG,
-				   "OCSP: No INTEGER (len=1) tag found for version field - found class %d tag 0x%x length %d",
-				   hdr.class, hdr.tag, hdr.length);
+		    !asn1_is_integer(&hdr) || hdr.length != 1) {
+			asn1_unexpected(&hdr,
+					"OCSP: No INTEGER (len=1) tag found for version field");
 			goto fail;
 		}
 		wpa_printf(MSG_DEBUG, "OCSP: ResponseData version %u",
@@ -524,9 +500,7 @@
 	 */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
 	    hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
-		wpa_printf(MSG_DEBUG,
-			   "OCSP: Expected CHOICE (ResponderID) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+		asn1_unexpected(&hdr, "OCSP: Expected CHOICE (ResponderID)");
 		goto fail;
 	}
 
@@ -539,11 +513,9 @@
 	} else if (hdr.tag == 2) {
 		/* KeyHash ::= OCTET STRING */
 		if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 ||
-		    hdr.class != ASN1_CLASS_UNIVERSAL ||
-		    hdr.tag != ASN1_TAG_OCTETSTRING) {
-			wpa_printf(MSG_DEBUG,
-				   "OCSP: Expected OCTET STRING (KeyHash) - found class %d tag 0x%x",
-				   hdr.class, hdr.tag);
+		    !asn1_is_octetstring(&hdr)) {
+			asn1_unexpected(&hdr,
+					"OCSP: Expected OCTET STRING (KeyHash)");
 			goto fail;
 		}
 		key_hash = hdr.payload;
@@ -564,8 +536,7 @@
 
 	/* producedAt  GeneralizedTime */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_GENERALIZEDTIME ||
+	    !asn1_is_generalizedtime(&hdr) ||
 	    x509_parse_time(hdr.payload, hdr.length, hdr.tag,
 			    &produced_at) < 0) {
 		wpa_printf(MSG_DEBUG, "OCSP: Failed to parse producedAt");
@@ -577,11 +548,9 @@
 
 	/* responses  SEQUENCE OF SingleResponse */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG,
-			   "OCSP: Expected SEQUENCE (responses) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"OCSP: Expected SEQUENCE (responses)");
 		goto fail;
 	}
 	responses = hdr.payload;
@@ -697,12 +666,9 @@
 	 *    responseBytes   [0] EXPLICIT ResponseBytes OPTIONAL }
 	 */
 
-	if (asn1_get_next(resp, len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG,
-			   "OCSP: Expected SEQUENCE (OCSPResponse) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(resp, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"OCSP: Expected SEQUENCE (OCSPResponse)");
 		return TLS_OCSP_INVALID;
 	}
 	pos = hdr.payload;
@@ -710,12 +676,9 @@
 
 	/* OCSPResponseStatus ::= ENUMERATED */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_ENUMERATED ||
-	    hdr.length != 1) {
-		wpa_printf(MSG_DEBUG,
-			   "OCSP: Expected ENUMERATED (responseStatus) - found class %d tag 0x%x length %u",
-			   hdr.class, hdr.tag, hdr.length);
+	    !asn1_is_enumerated(&hdr) || hdr.length != 1) {
+		asn1_unexpected(&hdr,
+				"OCSP: Expected ENUMERATED (responseStatus)");
 		return TLS_OCSP_INVALID;
 	}
 	resp_status = hdr.payload[0];
@@ -730,12 +693,10 @@
 	if (pos == end)
 		return TLS_OCSP_NO_RESPONSE;
 
-	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC ||
-	    hdr.tag != 0) {
-		wpa_printf(MSG_DEBUG,
-			   "OCSP: Expected [0] EXPLICIT (responseBytes) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !hdr.constructed ||
+	    !asn1_is_cs_tag(&hdr, 0)) {
+		asn1_unexpected(&hdr,
+				"OCSP: Expected [0] EXPLICIT (responseBytes)");
 		return TLS_OCSP_INVALID;
 	}
 
@@ -746,11 +707,9 @@
 	 */
 
 	if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG,
-			   "OCSP: Expected SEQUENCE (ResponseBytes) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"OCSP: Expected SEQUENCE (ResponseBytes)");
 		return TLS_OCSP_INVALID;
 	}
 	pos = hdr.payload;
@@ -771,11 +730,8 @@
 
 	/* response       OCTET STRING */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_OCTETSTRING) {
-		wpa_printf(MSG_DEBUG,
-			   "OCSP: Expected OCTET STRING (response) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_octetstring(&hdr)) {
+		asn1_unexpected(&hdr, "OCSP: Expected OCTET STRING (response)");
 		return TLS_OCSP_INVALID;
 	}
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/tls/tlsv1_client_write.c b/src/lynq/packages/thirdpart/lynq-wg870/src/tls/tlsv1_client_write.c
index 4a1147b..9b12618 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/tls/tlsv1_client_write.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/tls/tlsv1_client_write.c
@@ -48,21 +48,9 @@
 	struct os_time now;
 	size_t len, i;
 	u8 *ext_start;
-	u16 tls_version = TLS_VERSION;
+	u16 tls_version = tls_client_highest_ver(conn);
 
-	/* Pick the highest locally enabled TLS version */
-#ifdef CONFIG_TLSV12
-	if ((conn->flags & TLS_CONN_DISABLE_TLSv1_2) &&
-	    tls_version == TLS_VERSION_1_2)
-		tls_version = TLS_VERSION_1_1;
-#endif /* CONFIG_TLSV12 */
-#ifdef CONFIG_TLSV11
-	if ((conn->flags & TLS_CONN_DISABLE_TLSv1_1) &&
-	    tls_version == TLS_VERSION_1_1)
-		tls_version = TLS_VERSION_1;
-#endif /* CONFIG_TLSV11 */
-	if ((conn->flags & TLS_CONN_DISABLE_TLSv1_0) &&
-	    tls_version == TLS_VERSION_1) {
+	if (!tls_version) {
 		wpa_printf(MSG_INFO, "TLSv1: No TLS version allowed");
 		return NULL;
 	}
@@ -474,7 +462,7 @@
 	size_t clen;
 	int res;
 
-	if (tls_derive_pre_master_secret(pre_master_secret) < 0 ||
+	if (tls_derive_pre_master_secret(conn, pre_master_secret) < 0 ||
 	    tls_derive_keys(conn, pre_master_secret,
 			    TLS_PRE_MASTER_SECRET_LEN)) {
 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys");
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/tls/tlsv1_cred.c b/src/lynq/packages/thirdpart/lynq-wg870/src/tls/tlsv1_cred.c
index 01b2f83..1310f4e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/tls/tlsv1_cred.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/tls/tlsv1_cred.c
@@ -455,12 +455,8 @@
 	 * }
 	 */
 
-	if (asn1_get_next(buf, len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #12: Expected SEQUENCE (CertBag) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr, "PKCS #12: Expected SEQUENCE (CertBag)");
 		return -1;
 	}
 
@@ -482,21 +478,17 @@
 			   obuf);
 	}
 
-	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC ||
-	    hdr.tag != 0) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #12: Expected [0] EXPLICIT (certValue) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !hdr.constructed ||
+	    !asn1_is_cs_tag(&hdr, 0)) {
+		asn1_unexpected(&hdr,
+				"PKCS #12: Expected [0] EXPLICIT (certValue)");
 		return -1;
 	}
 
 	if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_OCTETSTRING) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #12: Expected OCTET STRING (x509Certificate) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_octetstring(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #12: Expected OCTET STRING (x509Certificate)");
 		return -1;
 	}
 
@@ -534,11 +526,9 @@
 	 * }
 	 */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_BMPSTRING) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #12: Expected BMPSTRING (friendlyName) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_bmpstring(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #12: Expected BMPSTRING (friendlyName)");
 		return 0;
 	}
 	wpa_hexdump_ascii(MSG_DEBUG, "PKCS #12: friendlyName",
@@ -561,11 +551,9 @@
 	 * }
 	 */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_OCTETSTRING) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #12: Expected OCTET STRING (localKeyID) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_octetstring(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #12: Expected OCTET STRING (localKeyID)");
 		return -1;
 	}
 	wpa_hexdump_key(MSG_DEBUG, "PKCS #12: localKeyID",
@@ -596,12 +584,8 @@
 	asn1_oid_to_str(&a_oid, obuf, sizeof(obuf));
 	wpa_printf(MSG_DEBUG, "PKCS #12: attrId %s", obuf);
 
-	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SET) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #12: Expected SET (attrValues) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !asn1_is_set(&hdr)) {
+		asn1_unexpected(&hdr, "PKCS #12: Expected SET (attrValues)");
 		return -1;
 	}
 	wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: attrValues",
@@ -641,12 +625,10 @@
 	asn1_oid_to_str(&oid, obuf, sizeof(obuf));
 	wpa_printf(MSG_DEBUG, "PKCS #12: BAG-TYPE %s", obuf);
 
-	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC ||
-	    hdr.tag != 0) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #12: Expected [0] EXPLICIT (bagValue) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !hdr.constructed ||
+	    !asn1_is_cs_tag(&hdr, 0)) {
+		asn1_unexpected(&hdr,
+				"PKCS #12: Expected [0] EXPLICIT (bagValue)");
 		return 0;
 	}
 	value = hdr.payload;
@@ -657,11 +639,9 @@
 	if (pos < end) {
 		/* bagAttributes  SET OF PKCS12Attribute OPTIONAL */
 		if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-		    hdr.class != ASN1_CLASS_UNIVERSAL ||
-		    hdr.tag != ASN1_TAG_SET) {
-			wpa_printf(MSG_DEBUG,
-				   "PKCS #12: Expected SET (bagAttributes) - found class %d tag 0x%x",
-				   hdr.class, hdr.tag);
+		    !asn1_is_set(&hdr)) {
+			asn1_unexpected(&hdr,
+					"PKCS #12: Expected SET (bagAttributes)");
 			return -1;
 		}
 		wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: bagAttributes",
@@ -672,11 +652,9 @@
 		while (pos < end) {
 			/* PKCS12Attribute ::= SEQUENCE */
 			if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-			    hdr.class != ASN1_CLASS_UNIVERSAL ||
-			    hdr.tag != ASN1_TAG_SEQUENCE) {
-				wpa_printf(MSG_DEBUG,
-					   "PKCS #12: Expected SEQUENCE (PKCS12Attribute) - found class %d tag 0x%x",
-					   hdr.class, hdr.tag);
+			    !asn1_is_sequence(&hdr)) {
+				asn1_unexpected(&hdr,
+						"PKCS #12: Expected SEQUENCE (PKCS12Attribute)");
 				return -1;
 			}
 			if (pkcs12_parse_attr(hdr.payload, hdr.length) < 0)
@@ -705,12 +683,9 @@
 	const u8 *pos, *end;
 
 	/* SafeContents ::= SEQUENCE OF SafeBag */
-	if (asn1_get_next(buf, len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #12: Expected SEQUENCE (SafeContents) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #12: Expected SEQUENCE (SafeContents)");
 		return -1;
 	}
 	pos = hdr.payload;
@@ -726,11 +701,9 @@
 
 	while (pos < end) {
 		if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-		    hdr.class != ASN1_CLASS_UNIVERSAL ||
-		    hdr.tag != ASN1_TAG_SEQUENCE) {
-			wpa_printf(MSG_DEBUG,
-				   "PKCS #12: Expected SEQUENCE (SafeBag) - found class %d tag 0x%x",
-				   hdr.class, hdr.tag);
+		    !asn1_is_sequence(&hdr)) {
+			asn1_unexpected(&hdr,
+					"PKCS #12: Expected SEQUENCE (SafeBag)");
 			return -1;
 		}
 		if (pkcs12_safebag(cred, hdr.payload, hdr.length, passwd) < 0)
@@ -750,11 +723,8 @@
 
 	/* Data ::= OCTET STRING */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_OCTETSTRING) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #12: Expected OCTET STRING (Data) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_octetstring(&hdr)) {
+		asn1_unexpected(&hdr, "PKCS #12: Expected OCTET STRING (Data)");
 		return -1;
 	}
 
@@ -782,21 +752,17 @@
 	 *   encryptedContentInfo EncryptedContentInfo }
 	 */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #12: Expected SEQUENCE (EncryptedData) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #12: Expected SEQUENCE (EncryptedData)");
 		return 0;
 	}
 	pos = hdr.payload;
 
 	/* Version ::= INTEGER */
-	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_INTEGER) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #12: No INTEGER tag found for version; class=%d tag=0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !asn1_is_integer(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #12: No INTEGER tag found for version");
 		return -1;
 	}
 	if (hdr.length != 1 || hdr.payload[0] != 0) {
@@ -815,11 +781,9 @@
 	 *   encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL }
 	 */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #12: Expected SEQUENCE (EncryptedContentInfo) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #12: Expected SEQUENCE (EncryptedContentInfo)");
 		return -1;
 	}
 
@@ -845,22 +809,19 @@
 
 	/* ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG, "PKCS #12: Expected SEQUENCE (ContentEncryptionAlgorithmIdentifier) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #12: Expected SEQUENCE (ContentEncryptionAlgorithmIdentifier)");
 		return -1;
 	}
 	enc_alg = hdr.payload;
 	enc_alg_len = hdr.length;
 	pos = hdr.payload + hdr.length;
 
-	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC ||
-	    hdr.tag != 0) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #12: Expected [0] IMPLICIT (encryptedContent) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, end - pos, &hdr) < 0 || hdr.constructed ||
+	    !asn1_is_cs_tag(&hdr, 0)) {
+		asn1_unexpected(&hdr,
+				"PKCS #12: Expected [0] IMPLICIT (encryptedContent)");
 		return -1;
 	}
 
@@ -900,12 +861,10 @@
 	asn1_oid_to_str(&oid, txt, sizeof(txt));
 	wpa_printf(MSG_DEBUG, "PKCS #12: contentType %s", txt);
 
-	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC ||
-	    hdr.tag != 0) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #12: Expected [0] EXPLICIT (content) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !hdr.constructed ||
+	    !asn1_is_cs_tag(&hdr, 0)) {
+		asn1_unexpected(&hdr,
+				"PKCS #12: Expected [0] EXPLICIT (content)");
 		return 0;
 	}
 	pos = hdr.payload;
@@ -938,23 +897,18 @@
 	 * }
 	 */
 
-	if (asn1_get_next(key, len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #12: Expected SEQUENCE (PFX) - found class %d tag 0x%x; assume PKCS #12 not used",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(key, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #12: Expected SEQUENCE (PFX); assume PKCS #12 not used");
 		return -1;
 	}
 
 	pos = hdr.payload;
 	end = pos + hdr.length;
 
-	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_INTEGER) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #12: No INTEGER tag found for version; class=%d tag=0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !asn1_is_integer(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #12: No INTEGER tag found for version");
 		return -1;
 	}
 	if (hdr.length != 1 || hdr.payload[0] != 3) {
@@ -970,11 +924,9 @@
 	 */
 
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #12: Expected SEQUENCE (authSafe) - found class %d tag 0x%x; assume PKCS #12 not used",
-			   hdr.class, hdr.tag);
+	    !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #12: Expected SEQUENCE (authSafe); assume PKCS #12 not used");
 		return -1;
 	}
 
@@ -995,12 +947,10 @@
 		return -1;
 	}
 
-	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC ||
-	    hdr.tag != 0) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #12: Expected [0] EXPLICIT (content) - found class %d tag 0x%x; assume PKCS #12 not used",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, end - pos, &hdr) < 0 || !hdr.constructed ||
+	    !asn1_is_cs_tag(&hdr, 0)) {
+		asn1_unexpected(&hdr,
+				"PKCS #12: Expected [0] EXPLICIT (content); assume PKCS #12 not used");
 		return -1;
 	}
 
@@ -1008,11 +958,9 @@
 
 	/* Data ::= OCTET STRING */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_OCTETSTRING) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #12: Expected OCTET STRING (Data) - found class %d tag 0x%x; assume PKCS #12 not used",
-			   hdr.class, hdr.tag);
+	    !asn1_is_octetstring(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #12: Expected OCTET STRING (Data); assume PKCS #12 not used");
 		return -1;
 	}
 
@@ -1026,11 +974,9 @@
 		    hdr.payload, hdr.length);
 
 	if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG,
-			   "PKCS #12: Expected SEQUENCE within Data content - found class %d tag 0x%x; assume PKCS #12 not used",
-			   hdr.class, hdr.tag);
+	    !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"PKCS #12: Expected SEQUENCE within Data content; assume PKCS #12 not used");
 		return -1;
 	}
 
@@ -1039,11 +985,9 @@
 
 	while (end > pos) {
 		if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-		    hdr.class != ASN1_CLASS_UNIVERSAL ||
-		    hdr.tag != ASN1_TAG_SEQUENCE) {
-			wpa_printf(MSG_DEBUG,
-				   "PKCS #12: Expected SEQUENCE (ContentInfo) - found class %d tag 0x%x; assume PKCS #12 not used",
-				   hdr.class, hdr.tag);
+		    !asn1_is_sequence(&hdr)) {
+			asn1_unexpected(&hdr,
+					"PKCS #12: Expected SEQUENCE (ContentInfo); assume PKCS #12 not used");
 			return -1;
 		}
 		if (pkcs12_parse_content(cred, hdr.payload, hdr.length,
@@ -1141,24 +1085,17 @@
 	 */
 
 	/* DHParamer ::= SEQUENCE */
-	if (asn1_get_next(pos, len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG, "DH: DH parameters did not start with a "
-			   "valid SEQUENCE - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"DH: DH parameters did not start with a valid SEQUENCE");
 		return -1;
 	}
 	pos = hdr.payload;
 
 	/* prime INTEGER */
-	if (asn1_get_next(pos, end - pos, &hdr) < 0)
-		return -1;
-
-	if (hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_INTEGER) {
-		wpa_printf(MSG_DEBUG, "DH: No INTEGER tag found for p; "
-			   "class=%d tag=0x%x", hdr.class, hdr.tag);
+	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
+	    !asn1_is_integer(&hdr)) {
+		asn1_unexpected(&hdr, "DH: No INTEGER tag found for p");
 		return -1;
 	}
 
@@ -1173,13 +1110,9 @@
 	pos = hdr.payload + hdr.length;
 
 	/* base INTEGER */
-	if (asn1_get_next(pos, end - pos, &hdr) < 0)
-		return -1;
-
-	if (hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_INTEGER) {
-		wpa_printf(MSG_DEBUG, "DH: No INTEGER tag found for g; "
-			   "class=%d tag=0x%x", hdr.class, hdr.tag);
+	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
+	    !asn1_is_integer(&hdr)) {
+		asn1_unexpected(&hdr, "DH: No INTEGER tag found for g");
 		return -1;
 	}
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/tls/x509v3.c b/src/lynq/packages/thirdpart/lynq-wg870/src/tls/x509v3.c
index d2e685c..b006e99 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/tls/x509v3.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/tls/x509v3.c
@@ -192,12 +192,9 @@
 	 * }
 	 */
 
-	if (asn1_get_next(buf, len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
-			   "(AlgorithmIdentifier) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"X509: Expected SEQUENCE (AlgorithmIdentifier)");
 		return -1;
 	}
 	if (hdr.length > buf + len - hdr.payload)
@@ -234,11 +231,9 @@
 	end = buf + len;
 
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
-			   "(SubjectPublicKeyInfo) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"X509: Expected SEQUENCE (SubjectPublicKeyInfo)");
 		return -1;
 	}
 	pos = hdr.payload;
@@ -253,11 +248,9 @@
 		return -1;
 
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_BITSTRING) {
-		wpa_printf(MSG_DEBUG, "X509: Expected BITSTRING "
-			   "(subjectPublicKey) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_bitstring(&hdr)) {
+		asn1_unexpected(&hdr,
+				"X509: Expected BITSTRING (subjectPublicKey)");
 		return -1;
 	}
 	if (hdr.length < 1)
@@ -309,12 +302,9 @@
 	 * AttributeValue ::= ANY DEFINED BY AttributeType
 	 */
 
-	if (asn1_get_next(buf, len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
-			   "(Name / RDNSequencer) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"X509: Expected SEQUENCE (Name / RDNSequencer)");
 		return -1;
 	}
 	pos = hdr.payload;
@@ -328,11 +318,9 @@
 		enum x509_name_attr_type type;
 
 		if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-		    hdr.class != ASN1_CLASS_UNIVERSAL ||
-		    hdr.tag != ASN1_TAG_SET) {
-			wpa_printf(MSG_DEBUG, "X509: Expected SET "
-				   "(RelativeDistinguishedName) - found class "
-				   "%d tag 0x%x", hdr.class, hdr.tag);
+		    !asn1_is_set(&hdr)) {
+			asn1_unexpected(&hdr,
+					"X509: Expected SET (RelativeDistinguishedName)");
 			x509_free_name(name);
 			return -1;
 		}
@@ -341,11 +329,9 @@
 		pos = set_end = hdr.payload + hdr.length;
 
 		if (asn1_get_next(set_pos, set_end - set_pos, &hdr) < 0 ||
-		    hdr.class != ASN1_CLASS_UNIVERSAL ||
-		    hdr.tag != ASN1_TAG_SEQUENCE) {
-			wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
-				   "(AttributeTypeAndValue) - found class %d "
-				   "tag 0x%x", hdr.class, hdr.tag);
+		    !asn1_is_sequence(&hdr)) {
+			asn1_unexpected(&hdr,
+					"X509: Expected SEQUENCE (AttributeTypeAndValue)");
 			x509_free_name(name);
 			return -1;
 		}
@@ -366,6 +352,13 @@
 			return -1;
 		}
 
+		if (!asn1_is_string_type(&hdr)) {
+			wpa_printf(MSG_DEBUG,
+				   "X509: Ignore non-string type attribute (tag 0x%x)",
+				   hdr.tag);
+			continue;
+		}
+
 		/* RFC 3280:
 		 * MUST: country, organization, organizational-unit,
 		 * distinguished name qualifier, state or province name,
@@ -709,12 +702,8 @@
 	 * validity dates in 2050 or later MUST be encoded as GeneralizedTime.
 	 */
 
-	if (asn1_get_next(buf, len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
-			   "(Validity) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr, "X509: Expected SEQUENCE (Validity)");
 		return -1;
 	}
 	pos = hdr.payload;
@@ -726,7 +715,7 @@
 	*next = pos + plen;
 
 	if (asn1_get_next(pos, plen, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
+	    (!asn1_is_utctime(&hdr) && !asn1_is_generalizedtime(&hdr)) ||
 	    x509_parse_time(hdr.payload, hdr.length, hdr.tag,
 			    &cert->not_before) < 0) {
 		wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse notBefore "
@@ -738,7 +727,7 @@
 	plen = *next - pos;
 
 	if (asn1_get_next(pos, plen, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
+	    (!asn1_is_utctime(&hdr) && !asn1_is_generalizedtime(&hdr)) ||
 	    x509_parse_time(hdr.payload, hdr.length, hdr.tag,
 			    &cert->not_after) < 0) {
 		wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to parse notAfter "
@@ -791,13 +780,9 @@
 	 *     decipherOnly            (8) }
 	 */
 
-	if (asn1_get_next(pos, len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_BITSTRING ||
+	if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_bitstring(&hdr) ||
 	    hdr.length < 1) {
-		wpa_printf(MSG_DEBUG, "X509: Expected BIT STRING in "
-			   "KeyUsage; found %d tag 0x%x len %d",
-			   hdr.class, hdr.tag, hdr.length);
+		asn1_unexpected(&hdr, "X509: Expected BIT STRING in KeyUsage");
 		return -1;
 	}
 
@@ -824,12 +809,9 @@
 	 * pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
 	 */
 
-	if (asn1_get_next(pos, len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE in "
-			   "BasicConstraints; found %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"X509: Expected SEQUENCE in BasicConstraints");
 		return -1;
 	}
 
@@ -839,14 +821,13 @@
 		return 0;
 
 	end_seq = hdr.payload + hdr.length;
-	if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL) {
+	if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0) {
 		wpa_printf(MSG_DEBUG, "X509: Failed to parse "
 			   "BasicConstraints");
 		return -1;
 	}
 
-	if (hdr.tag == ASN1_TAG_BOOLEAN) {
+	if (asn1_is_boolean(&hdr)) {
 		cert->ca = hdr.payload[0];
 
 		pos = hdr.payload + hdr.length;
@@ -856,18 +837,16 @@
 				   cert->ca);
 			return 0;
 		}
-		if (asn1_get_next(pos, end_seq - pos, &hdr) < 0 ||
-		    hdr.class != ASN1_CLASS_UNIVERSAL) {
+		if (asn1_get_next(pos, end_seq - pos, &hdr) < 0) {
 			wpa_printf(MSG_DEBUG, "X509: Failed to parse "
 				   "BasicConstraints");
 			return -1;
 		}
 	}
 
-	if (hdr.tag != ASN1_TAG_INTEGER) {
-		wpa_printf(MSG_DEBUG, "X509: Expected INTEGER in "
-			   "BasicConstraints; found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (!asn1_is_integer(&hdr)) {
+		asn1_unexpected(&hdr,
+				"X509: Expected INTEGER in BasicConstraints");
 		return -1;
 	}
 
@@ -1074,12 +1053,9 @@
 
 	/* SubjectAltName ::= GeneralNames */
 
-	if (asn1_get_next(pos, len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE in "
-			   "SubjectAltName; found %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"X509: Expected SEQUENCE in SubjectAltName");
 		return -1;
 	}
 
@@ -1101,12 +1077,9 @@
 
 	/* IssuerAltName ::= GeneralNames */
 
-	if (asn1_get_next(pos, len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE in "
-			   "IssuerAltName; found %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"X509: Expected SEQUENCE in IssuerAltName");
 		return -1;
 	}
 
@@ -1187,11 +1160,9 @@
 	 * CertPolicyId ::= OBJECT IDENTIFIER
 	 */
 
-	if (asn1_get_next(pos, len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE (certificatePolicies) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"X509: Expected SEQUENCE (certificatePolicies)");
 		return -1;
 	}
 	if (hdr.length > pos + len - hdr.payload)
@@ -1207,10 +1178,9 @@
 		char buf[80];
 
 		if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-		    hdr.class != ASN1_CLASS_UNIVERSAL ||
-		    hdr.tag != ASN1_TAG_SEQUENCE) {
-			wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE (PolicyInformation) - found class %d tag 0x%x",
-				   hdr.class, hdr.tag);
+		    !asn1_is_sequence(&hdr)) {
+			asn1_unexpected(&hdr,
+					"X509: Expected SEQUENCE (PolicyInformation)");
 			return -1;
 		}
 		if (hdr.length > end - hdr.payload)
@@ -1310,12 +1280,9 @@
 	 * KeyPurposeId ::= OBJECT IDENTIFIER
 	 */
 
-	if (asn1_get_next(pos, len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
-			   "(ExtKeyUsageSyntax) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"X509: Expected SEQUENCE (ExtKeyUsageSyntax)");
 		return -1;
 	}
 	if (hdr.length > pos + len - hdr.payload)
@@ -1402,12 +1369,8 @@
 	 * }
 	 */
 
-	if (asn1_get_next(pos, len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 header in "
-			   "Extensions: class %d tag 0x%x; expected SEQUENCE",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr, "X509: Expected SEQUENCE in Extensions");
 		return -1;
 	}
 	pos = hdr.payload;
@@ -1420,26 +1383,27 @@
 	}
 
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    (hdr.tag != ASN1_TAG_BOOLEAN &&
-	     hdr.tag != ASN1_TAG_OCTETSTRING)) {
-		wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 header in "
-			   "Extensions: class %d tag 0x%x; expected BOOLEAN "
-			   "or OCTET STRING", hdr.class, hdr.tag);
+	    (!asn1_is_boolean(&hdr) && !asn1_is_octetstring(&hdr))) {
+		asn1_unexpected(&hdr,
+				"X509: Expected BOOLEAN or OCTETSTRING in Extensions");
 		return -1;
 	}
 
 	if (hdr.tag == ASN1_TAG_BOOLEAN) {
 		critical_ext = hdr.payload[0];
 		pos = hdr.payload;
+		/*
+		 * Number of CA certificates seem to be using Private class in
+		 * one of the X.509v3 extensions, so let's accept that instead
+		 * of rejecting the certificate. asn1_is_octetstring() covers
+		 * the more common case.
+		 */
 		if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-		    (hdr.class != ASN1_CLASS_UNIVERSAL &&
-		     hdr.class != ASN1_CLASS_PRIVATE) ||
-		    hdr.tag != ASN1_TAG_OCTETSTRING) {
-			wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 header "
-				   "in Extensions: class %d tag 0x%x; "
-				   "expected OCTET STRING",
-				   hdr.class, hdr.tag);
+		    (!asn1_is_octetstring(&hdr) &&
+		     !(hdr.class == ASN1_CLASS_PRIVATE &&
+		       hdr.tag == ASN1_TAG_OCTETSTRING))) {
+			asn1_unexpected(&hdr,
+					"X509: Expected OCTETSTRING in Extensions");
 			return -1;
 		}
 	}
@@ -1470,12 +1434,8 @@
 
 	/* Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension */
 
-	if (asn1_get_next(pos, len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG, "X509: Unexpected ASN.1 data "
-			   "for Extensions: class %d tag 0x%x; "
-			   "expected SEQUENCE", hdr.class, hdr.tag);
+	if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr, "X509: Expected SEQUENCE for Extensions");
 		return -1;
 	}
 
@@ -1504,12 +1464,9 @@
 	const u8 *subject_dn;
 
 	/* tbsCertificate TBSCertificate ::= SEQUENCE */
-	if (asn1_get_next(buf, len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG, "X509: tbsCertificate did not start "
-			   "with a valid SEQUENCE - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"X509: tbsCertificate did not start with a valid SEQUENCE");
 		return -1;
 	}
 	pos = hdr.payload;
@@ -1523,15 +1480,11 @@
 		return -1;
 	pos = hdr.payload;
 
-	if (hdr.class == ASN1_CLASS_CONTEXT_SPECIFIC) {
-		if (asn1_get_next(pos, end - pos, &hdr) < 0)
-			return -1;
-
-		if (hdr.class != ASN1_CLASS_UNIVERSAL ||
-		    hdr.tag != ASN1_TAG_INTEGER) {
-			wpa_printf(MSG_DEBUG, "X509: No INTEGER tag found for "
-				   "version field - found class %d tag 0x%x",
-				   hdr.class, hdr.tag);
+	if (asn1_is_cs_tag(&hdr, 0) && hdr.constructed) {
+		if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
+		    !asn1_is_integer(&hdr)) {
+			asn1_unexpected(&hdr,
+					"X509: No INTEGER tag found for version field");
 			return -1;
 		}
 		if (hdr.length != 1) {
@@ -1564,12 +1517,10 @@
 	wpa_printf(MSG_MSGDUMP, "X509: Version X.509v%d", cert->version + 1);
 
 	/* serialNumber CertificateSerialNumber ::= INTEGER */
-	if (hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_INTEGER ||
+	if (!asn1_is_integer(&hdr) ||
 	    hdr.length < 1 || hdr.length > X509_MAX_SERIAL_NUM_LEN) {
-		wpa_printf(MSG_DEBUG, "X509: No INTEGER tag found for "
-			   "serialNumber; class=%d tag=0x%x length=%u",
-			   hdr.class, hdr.tag, hdr.length);
+		asn1_unexpected(&hdr,
+				"X509: No INTEGER tag found for serialNumber");
 		return -1;
 	}
 
@@ -1622,10 +1573,8 @@
 
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
 	    hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
-		wpa_printf(MSG_DEBUG, "X509: Expected Context-Specific"
-			   " tag to parse optional tbsCertificate "
-			   "field(s); parsed class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+		asn1_unexpected(&hdr,
+				"X509: Expected Context-Specific tag to parse optional tbsCertificate field(s)");
 		return -1;
 	}
 
@@ -1640,10 +1589,8 @@
 
 		if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
 		    hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
-			wpa_printf(MSG_DEBUG, "X509: Expected Context-Specific"
-				   " tag to parse optional tbsCertificate "
-				   "field(s); parsed class %d tag 0x%x",
-				   hdr.class, hdr.tag);
+			asn1_unexpected(&hdr,
+					"X509: Expected Context-Specific tag to parse optional tbsCertificate field(s)");
 			return -1;
 		}
 	}
@@ -1659,18 +1606,16 @@
 
 		if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
 		    hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
-			wpa_printf(MSG_DEBUG, "X509: Expected Context-Specific"
-				   " tag to parse optional tbsCertificate "
-				   "field(s); parsed class %d tag 0x%x",
-				   hdr.class, hdr.tag);
+			asn1_unexpected(&hdr,
+					"X509: Expected Context-Specific tag to parse optional tbsCertificate field(s)");
 			return -1;
 		}
 	}
 
 	if (hdr.tag != 3) {
-		wpa_printf(MSG_DEBUG, "X509: Ignored unexpected "
-			   "Context-Specific tag %d in optional "
-			   "tbsCertificate fields", hdr.tag);
+		wpa_printf(MSG_DEBUG,
+			   "X509: Ignored unexpected Context-Specific constructed %d tag %d in optional tbsCertificate fields",
+			   hdr.constructed, hdr.tag);
 		return 0;
 	}
 
@@ -1798,12 +1743,9 @@
 	/* RFC 3280 - X.509 v3 certificate / ASN.1 DER */
 
 	/* Certificate ::= SEQUENCE */
-	if (asn1_get_next(pos, len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG, "X509: Certificate did not start with "
-			   "a valid SEQUENCE - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"X509: Certificate did not start with a valid SEQUENCE");
 		x509_certificate_free(cert);
 		return NULL;
 	}
@@ -1838,11 +1780,9 @@
 
 	/* signatureValue BIT STRING */
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_BITSTRING) {
-		wpa_printf(MSG_DEBUG, "X509: Expected BITSTRING "
-			   "(signatureValue) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_bitstring(&hdr)) {
+		asn1_unexpected(&hdr,
+				"X509: Expected BITSTRING (signatureValue)");
 		x509_certificate_free(cert);
 		return NULL;
 	}
@@ -1956,14 +1896,12 @@
 	 *
 	 */
 	if (asn1_get_next(data, data_len, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
-			   "(DigestInfo) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr, "X509: Expected SEQUENCE (DigestInfo)");
 		os_free(data);
 		return -1;
 	}
+	wpa_hexdump(MSG_MSGDUMP, "X509: DigestInfo", hdr.payload, hdr.length);
 
 	pos = hdr.payload;
 	end = pos + hdr.length;
@@ -1977,14 +1915,14 @@
 	 */
 
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_SEQUENCE) {
-		wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE "
-			   "(AlgorithmIdentifier) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_sequence(&hdr)) {
+		asn1_unexpected(&hdr,
+				"X509: Expected SEQUENCE (AlgorithmIdentifier)");
 		os_free(data);
 		return -1;
 	}
+	wpa_hexdump(MSG_MSGDUMP, "X509: DigestAlgorithmIdentifier",
+		    hdr.payload, hdr.length);
 	da_end = hdr.payload + hdr.length;
 
 	if (asn1_get_oid(hdr.payload, hdr.length, &oid, &next)) {
@@ -1992,6 +1930,23 @@
 		os_free(data);
 		return -1;
 	}
+	wpa_hexdump(MSG_MSGDUMP, "X509: Digest algorithm parameters",
+		    next, da_end - next);
+
+	/*
+	 * RFC 5754: The correct encoding for the SHA2 algorithms would be to
+	 * omit the parameters, but there are implementation that encode these
+	 * as a NULL element. Allow these two cases and reject anything else.
+	 */
+	if (da_end > next &&
+	    (asn1_get_next(next, da_end - next, &hdr) < 0 ||
+	     !asn1_is_null(&hdr) ||
+	     hdr.payload + hdr.length != da_end)) {
+		wpa_printf(MSG_DEBUG,
+			   "X509: Unexpected digest algorithm parameters");
+		os_free(data);
+		return -1;
+	}
 
 	if (x509_sha1_oid(&oid)) {
 		if (signature->oid.oid[6] != 5 /* sha-1WithRSAEncryption */) {
@@ -2070,14 +2025,10 @@
 skip_digest_oid:
 	/* Digest ::= OCTET STRING */
 	pos = da_end;
-	end = data + data_len;
 
 	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
-	    hdr.class != ASN1_CLASS_UNIVERSAL ||
-	    hdr.tag != ASN1_TAG_OCTETSTRING) {
-		wpa_printf(MSG_DEBUG, "X509: Expected OCTETSTRING "
-			   "(Digest) - found class %d tag 0x%x",
-			   hdr.class, hdr.tag);
+	    !asn1_is_octetstring(&hdr)) {
+		asn1_unexpected(&hdr, "X509: Expected OCTETSTRING (Digest)");
 		os_free(data);
 		return -1;
 	}
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/Makefile b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/Makefile
index e8ad997..d995b81 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/Makefile
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/Makefile
@@ -6,6 +6,7 @@
 	base64.o \
 	bitfield.o \
 	common.o \
+	config.o \
 	crc32.o \
 	ip_addr.o \
 	json.o \
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/common.h b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/common.h
index 8fc3c9e..2e3e205 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/common.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/common.h
@@ -341,6 +341,11 @@
 #ifndef ETH_P_RRB
 #define ETH_P_RRB 0x890D
 #endif /* ETH_P_RRB */
+#if defined(WAPI_ANDROID)
+#ifndef ETH_HLEN
+#define ETH_HLEN 14
+#endif /* ETH_HLEN */
+#endif 
 #ifndef ETH_P_OUI
 #define ETH_P_OUI 0x88B7
 #endif /* ETH_P_OUI */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/config.c b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/config.c
new file mode 100755
index 0000000..ba26c2c
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/config.c
@@ -0,0 +1,105 @@
+/*
+ * Configuration parsing
+ * Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "includes.h"
+
+#include "utils/config.h"
+#include "common.h"
+
+
+static int newline_terminated(const char *buf, size_t buflen)
+{
+	size_t len = os_strlen(buf);
+	if (len == 0)
+		return 0;
+	if (len == buflen - 1 && buf[buflen - 1] != '\r' &&
+	    buf[len - 1] != '\n')
+		return 0;
+	return 1;
+}
+
+
+static void skip_line_end(FILE *stream)
+{
+	char buf[100];
+	while (fgets(buf, sizeof(buf), stream)) {
+		buf[sizeof(buf) - 1] = '\0';
+		if (newline_terminated(buf, sizeof(buf)))
+			return;
+	}
+}
+
+
+char * wpa_config_get_line(char *s, int size, FILE *stream, int *line,
+			   char **_pos)
+{
+	char *pos, *end, *sstart;
+
+	while (fgets(s, size, stream)) {
+		(*line)++;
+		s[size - 1] = '\0';
+		if (!newline_terminated(s, size)) {
+			/*
+			 * The line was truncated - skip rest of it to avoid
+			 * confusing error messages.
+			 */
+			wpa_printf(MSG_INFO, "Long line in configuration file "
+				   "truncated");
+			skip_line_end(stream);
+		}
+		pos = s;
+
+		/* Skip white space from the beginning of line. */
+		while (*pos == ' ' || *pos == '\t' || *pos == '\r')
+			pos++;
+
+		/* Skip comment lines and empty lines */
+		if (*pos == '#' || *pos == '\n' || *pos == '\0')
+			continue;
+
+		/*
+		 * Remove # comments unless they are within a double quoted
+		 * string.
+		 */
+		sstart = pos;
+		end = os_strchr(sstart, '#');
+		while (end) {
+			sstart = os_strchr(sstart, '"');
+			if (!sstart || sstart > end)
+				break;
+			sstart = os_strchr(sstart + 1, '"');
+			if (!sstart)
+				break;
+			sstart++;
+			if (sstart > end)
+				end = os_strchr(sstart, '#');
+		}
+
+		if (end)
+			*end-- = '\0';
+		else
+			end = pos + os_strlen(pos) - 1;
+
+		/* Remove trailing white space. */
+		while (end > pos &&
+		       (*end == '\n' || *end == ' ' || *end == '\t' ||
+			*end == '\r'))
+			*end-- = '\0';
+
+		if (*pos == '\0')
+			continue;
+
+		if (_pos)
+			*_pos = pos;
+		return pos;
+	}
+
+	if (_pos)
+		*_pos = NULL;
+	return NULL;
+}
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/config.h b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/config.h
new file mode 100755
index 0000000..074a88a
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/config.h
@@ -0,0 +1,29 @@
+/*
+ * Configuration parsing
+ * Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef UTILS_CONFIG_H
+#define UTILS_CONFIG_H
+
+/**
+ * wpa_config_get_line - Read the next configuration file line
+ * @s: Buffer for the line
+ * @size: The buffer length
+ * @stream: File stream to read from
+ * @line: Pointer to a variable storing the file line number
+ * @_pos: Buffer for the pointer to the beginning of data on the text line or
+ * %NULL if not needed (returned value used instead)
+ * Returns: Pointer to the beginning of data on the text line or %NULL if no
+ * more text lines are available.
+ *
+ * This function reads the next non-empty line from the configuration file and
+ * removes comments. The returned string is guaranteed to be null-terminated.
+ */
+char * wpa_config_get_line(char *s, int size, FILE *stream, int *line,
+			   char **_pos);
+
+#endif /* UTILS_CONFIG_H */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/eloop.c b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/eloop.c
index c05c418..ddb16b3 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/eloop.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/eloop.c
@@ -75,6 +75,9 @@
 };
 
 struct eloop_data {
+#if defined(WAPI_ANDROID)
+        void *user_data;
+#endif 
 	int max_sock;
 
 	size_t count; /* sum of all table counts */
@@ -163,6 +166,9 @@
 int eloop_init(void)
 {
 	os_memset(&eloop, 0, sizeof(eloop));
+#if defined(WAPI_ANDROID)
+        eloop.user_data = user_data;
+#endif 
 	dl_list_init(&eloop.timeout);
 #ifdef CONFIG_ELOOP_EPOLL
 	eloop.epollfd = epoll_create1(0);
@@ -785,21 +791,15 @@
 	}
 	now_sec = timeout->time.sec;
 	timeout->time.sec += secs;
-	if (timeout->time.sec < now_sec) {
-		/*
-		 * Integer overflow - assume long enough timeout to be assumed
-		 * to be infinite, i.e., the timeout would never happen.
-		 */
-		wpa_printf(MSG_DEBUG, "ELOOP: Too long timeout (secs=%u) to "
-			   "ever happen - ignore it", secs);
-		os_free(timeout);
-		return 0;
-	}
+	if (timeout->time.sec < now_sec)
+		goto overflow;
 	timeout->time.usec += usecs;
 	while (timeout->time.usec >= 1000000) {
 		timeout->time.sec++;
 		timeout->time.usec -= 1000000;
 	}
+	if (timeout->time.sec < now_sec)
+		goto overflow;
 	timeout->eloop_data = eloop_data;
 	timeout->user_data = user_data;
 	timeout->handler = handler;
@@ -817,6 +817,17 @@
 	dl_list_add_tail(&eloop.timeout, &timeout->list);
 
 	return 0;
+
+overflow:
+	/*
+	 * Integer overflow - assume long enough timeout to be assumed
+	 * to be infinite, i.e., the timeout would never happen.
+	 */
+	wpa_printf(MSG_DEBUG,
+		   "ELOOP: Too long timeout (secs=%u usecs=%u) to ever happen - ignore it",
+		   secs,usecs);
+	os_free(timeout);
+	return 0;
 }
 
 
@@ -1348,6 +1359,12 @@
 	close(kfd);
 #endif /* CONFIG_ELOOP_KQUEUE */
 }
+#if defined(WAPI_ANDROID)
+void * eloop_get_user_data(void)
+{
+        return eloop.user_data;
+}
+#endif 
 
 #ifdef CONFIG_ELOOP_SELECT
 #undef CONFIG_ELOOP_SELECT
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/eloop.h b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/eloop.h
index 04ee6d1..274ffde 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/eloop.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/eloop.h
@@ -17,6 +17,9 @@
 #ifndef ELOOP_H
 #define ELOOP_H
 
+#if defined(WAPI_ANDROID)
+#include "wapi_config.h"
+#endif 
 /**
  * ELOOP_ALL_CTX - eloop_cancel_timeout() magic number to match all timeouts
  */
@@ -363,5 +366,12 @@
  * Do a blocking wait for a single read socket.
  */
 void eloop_wait_for_read_sock(int sock);
+#if defined(WAPI_ANDROID)
+/**
+ *  * eloop_get_user_data - Get global user data
+ *   * Returns: user_data pointer that was registered with eloop_init()
+ *    */
+void * eloop_get_user_data(void);
+#endif 
 
 #endif /* ELOOP_H */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/ext_password.c b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/ext_password.c
index 5615bd7..cbf92de 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/ext_password.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/ext_password.c
@@ -20,6 +20,9 @@
 #ifdef CONFIG_EXT_PASSWORD_TEST
 	&ext_password_test,
 #endif /* CONFIG_EXT_PASSWORD_TEST */
+#ifdef CONFIG_EXT_PASSWORD_FILE
+	&ext_password_file,
+#endif /* CONFIG_EXT_PASSWORD_FILE */
 	NULL
 };
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/ext_password_file.c b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/ext_password_file.c
new file mode 100755
index 0000000..4bb0095
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/ext_password_file.c
@@ -0,0 +1,136 @@
+/*
+ * External backend for file-backed passwords
+ * Copyright (c) 2021, Patrick Steinhardt <ps@pks.im>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "includes.h"
+
+#include "utils/common.h"
+#include "utils/config.h"
+#include "ext_password_i.h"
+
+
+/**
+ * Data structure for the file-backed password backend.
+ */
+struct ext_password_file_data {
+	char *path; /* path of the password file */
+};
+
+
+/**
+ * ext_password_file_init - Initialize file-backed password backend
+ * @params: Parameters passed by the user.
+ * Returns: Pointer to the initialized backend.
+ *
+ * This function initializes a new file-backed password backend. The user is
+ * expected to initialize this backend with the parameters being the path of
+ * the file that contains the passwords.
+ */
+static void * ext_password_file_init(const char *params)
+{
+	struct ext_password_file_data *data;
+
+	if (!params) {
+		wpa_printf(MSG_ERROR, "EXT PW FILE: no path given");
+		return NULL;
+	}
+
+	data = os_zalloc(sizeof(*data));
+	if (!data)
+		return NULL;
+
+	data->path = os_strdup(params);
+	if (!data->path) {
+		os_free(data);
+		return NULL;
+	}
+
+	return data;
+}
+
+
+/**
+ * ext_password_file_deinit - Deinitialize file-backed password backend
+ * @ctx: The file-backed password backend
+ *
+ * This function frees all data associated with the file-backed password
+ * backend.
+ */
+static void ext_password_file_deinit(void *ctx)
+{
+	struct ext_password_file_data *data = ctx;
+
+	str_clear_free(data->path);
+	os_free(data);
+}
+
+/**
+ * ext_password_file_get - Retrieve password from the file-backed password backend
+ * @ctx: The file-backed password backend
+ * @name: Name of the password to retrieve
+ * Returns: Buffer containing the password if one was found or %NULL.
+ *
+ * This function tries to find a password identified by name in the password
+ * file. The password is expected to be stored in `NAME=PASSWORD` format.
+ * Comments and empty lines in the file are ignored. Invalid lines will cause
+ * an error message, but will not cause the function to fail.
+ */
+static struct wpabuf * ext_password_file_get(void *ctx, const char *name)
+{
+	struct ext_password_file_data *data = ctx;
+	struct wpabuf *password = NULL;
+	char buf[512], *pos;
+	int line = 0;
+	FILE *f;
+
+	f = fopen(data->path, "r");
+	if (!f) {
+		wpa_printf(MSG_ERROR,
+			   "EXT PW FILE: could not open file '%s': %s",
+			   data->path, strerror(errno));
+		return NULL;
+	}
+
+	wpa_printf(MSG_DEBUG, "EXT PW FILE: get(%s)", name);
+
+	while (wpa_config_get_line(buf, sizeof(buf), f, &line, &pos)) {
+		char *sep = os_strchr(pos, '=');
+
+		if (!sep) {
+			wpa_printf(MSG_ERROR, "Invalid password line %d.",
+				   line);
+			continue;
+		}
+
+		if (!sep[1]) {
+			wpa_printf(MSG_ERROR, "No password for line %d.", line);
+			continue;
+
+		}
+
+		if (os_strncmp(name, pos, sep - pos) != 0)
+			continue;
+
+		password = wpabuf_alloc_copy(sep + 1, os_strlen(sep + 1));
+		goto done;
+	}
+
+	wpa_printf(MSG_ERROR, "Password for '%s' was not found.", name);
+
+done:
+	forced_memzero(buf, sizeof(buf));
+	fclose(f);
+	return password;
+}
+
+
+const struct ext_password_backend ext_password_file = {
+	.name = "file",
+	.init = ext_password_file_init,
+	.deinit = ext_password_file_deinit,
+	.get = ext_password_file_get,
+};
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/ext_password_i.h b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/ext_password_i.h
index 948eaf5..872ccd1 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/ext_password_i.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/ext_password_i.h
@@ -26,4 +26,8 @@
 extern const struct ext_password_backend ext_password_test;
 #endif /* CONFIG_EXT_PASSWORD_TEST */
 
+#ifdef CONFIG_EXT_PASSWORD_FILE
+extern const struct ext_password_backend ext_password_file;
+#endif /* CONFIG_EXT_PASSWORD_FILE */
+
 #endif /* EXT_PASSWORD_I_H */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/http_curl.c b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/http_curl.c
index e62fbf9..ed21117 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/http_curl.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/http_curl.c
@@ -1423,10 +1423,6 @@
 	clone_str(&ctx->svc_client_cert, client_cert);
 	clone_str(&ctx->svc_client_key, client_key);
 
-	/*
-	 * Workaround for Apache "Hostname 'FOO' provided via SNI and hostname
-	 * 'foo' provided via HTTP are different.
-	 */
 	for (count = 0, pos = ctx->svc_address; count < 3 && pos && *pos;
 	     pos++) {
 		if (*pos == '/')
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/list.h b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/list.h
index 5298c26..aa62c08 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/list.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/list.h
@@ -76,8 +76,8 @@
 	 dl_list_entry((list)->prev, type, member))
 
 #define dl_list_for_each(item, list, type, member) \
-	for (item = dl_list_first((list), type, member); \
-	     item && item != dl_list_entry((list), type, member); \
+	for (item = dl_list_entry((list)->next, type, member); \
+	     &item->member != (list); \
 	     item = dl_list_entry(item->member.next, type, member))
 
 #define dl_list_for_each_safe(item, n, list, type, member) \
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/os_unix.c b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/os_unix.c
index 0705a1b..c73c4db 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/os_unix.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/os_unix.c
@@ -46,7 +46,7 @@
 
 struct os_alloc_trace {
 	unsigned int magic;
-	struct dl_list list;
+	struct dl_list list __attribute__((aligned(16)));
 	size_t len;
 	WPA_TRACE_INFO
 } __attribute__((aligned(16)));
@@ -499,9 +499,9 @@
 int os_fdatasync(FILE *stream)
 {
 	if (!fflush(stream)) {
-#ifdef __linux__
+#if defined __FreeBSD__ || defined __linux__
 		return fdatasync(fileno(stream));
-#else /* !__linux__ */
+#else /* !__linux__ && !__FreeBSD__ */
 #ifdef F_FULLFSYNC
 		/* OS X does not implement fdatasync(). */
 		return fcntl(fileno(stream), F_FULLFSYNC);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/platform.h b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/platform.h
index 813987e..b2ad856 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/platform.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/platform.h
@@ -1,21 +1,18 @@
+/*
+ * Platform definitions for Radiotap parser
+ * Copyright (c) 2021, Jouni Malinen <j@w1.fi>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
 #ifndef PLATFORM_H
 #define PLATFORM_H
 
 #include "includes.h"
 #include "common.h"
 
-#define le16_to_cpu		le_to_host16
-#define le32_to_cpu		le_to_host32
-
-#define get_unaligned(p)					\
-({								\
-	struct packed_dummy_struct {				\
-		typeof(*(p)) __val;				\
-	} __attribute__((packed)) *__ptr = (void *) (p);	\
-								\
-	__ptr->__val;						\
-})
-#define get_unaligned_le16(p)	le16_to_cpu(get_unaligned((le16 *)(p)))
-#define get_unaligned_le32(p)	le32_to_cpu(get_unaligned((le32 *)(p)))
+#define get_unaligned_le16(p)	WPA_GET_LE16((void *) (p))
+#define get_unaligned_le32(p)	WPA_GET_LE32((void *) (p))
 
 #endif /* PLATFORM_H */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/radiotap.c b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/radiotap.c
index 71996eb..6dfe298 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/radiotap.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/radiotap.c
@@ -8,10 +8,8 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See COPYING for more details.
+ * Alternatively, this software may be distributed under the terms of ISC
+ * license, see COPYING for more details.
  */
 #include "platform.h"
 #include "radiotap_iter.h"
@@ -39,6 +37,8 @@
 	[IEEE80211_RADIOTAP_DATA_RETRIES] = { .align = 1, .size = 1, },
 	[IEEE80211_RADIOTAP_MCS] = { .align = 1, .size = 3, },
 	[IEEE80211_RADIOTAP_AMPDU_STATUS] = { .align = 4, .size = 8, },
+	[IEEE80211_RADIOTAP_VHT] = { .align = 2, .size = 12, },
+	[IEEE80211_RADIOTAP_TIMESTAMP] = { .align = 8, .size = 12, },
 	/*
 	 * add more here as they are defined in radiotap.h
 	 */
@@ -111,7 +111,7 @@
 	iterator->_arg = (uint8_t *)radiotap_header + sizeof(*radiotap_header);
 	iterator->_next_ns_data = NULL;
 	iterator->_reset_on_ext = 0;
-	iterator->_next_bitmap = &radiotap_header->it_present;
+	iterator->_next_bitmap = (le32 *) (((u8 *) radiotap_header) + offsetof(struct ieee80211_radiotap_header, it_present));
 	iterator->_next_bitmap++;
 	iterator->_vns = vns;
 	iterator->current_namespace = &radiotap_ns;
@@ -222,7 +222,7 @@
  * present fields.  @this_arg can be changed by the caller (eg,
  * incremented to move inside a compound argument like
  * IEEE80211_RADIOTAP_CHANNEL).  The args pointed to are in
- * little-endian format whatever the endianess of your CPU.
+ * little-endian format whatever the endianness of your CPU.
  *
  * Alignment Gotcha:
  * You must take care when dereferencing iterator.this_arg
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/radiotap.h b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/radiotap.h
index 460af23..488d5a3 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/radiotap.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/radiotap.h
@@ -1,190 +1,51 @@
-/*-
- * Copyright (c) 2003, 2004 David Young.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of David Young may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DAVID
- * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- */
-
 /*
- * Modifications to fit into the linux IEEE 802.11 stack,
- * Mike Kershaw (dragorn@kismetwireless.net)
- */
-
-#ifndef IEEE80211RADIOTAP_H
-#define IEEE80211RADIOTAP_H
-
-#include <stdint.h>
-
-/* Base version of the radiotap packet header data */
-#define PKTHDR_RADIOTAP_VERSION		0
-
-/* A generic radio capture format is desirable. There is one for
- * Linux, but it is neither rigidly defined (there were not even
- * units given for some fields) nor easily extensible.
+ * Copyright (c) 2017		Intel Deutschland GmbH
  *
- * I suggest the following extensible radio capture format. It is
- * based on a bitmap indicating which fields are present.
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
  *
- * I am trying to describe precisely what the application programmer
- * should expect in the following, and for that reason I tell the
- * units and origin of each measurement (where it applies), or else I
- * use sufficiently weaselly language ("is a monotonically nondecreasing
- * function of...") that I cannot set false expectations for lawyerly
- * readers.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+#ifndef __RADIOTAP_H
+#define __RADIOTAP_H
 
-/* The radio capture header precedes the 802.11 header.
- * All data in the header is little endian on all platforms.
+/**
+ * struct ieee82011_radiotap_header - base radiotap header
  */
 struct ieee80211_radiotap_header {
-	uint8_t it_version;	/* Version 0. Only increases
-				 * for drastic changes,
-				 * introduction of compatible
-				 * new fields does not count.
-				 */
-	uint8_t it_pad;
-	le16 it_len;		/* length of the whole
-				 * header in bytes, including
-				 * it_version, it_pad,
-				 * it_len, and data fields.
-				 */
-	le32 it_present;	/* A bitmap telling which
-				 * fields are present. Set bit 31
-				 * (0x80000000) to extend the
-				 * bitmap by another 32 bits.
-				 * Additional extensions are made
-				 * by setting bit 31.
-				 */
-};
+	/**
+	 * @it_version: radiotap version, always 0
+	 */
+	uint8_t it_version;
 
-/* Name                                 Data type    Units
- * ----                                 ---------    -----
- *
- * IEEE80211_RADIOTAP_TSFT              __le64       microseconds
- *
- *      Value in microseconds of the MAC's 64-bit 802.11 Time
- *      Synchronization Function timer when the first bit of the
- *      MPDU arrived at the MAC. For received frames, only.
- *
- * IEEE80211_RADIOTAP_CHANNEL           2 x uint16_t   MHz, bitmap
- *
- *      Tx/Rx frequency in MHz, followed by flags (see below).
- *
- * IEEE80211_RADIOTAP_FHSS              uint16_t       see below
- *
- *      For frequency-hopping radios, the hop set (first byte)
- *      and pattern (second byte).
- *
- * IEEE80211_RADIOTAP_RATE              u8           500kb/s
- *
- *      Tx/Rx data rate
- *
- * IEEE80211_RADIOTAP_DBM_ANTSIGNAL     s8           decibels from
- *                                                   one milliwatt (dBm)
- *
- *      RF signal power at the antenna, decibel difference from
- *      one milliwatt.
- *
- * IEEE80211_RADIOTAP_DBM_ANTNOISE      s8           decibels from
- *                                                   one milliwatt (dBm)
- *
- *      RF noise power at the antenna, decibel difference from one
- *      milliwatt.
- *
- * IEEE80211_RADIOTAP_DB_ANTSIGNAL      u8           decibel (dB)
- *
- *      RF signal power at the antenna, decibel difference from an
- *      arbitrary, fixed reference.
- *
- * IEEE80211_RADIOTAP_DB_ANTNOISE       u8           decibel (dB)
- *
- *      RF noise power at the antenna, decibel difference from an
- *      arbitrary, fixed reference point.
- *
- * IEEE80211_RADIOTAP_LOCK_QUALITY      uint16_t       unitless
- *
- *      Quality of Barker code lock. Unitless. Monotonically
- *      nondecreasing with "better" lock strength. Called "Signal
- *      Quality" in datasheets.  (Is there a standard way to measure
- *      this?)
- *
- * IEEE80211_RADIOTAP_TX_ATTENUATION    uint16_t       unitless
- *
- *      Transmit power expressed as unitless distance from max
- *      power set at factory calibration.  0 is max power.
- *      Monotonically nondecreasing with lower power levels.
- *
- * IEEE80211_RADIOTAP_DB_TX_ATTENUATION uint16_t       decibels (dB)
- *
- *      Transmit power expressed as decibel distance from max power
- *      set at factory calibration.  0 is max power.  Monotonically
- *      nondecreasing with lower power levels.
- *
- * IEEE80211_RADIOTAP_DBM_TX_POWER      s8           decibels from
- *                                                   one milliwatt (dBm)
- *
- *      Transmit power expressed as dBm (decibels from a 1 milliwatt
- *      reference). This is the absolute power level measured at
- *      the antenna port.
- *
- * IEEE80211_RADIOTAP_FLAGS             u8           bitmap
- *
- *      Properties of transmitted and received frames. See flags
- *      defined below.
- *
- * IEEE80211_RADIOTAP_ANTENNA           u8           antenna index
- *
- *      Unitless indication of the Rx/Tx antenna for this packet.
- *      The first antenna is antenna 0.
- *
- * IEEE80211_RADIOTAP_RX_FLAGS          uint16_t       bitmap
- *
- *     Properties of received frames. See flags defined below.
- *
- * IEEE80211_RADIOTAP_TX_FLAGS          uint16_t       bitmap
- *
- *     Properties of transmitted frames. See flags defined below.
- *
- * IEEE80211_RADIOTAP_RTS_RETRIES       u8           data
- *
- *     Number of rts retries a transmitted frame used.
- *
- * IEEE80211_RADIOTAP_DATA_RETRIES      u8           data
- *
- *     Number of unicast retries a transmitted frame used.
- *
- * IEEE80211_RADIOTAP_MCS	u8, u8, u8		unitless
- *
- *     Contains a bitmap of known fields/flags, the flags, and
- *     the MCS index.
- *
- * IEEE80211_RADIOTAP_AMPDU_STATUS	u32, u16, u8, u8	unitlesss
- *
- *	Contains the AMPDU information for the subframe.
- */
-enum ieee80211_radiotap_type {
+	/**
+	 * @it_pad: padding (or alignment)
+	 */
+	uint8_t it_pad;
+
+	/**
+	 * @it_len: overall radiotap header length
+	 */
+	le16 it_len;
+
+	/**
+	 * @it_present: (first) present word
+	 */
+	le32 it_present;
+} STRUCT_PACKED;
+
+/* version is always 0 */
+#define PKTHDR_RADIOTAP_VERSION	0
+
+/* see the radiotap website for the descriptions */
+enum ieee80211_radiotap_presence {
 	IEEE80211_RADIOTAP_TSFT = 0,
 	IEEE80211_RADIOTAP_FLAGS = 1,
 	IEEE80211_RADIOTAP_RATE = 2,
@@ -203,9 +64,11 @@
 	IEEE80211_RADIOTAP_TX_FLAGS = 15,
 	IEEE80211_RADIOTAP_RTS_RETRIES = 16,
 	IEEE80211_RADIOTAP_DATA_RETRIES = 17,
-
+	/* 18 is XChannel, but it's not defined yet */
 	IEEE80211_RADIOTAP_MCS = 19,
 	IEEE80211_RADIOTAP_AMPDU_STATUS = 20,
+	IEEE80211_RADIOTAP_VHT = 21,
+	IEEE80211_RADIOTAP_TIMESTAMP = 22,
 
 	/* valid in every it_present bitmap, even vendor namespaces */
 	IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29,
@@ -213,79 +76,125 @@
 	IEEE80211_RADIOTAP_EXT = 31
 };
 
-/* Channel flags. */
-#define	IEEE80211_CHAN_TURBO	0x0010	/* Turbo channel */
-#define	IEEE80211_CHAN_CCK	0x0020	/* CCK channel */
-#define	IEEE80211_CHAN_OFDM	0x0040	/* OFDM channel */
-#define	IEEE80211_CHAN_2GHZ	0x0080	/* 2 GHz spectrum channel. */
-#define	IEEE80211_CHAN_5GHZ	0x0100	/* 5 GHz spectrum channel */
-#define	IEEE80211_CHAN_PASSIVE	0x0200	/* Only passive scan allowed */
-#define	IEEE80211_CHAN_DYN	0x0400	/* Dynamic CCK-OFDM channel */
-#define	IEEE80211_CHAN_GFSK	0x0800	/* GFSK channel (FHSS PHY) */
+/* for IEEE80211_RADIOTAP_FLAGS */
+enum ieee80211_radiotap_flags {
+	IEEE80211_RADIOTAP_F_CFP = 0x01,
+	IEEE80211_RADIOTAP_F_SHORTPRE = 0x02,
+	IEEE80211_RADIOTAP_F_WEP = 0x04,
+	IEEE80211_RADIOTAP_F_FRAG = 0x08,
+	IEEE80211_RADIOTAP_F_FCS = 0x10,
+	IEEE80211_RADIOTAP_F_DATAPAD = 0x20,
+	IEEE80211_RADIOTAP_F_BADFCS = 0x40,
+};
 
-/* For IEEE80211_RADIOTAP_FLAGS */
-#define	IEEE80211_RADIOTAP_F_CFP	0x01	/* sent/received
-						 * during CFP
-						 */
-#define	IEEE80211_RADIOTAP_F_SHORTPRE	0x02	/* sent/received
-						 * with short
-						 * preamble
-						 */
-#define	IEEE80211_RADIOTAP_F_WEP	0x04	/* sent/received
-						 * with WEP encryption
-						 */
-#define	IEEE80211_RADIOTAP_F_FRAG	0x08	/* sent/received
-						 * with fragmentation
-						 */
-#define	IEEE80211_RADIOTAP_F_FCS	0x10	/* frame includes FCS */
-#define	IEEE80211_RADIOTAP_F_DATAPAD	0x20	/* frame has padding between
-						 * 802.11 header and payload
-						 * (to 32-bit boundary)
-						 */
-#define IEEE80211_RADIOTAP_F_BADFCS	0x40	/* frame failed FCS check */
+/* for IEEE80211_RADIOTAP_CHANNEL */
+enum ieee80211_radiotap_channel_flags {
+	IEEE80211_CHAN_CCK = 0x0020,
+	IEEE80211_CHAN_OFDM = 0x0040,
+	IEEE80211_CHAN_2GHZ = 0x0080,
+	IEEE80211_CHAN_5GHZ = 0x0100,
+	IEEE80211_CHAN_DYN = 0x0400,
+	IEEE80211_CHAN_HALF = 0x4000,
+	IEEE80211_CHAN_QUARTER = 0x8000,
+};
 
-/* For IEEE80211_RADIOTAP_RX_FLAGS */
-#define IEEE80211_RADIOTAP_F_RX_BADPLCP	0x0002 /* bad PLCP */
+/* for IEEE80211_RADIOTAP_RX_FLAGS */
+enum ieee80211_radiotap_rx_flags {
+	IEEE80211_RADIOTAP_F_RX_BADPLCP = 0x0002,
+};
 
-/* For IEEE80211_RADIOTAP_TX_FLAGS */
-#define IEEE80211_RADIOTAP_F_TX_FAIL	0x0001	/* failed due to excessive
-						 * retries */
-#define IEEE80211_RADIOTAP_F_TX_CTS	0x0002	/* used cts 'protection' */
-#define IEEE80211_RADIOTAP_F_TX_RTS	0x0004	/* used rts/cts handshake */
-#define IEEE80211_RADIOTAP_F_TX_NOACK	0x0008	/* don't expect an ACK */
+/* for IEEE80211_RADIOTAP_TX_FLAGS */
+enum ieee80211_radiotap_tx_flags {
+	IEEE80211_RADIOTAP_F_TX_FAIL = 0x0001,
+	IEEE80211_RADIOTAP_F_TX_CTS = 0x0002,
+	IEEE80211_RADIOTAP_F_TX_RTS = 0x0004,
+	IEEE80211_RADIOTAP_F_TX_NOACK = 0x0008,
+};
 
-/* For IEEE80211_RADIOTAP_AMPDU_STATUS */
-#define IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN		0x0001
-#define IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN		0x0002
-#define IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN		0x0004
-#define IEEE80211_RADIOTAP_AMPDU_IS_LAST		0x0008
-#define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR		0x0010
-#define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN	0x0020
+/* for IEEE80211_RADIOTAP_MCS "have" flags */
+enum ieee80211_radiotap_mcs_have {
+	IEEE80211_RADIOTAP_MCS_HAVE_BW = 0x01,
+	IEEE80211_RADIOTAP_MCS_HAVE_MCS = 0x02,
+	IEEE80211_RADIOTAP_MCS_HAVE_GI = 0x04,
+	IEEE80211_RADIOTAP_MCS_HAVE_FMT = 0x08,
+	IEEE80211_RADIOTAP_MCS_HAVE_FEC = 0x10,
+	IEEE80211_RADIOTAP_MCS_HAVE_STBC = 0x20,
+};
 
-/* For IEEE80211_RADIOTAP_MCS */
-#define IEEE80211_RADIOTAP_MCS_HAVE_BW		0x01
-#define IEEE80211_RADIOTAP_MCS_HAVE_MCS		0x02
-#define IEEE80211_RADIOTAP_MCS_HAVE_GI		0x04
-#define IEEE80211_RADIOTAP_MCS_HAVE_FMT		0x08
-#define IEEE80211_RADIOTAP_MCS_HAVE_FEC		0x10
-#define IEEE80211_RADIOTAP_MCS_HAVE_STBC	0x20
-#define IEEE80211_RADIOTAP_MCS_HAVE_NESS	0x40
-#define IEEE80211_RADIOTAP_MCS_NESS_BIT1	0x80
+enum ieee80211_radiotap_mcs_flags {
+	IEEE80211_RADIOTAP_MCS_BW_MASK = 0x03,
+	IEEE80211_RADIOTAP_MCS_BW_20 = 0,
+	IEEE80211_RADIOTAP_MCS_BW_40 = 1,
+	IEEE80211_RADIOTAP_MCS_BW_20L = 2,
+	IEEE80211_RADIOTAP_MCS_BW_20U = 3,
 
+	IEEE80211_RADIOTAP_MCS_SGI = 0x04,
+	IEEE80211_RADIOTAP_MCS_FMT_GF = 0x08,
+	IEEE80211_RADIOTAP_MCS_FEC_LDPC = 0x10,
+	IEEE80211_RADIOTAP_MCS_STBC_MASK = 0x60,
+	IEEE80211_RADIOTAP_MCS_STBC_1 = 1,
+	IEEE80211_RADIOTAP_MCS_STBC_2 = 2,
+	IEEE80211_RADIOTAP_MCS_STBC_3 = 3,
+	IEEE80211_RADIOTAP_MCS_STBC_SHIFT = 5,
+};
 
-#define IEEE80211_RADIOTAP_MCS_BW_MASK		0x03
-#define		IEEE80211_RADIOTAP_MCS_BW_20	0
-#define		IEEE80211_RADIOTAP_MCS_BW_40	1
-#define		IEEE80211_RADIOTAP_MCS_BW_20L	2
-#define		IEEE80211_RADIOTAP_MCS_BW_20U	3
-#define IEEE80211_RADIOTAP_MCS_SGI		0x04
-#define IEEE80211_RADIOTAP_MCS_FMT_GF		0x08
-#define IEEE80211_RADIOTAP_MCS_FEC_LDPC		0x10
-#define IEEE80211_RADIOTAP_MCS_STBC_MASK	0x60
-#define IEEE80211_RADIOTAP_MCS_STBC_SHIFT	5
-#define		IEEE80211_RADIOTAP_MCS_STBC_1	1
-#define		IEEE80211_RADIOTAP_MCS_STBC_2	2
-#define		IEEE80211_RADIOTAP_MCS_STBC_3	3
-#define IEEE80211_RADIOTAP_MCS_NESS_BIT0	0x80
+/* for IEEE80211_RADIOTAP_AMPDU_STATUS */
+enum ieee80211_radiotap_ampdu_flags {
+	IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN = 0x0001,
+	IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN = 0x0002,
+	IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN = 0x0004,
+	IEEE80211_RADIOTAP_AMPDU_IS_LAST = 0x0008,
+	IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR = 0x0010,
+	IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN = 0x0020,
+};
 
-#endif				/* IEEE80211_RADIOTAP_H */
+/* for IEEE80211_RADIOTAP_VHT */
+enum ieee80211_radiotap_vht_known {
+	IEEE80211_RADIOTAP_VHT_KNOWN_STBC = 0x0001,
+	IEEE80211_RADIOTAP_VHT_KNOWN_TXOP_PS_NA = 0x0002,
+	IEEE80211_RADIOTAP_VHT_KNOWN_GI = 0x0004,
+	IEEE80211_RADIOTAP_VHT_KNOWN_SGI_NSYM_DIS = 0x0008,
+	IEEE80211_RADIOTAP_VHT_KNOWN_LDPC_EXTRA_OFDM_SYM = 0x0010,
+	IEEE80211_RADIOTAP_VHT_KNOWN_BEAMFORMED = 0x0020,
+	IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH = 0x0040,
+	IEEE80211_RADIOTAP_VHT_KNOWN_GROUP_ID = 0x0080,
+	IEEE80211_RADIOTAP_VHT_KNOWN_PARTIAL_AID = 0x0100,
+};
+
+enum ieee80211_radiotap_vht_flags {
+	IEEE80211_RADIOTAP_VHT_FLAG_STBC = 0x01,
+	IEEE80211_RADIOTAP_VHT_FLAG_TXOP_PS_NA = 0x02,
+	IEEE80211_RADIOTAP_VHT_FLAG_SGI = 0x04,
+	IEEE80211_RADIOTAP_VHT_FLAG_SGI_NSYM_M10_9 = 0x08,
+	IEEE80211_RADIOTAP_VHT_FLAG_LDPC_EXTRA_OFDM_SYM = 0x10,
+	IEEE80211_RADIOTAP_VHT_FLAG_BEAMFORMED = 0x20,
+};
+
+enum ieee80211_radiotap_vht_coding {
+	IEEE80211_RADIOTAP_CODING_LDPC_USER0 = 0x01,
+	IEEE80211_RADIOTAP_CODING_LDPC_USER1 = 0x02,
+	IEEE80211_RADIOTAP_CODING_LDPC_USER2 = 0x04,
+	IEEE80211_RADIOTAP_CODING_LDPC_USER3 = 0x08,
+};
+
+/* for IEEE80211_RADIOTAP_TIMESTAMP */
+enum ieee80211_radiotap_timestamp_unit_spos {
+	IEEE80211_RADIOTAP_TIMESTAMP_UNIT_MASK = 0x000F,
+	IEEE80211_RADIOTAP_TIMESTAMP_UNIT_MS = 0x0000,
+	IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US = 0x0001,
+	IEEE80211_RADIOTAP_TIMESTAMP_UNIT_NS = 0x0003,
+	IEEE80211_RADIOTAP_TIMESTAMP_SPOS_MASK = 0x00F0,
+	IEEE80211_RADIOTAP_TIMESTAMP_SPOS_BEGIN_MDPU = 0x0000,
+	IEEE80211_RADIOTAP_TIMESTAMP_SPOS_PLCP_SIG_ACQ = 0x0010,
+	IEEE80211_RADIOTAP_TIMESTAMP_SPOS_EO_PPDU = 0x0020,
+	IEEE80211_RADIOTAP_TIMESTAMP_SPOS_EO_MPDU = 0x0030,
+	IEEE80211_RADIOTAP_TIMESTAMP_SPOS_UNKNOWN = 0x00F0,
+};
+
+enum ieee80211_radiotap_timestamp_flags {
+	IEEE80211_RADIOTAP_TIMESTAMP_FLAG_64BIT = 0x00,
+	IEEE80211_RADIOTAP_TIMESTAMP_FLAG_32BIT = 0x01,
+	IEEE80211_RADIOTAP_TIMESTAMP_FLAG_ACCURACY = 0x02,
+};
+
+#endif /* __RADIOTAP_H */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/wpabuf.h b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/wpabuf.h
index b2a54b2..eb1db80 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/utils/wpabuf.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/utils/wpabuf.h
@@ -133,6 +133,12 @@
 	WPA_PUT_LE32(pos, data);
 }
 
+static inline void wpabuf_put_le64(struct wpabuf *buf, u64 data)
+{
+	u8 *pos = (u8 *) wpabuf_put(buf, 8);
+	WPA_PUT_LE64(pos, data);
+}
+
 static inline void wpabuf_put_be16(struct wpabuf *buf, u16 data)
 {
 	u8 *pos = (u8 *) wpabuf_put(buf, 2);
@@ -151,6 +157,12 @@
 	WPA_PUT_BE32(pos, data);
 }
 
+static inline void wpabuf_put_be64(struct wpabuf *buf, u64 data)
+{
+	u8 *pos = (u8 *) wpabuf_put(buf, 8);
+	WPA_PUT_BE64(pos, data);
+}
+
 static inline void wpabuf_put_data(struct wpabuf *buf, const void *data,
 				   size_t len)
 {
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps.c b/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps.c
index 484df26..1fe3806 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps.c
@@ -17,7 +17,7 @@
 
 #ifdef CONFIG_WPS_TESTING
 int wps_version_number = 0x20;
-int wps_testing_dummy_cred = 0;
+int wps_testing_stub_cred = 0;
 int wps_corrupt_pkhash = 0;
 int wps_force_auth_types_in_use = 0;
 u16 wps_force_auth_types = 0;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps.h b/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps.h
index 93888b0..48a43de 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps.h
@@ -177,12 +177,6 @@
 	 */
 	const u8 *p2p_dev_addr;
 
-	/**
-	 * pbc_in_m1 - Do not remove PushButton config method in M1 (AP)
-	 *
-	 * This can be used to enable a workaround to allow Windows 7 to use
-	 * PBC with the AP.
-	 */
 	int pbc_in_m1;
 
 	/**
@@ -841,6 +835,10 @@
 	struct wpabuf *ap_nfc_dh_pubkey;
 	struct wpabuf *ap_nfc_dh_privkey;
 	struct wpabuf *ap_nfc_dev_pw;
+
+	/* Whether to send WPA2-PSK passphrase as a passphrase instead of PSK
+	 * for WPA3-Personal transition mode needs. */
+	bool use_passphrase;
 };
 
 struct wps_registrar *
@@ -873,6 +871,11 @@
 					 const u8 *oob_dev_pw,
 					 size_t oob_dev_pw_len);
 void wps_registrar_flush(struct wps_registrar *reg);
+int wps_registrar_update_multi_ap(struct wps_registrar *reg,
+				  const u8 *multi_ap_backhaul_ssid,
+				  size_t multi_ap_backhaul_ssid_len,
+				  const u8 *multi_ap_backhaul_network_key,
+				  size_t multi_ap_backhaul_network_key_len);
 
 int wps_build_credential_wrap(struct wpabuf *msg,
 			      const struct wps_credential *cred);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps_defs.h b/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps_defs.h
index 9fccb4e..ddaeda5 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps_defs.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps_defs.h
@@ -12,7 +12,7 @@
 #ifdef CONFIG_WPS_TESTING
 
 extern int wps_version_number;
-extern int wps_testing_dummy_cred;
+extern int wps_testing_stub_cred;
 extern int wps_corrupt_pkhash;
 extern int wps_force_auth_types_in_use;
 extern u16 wps_force_auth_types;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps_dev_attr.c b/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps_dev_attr.c
index c2e949c..9335849 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps_dev_attr.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps_dev_attr.c
@@ -21,11 +21,6 @@
 	len = dev->manufacturer ? os_strlen(dev->manufacturer) : 0;
 #ifndef CONFIG_WPS_STRICT
 	if (len == 0) {
-		/*
-		 * Some deployed WPS implementations fail to parse zero-length
-		 * attributes. As a workaround, send a space character if the
-		 * device attribute string is empty.
-		 */
 		wpabuf_put_be16(msg, 1);
 		wpabuf_put_u8(msg, ' ');
 		return 0;
@@ -45,11 +40,6 @@
 	len = dev->model_name ? os_strlen(dev->model_name) : 0;
 #ifndef CONFIG_WPS_STRICT
 	if (len == 0) {
-		/*
-		 * Some deployed WPS implementations fail to parse zero-length
-		 * attributes. As a workaround, send a space character if the
-		 * device attribute string is empty.
-		 */
 		wpabuf_put_be16(msg, 1);
 		wpabuf_put_u8(msg, ' ');
 		return 0;
@@ -69,11 +59,6 @@
 	len = dev->model_number ? os_strlen(dev->model_number) : 0;
 #ifndef CONFIG_WPS_STRICT
 	if (len == 0) {
-		/*
-		 * Some deployed WPS implementations fail to parse zero-length
-		 * attributes. As a workaround, send a space character if the
-		 * device attribute string is empty.
-		 */
 		wpabuf_put_be16(msg, 1);
 		wpabuf_put_u8(msg, ' ');
 		return 0;
@@ -93,11 +78,6 @@
 	len = dev->serial_number ? os_strlen(dev->serial_number) : 0;
 #ifndef CONFIG_WPS_STRICT
 	if (len == 0) {
-		/*
-		 * Some deployed WPS implementations fail to parse zero-length
-		 * attributes. As a workaround, send a space character if the
-		 * device attribute string is empty.
-		 */
 		wpabuf_put_be16(msg, 1);
 		wpabuf_put_u8(msg, ' ');
 		return 0;
@@ -163,11 +143,6 @@
 	len = dev->device_name ? os_strlen(dev->device_name) : 0;
 #ifndef CONFIG_WPS_STRICT
 	if (len == 0) {
-		/*
-		 * Some deployed WPS implementations fail to parse zero-length
-		 * attributes. As a workaround, send a space character if the
-		 * device attribute string is empty.
-		 */
 		wpabuf_put_be16(msg, 1);
 		wpabuf_put_u8(msg, ' ');
 		return 0;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps_module_tests.c b/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps_module_tests.c
index 23bed4b..6669f0f 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps_module_tests.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps_module_tests.c
@@ -31,11 +31,9 @@
 	{ "10270000001057000101", -1, 0 },
 	{ "1027000010570001010000000000", -1, 0 },
 #else /* CONFIG_WPS_STRICT */
-	/* Network Key workaround */
 	{ "10270000001057000101", 0, 1 },
 	{ "10230000001057000101", -1, 0 },
 	{ "10270000101057000101", -1, 0 },
-	/* Mac OS X 10.6 padding workaround */
 	{ "1027000010570001010000000000", 0, 1 },
 	{ "1027000010570001010000000000000001000000", -1, 0 },
 #endif /* CONFIG_WPS_STRICT */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps_registrar.c b/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps_registrar.c
index 9e1ee36..9587293 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps_registrar.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps_registrar.c
@@ -1320,13 +1320,9 @@
 	}
 
 	beacon = wpabuf_alloc(400 + vendor_len);
-	if (beacon == NULL)
-		return -1;
 	probe = wpabuf_alloc(500 + vendor_len);
-	if (probe == NULL) {
-		wpabuf_free(beacon);
-		return -1;
-	}
+	if (!beacon || !probe)
+		goto fail;
 
 	auth_macs = wps_authorized_macs(reg, &count);
 
@@ -1342,19 +1338,13 @@
 	    (reg->dualband && wps_build_rf_bands(&reg->wps->dev, beacon, 0)) ||
 	    wps_build_wfa_ext(beacon, 0, auth_macs, count, 0) ||
 	    wps_build_vendor_ext(&reg->wps->dev, beacon) ||
-	    wps_build_application_ext(&reg->wps->dev, beacon)) {
-		wpabuf_free(beacon);
-		wpabuf_free(probe);
-		return -1;
-	}
+	    wps_build_application_ext(&reg->wps->dev, beacon))
+		goto fail;
 
 #ifdef CONFIG_P2P
 	if (wps_build_dev_name(&reg->wps->dev, beacon) ||
-	    wps_build_primary_dev_type(&reg->wps->dev, beacon)) {
-		wpabuf_free(beacon);
-		wpabuf_free(probe);
-		return -1;
-	}
+	    wps_build_primary_dev_type(&reg->wps->dev, beacon))
+		goto fail;
 #endif /* CONFIG_P2P */
 
 	wpa_printf(MSG_DEBUG, "WPS: Build Probe Response IEs");
@@ -1373,22 +1363,20 @@
 	    (reg->dualband && wps_build_rf_bands(&reg->wps->dev, probe, 0)) ||
 	    wps_build_wfa_ext(probe, 0, auth_macs, count, 0) ||
 	    wps_build_vendor_ext(&reg->wps->dev, probe) ||
-	    wps_build_application_ext(&reg->wps->dev, probe)) {
-		wpabuf_free(beacon);
-		wpabuf_free(probe);
-		return -1;
-	}
+	    wps_build_application_ext(&reg->wps->dev, probe))
+		goto fail;
 
 	beacon = wps_ie_encapsulate(beacon);
 	probe = wps_ie_encapsulate(probe);
 
-	if (!beacon || !probe) {
-		wpabuf_free(beacon);
-		wpabuf_free(probe);
-		return -1;
-	}
+	if (!beacon || !probe)
+		goto fail;
 
 	return wps_cb_set_ie(reg, beacon, probe);
+fail:
+	wpabuf_free(beacon);
+	wpabuf_free(probe);
+	return -1;
 }
 
 
@@ -1765,8 +1753,10 @@
 		wpa_snprintf_hex(hex, sizeof(hex), wps->wps->psk, PMK_LEN);
 		os_memcpy(wps->cred.key, hex, PMK_LEN * 2);
 		wps->cred.key_len = PMK_LEN * 2;
-	} else if (!wps->wps->registrar->force_per_enrollee_psk &&
-		   wps->wps->network_key) {
+	} else if ((!wps->wps->registrar->force_per_enrollee_psk ||
+		    wps->wps->use_passphrase) && wps->wps->network_key) {
+		wpa_printf(MSG_DEBUG,
+			   "WPS: Use passphrase format for Network key");
 		os_memcpy(wps->cred.key, wps->wps->network_key,
 			  wps->wps->network_key_len);
 		wps->cred.key_len = wps->wps->network_key_len;
@@ -1795,23 +1785,23 @@
 
 use_provided:
 #ifdef CONFIG_WPS_TESTING
-	if (wps_testing_dummy_cred)
+	if (wps_testing_stub_cred)
 		cred = wpabuf_alloc(200);
 	else
 		cred = NULL;
 	if (cred) {
-		struct wps_credential dummy;
-		wpa_printf(MSG_DEBUG, "WPS: Add dummy credential");
-		os_memset(&dummy, 0, sizeof(dummy));
-		os_memcpy(dummy.ssid, "dummy", 5);
-		dummy.ssid_len = 5;
-		dummy.auth_type = WPS_AUTH_WPA2PSK;
-		dummy.encr_type = WPS_ENCR_AES;
-		os_memcpy(dummy.key, "dummy psk", 9);
-		dummy.key_len = 9;
-		os_memcpy(dummy.mac_addr, wps->mac_addr_e, ETH_ALEN);
-		wps_build_credential(cred, &dummy);
-		wpa_hexdump_buf(MSG_DEBUG, "WPS: Dummy Credential", cred);
+		struct wps_credential stub;
+		wpa_printf(MSG_DEBUG, "WPS: Add stub credential");
+		os_memset(&stub, 0, sizeof(stub));
+		os_memcpy(stub.ssid, "stub", 5);
+		stub.ssid_len = 5;
+		stub.auth_type = WPS_AUTH_WPA2PSK;
+		stub.encr_type = WPS_ENCR_AES;
+		os_memcpy(stub.key, "stub psk", 9);
+		stub.key_len = 9;
+		os_memcpy(stub.mac_addr, wps->mac_addr_e, ETH_ALEN);
+		wps_build_credential(cred, &stub);
+		wpa_hexdump_buf(MSG_DEBUG, "WPS: Stub Credential", cred);
 
 		wpabuf_put_be16(msg, ATTR_CRED);
 		wpabuf_put_be16(msg, wpabuf_len(cred));
@@ -3669,6 +3659,35 @@
 }
 
 
+int wps_registrar_update_multi_ap(struct wps_registrar *reg,
+				  const u8 *multi_ap_backhaul_ssid,
+				  size_t multi_ap_backhaul_ssid_len,
+				  const u8 *multi_ap_backhaul_network_key,
+				  size_t multi_ap_backhaul_network_key_len)
+{
+	if (multi_ap_backhaul_ssid) {
+		os_memcpy(reg->multi_ap_backhaul_ssid,
+			  multi_ap_backhaul_ssid, multi_ap_backhaul_ssid_len);
+		reg->multi_ap_backhaul_ssid_len = multi_ap_backhaul_ssid_len;
+	}
+
+	os_free(reg->multi_ap_backhaul_network_key);
+	reg->multi_ap_backhaul_network_key = NULL;
+	reg->multi_ap_backhaul_network_key_len = 0;
+	if (multi_ap_backhaul_network_key) {
+		reg->multi_ap_backhaul_network_key =
+			os_memdup(multi_ap_backhaul_network_key,
+				  multi_ap_backhaul_network_key_len);
+		if (!reg->multi_ap_backhaul_network_key)
+			return -1;
+		reg->multi_ap_backhaul_network_key_len =
+			multi_ap_backhaul_network_key_len;
+	}
+
+	return 0;
+}
+
+
 #ifdef CONFIG_WPS_NFC
 
 int wps_registrar_add_nfc_pw_token(struct wps_registrar *reg,
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps_upnp.c b/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps_upnp.c
index ff58cb9..05bb9c5 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps_upnp.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps_upnp.c
@@ -658,7 +658,7 @@
 		/*
 		 * There has been no events before the subscription. However,
 		 * UPnP device architecture specification requires all the
-		 * evented variables to be included, so generate a dummy event
+		 * evented variables to be included, so generate a stub event
 		 * for this particular case using a WSC_ACK and all-zeros
 		 * nonces. The ER (UPnP control point) will ignore this, but at
 		 * least it will learn that WLANEvent variable will be used in
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps_upnp_web.c b/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps_upnp_web.c
index 2f336ea..feca164 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps_upnp_web.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/src/wps/wps_upnp_web.c
@@ -961,25 +961,6 @@
 }
 
 
-/* Given that we have received a header w/ SUBSCRIBE, act upon it
- *
- * Format of SUBSCRIBE (case-insensitive):
- *
- * First line must be:
- *      SUBSCRIBE /wps_event HTTP/1.1
- *
- * Our response (if no error) which includes only required lines is:
- * HTTP/1.1 200 OK
- * Server: xx, UPnP/1.0, xx
- * SID: uuid:xxxxxxxxx
- * Timeout: Second-<n>
- * Content-Length: 0
- * Date: xxxx
- *
- * Header lines must end with \r\n
- * Per RFC 2616, content-length: is not required but connection:close
- * would appear to be required (given that we will be closing it!).
- */
 static void web_connection_parse_subscribe(struct upnp_wps_device_sm *sm,
 					   struct http_request *req,
 					   const char *filename)
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/fuzzing/eap-aka-peer/eap-aka-peer.c b/src/lynq/packages/thirdpart/lynq-wg870/tests/fuzzing/eap-aka-peer/eap-aka-peer.c
index db06ed5..ce7b043 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/fuzzing/eap-aka-peer/eap-aka-peer.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/fuzzing/eap-aka-peer/eap-aka-peer.c
@@ -91,6 +91,7 @@
 	struct eap_sm *sm;
 	void *priv;
 	struct eap_method_ret ret;
+	unsigned int count = 0;
 
 	wpa_fuzzer_set_debug_level();
 
@@ -104,7 +105,7 @@
 	pos = data;
 	end = pos + size;
 
-	while (end - pos > 2) {
+	while (end - pos > 2 && count < 100) {
 		u16 flen;
 		struct wpabuf *buf, *req;
 
@@ -121,6 +122,7 @@
 		wpabuf_free(req);
 		wpabuf_free(buf);
 		pos += flen;
+		count++;
 	}
 
 	registered_eap_method->deinit(sm, priv);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/fuzzing/eap-sim-peer/eap-sim-peer.c b/src/lynq/packages/thirdpart/lynq-wg870/tests/fuzzing/eap-sim-peer/eap-sim-peer.c
index b6798ee..743a94b 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/fuzzing/eap-sim-peer/eap-sim-peer.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/fuzzing/eap-sim-peer/eap-sim-peer.c
@@ -85,6 +85,7 @@
 	struct eap_sm *sm;
 	void *priv;
 	struct eap_method_ret ret;
+	unsigned int count = 0;
 
 	wpa_fuzzer_set_debug_level();
 
@@ -98,7 +99,7 @@
 	pos = data;
 	end = pos + size;
 
-	while (end - pos > 2) {
+	while (end - pos > 2 && count < 100) {
 		u16 flen;
 		struct wpabuf *buf, *req;
 
@@ -115,6 +116,7 @@
 		wpabuf_free(req);
 		wpabuf_free(buf);
 		pos += flen;
+		count++;
 	}
 
 	registered_eap_method->deinit(sm, priv);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/fuzzing/p2p/p2p.c b/src/lynq/packages/thirdpart/lynq-wg870/tests/fuzzing/p2p/p2p.c
index 8ffcbbd..fc83c35 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/fuzzing/p2p/p2p.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/fuzzing/p2p/p2p.c
@@ -115,7 +115,7 @@
 	os_memset(&rx_time, 0, sizeof(rx_time));
 	p2p_scan_res_handler(ctx->p2p, (u8 *) "\x02\x00\x00\x00\x01\x00", 2412,
 			     &rx_time, 0, ctx->data, ctx->data_len);
-	p2p_scan_res_handled(ctx->p2p);
+	p2p_scan_res_handled(ctx->p2p, 0);
 
 	p2p_probe_req_rx(ctx->p2p, (u8 *) "\x02\x00\x00\x00\x01\x00",
 			 (u8 *) "\x02\x00\x00\x00\x00\x00",
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/fuzzing/wnm/Makefile b/src/lynq/packages/thirdpart/lynq-wg870/tests/fuzzing/wnm/Makefile
index 73eab53..60d27b3 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/fuzzing/wnm/Makefile
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/fuzzing/wnm/Makefile
@@ -20,7 +20,7 @@
 ELIBS += $(SRC)/crypto/libcrypto.a
 ELIBS += $(SRC)/tls/libtls.a
 
-OBJS += $(WPAS_SRC)/blacklist.o
+OBJS += $(WPAS_SRC)/bssid_ignore.o
 OBJS += $(WPAS_SRC)/bss.o
 OBJS += $(WPAS_SRC)/config.o
 OBJS += $(WPAS_SRC)/config_file.o
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/fuzzing/wnm/wnm.c b/src/lynq/packages/thirdpart/lynq-wg870/tests/fuzzing/wnm/wnm.c
index 9c0d541..7afc648 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/fuzzing/wnm/wnm.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/fuzzing/wnm/wnm.c
@@ -16,7 +16,7 @@
 #include "wpa_supplicant_i.h"
 #include "bss.h"
 #include "wnm_sta.h"
-#include "config.h"
+#include "../../../wpa_supplicant/config.h"
 #include "../fuzzer-common.h"
 
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/hlr_auc_gw.milenage_db b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/hlr_auc_gw.milenage_db
index 1c494f7..fefe514 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/hlr_auc_gw.milenage_db
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/hlr_auc_gw.milenage_db
@@ -3,7 +3,7 @@
 # 4.3.20 Test Set 20. SQN is the last used SQN value.
 # These values can be used for both UMTS (EAP-AKA) and GSM (EAP-SIM)
 # authentication. In case of GSM/EAP-SIM, AMF and SQN values are not used, but
-# dummy values will need to be included in this file.
+# stub values will need to be included in this file.
 
 # IMSI Ki OPc AMF SQN
 232010000000000 90dca4eda45b53cf0f12d7c9c3bc6a89 cb9cccc4b9258e6dca4760379fb82581 61df 000000000000
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/index-revoked.txt b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/index-revoked.txt
index fccc902..c58b7a4 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/index-revoked.txt
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/index-revoked.txt
@@ -5,4 +5,4 @@
 V	150228224144Z		D8D3E3A6CBE3CCCC	unknown	/C=FI/O=w1.fi/CN=server6.w1.fi
 V	160111185024Z		D8D3E3A6CBE3CCCD	unknown	/C=FI/O=w1.fi/CN=ocsp.w1.fi
 R	150929211300Z	160111185024Z	D8D3E3A6CBE3CCD1	unknown	/C=FI/O=w1.fi/CN=Test User
-R	191003221355Z	160111185024Z	D8D3E3A6CBE3CD17	unknown	/C=FI/O=w1.fi/CN=server.w1.fi
+R	210502195538Z	160111185024Z	D8D3E3A6CBE3CD5F	unknown	/C=FI/O=w1.fi/CN=server.w1.fi
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/index.txt b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/index.txt
index 090cb92..94f59ea 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/index.txt
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/index.txt
@@ -5,4 +5,4 @@
 V	150228224144Z		D8D3E3A6CBE3CCCC	unknown	/C=FI/O=w1.fi/CN=server6.w1.fi
 V	160111185024Z		D8D3E3A6CBE3CCCD	unknown	/C=FI/O=w1.fi/CN=ocsp.w1.fi
 V	150929211300Z		D8D3E3A6CBE3CCD1	unknown	/C=FI/O=w1.fi/CN=Test User
-V	210502195538Z		D8D3E3A6CBE3CD5F	unknown	/C=FI/O=w1.fi/CN=server.w1.fi
+V	220503170253Z		D8D3E3A6CBE3CD69	unknown	/C=FI/O=w1.fi/CN=server.w1.fi
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/ocsp-multi-server-cache.der b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/ocsp-multi-server-cache.der
index 36be811..8f76fc8 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/ocsp-multi-server-cache.der
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/ocsp-multi-server-cache.der
Binary files differ
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/ocsp-req.der b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/ocsp-req.der
index 3a70e38..5d33b69 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/ocsp-req.der
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/ocsp-req.der
Binary files differ
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/ocsp-responder.pem b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/ocsp-responder.pem
index 778f1b8..18fecde 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/ocsp-responder.pem
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/ocsp-responder.pem
@@ -2,12 +2,12 @@
     Data:
         Version: 3 (0x2)
         Serial Number:
-            d8:d3:e3:a6:cb:e3:cd:67
+            d8:d3:e3:a6:cb:e3:cd:72
         Signature Algorithm: sha256WithRSAEncryption
         Issuer: C=FI, L=Tuusula, O=w1.fi, CN=Root CA
         Validity
-            Not Before: May  3 14:01:18 2020 GMT
-            Not After : May  3 14:01:18 2021 GMT
+            Not Before: May  3 17:02:53 2021 GMT
+            Not After : May  3 17:02:53 2022 GMT
         Subject: C=FI, O=w1.fi, CN=ocsp.w1.fi
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
@@ -40,25 +40,25 @@
             X509v3 Extended Key Usage: 
                 OCSP Signing
     Signature Algorithm: sha256WithRSAEncryption
-         5d:f3:28:20:86:b7:cd:da:e2:e8:15:7a:97:52:79:63:69:0b:
-         92:96:53:89:69:a5:79:19:d1:7e:75:71:9c:e4:33:26:99:cc:
-         b9:fe:28:1a:40:a7:5f:83:ee:51:cd:fc:e4:cf:71:45:90:ba:
-         36:25:51:37:4c:19:9f:0e:fc:36:d5:64:05:8e:10:20:aa:53:
-         1e:e5:49:64:ae:54:7d:f3:51:a1:31:af:5f:30:46:5c:d0:db:
-         6d:fc:07:68:7e:63:26:24:82:52:cd:e0:3e:d1:fd:9b:e8:00:
-         93:e7:94:8c:d6:14:51:23:82:3b:51:ac:39:3d:6f:81:c7:ff:
-         fb:7a:92:eb:ec:c4:7e:0b:e6:16:5c:31:5f:a1:84:28:b3:ad:
-         75:8c:c3:c6:0c:b2:1a:23:4d:6c:a5:c7:e4:47:aa:5c:0d:ab:
-         75:40:a2:bd:9a:76:cb:50:ff:18:8c:c1:c0:bd:02:dd:51:1d:
-         d3:64:43:2c:a6:a8:40:42:c5:90:59:4c:76:56:a8:28:4d:df:
-         2d:8f:99:c3:2a:a9:f2:cc:5a:90:fc:29:6b:8e:f0:8e:89:79:
-         c1:b1:70:8b:2e:cb:98:d6:cf:46:ed:1a:c4:f7:32:78:5d:ca:
-         b1:0c:5a:05:99:45:f1:1a:80:48:1d:4f:83:7f:30:e9:ca:8f:
-         83:ff:f3:0b
+         b9:ef:0b:f2:ad:4b:e1:ac:0b:34:e2:ed:a7:db:20:3d:51:12:
+         62:f8:1a:e4:b7:25:8a:3e:fa:be:98:2e:e0:33:d8:d1:97:a6:
+         27:2a:c7:ba:05:ef:9b:f4:36:a2:b7:55:fc:85:fe:39:99:aa:
+         fe:b6:a0:cd:68:6b:3a:fd:a5:cc:63:e3:b2:90:70:bd:85:d8:
+         29:47:ba:d8:ae:46:46:4a:af:e6:19:4f:7e:b3:42:74:3b:1f:
+         c4:00:8f:a5:15:eb:cc:3d:d6:9d:92:c5:0a:61:78:10:0b:2a:
+         18:4e:eb:cd:74:32:c0:fb:d1:7d:00:3e:c3:00:4e:a6:c0:4e:
+         9b:b7:78:b7:5f:aa:96:d8:91:88:d5:83:fa:a3:65:69:b3:94:
+         e0:a9:4f:90:8d:64:ef:2e:bf:86:37:8a:61:3c:e9:a1:81:39:
+         08:75:d9:ea:c8:d6:5b:56:b0:f2:1a:36:2d:82:93:41:45:71:
+         c0:a1:f0:25:39:30:ef:44:79:ad:8b:18:fd:06:4c:c0:4b:62:
+         cf:f1:fb:bc:7b:ee:38:09:05:44:fa:4a:3c:c4:53:b9:68:18:
+         c1:6c:e4:ae:e0:ce:00:70:67:d1:37:ce:90:c6:0e:dc:c0:e3:
+         c8:01:5d:33:32:ab:c4:cb:45:1c:27:36:f7:b2:31:f7:99:8c:
+         b1:72:65:89
 -----BEGIN CERTIFICATE-----
-MIIDJTCCAg2gAwIBAgIJANjT46bL481nMA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
+MIIDJTCCAg2gAwIBAgIJANjT46bL481yMA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
 BAYTAkZJMRAwDgYDVQQHDAdUdXVzdWxhMQ4wDAYDVQQKDAV3MS5maTEQMA4GA1UE
-AwwHUm9vdCBDQTAeFw0yMDA1MDMxNDAxMThaFw0yMTA1MDMxNDAxMThaMDIxCzAJ
+AwwHUm9vdCBDQTAeFw0yMTA1MDMxNzAyNTNaFw0yMjA1MDMxNzAyNTNaMDIxCzAJ
 BgNVBAYTAkZJMQ4wDAYDVQQKDAV3MS5maTETMBEGA1UEAwwKb2NzcC53MS5maTCC
 ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKcihV27OxwCmgFzqohjbqFD
 M7X9Av4fyCMEi4xRUlvgzGJgKqq6iE9BOWv7NMCiencu4Vae78quZ9X5i1+rrofh
@@ -67,10 +67,10 @@
 TnwK2cRKDBZOPmh/G63JUwhcuATU1pNi/a/5tB30lj6bnRRtHGwjrj3HtM8xkCBq
 gJliflzp1dW9WU2j2dzp++h7ZYfV+Umevg7zqSHelOhU/IDP2uOPmsZMdhgO/qsC
 AwEAAaMvMC0wCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwEwYDVR0lBAwwCgYIKwYB
-BQUHAwkwDQYJKoZIhvcNAQELBQADggEBAF3zKCCGt83a4ugVepdSeWNpC5KWU4lp
-pXkZ0X51cZzkMyaZzLn+KBpAp1+D7lHN/OTPcUWQujYlUTdMGZ8O/DbVZAWOECCq
-Ux7lSWSuVH3zUaExr18wRlzQ2238B2h+YyYkglLN4D7R/ZvoAJPnlIzWFFEjgjtR
-rDk9b4HH//t6kuvsxH4L5hZcMV+hhCizrXWMw8YMshojTWylx+RHqlwNq3VAor2a
-dstQ/xiMwcC9At1RHdNkQyymqEBCxZBZTHZWqChN3y2PmcMqqfLMWpD8KWuO8I6J
-ecGxcIsuy5jWz0btGsT3MnhdyrEMWgWZRfEagEgdT4N/MOnKj4P/8ws=
+BQUHAwkwDQYJKoZIhvcNAQELBQADggEBALnvC/KtS+GsCzTi7afbID1REmL4GuS3
+JYo++r6YLuAz2NGXpicqx7oF75v0NqK3VfyF/jmZqv62oM1oazr9pcxj47KQcL2F
+2ClHutiuRkZKr+YZT36zQnQ7H8QAj6UV68w91p2SxQpheBALKhhO6810MsD70X0A
+PsMATqbATpu3eLdfqpbYkYjVg/qjZWmzlOCpT5CNZO8uv4Y3imE86aGBOQh12erI
+1ltWsPIaNi2Ck0FFccCh8CU5MO9Eea2LGP0GTMBLYs/x+7x77jgJBUT6SjzEU7lo
+GMFs5K7gzgBwZ9E3zpDGDtzA48gBXTMyq8TLRRwnNveyMfeZjLFyZYk=
 -----END CERTIFICATE-----
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/ocsp-server-cache.der b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/ocsp-server-cache.der
index 3d45879..3422159 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/ocsp-server-cache.der
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/ocsp-server-cache.der
Binary files differ
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/rsa3072-server.pem b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/rsa3072-server.pem
index 546361d..39e0221 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/rsa3072-server.pem
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/rsa3072-server.pem
@@ -2,12 +2,12 @@
     Data:
         Version: 3 (0x2)
         Serial Number:
-            ad:8c:09:e8:fb:a2:88:cb
+            ad:8c:09:e8:fb:a2:88:ce
         Signature Algorithm: sha384WithRSAEncryption
         Issuer: C=FI, L=Helsinki, O=w1.fi, CN=Suite B RSA 3k Root CA
         Validity
-            Not Before: Aug 16 13:19:41 2019 GMT
-            Not After : Aug 15 13:19:41 2021 GMT
+            Not Before: Aug 19 10:56:47 2021 GMT
+            Not After : Aug 19 10:56:47 2023 GMT
         Subject: C=FI, O=w1.fi, CN=rsa3072.server.w1.fi
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
@@ -55,33 +55,33 @@
             X509v3 Key Usage: 
                 Digital Signature, Key Encipherment
     Signature Algorithm: sha384WithRSAEncryption
-         39:6b:3b:eb:37:00:5d:71:35:15:bd:9d:59:7b:10:f5:57:51:
-         bf:e7:40:69:4d:05:f5:64:d0:42:d2:7e:74:12:bf:dc:20:13:
-         f5:24:1f:84:18:5c:75:18:34:f6:b3:57:a1:32:de:13:ef:d9:
-         79:6d:7a:9c:3a:3d:b0:3b:74:44:e8:9e:fc:19:6b:fa:55:74:
-         c8:e1:a1:2e:a9:ce:73:4c:7f:4d:0b:fd:33:33:10:c3:21:f1:
-         d1:80:31:ca:33:77:23:91:1d:11:b1:60:c9:ec:51:4c:70:31:
-         3c:b6:8a:8e:e3:42:d4:e7:e1:1c:11:a7:13:99:76:3c:25:55:
-         04:c2:e6:45:e5:21:39:5d:9f:e1:f2:35:84:ad:dd:3b:69:ab:
-         ca:f6:88:9a:4c:cc:cf:6a:82:b8:54:5a:60:40:aa:20:05:c3:
-         39:c1:46:11:8d:e4:cb:b1:7c:ee:48:cf:31:18:89:7a:5c:f7:
-         f9:51:18:65:e1:25:28:cb:49:1c:f5:5e:f6:68:d9:8e:c5:01:
-         cb:4f:da:7e:7a:54:f5:b4:4d:0a:e8:3f:6d:26:a1:72:c8:07:
-         50:ee:bf:64:01:8f:12:19:6d:ad:c0:6d:fa:29:ff:ab:31:9c:
-         fa:d4:55:46:83:a3:3b:53:cc:26:53:3f:b4:85:2f:90:76:6b:
-         39:4a:06:22:72:c0:0e:45:0d:3f:80:41:03:d7:65:89:fd:01:
-         3a:8c:8f:9c:af:77:93:ec:c0:fb:2e:f2:b0:db:ac:07:ac:e2:
-         0f:c8:af:24:0b:57:69:9f:bb:cb:e0:d7:bc:c2:c7:6f:3f:f3:
-         30:aa:42:88:7d:45:02:1e:ad:ac:da:89:8b:43:d9:80:0e:ab:
-         79:c5:c4:21:97:3b:e0:99:ef:9b:50:4a:86:62:e4:af:18:ed:
-         70:5b:e8:f8:87:9e:0c:c4:f0:6a:f4:1e:ce:05:f0:15:3f:68:
-         02:33:1d:9d:05:e4:d8:2f:20:38:33:1a:4e:46:7e:4b:10:b2:
-         6c:55:04:21:38:36
+         8c:3a:e4:8b:4f:42:ae:13:a4:c5:1e:eb:72:0d:15:c0:59:aa:
+         09:e9:ee:b4:97:94:ab:1a:fc:b1:b0:48:39:90:35:45:8b:40:
+         59:7b:51:d3:be:b1:ac:9c:90:9d:5c:0a:1c:34:41:d7:74:5f:
+         5a:84:a2:11:f6:66:ef:ae:22:66:1f:76:fb:c3:e0:65:3f:12:
+         59:6b:4b:84:6a:dd:58:ab:3d:1b:3f:d3:c8:51:84:72:7f:c1:
+         92:e5:d1:79:b4:62:9d:55:e1:6f:fa:c2:30:6c:6e:0d:ae:1c:
+         8b:d5:e5:02:99:c0:c2:95:ac:d5:d6:9a:2d:9d:a3:20:56:f4:
+         e7:60:0a:03:08:85:98:27:df:97:48:a6:92:6e:b4:fa:a5:e0:
+         46:0b:85:b7:6c:07:73:c5:59:a4:a9:db:3a:42:6c:1a:25:af:
+         4a:70:39:1d:5c:d7:08:41:57:b0:d7:59:66:c2:97:a5:09:4a:
+         11:1f:a5:f7:23:cb:c4:2c:d3:9e:ae:4a:86:56:e1:1a:e7:f3:
+         7c:c4:5c:b1:ae:c2:ea:1f:67:5a:10:e4:02:01:bd:92:b8:0f:
+         56:26:e3:27:24:6e:53:94:c0:16:fe:fa:e2:ed:4f:42:8d:dc:
+         23:9b:96:2e:5b:a5:47:56:a0:0d:09:17:28:3a:f2:a4:2e:71:
+         65:93:88:3c:ff:61:92:04:75:59:96:5f:40:85:e1:be:1d:59:
+         ec:8d:4b:b7:82:3b:bb:a1:06:c2:c4:44:7a:de:3e:fe:68:e8:
+         a3:43:a5:50:80:fd:11:1d:2c:ff:27:8d:e9:71:6d:c6:01:20:
+         0d:9a:5e:6c:c6:11:83:da:cc:fd:dd:a3:59:5c:b1:64:e1:81:
+         b4:6f:34:60:df:b5:bb:3d:5f:2b:f8:ef:73:d0:54:39:e4:dd:
+         4b:c9:5f:87:e9:1f:fb:c4:e2:f7:f6:6e:21:70:14:3b:0e:6e:
+         2d:11:e5:db:b8:18:d3:d2:9f:1b:a5:85:ae:89:f6:55:33:13:
+         e6:da:b4:1b:10:bc
 -----BEGIN CERTIFICATE-----
-MIIEqzCCAxOgAwIBAgIJAK2MCej7oojLMA0GCSqGSIb3DQEBDAUAMFExCzAJBgNV
+MIIEqzCCAxOgAwIBAgIJAK2MCej7oojOMA0GCSqGSIb3DQEBDAUAMFExCzAJBgNV
 BAYTAkZJMREwDwYDVQQHDAhIZWxzaW5raTEOMAwGA1UECgwFdzEuZmkxHzAdBgNV
-BAMMFlN1aXRlIEIgUlNBIDNrIFJvb3QgQ0EwHhcNMTkwODE2MTMxOTQxWhcNMjEw
-ODE1MTMxOTQxWjA8MQswCQYDVQQGEwJGSTEOMAwGA1UECgwFdzEuZmkxHTAbBgNV
+BAMMFlN1aXRlIEIgUlNBIDNrIFJvb3QgQ0EwHhcNMjEwODE5MTA1NjQ3WhcNMjMw
+ODE5MTA1NjQ3WjA8MQswCQYDVQQGEwJGSTEOMAwGA1UECgwFdzEuZmkxHTAbBgNV
 BAMMFHJzYTMwNzIuc2VydmVyLncxLmZpMIIBojANBgkqhkiG9w0BAQEFAAOCAY8A
 MIIBigKCAYEA/qlcWY+qgMu4Son5Ouh9JFG48gXGQuBotaTxfooxouAMWMWAIMsg
 8A7Ba03h1+vMRUjJsA+P74DbG2ACr+/oCinIBN9wkunx3GpHO1pvEOYZTZOS0AqO
@@ -94,13 +94,13 @@
 CmucaXj3TlRzAgMBAAGjgZowgZcwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUgtd1
 lZSeNfcfkW03nyZPPZ3BbpYwHwYDVR0jBBgwFoAUIffv2sM0Ou3N1VDAs7oJ7j+A
 13AwIgYDVR0RAQH/BBgwFoIUcnNhMzA3Mi5zZXJ2ZXIudzEuZmkwFgYDVR0lAQH/
-BAwwCgYIKwYBBQUHAwEwCwYDVR0PBAQDAgWgMA0GCSqGSIb3DQEBDAUAA4IBgQA5
-azvrNwBdcTUVvZ1ZexD1V1G/50BpTQX1ZNBC0n50Er/cIBP1JB+EGFx1GDT2s1eh
-Mt4T79l5bXqcOj2wO3RE6J78GWv6VXTI4aEuqc5zTH9NC/0zMxDDIfHRgDHKM3cj
-kR0RsWDJ7FFMcDE8toqO40LU5+EcEacTmXY8JVUEwuZF5SE5XZ/h8jWErd07aavK
-9oiaTMzPaoK4VFpgQKogBcM5wUYRjeTLsXzuSM8xGIl6XPf5URhl4SUoy0kc9V72
-aNmOxQHLT9p+elT1tE0K6D9tJqFyyAdQ7r9kAY8SGW2twG36Kf+rMZz61FVGg6M7
-U8wmUz+0hS+Qdms5SgYicsAORQ0/gEED12WJ/QE6jI+cr3eT7MD7LvKw26wHrOIP
-yK8kC1dpn7vL4Ne8wsdvP/MwqkKIfUUCHq2s2omLQ9mADqt5xcQhlzvgme+bUEqG
-YuSvGO1wW+j4h54MxPBq9B7OBfAVP2gCMx2dBeTYLyA4MxpORn5LELJsVQQhODY=
+BAwwCgYIKwYBBQUHAwEwCwYDVR0PBAQDAgWgMA0GCSqGSIb3DQEBDAUAA4IBgQCM
+OuSLT0KuE6TFHutyDRXAWaoJ6e60l5SrGvyxsEg5kDVFi0BZe1HTvrGsnJCdXAoc
+NEHXdF9ahKIR9mbvriJmH3b7w+BlPxJZa0uEat1Yqz0bP9PIUYRyf8GS5dF5tGKd
+VeFv+sIwbG4NrhyL1eUCmcDClazV1potnaMgVvTnYAoDCIWYJ9+XSKaSbrT6peBG
+C4W3bAdzxVmkqds6QmwaJa9KcDkdXNcIQVew11lmwpelCUoRH6X3I8vELNOerkqG
+VuEa5/N8xFyxrsLqH2daEOQCAb2SuA9WJuMnJG5TlMAW/vri7U9Cjdwjm5YuW6VH
+VqANCRcoOvKkLnFlk4g8/2GSBHVZll9AheG+HVnsjUu3gju7oQbCxER63j7+aOij
+Q6VQgP0RHSz/J43pcW3GASANml5sxhGD2sz93aNZXLFk4YG0bzRg37W7PV8r+O9z
+0FQ55N1LyV+H6R/7xOL39m4hcBQ7Dm4tEeXbuBjT0p8bpYWuifZVMxPm2rQbELw=
 -----END CERTIFICATE-----
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/rsa3072-user-rsa2048.pem b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/rsa3072-user-rsa2048.pem
index 56b4a59..f5a4d63 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/rsa3072-user-rsa2048.pem
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/rsa3072-user-rsa2048.pem
@@ -2,12 +2,12 @@
     Data:
         Version: 3 (0x2)
         Serial Number:
-            ad:8c:09:e8:fb:a2:88:cd
+            ad:8c:09:e8:fb:a2:88:d0
         Signature Algorithm: sha384WithRSAEncryption
         Issuer: C=FI, L=Helsinki, O=w1.fi, CN=Suite B RSA 3k Root CA
         Validity
-            Not Before: Aug 16 13:19:41 2019 GMT
-            Not After : Aug 15 13:19:41 2021 GMT
+            Not Before: Aug 19 10:56:47 2021 GMT
+            Not After : Aug 19 10:56:47 2023 GMT
         Subject: C=FI, O=w1.fi, CN=user-rsa3072-rsa2048
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
@@ -47,33 +47,33 @@
             X509v3 Key Usage: 
                 Digital Signature, Key Encipherment
     Signature Algorithm: sha384WithRSAEncryption
-         56:58:31:e4:90:41:01:ca:19:97:06:e0:5a:74:a4:a6:1d:1d:
-         e4:71:bf:dc:cd:94:99:5c:20:24:73:7f:42:6e:1e:d0:4b:89:
-         6f:e3:1e:fa:16:7d:1e:b6:92:5f:e2:f8:66:3f:9f:fe:4b:0c:
-         39:c0:c1:bf:e3:8b:e9:cd:25:39:f6:50:4f:2a:a0:8c:1d:0c:
-         26:6a:3a:65:42:ee:4e:2a:23:5d:54:79:ca:9e:57:9b:c0:c0:
-         04:55:d4:ad:4f:06:88:71:f7:d8:6f:cd:7d:8e:92:a9:85:aa:
-         a0:3c:0d:47:af:f9:cd:db:d6:41:f7:e1:a2:2d:b6:4d:70:78:
-         9f:08:07:dd:9b:27:bf:cb:85:07:55:0d:bc:55:1c:84:04:84:
-         98:9e:62:80:ca:93:b8:16:5b:74:fe:a1:cf:d7:59:99:be:23:
-         f4:e3:a3:5f:2b:22:a5:38:09:c0:04:89:2e:f4:64:fe:b9:90:
-         17:38:02:2c:6b:ae:ca:36:f1:3a:e0:e1:db:47:99:78:59:ed:
-         98:b7:95:f9:06:5a:37:03:9f:96:bd:87:cd:8d:f9:5c:3b:22:
-         b2:ca:f6:b0:e6:b9:70:4e:70:ea:ab:25:bd:f7:4f:1a:5d:7b:
-         d2:36:aa:30:c1:95:cb:e5:71:3a:51:6e:e5:b4:b6:e2:19:55:
-         05:50:e5:4d:88:8d:fd:0e:0e:e3:5b:86:61:cf:10:b7:dd:7f:
-         12:01:b8:bf:2c:a6:86:7b:86:ff:b3:cc:b0:c7:ca:2a:c6:33:
-         2e:81:f8:bc:19:e0:da:b4:d5:6a:69:dd:cb:c6:5d:41:7b:d0:
-         d1:02:67:7f:c0:39:e2:7c:60:9a:8b:ce:c9:1f:2a:0c:69:04:
-         22:36:4d:50:20:bc:cd:6a:fa:5e:c2:96:ef:d0:82:55:ea:2c:
-         64:87:59:36:f3:db:06:80:41:1b:8d:75:6e:db:bc:66:d5:15:
-         a3:72:89:d0:ee:ed:e4:37:b1:68:40:7c:9e:da:5d:01:12:91:
-         f3:bb:39:45:57:26
+         cf:0f:89:a8:6e:1e:ca:36:a7:35:90:60:66:0a:d3:ae:59:00:
+         10:18:e7:33:26:96:df:36:81:0e:43:bd:e2:f9:38:ee:6f:9a:
+         9f:a2:f4:a2:75:58:ef:47:83:64:1b:aa:61:99:f9:49:53:5d:
+         cf:ab:e1:79:33:ad:d0:87:3e:b7:0b:8a:8e:aa:a2:0f:e1:be:
+         c9:91:c1:e7:d6:0d:e0:16:3d:4c:01:62:eb:c0:d5:7c:7b:94:
+         d5:6b:7b:0c:c0:d8:bd:0f:b6:b4:1c:7f:c7:77:40:e3:d1:c8:
+         d8:df:36:56:01:69:c6:10:20:c0:88:57:a4:cf:4b:99:1a:ba:
+         1b:4c:d3:06:1a:ce:b7:92:3d:71:47:5a:66:c0:84:a3:b3:92:
+         01:62:b8:8d:c0:b4:c3:f5:07:a3:93:38:94:e8:d5:76:04:19:
+         68:8b:11:5e:2e:03:64:8e:a9:ad:29:8b:45:a2:0d:4e:a3:c1:
+         33:a5:5c:5e:a4:7d:9e:7f:13:96:b6:f0:18:3b:8b:03:9c:fa:
+         2a:03:02:17:ef:6f:23:fe:a0:6d:b1:52:32:64:da:ac:d9:f8:
+         aa:bc:d4:8b:50:a7:3c:b4:ca:b5:62:5e:ce:87:f1:85:4e:a7:
+         98:85:ea:17:6e:3a:ef:5e:74:4e:13:7c:17:5b:72:92:aa:bf:
+         dc:b3:03:28:79:83:89:e5:b2:f9:85:64:f2:d1:7a:cb:cb:22:
+         87:1a:ce:34:c7:a3:8d:06:04:3d:ad:f8:f1:af:0b:d0:2a:06:
+         26:de:8d:fc:7a:07:0a:82:98:0b:2f:40:bb:d8:36:d7:7f:df:
+         ba:f3:b7:5d:5b:9b:8f:4f:48:71:b6:cf:05:e7:a3:6c:e8:37:
+         3a:f1:23:73:da:00:c3:b5:99:b1:eb:24:7f:57:8d:71:f4:37:
+         11:c3:61:19:3c:70:8b:9b:2a:cb:6f:5e:25:33:99:0f:d2:a4:
+         68:35:b5:2a:fb:8b:d4:9f:04:3f:58:e0:f4:d5:dd:a5:ca:d8:
+         55:00:50:db:51:ce
 -----BEGIN CERTIFICATE-----
-MIIEKDCCApCgAwIBAgIJAK2MCej7oojNMA0GCSqGSIb3DQEBDAUAMFExCzAJBgNV
+MIIEKDCCApCgAwIBAgIJAK2MCej7oojQMA0GCSqGSIb3DQEBDAUAMFExCzAJBgNV
 BAYTAkZJMREwDwYDVQQHDAhIZWxzaW5raTEOMAwGA1UECgwFdzEuZmkxHzAdBgNV
-BAMMFlN1aXRlIEIgUlNBIDNrIFJvb3QgQ0EwHhcNMTkwODE2MTMxOTQxWhcNMjEw
-ODE1MTMxOTQxWjA8MQswCQYDVQQGEwJGSTEOMAwGA1UECgwFdzEuZmkxHTAbBgNV
+BAMMFlN1aXRlIEIgUlNBIDNrIFJvb3QgQ0EwHhcNMjEwODE5MTA1NjQ3WhcNMjMw
+ODE5MTA1NjQ3WjA8MQswCQYDVQQGEwJGSTEOMAwGA1UECgwFdzEuZmkxHTAbBgNV
 BAMMFHVzZXItcnNhMzA3Mi1yc2EyMDQ4MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
 MIIBCgKCAQEA22b/i5Vmli5KdAKAQ/wJ+rZBeAn46b9rQf1bv8xm2AfDDexIl40s
 T1j1tScH7kh8a5iiduiLlBF3aDZDHyyIn9ZA3+wnFmOuNBzV7CbF2a13qXMUhqOk
@@ -84,13 +84,13 @@
 HQYDVR0OBBYEFMyFqj3kN1E+cEaWjgBlw4Eg4OSHMB8GA1UdIwQYMBaAFCH379rD
 NDrtzdVQwLO6Ce4/gNdwMCUGA1UdEQQeMByBGnVzZXItcnNhMzA3Mi1yc2EyMDQ4
 QHcxLmZpMBMGA1UdJQQMMAoGCCsGAQUFBwMCMAsGA1UdDwQEAwIFoDANBgkqhkiG
-9w0BAQwFAAOCAYEAVlgx5JBBAcoZlwbgWnSkph0d5HG/3M2UmVwgJHN/Qm4e0EuJ
-b+Me+hZ9HraSX+L4Zj+f/ksMOcDBv+OL6c0lOfZQTyqgjB0MJmo6ZULuTiojXVR5
-yp5Xm8DABFXUrU8GiHH32G/NfY6SqYWqoDwNR6/5zdvWQffhoi22TXB4nwgH3Zsn
-v8uFB1UNvFUchASEmJ5igMqTuBZbdP6hz9dZmb4j9OOjXysipTgJwASJLvRk/rmQ
-FzgCLGuuyjbxOuDh20eZeFntmLeV+QZaNwOflr2HzY35XDsissr2sOa5cE5w6qsl
-vfdPGl170jaqMMGVy+VxOlFu5bS24hlVBVDlTYiN/Q4O41uGYc8Qt91/EgG4vyym
-hnuG/7PMsMfKKsYzLoH4vBng2rTVamndy8ZdQXvQ0QJnf8A54nxgmovOyR8qDGkE
-IjZNUCC8zWr6XsKW79CCVeosZIdZNvPbBoBBG411btu8ZtUVo3KJ0O7t5DexaEB8
-ntpdARKR87s5RVcm
+9w0BAQwFAAOCAYEAzw+JqG4eyjanNZBgZgrTrlkAEBjnMyaW3zaBDkO94vk47m+a
+n6L0onVY70eDZBuqYZn5SVNdz6vheTOt0Ic+twuKjqqiD+G+yZHB59YN4BY9TAFi
+68DVfHuU1Wt7DMDYvQ+2tBx/x3dA49HI2N82VgFpxhAgwIhXpM9LmRq6G0zTBhrO
+t5I9cUdaZsCEo7OSAWK4jcC0w/UHo5M4lOjVdgQZaIsRXi4DZI6prSmLRaINTqPB
+M6VcXqR9nn8TlrbwGDuLA5z6KgMCF+9vI/6gbbFSMmTarNn4qrzUi1CnPLTKtWJe
+zofxhU6nmIXqF2467150ThN8F1tykqq/3LMDKHmDieWy+YVk8tF6y8sihxrONMej
+jQYEPa348a8L0CoGJt6N/HoHCoKYCy9Au9g213/fuvO3XVubj09IcbbPBeejbOg3
+OvEjc9oAw7WZseskf1eNcfQ3EcNhGTxwi5sqy29eJTOZD9KkaDW1KvuL1J8EP1jg
+9NXdpcrYVQBQ21HO
 -----END CERTIFICATE-----
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/rsa3072-user.pem b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/rsa3072-user.pem
index fef367b..dff6581 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/rsa3072-user.pem
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/rsa3072-user.pem
@@ -2,12 +2,12 @@
     Data:
         Version: 3 (0x2)
         Serial Number:
-            ad:8c:09:e8:fb:a2:88:cc
+            ad:8c:09:e8:fb:a2:88:cf
         Signature Algorithm: sha384WithRSAEncryption
         Issuer: C=FI, L=Helsinki, O=w1.fi, CN=Suite B RSA 3k Root CA
         Validity
-            Not Before: Aug 16 13:19:41 2019 GMT
-            Not After : Aug 15 13:19:41 2021 GMT
+            Not Before: Aug 19 10:56:47 2021 GMT
+            Not After : Aug 19 10:56:47 2023 GMT
         Subject: C=FI, O=w1.fi, CN=user-rsa3072
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
@@ -55,33 +55,33 @@
             X509v3 Key Usage: 
                 Digital Signature, Key Encipherment
     Signature Algorithm: sha384WithRSAEncryption
-         b8:51:21:70:fc:ce:a2:a6:43:db:b1:54:c6:51:ee:a9:77:dd:
-         ad:3f:75:fc:23:0c:be:a5:e7:ec:f4:2d:33:04:08:48:45:58:
-         5d:1f:83:57:57:43:b0:be:81:69:d7:51:65:f8:24:97:8e:3c:
-         01:60:a3:b3:0a:11:43:94:2c:68:f0:a1:28:63:e4:ce:a8:27:
-         2d:74:6f:8f:e4:10:8e:9a:56:91:72:61:fd:85:82:8a:48:dd:
-         d6:f3:40:97:de:6d:8b:51:ef:e8:a0:a5:65:45:96:aa:85:d1:
-         b6:86:8e:53:68:2d:d0:c3:6b:11:ba:8e:15:3c:a4:b7:38:fe:
-         9f:1c:57:b8:58:a3:f6:ff:31:e4:95:f9:d8:52:80:66:b1:c4:
-         f9:ce:95:01:30:89:7b:e7:ec:86:b5:c6:95:46:55:5f:ce:36:
-         43:8f:9c:ca:48:86:20:d0:60:89:c8:03:d0:25:1e:38:25:bb:
-         d8:b1:e1:72:9a:f5:f3:97:e6:76:41:80:0e:00:47:06:59:46:
-         2b:37:57:07:77:e4:5e:9c:38:0e:80:81:61:ab:89:ef:43:99:
-         7a:2c:24:b5:60:c2:5e:a8:2b:59:03:1d:e3:ab:b9:0b:02:3f:
-         16:90:57:70:56:d7:40:42:70:0e:de:27:9e:f1:27:30:e0:2c:
-         56:5c:bf:56:43:db:fb:a6:14:ba:0a:ef:87:d5:a4:00:73:59:
-         8b:a0:10:1d:b1:8a:31:a8:ef:ae:c7:c5:25:65:b5:05:a0:df:
-         16:63:0e:58:f4:0e:5f:9c:e8:95:ea:b5:18:63:6e:ae:5a:dc:
-         c5:d5:95:c7:f9:23:46:76:96:d6:d2:ec:a0:63:01:3c:63:f1:
-         99:6e:b1:f2:3c:e7:08:ff:67:53:dd:b7:6e:83:91:cb:32:e9:
-         5e:64:8b:5f:46:6c:80:02:a8:37:3c:a3:17:ad:33:5f:dc:75:
-         e6:41:dc:db:19:26:c0:34:76:5d:19:a5:10:89:ad:59:5e:5d:
-         69:41:2d:3f:64:d0
+         46:8b:f8:99:9e:59:45:06:16:c4:09:52:4e:06:63:25:55:9f:
+         e7:4b:65:41:b3:af:64:1f:ff:70:17:18:a4:0f:d7:95:97:bd:
+         81:2a:f7:df:8f:c5:76:ec:f0:95:4d:c2:17:3f:54:7d:63:1a:
+         82:3c:22:7b:49:55:6c:c0:9b:a2:66:fe:9c:d5:ce:ee:9c:f0:
+         f3:17:32:84:09:0d:e6:a9:13:a5:af:94:95:ed:8c:85:cd:c9:
+         65:ed:6a:05:3f:56:8d:07:1e:be:b4:eb:5b:92:d3:bb:90:4f:
+         1c:e7:3b:bc:b0:9a:da:c9:d7:14:55:de:a7:68:d0:c7:58:7e:
+         73:21:4b:9c:9e:37:38:d3:e2:77:ec:56:8e:b7:43:01:4a:7c:
+         15:0e:ed:b9:e5:fe:28:b9:df:f4:4f:96:43:2d:9c:d3:7f:dc:
+         46:37:8e:3a:60:47:1b:24:b6:a5:df:34:7b:b5:32:6a:1c:f0:
+         37:3c:10:0a:5c:53:6b:11:11:aa:1c:4b:da:d2:b5:e0:59:ee:
+         f1:0f:0c:f5:ec:49:14:24:a1:68:39:b2:85:c6:30:79:e1:ac:
+         5e:08:1a:93:ba:fc:97:1c:aa:e2:1f:99:2c:ca:0b:3f:7a:ab:
+         9e:35:ab:b7:78:f5:a0:d2:38:f8:ed:91:e7:9e:0c:b7:fc:ce:
+         d9:bc:f6:f5:cc:6b:a2:0a:78:94:ac:16:aa:f5:b3:8b:7e:e8:
+         3d:67:4d:e8:5d:fc:6a:f1:a4:0f:7d:20:f0:e7:7f:af:f4:71:
+         73:e5:77:e3:6b:41:9b:25:fb:65:4a:96:60:ac:58:18:27:21:
+         a3:aa:89:fb:c3:e6:e5:bf:ad:89:92:ae:9e:66:18:49:6f:16:
+         01:2c:05:76:17:92:34:9a:dc:ed:d8:e0:f6:20:37:29:ef:4b:
+         6c:6e:23:94:67:3d:c8:04:39:46:10:c5:bf:02:cf:1a:52:b6:
+         43:35:84:aa:b1:0e:0b:d7:cb:4c:89:bc:43:f8:84:3f:39:8f:
+         6e:ea:28:e6:d9:a6
 -----BEGIN CERTIFICATE-----
-MIIEmDCCAwCgAwIBAgIJAK2MCej7oojMMA0GCSqGSIb3DQEBDAUAMFExCzAJBgNV
+MIIEmDCCAwCgAwIBAgIJAK2MCej7oojPMA0GCSqGSIb3DQEBDAUAMFExCzAJBgNV
 BAYTAkZJMREwDwYDVQQHDAhIZWxzaW5raTEOMAwGA1UECgwFdzEuZmkxHzAdBgNV
-BAMMFlN1aXRlIEIgUlNBIDNrIFJvb3QgQ0EwHhcNMTkwODE2MTMxOTQxWhcNMjEw
-ODE1MTMxOTQxWjA0MQswCQYDVQQGEwJGSTEOMAwGA1UECgwFdzEuZmkxFTATBgNV
+BAMMFlN1aXRlIEIgUlNBIDNrIFJvb3QgQ0EwHhcNMjEwODE5MTA1NjQ3WhcNMjMw
+ODE5MTA1NjQ3WjA0MQswCQYDVQQGEwJGSTEOMAwGA1UECgwFdzEuZmkxFTATBgNV
 BAMMDHVzZXItcnNhMzA3MjCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGB
 AJJ3Z45ENIOoN/mpxHJccXKdNR09jDQiXCT4h4He3qylk3fFOKSCnIwGmxSLUgky
 TDHF+OkvZIo5CnCeToqcvKWreBhSRHX+wwBh5x9FwBJy5DieKJ32dmBws3sRypCY
@@ -94,13 +94,13 @@
 IQIDAQABo4GPMIGMMAkGA1UdEwQCMAAwHQYDVR0OBBYEFLFPNhckQK1rBTOHxK1P
 SlOv9dYjMB8GA1UdIwQYMBaAFCH379rDNDrtzdVQwLO6Ce4/gNdwMB0GA1UdEQQW
 MBSBEnVzZXItcnNhMzA3MkB3MS5maTATBgNVHSUEDDAKBggrBgEFBQcDAjALBgNV
-HQ8EBAMCBaAwDQYJKoZIhvcNAQEMBQADggGBALhRIXD8zqKmQ9uxVMZR7ql33a0/
-dfwjDL6l5+z0LTMECEhFWF0fg1dXQ7C+gWnXUWX4JJeOPAFgo7MKEUOULGjwoShj
-5M6oJy10b4/kEI6aVpFyYf2FgopI3dbzQJfebYtR7+igpWVFlqqF0baGjlNoLdDD
-axG6jhU8pLc4/p8cV7hYo/b/MeSV+dhSgGaxxPnOlQEwiXvn7Ia1xpVGVV/ONkOP
-nMpIhiDQYInIA9AlHjglu9ix4XKa9fOX5nZBgA4ARwZZRis3Vwd35F6cOA6AgWGr
-ie9DmXosJLVgwl6oK1kDHeOruQsCPxaQV3BW10BCcA7eJ57xJzDgLFZcv1ZD2/um
-FLoK74fVpABzWYugEB2xijGo767HxSVltQWg3xZjDlj0Dl+c6JXqtRhjbq5a3MXV
-lcf5I0Z2ltbS7KBjATxj8ZlusfI85wj/Z1Pdt26Dkcsy6V5ki19GbIACqDc8oxet
-M1/cdeZB3NsZJsA0dl0ZpRCJrVleXWlBLT9k0A==
+HQ8EBAMCBaAwDQYJKoZIhvcNAQEMBQADggGBAEaL+JmeWUUGFsQJUk4GYyVVn+dL
+ZUGzr2Qf/3AXGKQP15WXvYEq99+PxXbs8JVNwhc/VH1jGoI8IntJVWzAm6Jm/pzV
+zu6c8PMXMoQJDeapE6WvlJXtjIXNyWXtagU/Vo0HHr6061uS07uQTxznO7ywmtrJ
+1xRV3qdo0MdYfnMhS5yeNzjT4nfsVo63QwFKfBUO7bnl/ii53/RPlkMtnNN/3EY3
+jjpgRxsktqXfNHu1Mmoc8Dc8EApcU2sREaocS9rSteBZ7vEPDPXsSRQkoWg5soXG
+MHnhrF4IGpO6/JccquIfmSzKCz96q541q7d49aDSOPjtkeeeDLf8ztm89vXMa6IK
+eJSsFqr1s4t+6D1nTehd/GrxpA99IPDnf6/0cXPld+NrQZsl+2VKlmCsWBgnIaOq
+ifvD5uW/rYmSrp5mGElvFgEsBXYXkjSa3O3Y4PYgNynvS2xuI5RnPcgEOUYQxb8C
+zxpStkM1hKqxDgvXy0yJvEP4hD85j27qKObZpg==
 -----END CERTIFICATE-----
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-certpol.pem b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-certpol.pem
index d014542..b72f528 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-certpol.pem
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-certpol.pem
@@ -2,12 +2,12 @@
     Data:
         Version: 3 (0x2)
         Serial Number:
-            d8:d3:e3:a6:cb:e3:cd:63
+            d8:d3:e3:a6:cb:e3:cd:6f
         Signature Algorithm: sha256WithRSAEncryption
         Issuer: C=FI, L=Tuusula, O=w1.fi, CN=Root CA
         Validity
-            Not Before: May  2 19:55:38 2020 GMT
-            Not After : May  2 19:55:38 2021 GMT
+            Not Before: May  3 17:02:53 2021 GMT
+            Not After : May  3 17:02:53 2022 GMT
         Subject: C=FI, O=w1.fi, CN=server-policies.w1.fi
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
@@ -59,25 +59,25 @@
             X509v3 Extended Key Usage: 
                 TLS Web Server Authentication
     Signature Algorithm: sha256WithRSAEncryption
-         b8:ef:8e:09:f5:67:a3:d6:5c:92:d2:55:f8:f2:52:e4:cd:ea:
-         87:a6:aa:42:73:b2:b4:30:d8:80:3f:aa:d5:f2:65:32:b9:88:
-         7d:f1:b2:c2:c1:fe:17:c7:76:7e:d9:7b:4b:1a:87:dc:1f:f6:
-         57:0d:8b:5f:2a:5d:e2:7f:f4:8d:39:3a:a4:9e:9d:f3:c1:58:
-         cf:04:fd:72:40:c2:9a:ef:98:b2:6a:67:86:27:2c:f6:e6:dd:
-         b1:a0:20:b1:c0:cf:fb:00:43:1f:6f:ac:b2:3f:02:a6:87:80:
-         18:74:6b:0b:26:07:d3:7a:72:1c:c7:1d:a7:dc:13:cb:70:ac:
-         24:2e:45:9c:bf:53:de:ea:eb:50:4a:60:87:26:8a:28:4e:16:
-         76:91:b1:b3:e2:4d:66:fd:12:60:ed:24:59:f4:f9:47:59:d1:
-         4c:6e:d1:9d:55:d4:72:d8:c4:da:2f:b4:73:20:d3:7e:f7:9f:
-         6e:99:b8:06:1d:5f:8c:18:ab:a3:a8:fa:50:52:50:e5:2b:c9:
-         fa:1d:fe:f0:ce:33:19:d5:38:e6:ba:90:c9:5e:e6:67:60:e0:
-         50:16:7c:4c:08:89:d2:e2:fe:bc:57:0f:ef:83:75:ec:1d:f3:
-         10:07:ce:c2:d6:30:44:f2:ec:b9:78:71:c2:41:8d:78:e4:d6:
-         67:42:d7:f5
+         ae:91:58:d8:0f:03:02:4e:84:da:cd:13:7d:5c:d0:52:04:08:
+         7f:ea:12:73:5d:ad:a1:64:a2:0d:e6:83:ca:fa:35:7d:1e:35:
+         bd:24:5d:19:b7:1b:f4:dd:75:a0:86:60:65:e0:73:69:55:ae:
+         37:13:82:99:ad:8a:fb:de:73:51:45:b6:38:e0:3a:6c:b0:f1:
+         e8:b3:09:10:f9:89:87:c9:64:be:ac:27:c2:cc:e9:1b:dc:0f:
+         c4:37:8e:1e:a3:16:2c:42:ed:da:c9:27:c0:ee:fd:45:62:b1:
+         e6:71:ca:a5:a3:3b:6b:62:03:fb:a3:aa:fd:b4:0e:e2:3f:d1:
+         c1:27:92:54:e8:fa:34:01:d3:4f:22:6e:00:24:e7:34:7a:e6:
+         ef:6e:d3:6b:ae:f2:a9:df:dd:79:1b:1f:ee:52:56:69:26:dc:
+         0e:e8:48:9f:36:11:0e:c7:7c:48:ec:0a:c2:d6:ea:f7:9a:06:
+         65:e1:6c:77:45:76:51:2d:74:2d:16:6a:0b:1b:76:d7:46:2f:
+         e1:30:ea:59:c9:0f:da:43:c6:bf:4b:0e:31:9c:ae:80:0a:bb:
+         86:d0:ee:91:0d:9a:72:3e:8d:c4:bc:08:43:d2:31:ba:06:2b:
+         b6:27:ba:f1:bb:56:22:1a:f8:b4:46:32:da:bf:0a:1c:a6:1e:
+         4b:03:23:c1
 -----BEGIN CERTIFICATE-----
-MIIEWDCCA0CgAwIBAgIJANjT46bL481jMA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
+MIIEWDCCA0CgAwIBAgIJANjT46bL481vMA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
 BAYTAkZJMRAwDgYDVQQHDAdUdXVzdWxhMQ4wDAYDVQQKDAV3MS5maTEQMA4GA1UE
-AwwHUm9vdCBDQTAeFw0yMDA1MDIxOTU1MzhaFw0yMTA1MDIxOTU1MzhaMD0xCzAJ
+AwwHUm9vdCBDQTAeFw0yMTA1MDMxNzAyNTNaFw0yMjA1MDMxNzAyNTNaMD0xCzAJ
 BgNVBAYTAkZJMQ4wDAYDVQQKDAV3MS5maTEeMBwGA1UEAwwVc2VydmVyLXBvbGlj
 aWVzLncxLmZpMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA0qbvm71g
 Y6F1rUvTb1lehPpkoGQkC3hI/I1miy9uHUQrrsNtlLrLozS+C05HjVvZmaaoBwmH
@@ -92,11 +92,11 @@
 HwYDVR0jBBgwFoAUpP25ORuBs6rriB3Ugam1EXDMp+EwNQYIKwYBBQUHAQEEKTAn
 MCUGCCsGAQUFBzABhhlodHRwOi8vc2VydmVyLncxLmZpOjg4ODgvMCAGA1UdEQQZ
 MBeCFXNlcnZlci1wb2xpY2llcy53MS5maTAYBgNVHSAEETAPMA0GCysGAQQBgr5o
-AQMBMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4IBAQC4744J
-9Wej1lyS0lX48lLkzeqHpqpCc7K0MNiAP6rV8mUyuYh98bLCwf4Xx3Z+2XtLGofc
-H/ZXDYtfKl3if/SNOTqknp3zwVjPBP1yQMKa75iyameGJyz25t2xoCCxwM/7AEMf
-b6yyPwKmh4AYdGsLJgfTenIcxx2n3BPLcKwkLkWcv1Pe6utQSmCHJoooThZ2kbGz
-4k1m/RJg7SRZ9PlHWdFMbtGdVdRy2MTaL7RzINN+959umbgGHV+MGKujqPpQUlDl
-K8n6Hf7wzjMZ1TjmupDJXuZnYOBQFnxMCInS4v68Vw/vg3XsHfMQB87C1jBE8uy5
-eHHCQY145NZnQtf1
+AQMBMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4IBAQCukVjY
+DwMCToTazRN9XNBSBAh/6hJzXa2hZKIN5oPK+jV9HjW9JF0Ztxv03XWghmBl4HNp
+Va43E4KZrYr73nNRRbY44DpssPHoswkQ+YmHyWS+rCfCzOkb3A/EN44eoxYsQu3a
+ySfA7v1FYrHmccqloztrYgP7o6r9tA7iP9HBJ5JU6Po0AdNPIm4AJOc0eubvbtNr
+rvKp3915Gx/uUlZpJtwO6EifNhEOx3xI7ArC1ur3mgZl4Wx3RXZRLXQtFmoLG3bX
+Ri/hMOpZyQ/aQ8a/Sw4xnK6ACruG0O6RDZpyPo3EvAhD0jG6Biu2J7rxu1YiGvi0
+RjLavwocph5LAyPB
 -----END CERTIFICATE-----
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-certpol2.pem b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-certpol2.pem
index 92c853d..cc8ff57 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-certpol2.pem
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-certpol2.pem
@@ -2,12 +2,12 @@
     Data:
         Version: 3 (0x2)
         Serial Number:
-            d8:d3:e3:a6:cb:e3:cd:64
+            d8:d3:e3:a6:cb:e3:cd:70
         Signature Algorithm: sha256WithRSAEncryption
         Issuer: C=FI, L=Tuusula, O=w1.fi, CN=Root CA
         Validity
-            Not Before: May  2 19:55:38 2020 GMT
-            Not After : May  2 19:55:38 2021 GMT
+            Not Before: May  3 17:02:53 2021 GMT
+            Not After : May  3 17:02:53 2022 GMT
         Subject: C=FI, O=w1.fi, CN=server-policies2.w1.fi
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
@@ -59,25 +59,25 @@
             X509v3 Extended Key Usage: 
                 TLS Web Server Authentication
     Signature Algorithm: sha256WithRSAEncryption
-         7d:38:98:e6:21:03:e4:1a:44:08:91:ca:21:31:5c:97:66:74:
-         4c:0a:84:21:83:92:22:63:53:8d:06:1f:48:62:c1:e3:ce:e9:
-         74:2a:63:0b:2b:f9:b5:d0:63:37:39:4c:b4:29:9e:98:49:48:
-         1f:cd:bc:28:5f:81:56:ee:d9:d9:f7:51:6b:31:62:3a:a4:59:
-         98:f3:18:3d:f9:c1:d8:71:6d:85:e1:67:0e:d6:cc:ab:61:22:
-         46:f1:38:11:53:74:41:44:22:63:ac:e7:6b:12:b6:39:20:7f:
-         fe:e2:c7:aa:e6:80:64:d7:24:92:4e:79:fa:9d:41:75:45:30:
-         4b:2b:ce:d9:b0:38:25:79:81:b3:c4:4b:60:a1:24:9f:ad:c7:
-         37:b9:44:d5:02:7c:2a:05:7f:d3:f1:76:21:6a:67:d7:a9:ab:
-         e0:3e:4c:90:30:28:8a:75:58:ae:6a:98:39:b6:6c:f6:eb:9f:
-         c8:24:11:a3:33:0f:aa:30:05:23:ab:1f:4f:f4:55:f3:b8:6b:
-         c5:dc:dc:32:15:58:fd:cc:cf:ba:f5:9a:1b:4e:58:68:85:b7:
-         eb:b0:db:e9:a9:87:f9:b0:4e:c9:43:79:26:97:75:ff:d4:55:
-         01:f7:c6:f5:21:56:8b:f7:f3:80:a2:f4:3f:50:2a:e3:60:52:
-         b6:5c:83:14
+         58:a7:cd:3e:71:b1:2c:df:ab:0e:bb:37:68:95:6d:20:75:c0:
+         38:96:e2:56:eb:57:4a:d7:43:93:d2:28:a7:d9:82:ff:eb:aa:
+         03:c3:c4:06:09:04:1e:1b:f0:18:2a:27:32:30:22:97:93:21:
+         06:e8:2b:4f:73:dc:84:39:6f:e9:ad:2e:d6:e3:c1:e9:36:59:
+         aa:7c:d0:a5:3e:23:9a:bc:db:d9:bf:38:f6:21:ef:bd:0e:4b:
+         4d:4d:5d:0e:8a:ae:fe:d0:47:ae:8f:4d:fc:c2:bb:5b:8f:a4:
+         06:4d:0b:26:e3:9e:f8:dd:d1:e0:21:92:55:17:85:49:09:ad:
+         45:24:e5:05:55:68:b9:45:36:af:0d:b8:6f:eb:66:3d:fb:ab:
+         68:c4:d2:e7:7e:6a:a9:ad:23:4a:25:72:db:ae:96:03:a5:c7:
+         3f:a4:8e:f8:7c:16:5a:c4:32:53:9f:56:eb:a4:f1:99:dc:ac:
+         0b:4f:2d:0f:f1:03:ca:ba:b2:0b:6f:9f:4d:90:84:66:3a:a5:
+         b3:f0:a2:50:59:cb:1b:19:af:6d:62:95:73:a4:94:76:8d:3e:
+         18:49:72:be:42:a1:66:a6:ee:d7:08:51:da:8b:d8:d6:6d:36:
+         e2:2f:4b:78:74:2c:10:17:0c:84:16:14:ba:b8:10:28:dc:0b:
+         22:aa:40:93
 -----BEGIN CERTIFICATE-----
-MIIEWjCCA0KgAwIBAgIJANjT46bL481kMA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
+MIIEWjCCA0KgAwIBAgIJANjT46bL481wMA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
 BAYTAkZJMRAwDgYDVQQHDAdUdXVzdWxhMQ4wDAYDVQQKDAV3MS5maTEQMA4GA1UE
-AwwHUm9vdCBDQTAeFw0yMDA1MDIxOTU1MzhaFw0yMTA1MDIxOTU1MzhaMD4xCzAJ
+AwwHUm9vdCBDQTAeFw0yMTA1MDMxNzAyNTNaFw0yMjA1MDMxNzAyNTNaMD4xCzAJ
 BgNVBAYTAkZJMQ4wDAYDVQQKDAV3MS5maTEfMB0GA1UEAwwWc2VydmVyLXBvbGlj
 aWVzMi53MS5maTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAOZQ0SgF
 J2zUQtNCx8xTqWvCo6sgbxc0neQdMdDEaGVC1ei9qrjk6fbuLnXNaoz2jqqvbHzr
@@ -92,11 +92,11 @@
 MB8GA1UdIwQYMBaAFKT9uTkbgbOq64gd1IGptRFwzKfhMDUGCCsGAQUFBwEBBCkw
 JzAlBggrBgEFBQcwAYYZaHR0cDovL3NlcnZlci53MS5maTo4ODg4LzAhBgNVHREE
 GjAYghZzZXJ2ZXItcG9saWNpZXMyLncxLmZpMBgGA1UdIAQRMA8wDQYLKwYBBAGC
-vmgBAwIwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAH04
-mOYhA+QaRAiRyiExXJdmdEwKhCGDkiJjU40GH0hiwePO6XQqYwsr+bXQYzc5TLQp
-nphJSB/NvChfgVbu2dn3UWsxYjqkWZjzGD35wdhxbYXhZw7WzKthIkbxOBFTdEFE
-ImOs52sStjkgf/7ix6rmgGTXJJJOefqdQXVFMEsrztmwOCV5gbPES2ChJJ+txze5
-RNUCfCoFf9PxdiFqZ9epq+A+TJAwKIp1WK5qmDm2bPbrn8gkEaMzD6owBSOrH0/0
-VfO4a8Xc3DIVWP3Mz7r1mhtOWGiFt+uw2+mph/mwTslDeSaXdf/UVQH3xvUhVov3
-84Ci9D9QKuNgUrZcgxQ=
+vmgBAwIwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAFin
+zT5xsSzfqw67N2iVbSB1wDiW4lbrV0rXQ5PSKKfZgv/rqgPDxAYJBB4b8BgqJzIw
+IpeTIQboK09z3IQ5b+mtLtbjwek2Wap80KU+I5q829m/OPYh770OS01NXQ6Krv7Q
+R66PTfzCu1uPpAZNCybjnvjd0eAhklUXhUkJrUUk5QVVaLlFNq8NuG/rZj37q2jE
+0ud+aqmtI0olctuulgOlxz+kjvh8FlrEMlOfVuuk8ZncrAtPLQ/xA8q6sgtvn02Q
+hGY6pbPwolBZyxsZr21ilXOklHaNPhhJcr5CoWam7tcIUdqL2NZtNuIvS3h0LBAX
+DIQWFLq4ECjcCyKqQJM=
 -----END CERTIFICATE-----
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-eku-client-server.pem b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-eku-client-server.pem
index b44f82c..6286160 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-eku-client-server.pem
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-eku-client-server.pem
@@ -2,12 +2,12 @@
     Data:
         Version: 3 (0x2)
         Serial Number:
-            d8:d3:e3:a6:cb:e3:cd:62
+            d8:d3:e3:a6:cb:e3:cd:6d
         Signature Algorithm: sha256WithRSAEncryption
         Issuer: C=FI, L=Tuusula, O=w1.fi, CN=Root CA
         Validity
-            Not Before: May  2 19:55:38 2020 GMT
-            Not After : May  2 19:55:38 2021 GMT
+            Not Before: May  3 17:02:53 2021 GMT
+            Not After : May  3 17:02:53 2022 GMT
         Subject: C=FI, O=w1.fi, CN=server6.w1.fi
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
@@ -46,25 +46,25 @@
             X509v3 Extended Key Usage: 
                 TLS Web Client Authentication, TLS Web Server Authentication
     Signature Algorithm: sha256WithRSAEncryption
-         5f:6e:13:f9:af:c4:47:4d:78:19:5e:d2:bb:21:55:c3:4b:64:
-         42:94:fe:37:7b:3a:4a:fc:42:f1:fc:b3:c3:05:93:46:39:cd:
-         a3:40:c9:90:47:a2:6b:af:d8:21:a9:1e:11:02:c8:84:e2:b2:
-         8b:52:ad:30:49:e7:80:16:98:d2:0c:01:56:c2:f5:6c:a4:98:
-         b0:a2:af:6c:e8:6e:6d:9b:31:21:22:91:51:81:e1:f0:0d:eb:
-         97:96:98:58:84:b3:29:a6:8f:d2:b5:ce:37:a7:64:b8:7f:fb:
-         f7:15:3c:c0:c7:2a:7f:bb:50:67:a0:5b:55:65:5d:1f:0a:90:
-         10:16:c1:93:cd:a3:ab:8b:4b:9a:f0:e2:e7:ac:e6:5a:fd:bf:
-         46:37:92:3e:f7:f5:d8:57:87:c2:88:cc:b1:40:06:92:d5:f0:
-         f2:3d:c5:d0:fd:48:5c:bf:bf:5b:da:82:11:55:6d:95:17:f2:
-         43:be:8e:e7:f5:0e:d3:b3:de:65:ea:8c:85:4b:bd:4d:93:f0:
-         6f:8b:2f:0e:fb:9f:cb:65:e8:72:68:92:43:08:1d:3e:1f:5a:
-         e5:1c:5d:7e:16:06:04:23:9e:c0:82:8a:a6:33:66:c3:3f:2a:
-         ad:1a:5a:90:02:56:3a:e6:45:d9:f1:02:a5:cd:16:63:03:04:
-         42:85:1c:49
+         97:a5:19:d6:b9:1e:74:53:d4:38:5d:95:2a:8c:6f:88:10:c4:
+         47:28:29:4e:08:65:51:8f:af:34:1e:17:7a:62:7c:8e:f4:c4:
+         6d:ed:94:a9:fa:03:85:9d:7d:01:f8:e3:03:a4:a7:52:0c:6e:
+         46:db:de:44:bc:ce:b3:5a:fc:72:01:a0:b2:49:b2:b2:ce:de:
+         46:d4:68:d7:70:94:7b:48:b9:c9:6c:78:d3:68:3d:4f:66:15:
+         7d:99:ac:65:70:0f:62:ed:b5:a5:b4:69:c4:bc:57:f5:ea:1d:
+         3c:cd:99:36:6f:86:bc:57:69:76:58:fd:15:5d:8d:ed:0c:ca:
+         d8:bb:8e:7d:72:39:ff:04:e9:35:88:88:fa:5c:d7:f5:10:f5:
+         19:4f:2d:90:2f:f3:82:36:7f:4f:45:c5:98:97:f5:f0:61:86:
+         64:ce:b7:24:98:85:f1:59:59:67:ee:51:d0:e7:37:fb:2f:a7:
+         5d:a5:91:a3:f9:97:a8:54:4d:df:ec:22:d1:3e:0e:4d:5c:40:
+         11:2a:43:7d:69:36:73:5e:be:c8:73:d4:74:99:5f:c8:87:c1:
+         99:c0:e6:38:af:f2:8c:39:b7:65:90:a8:58:fa:a2:99:69:e6:
+         ad:77:3e:94:fc:82:38:cf:5f:17:77:e8:4e:6a:8b:75:21:ce:
+         9b:7f:6c:00
 -----BEGIN CERTIFICATE-----
-MIIDnjCCAoagAwIBAgIJANjT46bL481iMA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
+MIIDnjCCAoagAwIBAgIJANjT46bL481tMA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
 BAYTAkZJMRAwDgYDVQQHDAdUdXVzdWxhMQ4wDAYDVQQKDAV3MS5maTEQMA4GA1UE
-AwwHUm9vdCBDQTAeFw0yMDA1MDIxOTU1MzhaFw0yMTA1MDIxOTU1MzhaMDUxCzAJ
+AwwHUm9vdCBDQTAeFw0yMTA1MDMxNzAyNTNaFw0yMjA1MDMxNzAyNTNaMDUxCzAJ
 BgNVBAYTAkZJMQ4wDAYDVQQKDAV3MS5maTEWMBQGA1UEAwwNc2VydmVyNi53MS5m
 aTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAj9IASvkpkTa+Zr1Lv
 jfVzmhooK5Lo1JAlPoVHn8nEuXo1JIQvHlEWZtOsMerxY6RM6ibw+mHHn/J0aWp4
@@ -76,10 +76,10 @@
 3VxpAp4ByzAfBgNVHSMEGDAWgBSk/bk5G4GzquuIHdSBqbURcMyn4TA1BggrBgEF
 BQcBAQQpMCcwJQYIKwYBBQUHMAGGGWh0dHA6Ly9zZXJ2ZXIudzEuZmk6ODg4OC8w
 HQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4IB
-AQBfbhP5r8RHTXgZXtK7IVXDS2RClP43ezpK/ELx/LPDBZNGOc2jQMmQR6Jrr9gh
-qR4RAsiE4rKLUq0wSeeAFpjSDAFWwvVspJiwoq9s6G5tmzEhIpFRgeHwDeuXlphY
-hLMppo/Stc43p2S4f/v3FTzAxyp/u1BnoFtVZV0fCpAQFsGTzaOri0ua8OLnrOZa
-/b9GN5I+9/XYV4fCiMyxQAaS1fDyPcXQ/Uhcv79b2oIRVW2VF/JDvo7n9Q7Ts95l
-6oyFS71Nk/Bviy8O+5/LZehyaJJDCB0+H1rlHF1+FgYEI57AgoqmM2bDPyqtGlqQ
-AlY65kXZ8QKlzRZjAwRChRxJ
+AQCXpRnWuR50U9Q4XZUqjG+IEMRHKClOCGVRj680Hhd6YnyO9MRt7ZSp+gOFnX0B
++OMDpKdSDG5G295EvM6zWvxyAaCySbKyzt5G1GjXcJR7SLnJbHjTaD1PZhV9maxl
+cA9i7bWltGnEvFf16h08zZk2b4a8V2l2WP0VXY3tDMrYu459cjn/BOk1iIj6XNf1
+EPUZTy2QL/OCNn9PRcWYl/XwYYZkzrckmIXxWVln7lHQ5zf7L6ddpZGj+ZeoVE3f
+7CLRPg5NXEARKkN9aTZzXr7Ic9R0mV/Ih8GZwOY4r/KMObdlkKhY+qKZaeatdz6U
+/II4z18Xd+hOaot1Ic6bf2wA
 -----END CERTIFICATE-----
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-eku-client.pem b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-eku-client.pem
index 2e6afa2..af5c5c2 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-eku-client.pem
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-eku-client.pem
@@ -2,12 +2,12 @@
     Data:
         Version: 3 (0x2)
         Serial Number:
-            d8:d3:e3:a6:cb:e3:cd:61
+            d8:d3:e3:a6:cb:e3:cd:6c
         Signature Algorithm: sha256WithRSAEncryption
         Issuer: C=FI, L=Tuusula, O=w1.fi, CN=Root CA
         Validity
-            Not Before: May  2 19:55:38 2020 GMT
-            Not After : May  2 19:55:38 2021 GMT
+            Not Before: May  3 17:02:53 2021 GMT
+            Not After : May  3 17:02:53 2022 GMT
         Subject: C=FI, O=w1.fi, CN=server5.w1.fi
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
@@ -46,25 +46,25 @@
             X509v3 Extended Key Usage: 
                 TLS Web Client Authentication
     Signature Algorithm: sha256WithRSAEncryption
-         22:02:38:3d:90:2f:5d:54:b9:36:61:fd:29:40:c0:88:5d:eb:
-         63:ec:b3:6d:9b:55:8f:10:6b:b7:4b:8a:3f:89:79:fa:52:87:
-         8d:91:3b:2e:ee:84:ae:f8:2d:8e:1d:35:72:cd:b8:7d:9d:98:
-         d3:88:9d:05:c7:85:e7:1a:29:4d:cb:00:da:a3:21:a0:f5:f3:
-         52:f5:80:88:cb:2a:4f:d9:9b:56:c0:37:13:61:74:64:61:fb:
-         8c:25:18:9c:96:e2:f8:bb:e2:48:60:e3:12:d8:a9:d9:9e:93:
-         e8:cd:46:f5:eb:b3:17:62:66:d1:5d:ea:c2:09:d1:7a:34:d2:
-         e0:88:1d:7f:6f:71:25:70:50:d8:51:93:61:8e:70:da:c2:ba:
-         f0:44:81:be:81:54:d6:3c:da:a6:54:62:40:bd:d1:2e:ce:1c:
-         dd:29:49:ba:b5:12:7e:42:64:54:b2:99:93:60:67:6e:1a:63:
-         4b:da:b4:96:28:90:81:c4:28:05:28:64:ff:c6:7a:b3:8c:68:
-         12:e3:28:64:00:82:88:bc:75:46:d2:e7:f9:0a:93:4c:5d:c8:
-         99:27:4c:40:65:0d:ec:b2:86:ea:76:e2:28:c5:77:6b:3d:fc:
-         91:30:89:0a:0b:e0:d4:59:cf:30:de:5f:f6:50:15:5a:40:01:
-         e2:a5:39:cf
+         95:fa:5c:72:fc:2e:aa:a2:b4:f9:22:11:d2:84:33:91:f4:2c:
+         27:59:b9:2d:0c:46:b1:cb:58:2e:66:bd:ed:8d:f8:ad:45:a2:
+         37:7c:51:41:42:5a:ca:8a:c6:8b:3d:60:0f:6e:88:d9:44:25:
+         d2:e1:5c:92:fb:38:2e:90:a1:c4:d0:81:07:59:79:58:50:23:
+         f5:1d:f9:ac:11:99:51:eb:78:49:64:11:84:4c:ce:6f:6a:5d:
+         51:1d:2f:99:10:e9:f2:46:33:94:5c:8c:be:0d:26:bb:27:57:
+         e7:c8:f1:c3:9e:8f:10:04:2f:8a:a0:cd:39:af:01:1c:19:b0:
+         f9:da:38:6f:e8:2e:df:7d:ec:05:0c:09:bc:56:01:50:15:63:
+         50:a5:06:55:37:04:7e:74:a0:08:20:e3:29:c6:c3:36:87:76:
+         1f:f2:98:dc:cf:58:cd:c6:17:51:46:d2:ff:3a:97:4d:b2:27:
+         bb:8c:f0:13:79:53:2b:a7:cf:e5:88:7c:eb:33:b8:54:c4:2e:
+         64:de:34:af:4e:74:05:b1:13:fd:ed:54:60:2c:31:b8:7f:a6:
+         0d:4f:dd:9d:e3:0d:aa:ad:ba:0d:25:07:c2:0d:53:a8:f4:93:
+         37:75:60:2b:75:5f:db:53:d8:44:fd:4d:c9:91:4e:6a:ca:6d:
+         a5:ae:ba:74
 -----BEGIN CERTIFICATE-----
-MIIDlDCCAnygAwIBAgIJANjT46bL481hMA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
+MIIDlDCCAnygAwIBAgIJANjT46bL481sMA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
 BAYTAkZJMRAwDgYDVQQHDAdUdXVzdWxhMQ4wDAYDVQQKDAV3MS5maTEQMA4GA1UE
-AwwHUm9vdCBDQTAeFw0yMDA1MDIxOTU1MzhaFw0yMTA1MDIxOTU1MzhaMDUxCzAJ
+AwwHUm9vdCBDQTAeFw0yMTA1MDMxNzAyNTNaFw0yMjA1MDMxNzAyNTNaMDUxCzAJ
 BgNVBAYTAkZJMQ4wDAYDVQQKDAV3MS5maTEWMBQGA1UEAwwNc2VydmVyNS53MS5m
 aTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKWUYIC4yGEYjAKd3MzE
 dNEXtTtHnDgPO5J0++onRUSKmipNECWOd84aCclzGf7ccDZejPqPTIS793LklE/8
@@ -75,11 +75,11 @@
 rGMCAwEAAaOBmjCBlzAJBgNVHRMEAjAAMB0GA1UdDgQWBBQyn58wJHNzy41TOoAj
 61tdTN0GATAfBgNVHSMEGDAWgBSk/bk5G4GzquuIHdSBqbURcMyn4TA1BggrBgEF
 BQcBAQQpMCcwJQYIKwYBBQUHMAGGGWh0dHA6Ly9zZXJ2ZXIudzEuZmk6ODg4OC8w
-EwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBACICOD2QL11U
-uTZh/SlAwIhd62Pss22bVY8Qa7dLij+JefpSh42ROy7uhK74LY4dNXLNuH2dmNOI
-nQXHhecaKU3LANqjIaD181L1gIjLKk/Zm1bANxNhdGRh+4wlGJyW4vi74khg4xLY
-qdmek+jNRvXrsxdiZtFd6sIJ0Xo00uCIHX9vcSVwUNhRk2GOcNrCuvBEgb6BVNY8
-2qZUYkC90S7OHN0pSbq1En5CZFSymZNgZ24aY0vatJYokIHEKAUoZP/GerOMaBLj
-KGQAgoi8dUbS5/kKk0xdyJknTEBlDeyyhup24ijFd2s9/JEwiQoL4NRZzzDeX/ZQ
-FVpAAeKlOc8=
+EwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAJX6XHL8Lqqi
+tPkiEdKEM5H0LCdZuS0MRrHLWC5mve2N+K1Fojd8UUFCWsqKxos9YA9uiNlEJdLh
+XJL7OC6QocTQgQdZeVhQI/Ud+awRmVHreElkEYRMzm9qXVEdL5kQ6fJGM5RcjL4N
+JrsnV+fI8cOejxAEL4qgzTmvARwZsPnaOG/oLt997AUMCbxWAVAVY1ClBlU3BH50
+oAgg4ynGwzaHdh/ymNzPWM3GF1FG0v86l02yJ7uM8BN5Uyunz+WIfOszuFTELmTe
+NK9OdAWxE/3tVGAsMbh/pg1P3Z3jDaqtug0lB8INU6j0kzd1YCt1X9tT2ET9TcmR
+TmrKbaWuunQ=
 -----END CERTIFICATE-----
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-expired.pem b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-expired.pem
index 308d57f..301ff60 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-expired.pem
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-expired.pem
@@ -2,7 +2,7 @@
     Data:
         Version: 3 (0x2)
         Serial Number:
-            d8:d3:e3:a6:cb:e3:cd:66
+            d8:d3:e3:a6:cb:e3:cd:6b
         Signature Algorithm: sha256WithRSAEncryption
         Issuer: C=FI, L=Tuusula, O=w1.fi, CN=Root CA
         Validity
@@ -46,23 +46,23 @@
             X509v3 Extended Key Usage: 
                 TLS Web Server Authentication
     Signature Algorithm: sha256WithRSAEncryption
-         89:4d:ee:04:3e:50:fc:a2:6e:4c:3e:4a:9e:3b:9c:2e:74:29:
-         06:86:1b:bb:96:01:70:f7:46:21:b4:ef:6f:73:93:31:bd:58:
-         f5:2f:40:61:f1:53:86:20:75:cf:0e:75:70:2c:94:b8:c5:4e:
-         ec:24:0f:42:d6:8b:80:b9:fa:b5:48:83:d6:cf:c8:47:3d:09:
-         50:11:4a:5d:83:c5:41:8b:4b:4e:1e:ff:96:95:f0:14:7a:7e:
-         cd:a6:4f:ce:0b:37:e8:f2:27:a2:72:e2:6b:18:d7:f8:86:f0:
-         14:db:4c:c5:8a:76:9b:fc:55:15:49:3f:eb:df:5c:c7:7a:64:
-         86:70:44:97:7e:ba:83:39:25:3b:23:8e:dc:b3:9e:59:cb:e0:
-         a2:ac:7e:9f:d2:60:91:a7:de:a9:a9:30:e1:97:81:e3:13:91:
-         75:68:08:11:e0:ca:f9:eb:39:28:72:ab:8c:18:d2:3c:2c:cc:
-         38:e5:73:1a:4e:7f:e6:74:25:8b:a2:40:45:59:28:b4:ec:ec:
-         5f:c9:f5:6f:ab:02:03:70:0d:11:9b:62:df:73:7b:e0:c6:c1:
-         c1:ee:da:69:9a:91:a3:6b:2b:15:d6:fb:e4:35:38:86:fe:ac:
-         ad:77:a5:a3:03:a5:9f:f4:e7:34:91:83:9e:5b:1e:88:e1:48:
-         5f:15:d8:de
+         55:80:01:89:67:34:7c:4b:99:71:f5:5e:49:ea:51:f4:21:a4:
+         0f:3d:85:1c:ac:70:bf:a6:ef:50:85:de:df:1f:c6:93:44:3a:
+         0b:4d:e9:d9:25:e4:23:4b:c6:d5:6d:bc:ad:19:bc:be:05:e7:
+         5a:16:c5:6b:97:b4:8c:fc:9c:4e:52:3d:73:58:9e:df:0d:1f:
+         ae:a5:95:59:ed:5b:d6:8f:02:aa:c1:76:81:66:c9:46:f6:c3:
+         18:f2:a9:fb:e3:42:92:09:5f:7c:82:2e:fb:21:96:93:d1:63:
+         56:1e:3f:68:d4:96:f0:a7:2d:2f:f1:f1:39:ff:2a:56:1b:59:
+         4a:7a:b2:e9:11:ad:c0:66:59:ae:b5:d4:88:ce:65:d7:98:d8:
+         bf:77:96:9d:50:59:1b:28:6f:e7:0c:c5:dc:99:55:2e:62:11:
+         19:f2:bc:22:f9:35:91:7b:c5:ea:59:48:be:b1:90:a2:b6:5c:
+         f4:da:3a:48:98:7a:9a:74:55:f3:85:bb:ab:31:8b:d1:75:68:
+         f0:c3:dd:f1:ba:42:c7:4b:43:18:77:77:32:c1:80:61:22:48:
+         39:39:5c:ad:c0:b0:3a:73:5f:43:89:8e:32:40:3d:48:c7:dd:
+         20:d3:ba:15:b4:ac:0a:b4:86:0e:34:53:21:e5:91:c8:8e:56:
+         6e:9f:ce:62
 -----BEGIN CERTIFICATE-----
-MIIDlDCCAnygAwIBAgIJANjT46bL481mMA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
+MIIDlDCCAnygAwIBAgIJANjT46bL481rMA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
 BAYTAkZJMRAwDgYDVQQHDAdUdXVzdWxhMQ4wDAYDVQQKDAV3MS5maTEQMA4GA1UE
 AwwHUm9vdCBDQTAeFw0yMDAxMDEwMDAwMDBaFw0yMDAxMDIwMDAwMDBaMDUxCzAJ
 BgNVBAYTAkZJMQ4wDAYDVQQKDAV3MS5maTEWMBQGA1UEAwwNc2VydmVyNC53MS5m
@@ -75,11 +75,11 @@
 zx0CAwEAAaOBmjCBlzAJBgNVHRMEAjAAMB0GA1UdDgQWBBQhsDHGFNS9XN9wJFE0
 npP1GLMcoTAfBgNVHSMEGDAWgBSk/bk5G4GzquuIHdSBqbURcMyn4TA1BggrBgEF
 BQcBAQQpMCcwJQYIKwYBBQUHMAGGGWh0dHA6Ly9zZXJ2ZXIudzEuZmk6ODg4OC8w
-EwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAIlN7gQ+UPyi
-bkw+Sp47nC50KQaGG7uWAXD3RiG0729zkzG9WPUvQGHxU4Ygdc8OdXAslLjFTuwk
-D0LWi4C5+rVIg9bPyEc9CVARSl2DxUGLS04e/5aV8BR6fs2mT84LN+jyJ6Jy4msY
-1/iG8BTbTMWKdpv8VRVJP+vfXMd6ZIZwRJd+uoM5JTsjjtyznlnL4KKsfp/SYJGn
-3qmpMOGXgeMTkXVoCBHgyvnrOShyq4wY0jwszDjlcxpOf+Z0JYuiQEVZKLTs7F/J
-9W+rAgNwDRGbYt9ze+DGwcHu2mmakaNrKxXW++Q1OIb+rK13paMDpZ/05zSRg55b
-HojhSF8V2N4=
+EwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAFWAAYlnNHxL
+mXH1XknqUfQhpA89hRyscL+m71CF3t8fxpNEOgtN6dkl5CNLxtVtvK0ZvL4F51oW
+xWuXtIz8nE5SPXNYnt8NH66llVntW9aPAqrBdoFmyUb2wxjyqfvjQpIJX3yCLvsh
+lpPRY1YeP2jUlvCnLS/x8Tn/KlYbWUp6sukRrcBmWa611IjOZdeY2L93lp1QWRso
+b+cMxdyZVS5iERnyvCL5NZF7xepZSL6xkKK2XPTaOkiYepp0VfOFu6sxi9F1aPDD
+3fG6QsdLQxh3dzLBgGEiSDk5XK3AsDpzX0OJjjJAPUjH3SDTuhW0rAq0hg40UyHl
+kciOVm6fzmI=
 -----END CERTIFICATE-----
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-extra.pkcs12 b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-extra.pkcs12
index 822af70..d9cd6e2 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-extra.pkcs12
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-extra.pkcs12
Binary files differ
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-long-duration.pem b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-long-duration.pem
index 88bd6af..930550d 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-long-duration.pem
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-long-duration.pem
@@ -2,12 +2,12 @@
     Data:
         Version: 3 (0x2)
         Serial Number:
-            d8:d3:e3:a6:cb:e3:cd:68
+            d8:d3:e3:a6:cb:e3:cd:6e
         Signature Algorithm: sha256WithRSAEncryption
         Issuer: C=FI, L=Tuusula, O=w1.fi, CN=Root CA
         Validity
-            Not Before: May  3 14:07:41 2020 GMT
-            Not After : Apr 21 14:07:41 2070 GMT
+            Not Before: May  3 17:02:53 2021 GMT
+            Not After : Apr 21 17:02:53 2071 GMT
         Subject: C=FI, O=w1.fi, CN=server7.w1.fi
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
@@ -63,25 +63,25 @@
             X509v3 Extended Key Usage: 
                 TLS Web Server Authentication
     Signature Algorithm: sha256WithRSAEncryption
-         01:87:4b:93:49:c5:28:8b:2f:8a:45:f3:ed:a2:1e:2f:b0:d0:
-         0b:d3:cc:dc:a5:bd:ff:f5:df:86:45:f3:3e:94:ff:32:16:de:
-         f4:08:4a:2d:24:f3:5b:da:a8:ea:21:6d:06:c9:9c:08:1c:0e:
-         dc:a1:82:b9:5f:67:e4:e1:1c:29:b3:b1:58:af:ce:6c:2f:e1:
-         9b:dd:98:53:45:aa:d2:02:81:fd:a1:74:e4:75:69:07:9c:cc:
-         5d:b7:1a:25:ba:52:3b:8e:5c:62:12:0c:0e:a2:38:2f:b5:d3:
-         33:97:fe:d1:ec:6a:5d:15:93:67:98:d9:d0:93:03:bd:78:90:
-         df:bd:4f:50:af:79:83:70:02:9e:eb:bc:6d:d7:0f:9b:65:8d:
-         4e:79:79:d1:03:18:3d:47:3e:78:05:1d:f5:23:d2:f8:8f:fb:
-         56:a1:ce:ee:e0:40:25:57:cc:4d:4c:f2:ca:65:90:e0:f8:7f:
-         ed:4f:12:5f:1d:9c:5e:15:3c:5e:fa:a4:5f:85:3c:a1:47:a3:
-         3a:db:3f:93:3a:21:f4:55:be:fb:7c:3a:3d:58:ec:91:a0:83:
-         d5:b0:b9:79:08:12:1d:3b:3c:31:8d:f5:f6:da:20:d3:ca:76:
-         fb:83:c9:20:36:32:e5:4a:44:25:c6:d5:4d:04:59:06:71:9a:
-         cc:b9:47:e7
+         aa:73:6c:8d:3b:7e:cb:87:82:2f:b8:05:f7:79:1c:5d:ec:37:
+         76:ac:c1:e3:27:73:1b:71:0a:85:ba:55:ce:53:a2:70:38:b4:
+         e4:09:f4:19:c1:b5:0e:a1:52:d3:9f:3b:3b:dd:a9:86:97:3d:
+         e7:40:b8:16:9f:47:51:e5:39:2e:93:cb:61:a8:b1:f2:f6:53:
+         9f:50:04:c6:88:5c:ce:69:ed:cc:c3:39:0a:76:af:64:8f:ce:
+         6c:88:62:b7:46:ce:fc:fe:4a:e2:ea:f7:a8:af:5b:f5:43:a1:
+         96:fe:3c:db:a1:a2:72:3f:47:f3:5b:ae:50:27:7b:11:f8:e8:
+         22:a6:8d:73:32:56:c8:dd:d5:95:51:aa:9f:f7:4d:53:e7:0b:
+         e6:fa:c2:4e:59:55:92:44:78:df:e5:b0:1d:cc:69:3e:86:73:
+         3a:9f:69:30:54:9c:6b:55:7c:79:ba:62:d5:0a:de:18:b3:0c:
+         29:34:7b:ef:0d:5c:54:71:ad:69:f5:63:93:49:31:03:2e:dc:
+         3c:2b:78:82:ff:4f:b7:59:77:5d:34:0b:4a:41:3e:51:47:83:
+         4e:2a:cb:88:28:33:42:df:8f:81:c3:89:01:f4:8a:ef:56:db:
+         ca:07:95:53:c6:68:bf:21:5f:1d:20:da:55:c7:0a:7f:a5:4b:
+         7c:f4:04:32
 -----BEGIN CERTIFICATE-----
-MIIEljCCA36gAwIBAgIJANjT46bL481oMA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
+MIIEljCCA36gAwIBAgIJANjT46bL481uMA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
 BAYTAkZJMRAwDgYDVQQHDAdUdXVzdWxhMQ4wDAYDVQQKDAV3MS5maTEQMA4GA1UE
-AwwHUm9vdCBDQTAgFw0yMDA1MDMxNDA3NDFaGA8yMDcwMDQyMTE0MDc0MVowNTEL
+AwwHUm9vdCBDQTAgFw0yMTA1MDMxNzAyNTNaGA8yMDcxMDQyMTE3MDI1M1owNTEL
 MAkGA1UEBhMCRkkxDjAMBgNVBAoMBXcxLmZpMRYwFAYDVQQDDA1zZXJ2ZXI3Lncx
 LmZpMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvxDC67+9DyFoRCZ4
 1pAP3pxneAdvLjThUaY0bh1P8R8at5N6GgE2BNTjNfCbUo3MLYCTaDcACV/hDYo1
@@ -98,10 +98,10 @@
 DgQWBBQwyUXY08iO5kG4Kb1I3r/NmqWBzjAfBgNVHSMEGDAWgBSk/bk5G4GzquuI
 HdSBqbURcMyn4TA1BggrBgEFBQcBAQQpMCcwJQYIKwYBBQUHMAGGGWh0dHA6Ly9z
 ZXJ2ZXIudzEuZmk6ODg4OC8wEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcN
-AQELBQADggEBAAGHS5NJxSiLL4pF8+2iHi+w0AvTzNylvf/134ZF8z6U/zIW3vQI
-Si0k81vaqOohbQbJnAgcDtyhgrlfZ+ThHCmzsVivzmwv4ZvdmFNFqtICgf2hdOR1
-aQeczF23GiW6UjuOXGISDA6iOC+10zOX/tHsal0Vk2eY2dCTA714kN+9T1CveYNw
-Ap7rvG3XD5tljU55edEDGD1HPngFHfUj0viP+1ahzu7gQCVXzE1M8splkOD4f+1P
-El8dnF4VPF76pF+FPKFHozrbP5M6IfRVvvt8Oj1Y7JGgg9WwuXkIEh07PDGN9fba
-INPKdvuDySA2MuVKRCXG1U0EWQZxmsy5R+c=
+AQELBQADggEBAKpzbI07fsuHgi+4Bfd5HF3sN3asweMncxtxCoW6Vc5TonA4tOQJ
+9BnBtQ6hUtOfOzvdqYaXPedAuBafR1HlOS6Ty2GosfL2U59QBMaIXM5p7czDOQp2
+r2SPzmyIYrdGzvz+SuLq96ivW/VDoZb+PNuhonI/R/NbrlAnexH46CKmjXMyVsjd
+1ZVRqp/3TVPnC+b6wk5ZVZJEeN/lsB3MaT6GczqfaTBUnGtVfHm6YtUK3hizDCk0
+e+8NXFRxrWn1Y5NJMQMu3DwreIL/T7dZd100C0pBPlFHg04qy4goM0Lfj4HDiQH0
+iu9W28oHlVPGaL8hXx0g2lXHCn+lS3z0BDI=
 -----END CERTIFICATE-----
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-no-dnsname.pem b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-no-dnsname.pem
index a09e511..170098d 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-no-dnsname.pem
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server-no-dnsname.pem
@@ -2,12 +2,12 @@
     Data:
         Version: 3 (0x2)
         Serial Number:
-            d8:d3:e3:a6:cb:e3:cd:60
+            d8:d3:e3:a6:cb:e3:cd:6a
         Signature Algorithm: sha256WithRSAEncryption
         Issuer: C=FI, L=Tuusula, O=w1.fi, CN=Root CA
         Validity
-            Not Before: May  2 19:55:38 2020 GMT
-            Not After : May  2 19:55:38 2021 GMT
+            Not Before: May  3 17:02:53 2021 GMT
+            Not After : May  3 17:02:53 2022 GMT
         Subject: C=FI, O=w1.fi, CN=server3.w1.fi
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
@@ -46,25 +46,25 @@
             X509v3 Extended Key Usage: 
                 TLS Web Server Authentication
     Signature Algorithm: sha256WithRSAEncryption
-         47:5a:18:97:c2:3a:a5:4a:6c:f6:11:53:ac:d3:3f:d7:0c:7f:
-         e5:cb:9c:7d:02:f3:b7:ab:0c:a6:8d:d9:77:6c:bd:2a:41:47:
-         fb:70:7f:0d:09:53:fc:e4:a4:5e:0b:1c:4d:84:05:71:ab:f9:
-         68:9a:df:4f:b6:73:20:fd:05:cc:e2:f1:8a:9d:20:7a:27:8a:
-         60:a6:ed:0e:eb:cf:5f:13:32:1b:89:ec:f6:dc:eb:5f:42:f0:
-         a8:f9:42:dd:e5:e6:19:28:82:61:df:07:24:7b:c6:c9:ce:a5:
-         44:f0:d7:ba:4b:2b:9d:d7:97:1c:13:e9:da:0a:58:26:97:48:
-         6e:33:ec:d5:d3:32:96:23:b6:40:01:a8:e0:88:ea:2a:73:82:
-         d7:41:58:9b:b3:dc:6b:41:2f:ae:33:38:43:05:ed:04:ff:b9:
-         63:b7:7e:9b:fa:85:ab:df:12:36:24:cf:ec:8d:f8:d5:1c:95:
-         4e:a8:9c:e4:8a:90:ac:db:a0:4b:d8:14:e0:84:97:f7:cb:da:
-         95:cd:02:11:65:23:8b:ad:f1:c3:46:2d:2d:20:4d:cb:63:ef:
-         ae:be:ea:19:1d:2d:c5:35:c8:aa:b9:d3:8c:4f:cd:44:9c:fc:
-         a4:37:f5:b8:80:06:af:5e:ce:bc:81:23:cd:6b:de:31:c2:4c:
-         e8:e6:68:71
+         8a:b4:ef:15:b7:6f:b7:cd:e6:c0:3b:e2:bb:67:5e:d0:0a:81:
+         53:84:60:b8:60:05:9b:c7:b9:b9:87:34:1f:33:a4:fb:db:ed:
+         e9:0f:83:a4:3d:8b:4e:ff:aa:35:a8:f4:8c:35:78:a0:fb:e0:
+         b3:a3:11:92:ce:76:b2:3a:06:4f:3f:bb:9c:ca:e3:95:ec:44:
+         cb:72:1f:93:5d:df:d7:9e:76:41:4c:61:cb:70:03:5d:45:69:
+         da:c6:f5:60:68:83:f9:c7:73:8e:fb:4c:47:28:8e:b7:c9:e4:
+         cc:12:44:46:cc:97:77:6c:aa:02:57:d9:5a:f9:92:0c:a6:81:
+         12:b3:e0:fd:e1:9b:46:83:c8:bc:b5:85:4e:bd:9a:1b:9b:a5:
+         bd:cb:af:9b:dc:ce:62:3b:b3:ff:0f:85:e3:47:66:d0:dc:c6:
+         c4:02:36:e0:01:42:4c:c5:1f:de:da:92:1f:09:f3:22:f5:37:
+         ef:55:ca:7c:12:f7:2f:34:a1:ff:fe:b8:fc:32:34:ee:a4:ff:
+         f1:ba:c5:f5:d3:9e:d2:f8:3d:d9:fa:81:8f:40:80:7f:67:b5:
+         4d:0a:03:f7:f9:4e:3f:f8:74:29:f8:26:6d:5e:9e:dd:6d:f2:
+         0a:1d:6a:41:0c:5b:c2:27:81:2b:c1:86:0e:24:64:37:92:2a:
+         09:fb:ae:c7
 -----BEGIN CERTIFICATE-----
-MIIDlDCCAnygAwIBAgIJANjT46bL481gMA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
+MIIDlDCCAnygAwIBAgIJANjT46bL481qMA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
 BAYTAkZJMRAwDgYDVQQHDAdUdXVzdWxhMQ4wDAYDVQQKDAV3MS5maTEQMA4GA1UE
-AwwHUm9vdCBDQTAeFw0yMDA1MDIxOTU1MzhaFw0yMTA1MDIxOTU1MzhaMDUxCzAJ
+AwwHUm9vdCBDQTAeFw0yMTA1MDMxNzAyNTNaFw0yMjA1MDMxNzAyNTNaMDUxCzAJ
 BgNVBAYTAkZJMQ4wDAYDVQQKDAV3MS5maTEWMBQGA1UEAwwNc2VydmVyMy53MS5m
 aTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMLrrQRvTOsjuJJOddwA
 0A3ZrQkh+BJKLc3bfWOhMhKOuOO935U5OhdlVPgg1nE3fbe0cjF6ej26dHLzrJ0W
@@ -75,11 +75,11 @@
 94kCAwEAAaOBmjCBlzAJBgNVHRMEAjAAMB0GA1UdDgQWBBRehNYxmBdx+GNcMlt9
 M8DU+janajAfBgNVHSMEGDAWgBSk/bk5G4GzquuIHdSBqbURcMyn4TA1BggrBgEF
 BQcBAQQpMCcwJQYIKwYBBQUHMAGGGWh0dHA6Ly9zZXJ2ZXIudzEuZmk6ODg4OC8w
-EwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAEdaGJfCOqVK
-bPYRU6zTP9cMf+XLnH0C87erDKaN2XdsvSpBR/twfw0JU/zkpF4LHE2EBXGr+Wia
-30+2cyD9Bczi8YqdIHonimCm7Q7rz18TMhuJ7Pbc619C8Kj5Qt3l5hkogmHfByR7
-xsnOpUTw17pLK53XlxwT6doKWCaXSG4z7NXTMpYjtkABqOCI6ipzgtdBWJuz3GtB
-L64zOEMF7QT/uWO3fpv6havfEjYkz+yN+NUclU6onOSKkKzboEvYFOCEl/fL2pXN
-AhFlI4ut8cNGLS0gTctj766+6hkdLcU1yKq504xPzUSc/KQ39biABq9ezryBI81r
-3jHCTOjmaHE=
+EwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAIq07xW3b7fN
+5sA74rtnXtAKgVOEYLhgBZvHubmHNB8zpPvb7ekPg6Q9i07/qjWo9Iw1eKD74LOj
+EZLOdrI6Bk8/u5zK45XsRMtyH5Nd39eedkFMYctwA11FadrG9WBog/nHc477TEco
+jrfJ5MwSREbMl3dsqgJX2Vr5kgymgRKz4P3hm0aDyLy1hU69mhubpb3Lr5vczmI7
+s/8PheNHZtDcxsQCNuABQkzFH97akh8J8yL1N+9VynwS9y80of/+uPwyNO6k//G6
+xfXTntL4Pdn6gY9AgH9ntU0KA/f5Tj/4dCn4Jm1ent1t8godakEMW8IngSvBhg4k
+ZDeSKgn7rsc=
 -----END CERTIFICATE-----
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server.pem b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server.pem
index 98fc032..bc95b1b 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server.pem
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server.pem
@@ -2,12 +2,12 @@
     Data:
         Version: 3 (0x2)
         Serial Number:
-            d8:d3:e3:a6:cb:e3:cd:5f
+            d8:d3:e3:a6:cb:e3:cd:69
         Signature Algorithm: sha256WithRSAEncryption
         Issuer: C=FI, L=Tuusula, O=w1.fi, CN=Root CA
         Validity
-            Not Before: May  2 19:55:38 2020 GMT
-            Not After : May  2 19:55:38 2021 GMT
+            Not Before: May  3 17:02:53 2021 GMT
+            Not After : May  3 17:02:53 2022 GMT
         Subject: C=FI, O=w1.fi, CN=server.w1.fi
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
@@ -48,25 +48,25 @@
             X509v3 Extended Key Usage: 
                 TLS Web Server Authentication
     Signature Algorithm: sha256WithRSAEncryption
-         62:10:9c:ed:50:98:34:2e:7c:ef:1a:11:93:a5:f0:ad:8d:03:
-         71:9a:a1:be:c0:24:9a:4d:28:cd:28:ea:55:7e:7b:b3:9c:f4:
-         ad:94:44:7b:9c:e2:0a:c0:35:7e:80:a6:aa:9c:ae:36:22:fd:
-         4e:25:b3:1f:66:1d:2e:66:4b:d4:8c:ad:3e:0d:92:7d:3a:93:
-         05:c6:51:e4:75:fc:b4:6c:24:cb:c4:79:06:2f:d1:b3:6c:0c:
-         d8:82:76:08:cc:9a:c4:61:14:1b:3d:38:f4:a2:2c:49:0e:d5:
-         82:58:46:52:3c:cd:12:d9:57:dd:58:25:34:0b:d7:7b:2a:2f:
-         60:ce:da:9f:f2:98:e2:8e:0b:6c:69:42:1c:27:75:3a:7c:ae:
-         a5:9a:19:bc:6c:67:fc:04:a9:f4:fd:2c:17:79:56:52:a3:3b:
-         01:60:ae:ea:9b:ed:a4:30:53:fc:ef:57:bb:f1:fc:04:2a:5c:
-         2b:74:d0:1f:0b:30:ec:0a:b2:8b:4d:4a:b4:33:0d:cd:dc:28:
-         29:0a:d1:eb:36:09:bc:15:a7:c7:f0:f0:9c:7e:48:75:14:75:
-         2d:ed:fb:7a:14:e4:69:4a:54:b9:ad:25:ba:bb:d9:c0:eb:a0:
-         81:53:c7:07:ea:34:73:1f:9d:43:63:8e:f9:06:c9:4d:15:bf:
-         68:f9:91:de
+         b1:d9:6f:63:a1:39:81:55:10:cd:05:c1:cc:14:7d:33:0a:9a:
+         ef:c0:34:dc:77:76:5b:41:92:20:15:a3:c6:01:af:1f:05:7c:
+         bb:37:4a:1d:1f:00:5e:4a:17:6b:7a:6a:6c:a4:fb:c7:e4:1e:
+         e2:38:7f:25:d1:45:9b:eb:68:95:f9:1b:ba:9f:40:b9:5d:c7:
+         6c:a0:46:6b:05:ac:f4:38:4d:64:0b:5d:e0:7b:30:31:b8:a6:
+         da:d0:a5:3e:81:7b:6a:1a:b5:4f:2d:4a:f2:00:68:13:68:b8:
+         83:6b:79:f9:b2:63:a7:df:52:de:8e:12:9d:87:73:ec:4b:47:
+         38:a2:98:29:a8:c8:8b:8e:b1:2b:47:dd:eb:cf:6a:dd:21:02:
+         00:5e:7d:8d:4c:19:aa:7d:1b:f4:9b:a6:a8:f8:f3:a7:9d:66:
+         e8:54:0c:dc:7f:e9:af:a2:4c:88:8b:87:54:28:33:c5:53:87:
+         b0:41:e4:2e:33:7b:aa:c0:29:82:c2:bd:54:10:29:f9:2d:a4:
+         99:d1:e7:c7:57:07:66:cc:d0:2e:74:5d:98:28:0a:fe:8a:32:
+         3c:62:3d:30:7c:75:0c:16:31:ce:cb:e7:41:1e:4f:3c:92:1a:
+         3e:80:b1:13:78:b5:53:b2:6a:44:9f:c1:3b:92:cf:08:0e:08:
+         32:10:27:1b
 -----BEGIN CERTIFICATE-----
-MIIDrDCCApSgAwIBAgIJANjT46bL481fMA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
+MIIDrDCCApSgAwIBAgIJANjT46bL481pMA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
 BAYTAkZJMRAwDgYDVQQHDAdUdXVzdWxhMQ4wDAYDVQQKDAV3MS5maTEQMA4GA1UE
-AwwHUm9vdCBDQTAeFw0yMDA1MDIxOTU1MzhaFw0yMTA1MDIxOTU1MzhaMDQxCzAJ
+AwwHUm9vdCBDQTAeFw0yMTA1MDMxNzAyNTNaFw0yMjA1MDMxNzAyNTNaMDQxCzAJ
 BgNVBAYTAkZJMQ4wDAYDVQQKDAV3MS5maTEVMBMGA1UEAwwMc2VydmVyLncxLmZp
 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/Q5ezRksakGD2SwONs0J
 sI+yyYzI0gM4blS8Q+7O+Fmx6T9t1F7jxXMZPQu8KdfQbnUANfz3ZbG2D8sGSc+p
@@ -78,10 +78,10 @@
 MRBpSdDnMB8GA1UdIwQYMBaAFKT9uTkbgbOq64gd1IGptRFwzKfhMDUGCCsGAQUF
 BwEBBCkwJzAlBggrBgEFBQcwAYYZaHR0cDovL3NlcnZlci53MS5maTo4ODg4LzAX
 BgNVHREEEDAOggxzZXJ2ZXIudzEuZmkwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJ
-KoZIhvcNAQELBQADggEBAGIQnO1QmDQufO8aEZOl8K2NA3Gaob7AJJpNKM0o6lV+
-e7Oc9K2URHuc4grANX6ApqqcrjYi/U4lsx9mHS5mS9SMrT4Nkn06kwXGUeR1/LRs
-JMvEeQYv0bNsDNiCdgjMmsRhFBs9OPSiLEkO1YJYRlI8zRLZV91YJTQL13sqL2DO
-2p/ymOKOC2xpQhwndTp8rqWaGbxsZ/wEqfT9LBd5VlKjOwFgruqb7aQwU/zvV7vx
-/AQqXCt00B8LMOwKsotNSrQzDc3cKCkK0es2CbwVp8fw8Jx+SHUUdS3t+3oU5GlK
-VLmtJbq72cDroIFTxwfqNHMfnUNjjvkGyU0Vv2j5kd4=
+KoZIhvcNAQELBQADggEBALHZb2OhOYFVEM0FwcwUfTMKmu/ANNx3dltBkiAVo8YB
+rx8FfLs3Sh0fAF5KF2t6amyk+8fkHuI4fyXRRZvraJX5G7qfQLldx2ygRmsFrPQ4
+TWQLXeB7MDG4ptrQpT6Be2oatU8tSvIAaBNouINrefmyY6ffUt6OEp2Hc+xLRzii
+mCmoyIuOsStH3evPat0hAgBefY1MGap9G/Sbpqj486edZuhUDNx/6a+iTIiLh1Qo
+M8VTh7BB5C4ze6rAKYLCvVQQKfktpJnR58dXB2bM0C50XZgoCv6KMjxiPTB8dQwW
+Mc7L50EeTzySGj6AsRN4tVOyakSfwTuSzwgOCDIQJxs=
 -----END CERTIFICATE-----
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server.pkcs12 b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server.pkcs12
index ba2516c..310e988 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server.pkcs12
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/server.pkcs12
Binary files differ
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/test-ca/index.txt b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/test-ca/index.txt
index b531826..87cc2f1 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/test-ca/index.txt
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/test-ca/index.txt
@@ -118,3 +118,13 @@
 V	200102000000Z		D8D3E3A6CBE3CD66	unknown	/C=FI/O=w1.fi/CN=server4.w1.fi
 V	210503140118Z		D8D3E3A6CBE3CD67	unknown	/C=FI/O=w1.fi/CN=ocsp.w1.fi
 V	20700421140741Z		D8D3E3A6CBE3CD68	unknown	/C=FI/O=w1.fi/CN=server7.w1.fi
+V	220503170253Z		D8D3E3A6CBE3CD69	unknown	/C=FI/O=w1.fi/CN=server.w1.fi
+V	220503170253Z		D8D3E3A6CBE3CD6A	unknown	/C=FI/O=w1.fi/CN=server3.w1.fi
+V	200102000000Z		D8D3E3A6CBE3CD6B	unknown	/C=FI/O=w1.fi/CN=server4.w1.fi
+V	220503170253Z		D8D3E3A6CBE3CD6C	unknown	/C=FI/O=w1.fi/CN=server5.w1.fi
+V	220503170253Z		D8D3E3A6CBE3CD6D	unknown	/C=FI/O=w1.fi/CN=server6.w1.fi
+V	20710421170253Z		D8D3E3A6CBE3CD6E	unknown	/C=FI/O=w1.fi/CN=server7.w1.fi
+V	220503170253Z		D8D3E3A6CBE3CD6F	unknown	/C=FI/O=w1.fi/CN=server-policies.w1.fi
+V	220503170253Z		D8D3E3A6CBE3CD70	unknown	/C=FI/O=w1.fi/CN=server-policies2.w1.fi
+V	220503170253Z		D8D3E3A6CBE3CD71	unknown	/C=FI/O=w1.fi/CN=Test User
+V	220503170253Z		D8D3E3A6CBE3CD72	unknown	/C=FI/O=w1.fi/CN=ocsp.w1.fi
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/test-ca/serial b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/test-ca/serial
index 0cf1e42..3b74f6c 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/test-ca/serial
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/test-ca/serial
@@ -1 +1 @@
-D8D3E3A6CBE3CD69
+D8D3E3A6CBE3CD73
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/user.pem b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/user.pem
index 66be8f8..08ee21e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/user.pem
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/user.pem
@@ -2,12 +2,12 @@
     Data:
         Version: 3 (0x2)
         Serial Number:
-            d8:d3:e3:a6:cb:e3:cd:65
+            d8:d3:e3:a6:cb:e3:cd:71
         Signature Algorithm: sha256WithRSAEncryption
         Issuer: C=FI, L=Tuusula, O=w1.fi, CN=Root CA
         Validity
-            Not Before: May  2 19:55:38 2020 GMT
-            Not After : May  2 19:55:38 2021 GMT
+            Not Before: May  3 17:02:53 2021 GMT
+            Not After : May  3 17:02:53 2022 GMT
         Subject: C=FI, O=w1.fi, CN=Test User
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
@@ -46,25 +46,25 @@
             X509v3 Extended Key Usage: 
                 TLS Web Client Authentication
     Signature Algorithm: sha256WithRSAEncryption
-         94:10:ec:75:db:4d:98:80:bd:b7:b2:b1:4d:b8:99:0a:ba:e1:
-         47:d4:ef:50:48:5b:89:97:8b:ee:ee:56:2e:e6:ba:2d:0c:90:
-         59:29:a1:c9:10:08:9a:c7:e9:57:42:5a:f6:7e:72:cd:d9:ff:
-         8b:b2:13:6f:6e:e1:49:04:a5:82:cd:10:59:37:a5:9a:b2:2c:
-         6e:a7:9e:ba:1f:e3:b7:79:79:37:65:a8:9b:49:39:c2:13:7d:
-         6d:a8:37:23:c4:10:c9:73:25:67:1f:78:fb:b6:86:00:c1:1a:
-         60:d7:5e:b9:63:c6:43:41:dd:37:0f:39:c9:fa:ff:8a:f9:62:
-         59:00:e6:91:cd:79:28:82:db:30:88:c5:b8:79:8e:63:4c:65:
-         50:3d:d2:65:b3:45:62:e5:d1:6f:1c:c1:1f:c2:b5:1a:0f:31:
-         75:62:b3:7d:0b:8d:36:f9:43:eb:26:59:59:29:39:ad:37:0c:
-         4f:95:7e:86:05:f5:70:fa:45:de:3c:f5:7e:e1:29:bc:82:d3:
-         a0:63:73:a3:e1:25:f3:5a:14:2d:c7:78:da:aa:e2:8a:df:08:
-         c5:be:1f:d3:9f:70:0b:7d:ea:5b:f4:2d:22:94:e6:95:92:50:
-         e2:55:72:13:c5:a1:3a:44:c4:25:18:9d:9d:a9:c8:c0:ea:7a:
-         d6:76:91:4e
+         a1:96:48:41:04:5c:06:bd:0b:34:59:c0:49:fa:d6:08:e4:30:
+         79:cf:0d:42:36:10:a1:4a:8d:41:f9:c4:91:1b:8c:cf:36:24:
+         21:e8:cc:d8:7e:ac:cc:ca:79:fd:49:fa:6d:0b:20:3f:cc:1e:
+         0b:df:bc:ac:3d:f6:19:c6:99:f9:5f:86:17:ce:00:63:8a:95:
+         42:4c:92:5e:d7:5c:6d:1c:3a:13:b9:3e:d1:dd:d0:78:0d:7e:
+         b4:13:19:95:4b:e0:7f:11:97:41:c2:92:de:f0:43:0f:8b:36:
+         53:0f:5d:d9:12:16:85:22:bf:8f:e6:b1:95:94:0b:dc:ff:3a:
+         a3:ce:27:f9:1d:58:20:bc:0c:45:d7:96:fc:76:de:26:57:58:
+         d0:e2:57:d3:32:e1:c5:1b:37:0c:54:36:ed:5b:0d:d4:ef:cc:
+         43:c6:a6:66:0f:ce:33:4f:96:b9:22:6d:1d:1d:3f:4c:6c:05:
+         68:8d:48:2b:12:37:2a:d5:05:33:e0:b5:12:8f:00:73:43:64:
+         0e:28:75:04:b8:6f:29:da:22:e7:2c:78:97:f8:b0:37:8e:f6:
+         0d:04:98:e1:2f:6e:fd:40:97:54:50:2c:ca:cf:68:16:55:ca:
+         c0:37:bd:d5:3c:5e:50:64:4b:dd:3c:d3:b4:88:25:a9:11:d3:
+         60:bc:a7:88
 -----BEGIN CERTIFICATE-----
-MIIDkDCCAnigAwIBAgIJANjT46bL481lMA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
+MIIDkDCCAnigAwIBAgIJANjT46bL481xMA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
 BAYTAkZJMRAwDgYDVQQHDAdUdXVzdWxhMQ4wDAYDVQQKDAV3MS5maTEQMA4GA1UE
-AwwHUm9vdCBDQTAeFw0yMDA1MDIxOTU1MzhaFw0yMTA1MDIxOTU1MzhaMDExCzAJ
+AwwHUm9vdCBDQTAeFw0yMTA1MDMxNzAyNTNaFw0yMjA1MDMxNzAyNTNaMDExCzAJ
 BgNVBAYTAkZJMQ4wDAYDVQQKDAV3MS5maTESMBAGA1UEAwwJVGVzdCBVc2VyMIIB
 IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvCQI2QdtGQ6UXGvZioQbAyLi
 GgZC0wtgjV8xBAb6okBqDCQpWM2DvzqdfzcNTSdd1VdXHPO+dT86TERvAi9biyyw
@@ -75,11 +75,11 @@
 AQABo4GaMIGXMAkGA1UdEwQCMAAwHQYDVR0OBBYEFPuFAKjf1gwOp+M5Ydm+zirv
 bSjYMB8GA1UdIwQYMBaAFKT9uTkbgbOq64gd1IGptRFwzKfhMDUGCCsGAQUFBwEB
 BCkwJzAlBggrBgEFBQcwAYYZaHR0cDovL3NlcnZlci53MS5maTo4ODg4LzATBgNV
-HSUEDDAKBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAlBDsddtNmIC9t7Kx
-TbiZCrrhR9TvUEhbiZeL7u5WLua6LQyQWSmhyRAImsfpV0Ja9n5yzdn/i7ITb27h
-SQSlgs0QWTelmrIsbqeeuh/jt3l5N2Wom0k5whN9bag3I8QQyXMlZx94+7aGAMEa
-YNdeuWPGQ0HdNw85yfr/ivliWQDmkc15KILbMIjFuHmOY0xlUD3SZbNFYuXRbxzB
-H8K1Gg8xdWKzfQuNNvlD6yZZWSk5rTcMT5V+hgX1cPpF3jz1fuEpvILToGNzo+El
-81oULcd42qriit8Ixb4f059wC33qW/QtIpTmlZJQ4lVyE8WhOkTEJRidnanIwOp6
-1naRTg==
+HSUEDDAKBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAoZZIQQRcBr0LNFnA
+SfrWCOQwec8NQjYQoUqNQfnEkRuMzzYkIejM2H6szMp5/Un6bQsgP8weC9+8rD32
+GcaZ+V+GF84AY4qVQkySXtdcbRw6E7k+0d3QeA1+tBMZlUvgfxGXQcKS3vBDD4s2
+Uw9d2RIWhSK/j+axlZQL3P86o84n+R1YILwMRdeW/HbeJldY0OJX0zLhxRs3DFQ2
+7VsN1O/MQ8amZg/OM0+WuSJtHR0/TGwFaI1IKxI3KtUFM+C1Eo8Ac0NkDih1BLhv
+Kdoi5yx4l/iwN472DQSY4S9u/UCXVFAsys9oFlXKwDe91TxeUGRL3TzTtIglqRHT
+YLyniA==
 -----END CERTIFICATE-----
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/user.pkcs12 b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/user.pkcs12
index bd8abd5..96108f2 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/user.pkcs12
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/user.pkcs12
Binary files differ
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/user2.pkcs12 b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/user2.pkcs12
index de39b79..1ede5d9 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/user2.pkcs12
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/user2.pkcs12
Binary files differ
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/user3.pkcs12 b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/user3.pkcs12
index 3100ca9..a5dfb75 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/user3.pkcs12
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/auth_serv/user3.pkcs12
Binary files differ
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/build.sh b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/build.sh
index 2a3dd70..cb47001 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/build.sh
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/build.sh
@@ -26,13 +26,18 @@
 	esac
 done
 
+JOBS=`nproc`
+if [ -z "$ABC" ]; then
+    JOBS=8
+fi
+
 echo "Building TNC testing tools"
 cd tnc
-make QUIET=1 -j8
+make QUIET=1 -j$JOBS
 
 echo "Building wlantest"
 cd ../../../wlantest
-make QUIET=1 -j8 > /dev/null
+make QUIET=1 -j$JOBS > /dev/null
 
 echo "Building hs20-osu-client"
 cd ../hs20/client/
@@ -54,7 +59,7 @@
     fi
 fi
 
-make QUIET=1 -j8 hostapd hostapd_cli hlr_auc_gw
+make QUIET=1 -j$JOBS hostapd hostapd_cli hlr_auc_gw
 
 echo "Building wpa_supplicant"
 cd ../wpa_supplicant
@@ -75,4 +80,4 @@
 if [ -z $FIPSLD_CC ]; then
 export FIPSLD_CC=gcc
 fi
-make QUIET=1 -j8
+make QUIET=1 -j$JOBS
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/example-hostapd.config b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/example-hostapd.config
index 972d35c..d01a1d2 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/example-hostapd.config
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/example-hostapd.config
@@ -112,3 +112,5 @@
 CONFIG_DPP=y
 CONFIG_DPP2=y
 CONFIG_WEP=y
+CONFIG_PASN=y
+CONFIG_AIRTIME_POLICY=y
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/example-wpa_supplicant.config b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/example-wpa_supplicant.config
index 9e3cc67..5e5acd6 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/example-wpa_supplicant.config
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/example-wpa_supplicant.config
@@ -102,6 +102,7 @@
 
 CONFIG_HT_OVERRIDES=y
 CONFIG_VHT_OVERRIDES=y
+CONFIG_HE_OVERRIDES=y
 
 CONFIG_DEBUG_LINUX_TRACING=y
 
@@ -112,6 +113,7 @@
 CONFIG_AUTOSCAN_PERIODIC=y
 
 CONFIG_EXT_PASSWORD_TEST=y
+CONFIG_EXT_PASSWORD_FILE=y
 
 CONFIG_EAP_UNAUTH_TLS=y
 
@@ -155,3 +157,4 @@
 CONFIG_DPP=y
 CONFIG_DPP2=y
 CONFIG_WEP=y
+CONFIG_PASN=y
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/fst_test_common.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/fst_test_common.py
index 4b6bab0..440d65f 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/fst_test_common.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/fst_test_common.py
@@ -24,14 +24,9 @@
 
 class HapdRegCtrl:
     def __init__(self):
-        self.refcnt = 0
         self.ifname = None
         self.changed = False
 
-    def __del__(self):
-        if self.refcnt != 0 and self.changed == True:
-            self.restore_reg_domain()
-
     def start(self):
         if self.ifname != None:
              hapd = hostapd.Hostapd(self.ifname)
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/hostapd.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/hostapd.py
index 5717575..f9becfc 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/hostapd.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/hostapd.py
@@ -419,6 +419,12 @@
             raise Exception("Failed to parse QR Code URI")
         return int(res)
 
+    def dpp_nfc_uri(self, uri):
+        res = self.request("DPP_NFC_URI " + uri)
+        if "FAIL" in res:
+            raise Exception("Failed to parse NFC URI")
+        return int(res)
+
     def dpp_bootstrap_gen(self, type="qrcode", chan=None, mac=None, info=None,
                           curve=None, key=None):
         cmd = "DPP_BOOTSTRAP_GEN type=" + type
@@ -439,6 +445,20 @@
             raise Exception("Failed to generate bootstrapping info")
         return int(res)
 
+    def dpp_bootstrap_set(self, id, conf=None, configurator=None, ssid=None,
+                          extra=None):
+        cmd = "DPP_BOOTSTRAP_SET %d" % id
+        if ssid:
+            cmd += " ssid=" + binascii.hexlify(ssid.encode()).decode()
+        if extra:
+            cmd += " " + extra
+        if conf:
+            cmd += " conf=" + conf
+        if configurator is not None:
+            cmd += " configurator=%d" % configurator
+        if "OK" not in self.request(cmd):
+            raise Exception("Failed to set bootstrapping parameters")
+
     def dpp_listen(self, freq, netrole=None, qr=None, role=None):
         cmd = "DPP_LISTEN " + str(freq)
         if netrole:
@@ -452,10 +472,14 @@
 
     def dpp_auth_init(self, peer=None, uri=None, conf=None, configurator=None,
                       extra=None, own=None, role=None, neg_freq=None,
-                      ssid=None, passphrase=None, expect_fail=False):
+                      ssid=None, passphrase=None, expect_fail=False,
+                      conn_status=False, nfc_uri=None):
         cmd = "DPP_AUTH_INIT"
         if peer is None:
-            peer = self.dpp_qr_code(uri)
+            if nfc_uri:
+                peer = self.dpp_nfc_uri(nfc_uri)
+            else:
+                peer = self.dpp_qr_code(uri)
         cmd += " peer=%d" % peer
         if own is not None:
             cmd += " own=%d" % own
@@ -473,6 +497,8 @@
             cmd += " ssid=" + binascii.hexlify(ssid.encode()).decode()
         if passphrase:
             cmd += " pass=" + binascii.hexlify(passphrase.encode()).decode()
+        if conn_status:
+            cmd += " conn_status=1"
         res = self.request(cmd)
         if expect_fail:
             if "FAIL" not in res:
@@ -482,7 +508,7 @@
             raise Exception("Failed to initiate DPP Authentication")
 
     def dpp_pkex_init(self, identifier, code, role=None, key=None, curve=None,
-                      extra=None, use_id=None):
+                      extra=None, use_id=None, v2=False):
         if use_id is None:
             id1 = self.dpp_bootstrap_gen(type="pkex", key=key, curve=curve)
         else:
@@ -490,7 +516,10 @@
         cmd = "own=%d " % id1
         if identifier:
             cmd += "identifier=%s " % identifier
-        cmd += "init=1 "
+        if v2:
+            cmd += "init=2 "
+        else:
+            cmd += "init=1 "
         if role:
             cmd += "role=%s " % role
         if extra:
@@ -535,6 +564,23 @@
     def send_file(self, src, dst):
         self.host.send_file(src, dst)
 
+    def get_ptksa(self, bssid, cipher):
+        res = self.request("PTKSA_CACHE_LIST")
+        lines = res.splitlines()
+        for l in lines:
+            if bssid not in l or cipher not in l:
+                continue
+            vals = dict()
+            [index, addr, cipher, expiration, tk, kdk] = l.split(' ', 5)
+            vals['index'] = index
+            vals['addr'] = addr
+            vals['cipher'] = cipher
+            vals['expiration'] = expiration
+            vals['tk'] = tk
+            vals['kdk'] = kdk
+            return vals
+        return None
+
 def add_ap(apdev, params, wait_enabled=True, no_enable=False, timeout=30,
            global_ctrl_override=None, driver=False):
         if isinstance(apdev, dict):
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/multi-bss-iface-per_sta_vif.conf b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/multi-bss-iface-per_sta_vif.conf
index f07c13b..874cb07 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/multi-bss-iface-per_sta_vif.conf
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/multi-bss-iface-per_sta_vif.conf
@@ -9,7 +9,7 @@
 
 ssid=bss-1
 dynamic_vlan=1
-vlan_tagged_interface=dummy0
+vlan_tagged_interface=stub0
 vlan_bridge=brvlan
 wpa=2
 wpa_key_mgmt=WPA-EAP
@@ -28,7 +28,7 @@
 ssid=bss-2
 
 dynamic_vlan=1
-vlan_tagged_interface=dummy0
+vlan_tagged_interface=stub0
 vlan_bridge=brvlan
 wpa=2
 wpa_key_mgmt=WPA-EAP
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/multi-bss-iface.conf b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/multi-bss-iface.conf
index 6b6167f..5370352 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/multi-bss-iface.conf
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/multi-bss-iface.conf
@@ -9,7 +9,7 @@
 
 ssid=bss-1
 dynamic_vlan=1
-vlan_tagged_interface=dummy0
+vlan_tagged_interface=stub0
 vlan_bridge=brvlan
 wpa=2
 wpa_key_mgmt=WPA-EAP
@@ -27,7 +27,7 @@
 ssid=bss-2
 
 dynamic_vlan=1
-vlan_tagged_interface=dummy0
+vlan_tagged_interface=stub0
 vlan_bridge=brvlan
 wpa=2
 wpa_key_mgmt=WPA-EAP
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/remotehost.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/remotehost.py
index dec1ad5..9d7c657 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/remotehost.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/remotehost.py
@@ -9,6 +9,8 @@
 import threading
 import tempfile
 import os
+import traceback
+import select
 
 logger = logging.getLogger()
 
@@ -22,7 +24,7 @@
     err = tempfile.TemporaryFile()
     try:
         status = 0
-        buf = subprocess.check_output(command, stderr=err).decode()
+        buf = subprocess.check_output(command, stderr=err, bufsize=0).decode()
     except subprocess.CalledProcessError as e:
         status = e.returncode
         err.seek(0)
@@ -99,7 +101,7 @@
         return status, buf.decode()
 
     # async execute
-    def execute_run(self, command, res, use_reaper=True):
+    def thread_run(self, command, res, use_reaper=True):
         if use_reaper:
             filename = gen_reaper_file("reaper")
             self.send_file(filename, filename)
@@ -113,51 +115,133 @@
             cmd = _command
         else:
             cmd = ["ssh", self.user + "@" + self.host, ' '.join(_command)]
-        _cmd = self.name + " execute_run: " + ' '.join(cmd)
+        _cmd = self.name + " thread_run: " + ' '.join(cmd)
         logger.debug(_cmd)
         t = threading.Thread(target=execute_thread, name=filename, args=(cmd, res))
         t.start()
         return t
 
-    def execute_stop(self, t):
+    def thread_stop(self, t):
         if t.name.find("reaper") == -1:
             raise Exception("use_reaper required")
 
         pid_file = t.name + ".pid"
 
-        if t.isAlive():
+        if t.is_alive():
             cmd = ["kill `cat " + pid_file + "`"]
             self.execute(cmd)
 
         # try again
-        self.wait_execute_complete(t, 5)
-        if t.isAlive():
+        self.thread_wait(t, 5)
+        if t.is_alive():
             cmd = ["kill `cat " + pid_file + "`"]
             self.execute(cmd)
 
         # try with -9
-        self.wait_execute_complete(t, 5)
-        if t.isAlive():
+        self.thread_wait(t, 5)
+        if t.is_alive():
             cmd = ["kill -9 `cat " + pid_file + "`"]
             self.execute(cmd)
 
-        self.wait_execute_complete(t, 5)
-        if t.isAlive():
+        self.thread_wait(t, 5)
+        if t.is_alive():
             raise Exception("thread still alive")
 
         self.execute(["rm", pid_file])
         self.execute(["rm", t.name])
+        self.local_execute(["rm", t.name])
 
-    def wait_execute_complete(self, t, wait=None):
+    def thread_wait(self, t, wait=None):
         if wait == None:
             wait_str = "infinite"
         else:
             wait_str = str(wait) + "s"
 
-        logger.debug(self.name + " wait_execute_complete(" + wait_str + "): ")
-        if t.isAlive():
+        logger.debug(self.name + " thread_wait(" + wait_str + "): ")
+        if t.is_alive():
             t.join(wait)
 
+    def pending(self, s, timeout=0):
+        [r, w, e] = select.select([s], [], [], timeout)
+        if r:
+            return True
+        return False
+
+    def proc_run(self, command):
+        filename = gen_reaper_file("reaper")
+        self.send_file(filename, filename)
+        self.execute(["chmod", "755", filename])
+        _command = [filename] + command
+
+        if self.host:
+            cmd = ["ssh", self.user + "@" + self.host, ' '.join(_command)]
+        else:
+            cmd = _command
+
+        _cmd = self.name + " proc_run: " + ' '.join(cmd)
+        logger.debug(_cmd)
+        err = tempfile.TemporaryFile()
+        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=err,
+                                bufsize=0)
+        proc.reaper_file = filename
+        return proc
+
+    def proc_wait_event(self, proc, events, timeout=10):
+        if not isinstance(events, list):
+            raise Exception("proc_wait_event() events not a list")
+
+        logger.debug(self.name + " proc_wait_event: " + ' '.join(events) + " timeout: " + str(timeout))
+        start = os.times()[4]
+        try:
+            while True:
+                while self.pending(proc.stdout):
+                    line = proc.stdout.readline()
+                    if not line:
+                        return None
+                    line = line.decode()
+                    logger.debug(line.strip('\n'))
+                    for event in events:
+                        if event in line:
+                            return line
+                now = os.times()[4]
+                remaining = start + timeout - now
+                if remaining <= 0:
+                    break
+                if not self.pending(proc.stdout, timeout=remaining):
+                    break
+        except:
+            logger.debug(traceback.format_exc())
+            pass
+        return None
+
+    def proc_stop(self, proc):
+        if not proc:
+            return
+
+        self.execute(["kill `cat " + proc.reaper_file + ".pid`"])
+        self.execute(["rm", proc.reaper_file + ".pid"])
+        self.execute(["rm", proc.reaper_file])
+        self.local_execute(["rm", proc.reaper_file])
+        proc.kill()
+
+    def proc_dump(self, proc):
+        if not proc:
+            return ""
+        return proc.stdout.read()
+
+    def execute_and_wait_event(self, command, events, timeout=10):
+        proc = None
+        ev = None
+
+        try:
+            proc = self.proc_run(command)
+            ev = self.proc_wait_event(proc, events, timeout)
+        except:
+            pass
+
+        self.proc_stop(proc)
+        return ev
+
     def add_log(self, log_file):
         self.logs.append(log_file)
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/rfkill.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/rfkill.py
index f08cf50..72b2527 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/rfkill.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/rfkill.py
@@ -126,7 +126,7 @@
     @classmethod
     def list(cls):
         res = []
-        rfk = open('/dev/rfkill', 'rb')
+        rfk = open('/dev/rfkill', 'rb', buffering=0)
         fd = rfk.fileno()
         flgs = fcntl.fcntl(fd, fcntl.F_GETFL)
         fcntl.fcntl(fd, fcntl.F_SETFL, flgs | os.O_NONBLOCK)
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_acs.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_acs.py
index eb245e7..8fc5ec4 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_acs.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_acs.py
@@ -284,6 +284,30 @@
     finally:
         clear_regdom(hapd, dev)
 
+def test_ap_acs_vht80p80(dev, apdev):
+    """Automatic channel selection for VHT 80+80"""
+    try:
+        hapd = None
+        force_prev_ap_on_5g(apdev[0])
+        params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
+        params['hw_mode'] = 'a'
+        params['channel'] = '0'
+        params['ht_capab'] = '[HT40+]'
+        params['country_code'] = 'US'
+        params['ieee80211ac'] = '1'
+        params['vht_oper_chwidth'] = '3'
+        hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
+        ev = hapd.wait_event(["ACS-COMPLETED"], timeout=20)
+        if ev is None:
+            raise Exception("ACS did not complete")
+        # ACS for 80+80 is not yet supported, so the AP setup itself will fail.
+        # Do not try to connection before this gets fully supported.
+        ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=10)
+        if ev is None:
+            raise Exception("AP enabled/disabled not reported")
+    finally:
+        clear_regdom(hapd, dev)
+
 def test_ap_acs_vht160(dev, apdev):
     """Automatic channel selection for VHT160"""
     try:
@@ -622,3 +646,43 @@
     finally:
         for i in range(3):
             dev[i].request("SCAN_INTERVAL 5")
+
+def test_ap_acs_he_24g(dev, apdev):
+    """Automatic channel selection on 2.4 GHz with HE"""
+    clear_scan_cache(apdev[0])
+    force_prev_ap_on_24g(apdev[0])
+
+    params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
+    params['channel'] = '0'
+    params['ieee80211ax'] = '1'
+    params['ht_capab'] = '[HT40+]'
+    hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
+    wait_acs(hapd)
+
+    freq = hapd.get_status_field("freq")
+    if int(freq) < 2400:
+        raise Exception("Unexpected frequency")
+
+    dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
+
+def test_ap_acs_he_24g_overlap(dev, apdev):
+    """Automatic channel selection on 2.4 GHz with HE (overlap)"""
+    clear_scan_cache(apdev[0])
+    force_prev_ap_on_24g(apdev[0])
+
+    params = {"ssid": "overlapping",
+              "channel": "6", "ieee80211n": "1"}
+    hostapd.add_ap(apdev[1], params)
+
+    params = hostapd.wpa2_params(ssid="test-acs", passphrase="12345678")
+    params['channel'] = '0'
+    params['ieee80211ax'] = '1'
+    params['ht_capab'] = '[HT40+]'
+    hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
+    wait_acs(hapd)
+
+    freq = hapd.get_status_field("freq")
+    if int(freq) < 2400:
+        raise Exception("Unexpected frequency")
+
+    dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_ciphers.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_ciphers.py
index d9f827a..72dcfa5 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_ciphers.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_ciphers.py
@@ -415,6 +415,36 @@
     hwsim_utils.test_connectivity(dev[0], dev[1])
 
 @remote_compatible
+def test_ap_cipher_wpa_sae(dev, apdev):
+    """WPA-PSK/TKIP and SAE mixed AP - WPA IE and RSNXE coexistence"""
+    skip_with_fips(dev[0])
+    skip_without_tkip(dev[0])
+    check_sae_capab(dev[0])
+    ssid = "test-wpa-sae"
+    passphrase = "12345678"
+    params = {"ssid": ssid,
+              "wpa_passphrase": passphrase,
+              "wpa": "3",
+              "wpa_key_mgmt": "WPA-PSK SAE",
+              "rsn_pairwise": "CCMP",
+              "wpa_pairwise": "TKIP",
+              "sae_pwe": "1"}
+    hapd = hostapd.add_ap(apdev[0], params)
+    dev[0].flush_scan_cache()
+
+    dev[0].connect(ssid, psk=passphrase, proto="WPA",
+                   pairwise="TKIP", group="TKIP", scan_freq="2412")
+    status = dev[0].get_status()
+    if status['key_mgmt'] != 'WPA-PSK':
+        raise Exception("Incorrect key_mgmt reported")
+    if status['pairwise_cipher'] != 'TKIP':
+        raise Exception("Incorrect pairwise_cipher reported")
+    if status['group_cipher'] != 'TKIP':
+        raise Exception("Incorrect group_cipher reported")
+    hapd.wait_sta()
+    hwsim_utils.test_connectivity(dev[0], hapd)
+
+@remote_compatible
 def test_ap_cipher_bip(dev, apdev):
     """WPA2-PSK with BIP"""
     check_group_mgmt_cipher(dev[0], apdev[0], "AES-128-CMAC")
@@ -620,12 +650,24 @@
         raise HwsimSkip("GCMP not supported")
     run_ap_cipher_replay_protection_sta(dev, apdev, "GCMP", keytype=KT_GTK)
 
+def test_ap_cipher_replay_protection_sta_igtk(dev, apdev):
+    """CCMP replay protection on STA (IGTK)"""
+    run_ap_cipher_replay_protection_sta(dev, apdev, "CCMP", keytype=KT_IGTK)
+
+def test_ap_cipher_replay_protection_sta_bigtk(dev, apdev):
+    """CCMP replay protection on STA (BIGTK)"""
+    run_ap_cipher_replay_protection_sta(dev, apdev, "CCMP", keytype=KT_BIGTK)
+
 def run_ap_cipher_replay_protection_sta(dev, apdev, cipher, keytype=KT_PTK):
     params = {"ssid": "test-wpa2-psk",
               "wpa_passphrase": "12345678",
               "wpa": "2",
               "wpa_key_mgmt": "WPA-PSK",
               "rsn_pairwise": cipher}
+    if keytype == KT_IGTK or keytype == KT_BIGTK:
+        params['ieee80211w'] = '2'
+    if keytype == KT_BIGTK:
+        params['beacon_prot'] = '1'
     hapd = hostapd.add_ap(apdev[0], params)
 
     Wlantest.setup(hapd)
@@ -634,10 +676,14 @@
     wt.add_passphrase("12345678")
 
     phy = dev[0].get_driver_status_field("phyname")
-    dev[0].connect("test-wpa2-psk", psk="12345678",
+    dev[0].connect("test-wpa2-psk", psk="12345678", ieee80211w='1',
+                   beacon_prot='1',
                    pairwise=cipher, group=cipher, scan_freq="2412")
     hapd.wait_sta()
 
+    if keytype == KT_BIGTK:
+        time.sleep(1)
+
     if cipher != "TKIP":
         replays = get_tk_replay_counter(phy, keytype)
         if replays != 0:
@@ -651,12 +697,29 @@
         if replays != 0:
             raise Exception("Unexpected replay reported (2)")
 
+    if keytype == KT_IGTK:
+        hapd.request("DEAUTHENTICATE ff:ff:ff:ff:ff:ff test=1")
+        ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
+        if ev:
+            dev[0].wait_connected()
+
     addr = "ff:ff:ff:ff:ff:ff" if keytype != KT_PTK else dev[0].own_addr()
-    if "OK" not in hapd.request("RESET_PN " + addr):
+    cmd = "RESET_PN " + addr
+    if keytype == KT_IGTK:
+        cmd += " IGTK"
+    if keytype == KT_BIGTK:
+        cmd += " BIGTK"
+    if "OK" not in hapd.request(cmd):
         raise Exception("RESET_PN failed")
     time.sleep(0.1)
-    hwsim_utils.test_connectivity(dev[0], hapd, timeout=1,
-                                  success_expected=False)
+    if keytype == KT_IGTK:
+        hapd.request("DEAUTHENTICATE ff:ff:ff:ff:ff:ff test=1")
+        ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
+    elif keytype == KT_BIGTK:
+        time.sleep(1)
+    else:
+        hwsim_utils.test_connectivity(dev[0], hapd, timeout=1,
+                                      success_expected=False)
 
     if cipher != "TKIP":
         replays = get_tk_replay_counter(phy, keytype)
@@ -1005,6 +1068,35 @@
         raise Exception("RESEND_GROUP_M1 failed")
     time.sleep(0.1)
 
+def test_ap_wpa2_test_command_failures(dev, apdev):
+    """EAPOL/key config test command failures"""
+    params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678")
+    hapd = hostapd.add_ap(apdev[0], params)
+    tests = ["RESEND_M1 foo",
+             "RESEND_M1 22:22:22:22:22:22",
+             "RESEND_M3 foo",
+             "RESEND_M3 22:22:22:22:22:22",
+             "RESEND_GROUP_M1 foo",
+             "RESEND_GROUP_M1 22:22:22:22:22:22",
+             "SET_KEY foo",
+             "SET_KEY 3 foo",
+             "SET_KEY 3 22:22:22:22:22:22",
+             "SET_KEY 3 22:22:22:22:22:22 1",
+             "SET_KEY 3 22:22:22:22:22:22 1 1",
+             "SET_KEY 3 22:22:22:22:22:22 1 1 q",
+             "SET_KEY 3 22:22:22:22:22:22 1 1 112233445566",
+             "SET_KEY 3 22:22:22:22:22:22 1 1 112233445566 1",
+             "SET_KEY 3 22:22:22:22:22:22 1 1 112233445566 12",
+             "SET_KEY 3 22:22:22:22:22:22 1 1 112233445566 12 1",
+             "SET_KEY 3 22:22:22:22:22:22 1 1 112233445566 12 1 ",
+             "RESET_PN ff:ff:ff:ff:ff:ff BIGTK",
+             "RESET_PN ff:ff:ff:ff:ff:ff IGTK",
+             "RESET_PN 22:22:22:22:22:22",
+             "RESET_PN foo"]
+    for t in tests:
+        if "FAIL" not in hapd.request(t):
+            raise Exception("Invalid command accepted: " + t)
+
 def test_ap_wpa2_gtk_initial_rsc_tkip(dev, apdev):
     """Initial group cipher RSC (TKIP)"""
     skip_without_tkip(dev[0])
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_dynamic.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_dynamic.py
index 96d35b9..ad29eb7 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_dynamic.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_dynamic.py
@@ -37,6 +37,55 @@
     dev[0].set_network_quoted(id, "ssid", "test-wpa2-psk-new")
     dev[0].connect_network(id)
 
+def test_ap_change_ssid_wps(dev, apdev):
+    """Dynamic SSID change with hostapd and WPA2-PSK using WPS"""
+    params = hostapd.wpa2_params(ssid="test-wpa2-psk-start",
+                                 passphrase="12345678")
+    # Use a PSK and not the passphrase, because the PSK will have to be computed
+    # again if we use a passphrase.
+    del params["wpa_passphrase"]
+    params["wpa_psk"] = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
+
+    params.update({"wps_state": "2", "eap_server": "1"})
+    bssid = apdev[0]['bssid']
+    hapd = hostapd.add_ap(apdev[0], params)
+
+    new_ssid = "test-wpa2-psk-new"
+    logger.info("Change SSID dynamically (WPS)")
+    res = hapd.request("SET ssid " + new_ssid)
+    if "OK" not in res:
+        raise Exception("SET command failed")
+    res = hapd.request("RELOAD")
+    if "OK" not in res:
+        raise Exception("RELOAD command failed")
+
+    # Connect to the new ssid using wps:
+    hapd.request("WPS_PBC")
+    if "PBC Status: Active" not in hapd.request("WPS_GET_STATUS"):
+        raise Exception("PBC status not shown correctly")
+
+    dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
+    dev[0].request("WPS_PBC")
+    dev[0].wait_connected(timeout=20)
+    status = dev[0].get_status()
+    if status['wpa_state'] != 'COMPLETED' or status['bssid'] != bssid:
+        raise Exception("Not fully connected")
+    if status['ssid'] != new_ssid:
+        raise Exception("Unexpected SSID %s != %s" % (status['ssid'], new_ssid))
+    dev[0].request("DISCONNECT")
+    dev[0].wait_disconnected()
+
+def test_ap_reload_invalid(dev, apdev):
+    """hostapd RELOAD with invalid configuration"""
+    params = hostapd.wpa2_params(ssid="test-wpa2-psk-start",
+                                 passphrase="12345678")
+    hapd = hostapd.add_ap(apdev[0], params)
+    # Enable IEEE 802.11d without specifying country code
+    hapd.set("ieee80211d", "1")
+    if "FAIL" not in hapd.request("RELOAD"):
+        raise Exception("RELOAD command succeeded")
+    dev[0].connect("test-wpa2-psk-start", psk="12345678", scan_freq="2412")
+
 def multi_check(apdev, dev, check, scan_opt=True):
     id = []
     num_bss = len(check)
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_eap.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_eap.py
index 7395c79..a9715ee 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_eap.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_eap.py
@@ -97,6 +97,11 @@
     if "BoringSSL" in tls or "GnuTLS" in tls:
         raise HwsimSkip("PKCS#5 v1.5 not supported with this TLS library: " + tls)
 
+def check_tls13_support(dev):
+    tls = dev.request("GET tls_library")
+    if "run=OpenSSL 1.1.1" not in tls and "run=OpenSSL 3.0" not in tls:
+        raise HwsimSkip("TLS v1.3 not supported")
+
 def check_ocsp_multi_support(dev):
     tls = dev.request("GET tls_library")
     if not tls.startswith("internal"):
@@ -124,19 +129,25 @@
     if tls.startswith("internal"):
         raise HwsimSkip("EC not supported with this TLS library: " + tls)
 
-def read_pem(fname):
+def read_pem(fname, decode=True):
     with open(fname, "r") as f:
         lines = f.readlines()
         copy = False
         cert = ""
         for l in lines:
             if "-----END" in l:
+                if not decode:
+                    cert = cert + l
                 break
             if copy:
                 cert = cert + l
             if "-----BEGIN" in l:
                 copy = True
-    return base64.b64decode(cert)
+                if not decode:
+                    cert = cert + l
+    if decode:
+        return base64.b64decode(cert)
+    return cert.encode()
 
 def eap_connect(dev, hapd, method, identity,
                 sha256=False, expect_failure=False, local_error_report=False,
@@ -881,6 +892,7 @@
     try:
         run_ap_wpa2_eap_sim_ext_anonymous(dev, "anonymous@example.org")
         run_ap_wpa2_eap_sim_ext_anonymous(dev, "@example.org")
+        run_ap_wpa2_eap_sim_ext_anonymous(dev, "example.org!anonymous@otherexample.org")
     finally:
         dev[0].request("SET external_sim 0")
 
@@ -2243,6 +2255,24 @@
                 client_cert="blob://usercert",
                 private_key="blob://userkey")
 
+def test_ap_wpa2_eap_tls_blob_pem(dev, apdev):
+    """WPA2-Enterprise connection using EAP-TLS and config blobs (PEM)"""
+    params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
+    hapd = hostapd.add_ap(apdev[0], params)
+    cert = read_pem("auth_serv/ca.pem", decode=False)
+    if "OK" not in dev[0].request("SET blob cacert " +  binascii.hexlify(cert).decode()):
+        raise Exception("Could not set cacert blob")
+    cert = read_pem("auth_serv/user.pem", decode=False)
+    if "OK" not in dev[0].request("SET blob usercert " + binascii.hexlify(cert).decode()):
+        raise Exception("Could not set usercert blob")
+    key = read_pem("auth_serv/user.key.pkcs8", decode=False)
+    if "OK" not in dev[0].request("SET blob userkey " + binascii.hexlify(key).decode()):
+        raise Exception("Could not set cacert blob")
+    eap_connect(dev[0], hapd, "TLS", "tls user", ca_cert="blob://cacert",
+                client_cert="blob://usercert",
+                private_key="blob://userkey",
+                private_key_passwd="whatever")
+
 def test_ap_wpa2_eap_tls_blob_missing(dev, apdev):
     """EAP-TLS and config blob missing"""
     params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
@@ -2731,7 +2761,7 @@
     """WPA2-Enterprise connection using EAP-TTLS and server certificate hash"""
     check_cert_probe_support(dev[0])
     skip_with_fips(dev[0])
-    srv_cert_hash = "f75a953c1aa9967926525d4d860d1ff7e872f7088782f060768d12aecbd5f25e"
+    srv_cert_hash = "5891bd91eaf977684e70d4376d1514621d18f09ab2020bea1ad293d59a6e8944"
     params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
     hapd = hostapd.add_ap(apdev[0], params)
     dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
@@ -3946,7 +3976,7 @@
             if cipher == "RC4-SHA" and \
                ("Could not select EAP method" in str(e) or \
                 "EAP failed" in str(e)):
-                if "run=OpenSSL 1.1" in tls:
+                if "run=OpenSSL 1.1" in tls or "run=OpenSSL 3.0" in tls:
                     logger.info("Allow failure due to missing TLS library support")
                     dev[0].request("REMOVE_NETWORK all")
                     dev[0].wait_disconnected()
@@ -4175,7 +4205,7 @@
            "-reqout", outfile,
            '-issuer', 'auth_serv/ca.pem',
            '-sha256',
-           '-serial', '0xD8D3E3A6CBE3CD5F',
+           '-serial', '0xD8D3E3A6CBE3CD69',
            '-no_nonce']
     run_openssl(arg)
     if not os.path.exists(outfile):
@@ -5350,6 +5380,15 @@
         eap_connect(dev[1], hapd, "TTLS", "user-pap",
                     anonymous_identity="ttls", password="password",
                     ca_cert="auth_serv/ca.pem", phase2="auth=PAP")
+        dev[0].request("REMOVE_NETWORK all")
+        dev[1].request("REMOVE_NETWORK all")
+        dev[0].wait_disconnected()
+        dev[1].wait_disconnected()
+        hapd.disable()
+        hapd.enable()
+        eap_connect(dev[0], hapd, "TTLS", "user-mschapv2",
+                    anonymous_identity="ttls", password="password",
+                    ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2")
     finally:
         os.remove(dbfile)
 
@@ -5871,7 +5910,7 @@
                   "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=0 tls_disable_tlsv1_2=1", "TLSv1.1")
     check_tls_ver(dev[2], hapd,
                   "tls_disable_tlsv1_0=0 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1", "TLSv1")
-    if "run=OpenSSL 1.1.1" in tls:
+    if "run=OpenSSL 1.1.1" in tls or "run=OpenSSL 3.0" in tls:
         check_tls_ver(dev[0], hapd,
                       "tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1 tls_disable_tlsv1_3=0", "TLSv1.3")
 
@@ -5903,9 +5942,7 @@
     params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
     hapd = hostapd.add_ap(apdev[0], params)
 
-    tls = dev[0].request("GET tls_library")
-    if "run=OpenSSL 1.1.1" not in tls:
-        raise HwsimSkip("TLS v1.3 not supported")
+    check_tls13_support(dev[0])
     id = eap_connect(dev[0], hapd, "TLS", "tls user",
                      ca_cert="auth_serv/ca.pem",
                      client_cert="auth_serv/user.pem",
@@ -5922,6 +5959,51 @@
     dev[0].request("RECONNECT")
     dev[0].wait_connected()
 
+def test_ap_wpa2_eap_ttls_13(dev, apdev):
+    """EAP-TTLS and TLS 1.3"""
+    params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
+    hapd = hostapd.add_ap(apdev[0], params)
+
+    check_tls13_support(dev[0])
+    id = eap_connect(dev[0], hapd, "TTLS", "pap user",
+                     anonymous_identity="ttls", password="password",
+                     ca_cert="auth_serv/ca.pem",
+                     phase1="tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1 tls_disable_tlsv1_3=0",
+                     phase2="auth=PAP")
+    ver = dev[0].get_status_field("eap_tls_version")
+    if ver != "TLSv1.3":
+        raise Exception("Unexpected TLS version")
+
+    eap_reauth(dev[0], "TTLS")
+    dev[0].request("DISCONNECT")
+    dev[0].wait_disconnected()
+    dev[0].request("PMKSA_FLUSH")
+    dev[0].request("RECONNECT")
+    dev[0].wait_connected()
+
+def test_ap_wpa2_eap_peap_13(dev, apdev):
+    """PEAP and TLS 1.3"""
+    check_eap_capa(dev[0], "MSCHAPV2")
+    params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
+    hapd = hostapd.add_ap(apdev[0], params)
+
+    check_tls13_support(dev[0])
+    id = eap_connect(dev[0], hapd, "PEAP", "user",
+                     anonymous_identity="peap", password="password",
+                     ca_cert="auth_serv/ca.pem",
+                     phase1="tls_disable_tlsv1_0=1 tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1 tls_disable_tlsv1_3=0",
+                     phase2="auth=MSCHAPV2")
+    ver = dev[0].get_status_field("eap_tls_version")
+    if ver != "TLSv1.3":
+        raise Exception("Unexpected TLS version")
+
+    eap_reauth(dev[0], "PEAP")
+    dev[0].request("DISCONNECT")
+    dev[0].wait_disconnected()
+    dev[0].request("PMKSA_FLUSH")
+    dev[0].request("RECONNECT")
+    dev[0].wait_connected()
+
 def test_ap_wpa2_eap_tls_13_ec(dev, apdev):
     """EAP-TLS and TLS 1.3 (EC certificates)"""
     params = {"ssid": "test-wpa2-eap",
@@ -5936,13 +6018,9 @@
               "private_key": "auth_serv/ec-server.key",
               "tls_flags": "[ENABLE-TLSv1.3]"}
     hapd = hostapd.add_ap(apdev[0], params)
-    tls = hapd.request("GET tls_library")
-    if "run=OpenSSL 1.1.1" not in tls:
-        raise HwsimSkip("TLS v1.3 not supported")
+    check_tls13_support(hapd)
 
-    tls = dev[0].request("GET tls_library")
-    if "run=OpenSSL 1.1.1" not in tls:
-        raise HwsimSkip("TLS v1.3 not supported")
+    check_tls13_support(dev[0])
     id = eap_connect(dev[0], hapd, "TLS", "tls user",
                      ca_cert="auth_serv/ec-ca.pem",
                      client_cert="auth_serv/ec-user.pem",
@@ -6657,6 +6735,62 @@
     dev[0].request("DISCONNECT")
     dev[0].wait_disconnected()
 
+def test_ap_wpa2_eap_sim_db_sqlite(dev, apdev, params):
+    """EAP-SIM DB error cases (SQLite)"""
+    sockpath = '/tmp/hlr_auc_gw.sock-test'
+    try:
+        os.remove(sockpath)
+    except:
+        pass
+    hparams = int_eap_server_params()
+    hparams['eap_sim_db'] = 'unix:' + sockpath
+    hapd = hostapd.add_ap(apdev[0], hparams)
+
+    fname = params['prefix'] + ".milenage_db.sqlite"
+    cmd = subprocess.Popen(['../../hostapd/hlr_auc_gw',
+                            '-D', fname, "FOO"],
+                           stdout=subprocess.PIPE)
+    res = cmd.stdout.read().decode().strip()
+    cmd.stdout.close()
+    logger.debug("hlr_auc_gw response: " + res)
+
+    try:
+        import sqlite3
+    except ImportError:
+        raise HwsimSkip("No sqlite3 module available")
+    con = sqlite3.connect(fname)
+    with con:
+        cur = con.cursor()
+        try:
+            cur.execute("INSERT INTO milenage(imsi,ki,opc,amf,sqn) VALUES ('232010000000000', '90dca4eda45b53cf0f12d7c9c3bc6a89', 'cb9cccc4b9258e6dca4760379fb82581', '61df', '000000000000')")
+        except sqlite3.IntegrityError as e:
+            pass
+
+    class test_handler3(SocketServer.DatagramRequestHandler):
+        def handle(self):
+            data = self.request[0].decode().strip()
+            socket = self.request[1]
+            logger.debug("Received hlr_auc_gw request: " + data)
+            cmd = subprocess.Popen(['../../hostapd/hlr_auc_gw',
+                                    '-D', fname, data],
+                                   stdout=subprocess.PIPE)
+            res = cmd.stdout.read().decode().strip()
+            cmd.stdout.close()
+            logger.debug("hlr_auc_gw response: " + res)
+            socket.sendto(res.encode(), self.client_address)
+
+    server = SocketServer.UnixDatagramServer(sockpath, test_handler3)
+    server.timeout = 1
+
+    id = dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP WPA-EAP-SHA256",
+                        eap="SIM", identity="1232010000000000",
+                        password="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
+                        scan_freq="2412", wait_connect=False)
+    server.handle_request()
+    dev[0].wait_connected()
+    dev[0].request("DISCONNECT")
+    dev[0].wait_disconnected()
+
 def test_eap_tls_sha512(dev, apdev, params):
     """EAP-TLS with SHA512 signature"""
     params = int_eap_server_params()
@@ -7224,6 +7358,13 @@
     logger.info("Start wpa_supplicant: " + str(arg))
     subprocess.call(arg, env={'OPENSSL_CONF': openssl_cnf})
     wpas = WpaSupplicant(ifname=iface)
+    try:
+        finish_openssl_systemwide_policy(wpas)
+    finally:
+        wpas.close_monitor()
+        wpas.request("TERMINATE")
+
+def finish_openssl_systemwide_policy(wpas):
     if "PONG" not in wpas.request("PING"):
         raise Exception("Could not PING wpa_supplicant")
     tls = wpas.request("GET tls_library")
@@ -7256,8 +7397,6 @@
     wpas.select_network(id, freq="2412")
     wpas.wait_connected()
 
-    wpas.request("TERMINATE")
-
 def test_ap_wpa2_eap_tls_tod(dev, apdev):
     """EAP-TLS server certificate validation and TOD-STRICT"""
     check_tls_tod(dev[0])
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_ft.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_ft.py
index f2ca6f1..00b1635 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_ft.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_ft.py
@@ -136,7 +136,8 @@
               group_mgmt=None, ocv=None, sae_password=None,
               sae_password_id=None, sae_and_psk=False, pmksa_caching=False,
               roam_with_reassoc=False, also_non_ft=False, only_one_way=False,
-              wait_before_roam=0, return_after_initial=False, ieee80211w="1"):
+              wait_before_roam=0, return_after_initial=False, ieee80211w="1",
+              sae_transition=False, beacon_prot=False):
     logger.info("Connect to first AP")
 
     copts = {}
@@ -150,6 +151,8 @@
         copts["group_mgmt"] = group_mgmt
     if ocv:
         copts["ocv"] = ocv
+    if beacon_prot:
+        copts["beacon_prot"] = "1"
     if eap:
         if pmksa_caching:
             copts["ft_eap_pmksa_caching"] = "1"
@@ -161,7 +164,9 @@
         copts["identity"] = eap_identity
         copts["password"] = "abcdefghijklmnop0123456789abcdef"
     else:
-        if sae:
+        if sae_transition:
+            copts["key_mgmt"] = "FT-SAE FT-PSK"
+        elif sae:
             copts["key_mgmt"] = "SAE FT-SAE" if sae_and_psk else "FT-SAE"
         else:
             copts["key_mgmt"] = "FT-PSK"
@@ -218,6 +223,10 @@
     dev.scan_for_bss(ap2['bssid'], freq="2412")
 
     for i in range(0, roams):
+        dev.dump_monitor()
+        hapd1ap.dump_monitor()
+        hapd2ap.dump_monitor()
+
         # Roaming artificially fast can make data test fail because the key is
         # set later.
         time.sleep(0.01)
@@ -236,11 +245,18 @@
             raise Exception("Did not connect to correct AP")
         if (i == 0 or i == roams - 1) and test_connectivity:
             hapd2ap.wait_sta()
+            dev.dump_monitor()
+            hapd1ap.dump_monitor()
+            hapd2ap.dump_monitor()
             if conndev:
                 hwsim_utils.test_connectivity_iface(dev, hapd2ap, conndev)
             else:
                 hwsim_utils.test_connectivity(dev, hapd2ap)
 
+        dev.dump_monitor()
+        hapd1ap.dump_monitor()
+        hapd2ap.dump_monitor()
+
         if only_one_way:
             return
         # Roaming artificially fast can make data test fail because the key is
@@ -259,6 +275,9 @@
             raise Exception("Did not connect to correct AP")
         if (i == 0 or i == roams - 1) and test_connectivity:
             hapd1ap.wait_sta()
+            dev.dump_monitor()
+            hapd1ap.dump_monitor()
+            hapd2ap.dump_monitor()
             if conndev:
                 hwsim_utils.test_connectivity_iface(dev, hapd1ap, conndev)
             else:
@@ -474,15 +493,23 @@
     """WPA2-PSK-FT AP with PMF required on STA (over DS)"""
     run_ap_ft_pmf(dev, apdev, "2", over_ds=True)
 
-def run_ap_ft_pmf(dev, apdev, ieee80211w, over_ds=False):
+def test_ap_ft_pmf_beacon_prot(dev, apdev):
+    """WPA2-PSK-FT AP with PMF and beacon protection"""
+    run_ap_ft_pmf(dev, apdev, "1", beacon_prot=True)
+
+def run_ap_ft_pmf(dev, apdev, ieee80211w, over_ds=False, beacon_prot=False):
     ssid = "test-ft"
     passphrase = "12345678"
 
     params = ft_params1(ssid=ssid, passphrase=passphrase)
     params["ieee80211w"] = "2"
+    if beacon_prot:
+        params["beacon_prot"] = "1"
     hapd0 = hostapd.add_ap(apdev[0], params)
     params = ft_params2(ssid=ssid, passphrase=passphrase)
     params["ieee80211w"] = "2"
+    if beacon_prot:
+        params["beacon_prot"] = "1"
     hapd1 = hostapd.add_ap(apdev[1], params)
 
     Wlantest.setup(hapd0)
@@ -491,7 +518,7 @@
     wt.add_passphrase(passphrase)
 
     run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase,
-              ieee80211w=ieee80211w, over_ds=over_ds)
+              ieee80211w=ieee80211w, over_ds=over_ds, beacon_prot=beacon_prot)
 
 def test_ap_ft_pmf_required_mismatch(dev, apdev):
     """WPA2-PSK-FT AP with PMF required on STA but AP2 not enabling PMF"""
@@ -998,7 +1025,8 @@
 def start_ft_sae(dev, apdev, wpa_ptk_rekey=None, sae_pwe=None,
                  rsne_override=None, rsnxe_override=None,
                  no_beacon_rsnxe2=False, ext_key_id=False,
-                 skip_prune_assoc=False, ft_rsnxe_used=False):
+                 skip_prune_assoc=False, ft_rsnxe_used=False,
+                 sae_transition=False):
     if "SAE" not in dev.get_capability("auth_alg"):
         raise HwsimSkip("SAE not supported")
     ssid = "test-ft"
@@ -1022,7 +1050,8 @@
         params['ft_rsnxe_used'] = '1'
     hapd0 = hostapd.add_ap(apdev[0], params)
     params = ft_params2(ssid=ssid, passphrase=passphrase)
-    params['wpa_key_mgmt'] = "FT-SAE"
+    if not sae_transition:
+        params['wpa_key_mgmt'] = "FT-SAE"
     if wpa_ptk_rekey:
         params['wpa_ptk_rekey'] = str(wpa_ptk_rekey)
     if sae_pwe is not None:
@@ -1041,7 +1070,7 @@
         params['ft_rsnxe_used'] = '1'
     hapd1 = hostapd.add_ap(apdev[1], params)
     key_mgmt = hapd1.get_config()['key_mgmt']
-    if key_mgmt.split(' ')[0] != "FT-SAE":
+    if key_mgmt.split(' ')[0] != "FT-SAE" and not sae_transition:
         raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
 
     dev.request("SET sae_groups ")
@@ -1052,6 +1081,12 @@
     hapd0, hapd1 = start_ft_sae(dev[0], apdev)
     run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678", sae=True)
 
+def test_ap_ft_sae_transition(dev, apdev):
+    """WPA2-PSK-FT-SAE/PSK AP"""
+    hapd0, hapd1 = start_ft_sae(dev[0], apdev, sae_transition=True)
+    run_roams(dev[0], apdev, hapd0, hapd1, "test-ft", "12345678",
+              sae_transition=True)
+
 def test_ap_ft_sae_h2e(dev, apdev):
     """WPA2-PSK-FT-SAE AP (H2E)"""
     try:
@@ -1595,7 +1630,14 @@
         f.write("interface=%s\n" % ifname2)
         f.write("bssid=%s\n" % bssid2)
         f.write("ctrl_interface=/var/run/hostapd\n")
+
+        fields = ["ssid", "wpa_passphrase", "nas_identifier", "wpa_key_mgmt",
+                  "wpa", "rsn_pairwise", "auth_server_addr"]
+        for name in fields:
+            f.write("%s=%s\n" % (name, params[name]))
         for name, val in params.items():
+            if name in fields:
+                continue
             f.write("%s=%s\n" % (name, val))
     hapd2 = hostapd.add_bss(apdev[0], ifname2, bssconf)
 
@@ -3183,6 +3225,10 @@
     params["ieee8021x"] = "1"
     params = dict(list(radius.items()) + list(params.items()))
     hapd0 = hostapd.add_ap(apdev[0], params)
+    conf = hapd0.request("GET_CONFIG")
+    if "key_mgmt=FT-EAP-SHA384" not in conf.splitlines():
+        logger.info("GET_CONFIG:\n" + conf)
+        raise Exception("GET_CONFIG did not report correct key_mgmt")
     params = ft_params2(ssid=ssid, passphrase=passphrase)
     params["ieee80211w"] = "2"
     params['wpa_key_mgmt'] = "FT-EAP-SHA384"
@@ -3334,9 +3380,11 @@
     passphrase = "12345678"
 
     params = ft_params1(ssid=ssid, passphrase=passphrase)
+    params.pop('r0_key_lifetime', None)
     params['ft_r0_key_lifetime'] = "2"
     hapd0 = hostapd.add_ap(apdev[0], params)
     params = ft_params2(ssid=ssid, passphrase=passphrase)
+    params.pop('r0_key_lifetime', None)
     params['ft_r0_key_lifetime'] = "2"
     hapd1 = hostapd.add_ap(apdev[1], params)
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_hs20.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_hs20.py
index c8ba767..e3cb8a4 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_hs20.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_hs20.py
@@ -2817,6 +2817,7 @@
 def test_ap_hs20_network_preference(dev, apdev):
     """Hotspot 2.0 network selection with preferred home network"""
     check_eap_capa(dev[0], "MSCHAPV2")
+    dev[0].flush_scan_cache()
     bssid = apdev[0]['bssid']
     params = hs20_ap_params()
     hostapd.add_ap(apdev[0], params)
@@ -2858,6 +2859,7 @@
 def test_ap_hs20_network_preference2(dev, apdev):
     """Hotspot 2.0 network selection with preferred credential"""
     check_eap_capa(dev[0], "MSCHAPV2")
+    dev[0].flush_scan_cache()
     bssid2 = apdev[1]['bssid']
     params = hostapd.wpa2_params(ssid="home", passphrase="12345678")
     hostapd.add_ap(apdev[1], params)
@@ -2899,6 +2901,7 @@
 def test_ap_hs20_network_preference3(dev, apdev):
     """Hotspot 2.0 network selection with two credential (one preferred)"""
     check_eap_capa(dev[0], "MSCHAPV2")
+    dev[0].flush_scan_cache()
     bssid = apdev[0]['bssid']
     params = hs20_ap_params()
     hostapd.add_ap(apdev[0], params)
@@ -2940,6 +2943,7 @@
 def test_ap_hs20_network_preference4(dev, apdev):
     """Hotspot 2.0 network selection with username vs. SIM credential"""
     check_eap_capa(dev[0], "MSCHAPV2")
+    dev[0].flush_scan_cache()
     bssid = apdev[0]['bssid']
     params = hs20_ap_params()
     hostapd.add_ap(apdev[0], params)
@@ -4176,12 +4180,12 @@
     interworking_connect(dev[0], bssid, "PEAP")
     dev[0].add_network()
     if len(dev[0].list_networks()) != 5:
-        raise Exception("Unexpected number of networks prior to remove_crec")
+        raise Exception("Unexpected number of networks prior to remove_cred")
 
     dev[0].dump_monitor()
     dev[0].remove_cred(id)
     if len(dev[0].list_networks()) != 3:
-        raise Exception("Unexpected number of networks after to remove_crec")
+        raise Exception("Unexpected number of networks after to remove_cred")
     dev[0].wait_disconnected(timeout=10)
 
 def test_ap_hs20_interworking_add_network(dev, apdev):
@@ -6330,6 +6334,10 @@
                 raise Exeception("Unexpected number of rows in current_sessions (%d; expected %d)" % (len(rows), 1))
             logger.info("current_sessions: " + str(rows))
 
+        tests = ["foo", "disconnect q", "coa %s" % dev[0].own_addr()]
+        for t in tests:
+            if "FAIL" not in authsrv.request("DAC_REQUEST " + t):
+                raise Exception("Invalid DAC_REQUEST accepted: " + t)
         if "OK" not in authsrv.request("DAC_REQUEST coa %s t_c_clear" % dev[0].own_addr()):
             raise Exception("DAC_REQUEST failed")
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_ht.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_ht.py
index 99adb12..510fe08 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_ht.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_ht.py
@@ -1370,13 +1370,15 @@
     hwsim_utils.test_connectivity(dev[1], hapd2)
 
 def run_op_class(dev, apdev, hw_mode, channel, country, ht_capab, sec_chan,
-                 freq, opclass):
+                 freq, opclass, use_op_class=False):
     clear_scan_cache(apdev[0])
     try:
         params = {"ssid": "test-ht40",
                   "hw_mode": hw_mode,
                   "channel": channel,
                   "ht_capab": ht_capab}
+        if use_op_class:
+            params['op_class'] = str(opclass)
         if country:
             params['country_code'] = country
         hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
@@ -1397,6 +1399,7 @@
         if rx_opclass != opclass:
             raise Exception("Unexpected operating class: %d" % rx_opclass)
         hapd.disable()
+        hapd.dump_monitor()
         dev[0].request("REMOVE_NETWORK all")
         dev[0].request("ABORT_SCAN")
         dev[0].wait_disconnected()
@@ -1407,67 +1410,99 @@
 
 def test_ap_ht_op_class_81(dev, apdev):
     """HT20 on operationg class 81"""
-    run_op_class(dev, apdev, "g", "1", None, "", "0", "2412", 81)
+    for o in [False, True]:
+        run_op_class(dev, apdev, "g", "1", None, "", "0", "2412", 81,
+                     use_op_class=o)
 
 def test_ap_ht_op_class_83(dev, apdev):
     """HT40 on operationg class 83"""
-    run_op_class(dev, apdev, "g", "1", None, "[HT40+]", "1", "2412", 83)
+    for o in [False, True]:
+        run_op_class(dev, apdev, "g", "1", None, "[HT40+]", "1", "2412", 83,
+                     use_op_class=o)
 
 def test_ap_ht_op_class_84(dev, apdev):
     """HT40 on operationg class 84"""
-    run_op_class(dev, apdev, "g", "11", None, "[HT40-]", "-1", "2462", 84)
+    for o in [False, True]:
+        run_op_class(dev, apdev, "g", "11", None, "[HT40-]", "-1", "2462", 84,
+                     use_op_class=o)
 
 def test_ap_ht_op_class_115(dev, apdev):
     """HT20 on operationg class 115"""
-    run_op_class(dev, apdev, "a", "36", "FI", "", "0", "5180", 115)
+    for o in [False, True]:
+        run_op_class(dev, apdev, "a", "36", "FI", "", "0", "5180", 115,
+                     use_op_class=o)
 
 def test_ap_ht_op_class_116(dev, apdev):
     """HT40 on operationg class 116"""
-    run_op_class(dev, apdev, "a", "36", "FI", "[HT40+]", "1", "5180", 116)
+    for o in [False, True]:
+        run_op_class(dev, apdev, "a", "36", "FI", "[HT40+]", "1", "5180", 116,
+                     use_op_class=o)
 
 def test_ap_ht_op_class_117(dev, apdev):
     """HT40 on operationg class 117"""
-    run_op_class(dev, apdev, "a", "40", "FI", "[HT40-]", "-1", "5200", 117)
+    for o in [False, True]:
+        run_op_class(dev, apdev, "a", "40", "FI", "[HT40-]", "-1", "5200", 117,
+                     use_op_class=o)
 
 def test_ap_ht_op_class_118(dev, apdev):
     """HT20 on operationg class 118"""
-    run_op_class(dev, apdev, "a", "60", "RS", "", "0", "5300", 118)
+    for o in [False, True]:
+        run_op_class(dev, apdev, "a", "60", "PA", "", "0", "5300", 118,
+                     use_op_class=o)
 
 def test_ap_ht_op_class_119(dev, apdev):
     """HT40 on operationg class 119"""
-    run_op_class(dev, apdev, "a", "60", "RS", "[HT40+]", "1", "5300", 119)
+    for o in [False, True]:
+        run_op_class(dev, apdev, "a", "60", "PA", "[HT40+]", "1", "5300", 119,
+                     use_op_class=o)
 
 def test_ap_ht_op_class_120(dev, apdev):
     """HT40 on operationg class 120"""
-    run_op_class(dev, apdev, "a", "64", "RS", "[HT40-]", "-1", "5320", 120)
+    for o in [False, True]:
+        run_op_class(dev, apdev, "a", "64", "PA", "[HT40-]", "-1", "5320", 120,
+                     use_op_class=o)
 
 def test_ap_ht_op_class_121(dev, apdev):
     """HT20 on operationg class 121"""
-    run_op_class(dev, apdev, "a", "100", "ZA", "", "0", "5500", 121)
+    for o in [False, True]:
+        run_op_class(dev, apdev, "a", "100", "ZA", "", "0", "5500", 121,
+                     use_op_class=o)
 
 def test_ap_ht_op_class_122(dev, apdev):
     """HT40 on operationg class 122"""
-    run_op_class(dev, apdev, "a", "100", "ZA", "[HT40+]", "1", "5500", 122)
+    for o in [False, True]:
+        run_op_class(dev, apdev, "a", "100", "ZA", "[HT40+]", "1", "5500", 122,
+                     use_op_class=o)
 
 def test_ap_ht_op_class_123(dev, apdev):
     """HT40 on operationg class 123"""
-    run_op_class(dev, apdev, "a", "104", "ZA", "[HT40-]", "-1", "5520", 123)
+    for o in [False, True]:
+        run_op_class(dev, apdev, "a", "104", "ZA", "[HT40-]", "-1", "5520", 123,
+                     use_op_class=o)
 
 def test_ap_ht_op_class_124(dev, apdev):
     """HT20 on operationg class 124"""
-    run_op_class(dev, apdev, "a", "149", "US", "", "0", "5745", 124)
+    for o in [False, True]:
+        run_op_class(dev, apdev, "a", "149", "US", "", "0", "5745", 124,
+                     use_op_class=o)
 
 def test_ap_ht_op_class_125(dev, apdev):
     """HT20 on operationg class 125"""
-    run_op_class(dev, apdev, "a", "169", "NL", "", "0", "5845", 125)
+    for o in [False, True]:
+        run_op_class(dev, apdev, "a", "169", "NL", "", "0", "5845", 125,
+                     use_op_class=o)
 
 def test_ap_ht_op_class_126(dev, apdev):
     """HT40 on operationg class 126"""
-    run_op_class(dev, apdev, "a", "149", "US", "[HT40+]", "1", "5745", 126)
+    for o in [False, True]:
+        run_op_class(dev, apdev, "a", "149", "US", "[HT40+]", "1", "5745", 126,
+                     use_op_class=o)
 
 def test_ap_ht_op_class_127(dev, apdev):
     """HT40 on operationg class 127"""
-    run_op_class(dev, apdev, "a", "153", "US", "[HT40-]", "-1", "5765", 127)
+    for o in [False, True]:
+        run_op_class(dev, apdev, "a", "153", "US", "[HT40-]", "-1", "5765", 127,
+                     use_op_class=o)
 
 def test_ap_ht40_plus_minus1(dev, apdev):
     """HT40 with both plus and minus allowed (1)"""
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_open.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_open.py
index 62b4446..a3bea76 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_open.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_open.py
@@ -198,19 +198,15 @@
     dev[0].request("DISCONNECT")
     dev[0].wait_disconnected(timeout=15)
     dev[0].dump_monitor()
-    # This will be accepted due to matching network
+    # This association will be ignored by wpa_supplicant since the current
+    # state is not to try to connect after that DISCONNECT command.
     dev[0].cmd_execute(['iw', 'dev', dev[0].ifname, 'connect', 'open', "2412",
                         apdev[0]['bssid']])
-    dev[0].wait_connected(timeout=15)
+    ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=0.3)
+    dev[0].cmd_execute(['iw', 'dev', dev[0].ifname, 'disconnect'])
     dev[0].dump_monitor()
-
-    dev[0].request("REMOVE_NETWORK all")
-    dev[0].wait_disconnected(timeout=5)
-    dev[0].dump_monitor()
-    # This will result in disconnection due to no matching network
-    dev[0].cmd_execute(['iw', 'dev', dev[0].ifname, 'connect', 'open', "2412",
-                        apdev[0]['bssid']])
-    dev[0].wait_disconnected(timeout=15)
+    if ev is not None:
+        raise Exception("Unexpected connection")
 
 def test_ap_open_external_assoc(dev, apdev):
     """AP with open mode and external association"""
@@ -301,18 +297,18 @@
     # not fail
     hostapd.add_ap(apdev[1], {"ssid": "open"})
 
-def test_bssid_black_white_list(dev, apdev):
-    """BSSID black/white list"""
+def test_bssid_ignore_accept(dev, apdev):
+    """BSSID ignore/accept list"""
     hapd = hostapd.add_ap(apdev[0], {"ssid": "open"})
     hapd2 = hostapd.add_ap(apdev[1], {"ssid": "open"})
 
     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
-                   bssid_whitelist=apdev[1]['bssid'])
+                   bssid_accept=apdev[1]['bssid'])
     dev[1].connect("open", key_mgmt="NONE", scan_freq="2412",
-                   bssid_blacklist=apdev[1]['bssid'])
+                   bssid_ignore=apdev[1]['bssid'])
     dev[2].connect("open", key_mgmt="NONE", scan_freq="2412",
-                   bssid_whitelist="00:00:00:00:00:00/00:00:00:00:00:00",
-                   bssid_blacklist=apdev[1]['bssid'])
+                   bssid_accept="00:00:00:00:00:00/00:00:00:00:00:00",
+                   bssid_ignore=apdev[1]['bssid'])
     if dev[0].get_status_field('bssid') != apdev[1]['bssid']:
         raise Exception("dev[0] connected to unexpected AP")
     if dev[1].get_status_field('bssid') != apdev[0]['bssid']:
@@ -324,11 +320,11 @@
     dev[2].request("REMOVE_NETWORK all")
 
     dev[2].connect("open", key_mgmt="NONE", scan_freq="2412",
-                   bssid_whitelist="00:00:00:00:00:00", wait_connect=False)
+                   bssid_accept="00:00:00:00:00:00", wait_connect=False)
     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
-                   bssid_whitelist="11:22:33:44:55:66/ff:00:00:00:00:00 " + apdev[1]['bssid'] + " aa:bb:cc:dd:ee:ff")
+                   bssid_accept="11:22:33:44:55:66/ff:00:00:00:00:00 " + apdev[1]['bssid'] + " aa:bb:cc:dd:ee:ff")
     dev[1].connect("open", key_mgmt="NONE", scan_freq="2412",
-                   bssid_blacklist="11:22:33:44:55:66/ff:00:00:00:00:00 " + apdev[1]['bssid'] + " aa:bb:cc:dd:ee:ff")
+                   bssid_ignore="11:22:33:44:55:66/ff:00:00:00:00:00 " + apdev[1]['bssid'] + " aa:bb:cc:dd:ee:ff")
     if dev[0].get_status_field('bssid') != apdev[1]['bssid']:
         raise Exception("dev[0] connected to unexpected AP")
     if dev[1].get_status_field('bssid') != apdev[0]['bssid']:
@@ -586,17 +582,17 @@
 
     dev[0].select_network(id1)
     dev[0].wait_connected()
-    res = dev[0].request("BLACKLIST")
+    res = dev[0].request("BSSID_IGNORE")
     if bssid1 in res or bssid2 in res:
-        raise Exception("Unexpected blacklist entry")
+        raise Exception("Unexpected BSSID ignore list entry")
     hwsim_utils.test_connectivity(dev[0], hapd1)
 
     dev[0].select_network(id2)
     dev[0].wait_connected()
     hwsim_utils.test_connectivity(dev[0], hapd2)
-    res = dev[0].request("BLACKLIST")
+    res = dev[0].request("BSSID_IGNORE")
     if bssid1 in res or bssid2 in res:
-        raise Exception("Unexpected blacklist entry(2)")
+        raise Exception("Unexpected BSSID ignore list entry(2)")
 
 @remote_compatible
 def test_ap_open_disable_enable(dev, apdev):
@@ -917,9 +913,9 @@
 
     dev[0].request("DISABLE_NETWORK %d" % id)
     dev[0].wait_disconnected()
-    res = dev[0].request("BLACKLIST")
+    res = dev[0].request("BSSID_IGNORE")
     if hapd1.own_addr() in res or hapd2.own_addr() in res:
-        raise Exception("Unexpected blacklist entry added")
+        raise Exception("Unexpected BSSID ignore list entry added")
     dev[0].request("SELECT_NETWORK %d" % id)
     dev[0].wait_connected()
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_params.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_params.py
index 7918057..72ac8e4 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_params.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_params.py
@@ -201,7 +201,13 @@
     if "01:01:01:01:01:01 VLAN_ID=0" not in deny:
         raise Exception("Missing deny entry")
 
+    if "OK" not in hapd.request("ACCEPT_ACL DEL_MAC 22:33:44:55:66:77"):
+        raise Exception("DEL_MAC with empty list failed")
+    if "FAIL" not in hapd.request("ACCEPT_ACL ADD_MAC 22:33:44:55:66"):
+        raise Exception("ADD_MAC with invalid MAC address accepted")
     hapd.request("ACCEPT_ACL ADD_MAC 22:33:44:55:66:77")
+    if "FAIL" not in hapd.request("ACCEPT_ACL DEL_MAC 22:33:44:55:66"):
+        raise Exception("DEL_MAC with invalid MAC address accepted")
     hapd.request("DENY_ACL ADD_MAC 22:33:44:55:66:88 VLAN_ID=2")
 
     accept = hapd.request("ACCEPT_ACL SHOW").splitlines()
@@ -254,6 +260,29 @@
     if filename.startswith('/tmp/'):
         os.unlink(filename)
 
+def test_ap_acl_accept_changes(dev, apdev):
+    """MAC ACL accept list changes"""
+    ssid = "acl"
+    params = {}
+    params['ssid'] = ssid
+    params['macaddr_acl'] = "1"
+    hapd = hostapd.add_ap(apdev[0], params)
+    hapd.request("ACCEPT_ACL ADD_MAC " + dev[0].own_addr())
+    hapd.request("ACCEPT_ACL ADD_MAC " + dev[1].own_addr())
+    dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
+    dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412")
+    dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
+    dev[1].connect(ssid, key_mgmt="NONE", scan_freq="2412")
+    hapd.request("ACCEPT_ACL DEL_MAC " + dev[0].own_addr())
+    dev[0].wait_disconnected()
+    dev[0].request("DISCONNECT")
+    ev = dev[1].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.1)
+    if ev is not None:
+        raise Exception("Unexpected disconnection")
+    hapd.request("ACCEPT_ACL CLEAR")
+    dev[1].wait_disconnected()
+    dev[1].request("DISCONNECT")
+
 @remote_compatible
 def test_ap_wds_sta(dev, apdev):
     """WPA2-PSK AP with STA using 4addr mode"""
@@ -591,6 +620,17 @@
     if "FAIL" not in hapd.request('SET wmm_ac_bk_cwmax 3'):
         raise Exception("AC cwMax < cwMin accepted")
 
+    hapd.request("SET tx_queue_data2_cwmax 1023")
+    hapd.set("wmm_ac_bk_cwmax", "10")
+    # Invalid IEs to cause WMM parameter update failing
+    hapd.set("vendor_elements", "dd04112233")
+    hapd.set("wmm_ac_be_cwmin", "3")
+    # Valid IEs to cause WMM parameter update succeeding
+    hapd.set("vendor_elements", "dd0411223344")
+    hapd.set("wmm_ac_be_cwmin", "3")
+
+    dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412")
+
 def test_ap_beacon_rate_legacy(dev, apdev):
     """Open AP with Beacon frame TX rate 5.5 Mbps"""
     hapd = hostapd.add_ap(apdev[0], {'ssid': 'beacon-rate'})
@@ -843,3 +883,90 @@
     dev[0].scan_for_bss(bssid, freq="2412")
     dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412")
     hwsim_utils.test_connectivity(dev[0], hapd)
+
+def test_ap_notify_mgmt_frames(dev, apdev):
+    """hostapd notify_mgmt_frames configuration enabled"""
+    ssid = "mgmt_frames"
+    params = {'ssid': ssid, 'notify_mgmt_frames': "1"}
+    hapd = hostapd.add_ap(apdev[0], params)
+    bssid = hapd.own_addr()
+    dev[0].scan_for_bss(bssid, freq="2412")
+    dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412")
+    ev = hapd.wait_event(["AP-MGMT-FRAME-RECEIVED"], timeout=5)
+    if ev is None:
+        raise Exception("AP-MGMT-FRAME-RECEIVED wait timed out")
+    if "buf=b0" not in ev:
+        raise Exception("Expected auth request in AP-MGMT-FRAME-RECEIVED")
+
+def test_ap_notify_mgmt_frames_disabled(dev, apdev):
+    """hostapd notify_mgmt_frames configuration disabled"""
+    ssid = "mgmt_frames"
+    params = {'ssid': ssid, 'notify_mgmt_frames': "0"}
+    hapd = hostapd.add_ap(apdev[0], params)
+    bssid = hapd.own_addr()
+    dev[0].scan_for_bss(bssid, freq="2412")
+    dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412")
+    ev = hapd.wait_event(["AP-MGMT-FRAME-RECEIVED"], timeout=0.1)
+    if ev is not None:
+        raise Exception("Unexpected AP-MGMT-FRAME-RECEIVED")
+
+def test_ap_airtime_policy_static(dev, apdev):
+    """Airtime policy - static"""
+    ssid = "test-wpa2-psk"
+    passphrase = 'qwertyuiop'
+    params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
+    params['airtime_mode'] = "1"
+    params['airtime_update_interval'] = "200"
+    params['airtime_sta_weight'] = dev[0].own_addr() + " 512"
+    hapd = hostapd.add_ap(apdev[0], params)
+    dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
+    dev[1].connect(ssid, psk=passphrase, scan_freq="2412")
+    time.sleep(1)
+
+def test_ap_airtime_policy_per_bss_dynamic(dev, apdev):
+    """Airtime policy - per-BSS dynamic"""
+    ssid = "test-wpa2-psk"
+    passphrase = 'qwertyuiop'
+    params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
+    params['airtime_mode'] = "2"
+    params['airtime_update_interval'] = "200"
+    params['airtime_bss_weight'] = "2"
+    hapd = hostapd.add_ap(apdev[0], params)
+    dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
+    dev[1].connect(ssid, psk=passphrase, scan_freq="2412")
+    time.sleep(1)
+
+def test_ap_airtime_policy_per_bss_limit(dev, apdev):
+    """Airtime policy - per-BSS limit"""
+    ssid = "test-wpa2-psk"
+    passphrase = 'qwertyuiop'
+    params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
+    params['airtime_mode'] = "3"
+    params['airtime_update_interval'] = "200"
+    params['airtime_bss_weight'] = "2"
+    params['airtime_bss_limit'] = "1"
+    hapd = hostapd.add_ap(apdev[0], params)
+    dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
+    dev[1].connect(ssid, psk=passphrase, scan_freq="2412")
+    time.sleep(1)
+    hapd.set("force_backlog_bytes", "1")
+    time.sleep(1)
+
+def test_ap_airtime_policy_per_bss_limit_invalid(dev, apdev):
+    """Airtime policy - per-BSS limit (invalid)"""
+    ssid = "test-wpa2-psk"
+    passphrase = 'qwertyuiop'
+    params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
+    params['airtime_mode'] = "3"
+    params['airtime_update_interval'] = "0"
+    params['airtime_bss_weight'] = "2"
+    params['airtime_bss_limit'] = "1"
+    hapd = hostapd.add_ap(apdev[0], params, no_enable=True)
+    if "FAIL" not in hapd.request("ENABLE"):
+        raise Exception("Invalid airtime policy configuration accepted")
+    hapd.set("airtime_update_interval", "200")
+    hapd.enable()
+    hapd.set("airtime_update_interval", "0")
+    dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
+    dev[1].connect(ssid, psk=passphrase, scan_freq="2412")
+    time.sleep(1)
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_psk.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_psk.py
index db10377..2271fc3 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_psk.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_psk.py
@@ -168,6 +168,11 @@
 
     check_disconnect(dev, [True, True, False])
 
+    with open(psk_file, 'w') as f:
+        f.write('broken\n')
+    if "FAIL" not in hapd.request("RELOAD_WPA_PSK"):
+        raise Exception("RELOAD_WPA_PSK succeeded with invalid file")
+
 @remote_compatible
 def test_ap_wpa2_psk_mem(dev, apdev):
     """WPA2-PSK AP with passphrase only in memory"""
@@ -232,6 +237,9 @@
     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
     params['wpa_deny_ptk0_rekey'] = "2"
     hapd = hostapd.add_ap(apdev[0], params)
+    conf = hapd.request("GET_CONFIG").splitlines()
+    if "wpa_deny_ptk0_rekey=2" not in conf:
+        raise Exception("wpa_deny_ptk0_rekey value not in GET_CONFIG")
     dev[0].connect(ssid, psk=passphrase, wpa_ptk_rekey="1", scan_freq="2412")
     ev = dev[0].wait_event(["WPA: Key negotiation completed",
                             "CTRL-EVENT-DISCONNECTED"])
@@ -492,6 +500,42 @@
         raise Exception("GTK rekey timed out")
     hwsim_utils.test_connectivity(dev[0], hapd)
 
+def test_ap_wpa2_gtk_rekey_failure(dev, apdev):
+    """WPA2-PSK AP and GTK rekey failure"""
+    ssid = "test-wpa2-psk"
+    passphrase = 'qwertyuiop'
+    params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
+    hapd = hostapd.add_ap(apdev[0], params)
+    dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
+    with fail_test(hapd, 1, "wpa_group_config_group_keys"):
+        if "OK" not in hapd.request("REKEY_GTK"):
+            raise Exception("REKEY_GTK failed")
+        wait_fail_trigger(hapd, "GET_FAIL")
+    ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
+    if ev is None:
+        raise Exception("GTK rekey timed out")
+    dev[0].wait_disconnected()
+
+def test_ap_wpa2_gtk_rekey_request(dev, apdev):
+    """WPA2-PSK AP and GTK rekey request from multiple stations"""
+    ssid = "test-wpa2-psk"
+    passphrase = 'qwertyuiop'
+    params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
+    hapd = hostapd.add_ap(apdev[0], params)
+    for i in range(3):
+        dev[i].connect(ssid, psk=passphrase, scan_freq="2412")
+        hapd.wait_sta()
+    for i in range(3):
+        if "OK" not in dev[i].request("KEY_REQUEST 0 0"):
+            raise Exception("KEY_REQUEST failed")
+    for i in range(3):
+        ev = dev[i].wait_event(["WPA: Group rekeying completed"], timeout=2)
+        if ev is None:
+            raise Exception("GTK rekey timed out")
+    time.sleep(1)
+    for i in range(3):
+        hwsim_utils.test_connectivity(dev[i], hapd)
+
 @remote_compatible
 def test_ap_wpa_gtk_rekey(dev, apdev):
     """WPA-PSK/TKIP AP and GTK rekey enforced by AP"""
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_roam.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_roam.py
index fca3b57..0bc54b3 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_roam.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_roam.py
@@ -1,5 +1,5 @@
 # Roaming tests
-# Copyright (c) 2013-2019, Jouni Malinen <j@w1.fi>
+# Copyright (c) 2013-2021, Jouni Malinen <j@w1.fi>
 #
 # This software may be distributed under the terms of the BSD license.
 # See README for more details.
@@ -26,8 +26,8 @@
     dev[0].roam(apdev[0]['bssid'])
     hwsim_utils.test_connectivity(dev[0], hapd0)
 
-def test_ap_blacklist_all(dev, apdev, params):
-    """Ensure we clear the blacklist if all visible APs reject"""
+def test_ap_ignore_bssid_all(dev, apdev, params):
+    """Ensure we clear the ignore BSSID list if all visible APs reject"""
     hapd0 = hostapd.add_ap(apdev[0], {"ssid": "test-open", "max_num_sta": "0"})
     hapd1 = hostapd.add_ap(apdev[1], {"ssid": "test-open", "max_num_sta": "0"})
     bss0 = hapd0.own_addr()
@@ -43,13 +43,13 @@
                    wait_connect=False, bssid=bss1)
     if not dev[0].wait_event(["CTRL-EVENT-AUTH-REJECT"], timeout=10):
         raise Exception("AP 1 didn't reject us")
-    blacklist = get_blacklist(dev[0])
-    logger.info("blacklist: " + str(blacklist))
+    ignore_list = get_bssid_ignore_list(dev[0])
+    logger.info("ignore list: " + str(ignore_list))
     dev[0].request("REMOVE_NETWORK all")
     dev[0].dump_monitor()
 
     hapd0.set("max_num_sta", "1")
-    # All visible APs were blacklisted; we should clear the blacklist and find
+    # All visible APs were ignored; we should clear the ignore list and find
     # the AP that now accepts us.
     dev[0].scan_for_bss(bss0, freq=2412)
     dev[0].connect("test-open", key_mgmt="NONE", scan_freq="2412", bssid=bss0)
@@ -141,8 +141,8 @@
         raise Exception("Unexpected BSSID reported after failed roam attempt: " + bssid)
     hwsim_utils.test_connectivity(dev[0], hapd0)
 
-def get_blacklist(dev):
-    return dev.request("BLACKLIST").splitlines()
+def get_bssid_ignore_list(dev):
+    return dev.request("BSSID_IGNORE").splitlines()
 
 def test_ap_reconnect_auth_timeout(dev, apdev, params):
     """Reconnect to 2nd AP and authentication times out"""
@@ -162,7 +162,7 @@
     hapd1 = hostapd.add_ap(apdev[1], params)
     bssid1 = hapd1.own_addr()
 
-    wpas.request("BLACKLIST " + bssid0)
+    wpas.request("BSSID_IGNORE " + bssid0)
 
     wpas.scan_for_bss(bssid1, freq=2412)
     wpas.request("DISCONNECT")
@@ -179,11 +179,11 @@
     if not ev:
         raise Exception("CTRL-EVENT-SCAN-STARTED not seen")
 
-    b = get_blacklist(wpas)
+    b = get_bssid_ignore_list(wpas)
     if '00:00:00:00:00:00' in b:
-        raise Exception("Unexpected blacklist contents: " + str(b))
+        raise Exception("Unexpected ignore list contents: " + str(b))
     if bssid1 not in b:
-        raise Exception("Unexpected blacklist contents: " + str(b))
+        raise Exception("Unexpected ignore list contents: " + str(b))
 
 def test_ap_roam_with_reassoc_auth_timeout(dev, apdev, params):
     """Roam using reassoc between two APs and authentication times out"""
@@ -216,9 +216,9 @@
     if not ev:
         raise Exception("CTRL-EVENT-SCAN-STARTED not seen")
 
-    b = get_blacklist(wpas)
+    b = get_bssid_ignore_list(wpas)
     if bssid0 in b:
-        raise Exception("Unexpected blacklist contents: " + str(b))
+        raise Exception("Unexpected ignore list contents: " + str(b))
 
 def test_ap_roam_wpa2_psk_failed(dev, apdev, params):
     """Roam failure with WPA2-PSK AP due to wrong passphrase"""
@@ -376,3 +376,20 @@
     if dst != dev[0].get_status_field('bssid'):
         raise Exception("Unexpected AP after roam")
     dev[0].dump_monitor()
+
+def test_ap_roam_during_scan(dev, apdev):
+    """Roam command during a scan operation"""
+    hapd0 = hostapd.add_ap(apdev[0], {"ssid": "test-open"})
+    dev[0].scan_for_bss(hapd0.own_addr(), freq=2412)
+    dev[0].connect("test-open", key_mgmt="NONE")
+    hapd1 = hostapd.add_ap(apdev[1], {"ssid": "test-open"})
+    dev[0].scan_for_bss(hapd1.own_addr(), freq=2412)
+    if "OK" not in dev[0].request("SCAN"):
+        raise Exception("Failed to start scan")
+    if "OK" not in dev[0].request("ROAM " + hapd1.own_addr()):
+        raise Exception("Failed to issue ROAM")
+    ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=10)
+    if ev is None:
+        raise Exception("Connection not reported after ROAM")
+    if hapd1.own_addr() not in ev:
+        raise Exception("Connected to unexpected AP")
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_tdls.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_tdls.py
index a2bf6d4..8cdd002 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_tdls.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_tdls.py
@@ -639,6 +639,8 @@
     """SAE AP and two stations using TDLS"""
     check_sae_capab(dev[0])
     check_sae_capab(dev[1])
+    dev[0].request("SET sae_groups ")
+    dev[1].request("SET sae_groups ")
     params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678")
     params['wpa_key_mgmt'] = 'SAE'
     params["ieee80211w"] = "2"
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_track.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_track.py
index 9d9e2cd..ba8f3eb 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_track.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_track.py
@@ -403,3 +403,35 @@
         raise Exception("Unexpected SIGNATURE prefix")
     if "|assoc:" not in res:
         raise Exception("Missing assoc info in SIGNATURE")
+
+def test_ap_track_taxonomy_5g(dev, apdev):
+    """AP tracking STA taxonomy (5 GHz)"""
+    try:
+        _test_ap_track_taxonomy_5g(dev, apdev)
+    finally:
+        subprocess.call(['iw', 'reg', 'set', '00'])
+        dev[0].flush_scan_cache()
+
+def _test_ap_track_taxonomy_5g(dev, apdev):
+    params = {"ssid": "track",
+              "country_code": "US",
+              "hw_mode": "a",
+              "channel": "40",
+              "track_sta_max_num": "2"}
+    hapd = hostapd.add_ap(apdev[0], params)
+    bssid = apdev[0]['bssid']
+
+    dev[0].scan_for_bss(bssid, freq=5200, force_scan=True)
+    addr0 = dev[0].own_addr()
+    dev[0].connect("track", key_mgmt="NONE", scan_freq="5200")
+
+    res = hapd.request("SIGNATURE " + addr0)
+    logger.info("sta0: " + res)
+    if not res.startswith("wifi4|probe:"):
+        raise Exception("Unexpected SIGNATURE prefix")
+    if "|assoc:" not in res:
+        raise Exception("Missing assoc info in SIGNATURE")
+    if ",htcap:" not in res:
+        raise Exception("Missing HT info in SIGNATURE")
+    if ",vhtcap:" not in res:
+        raise Exception("Missing VHT info in SIGNATURE")
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_vht.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_vht.py
index 2b691ff..b47aaa2 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_vht.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_vht.py
@@ -369,6 +369,7 @@
                   'ieee80211d': '1',
                   'ieee80211h': '1'}
         hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
+        bssid = apdev[0]['bssid']
 
         ev = wait_dfs_event(hapd, "DFS-CAC-START", 5)
         if "DFS-CAC-START" not in ev:
@@ -408,6 +409,10 @@
         if "WIDTH=160 MHz" not in sig:
             raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
 
+        est = dev[0].get_bss(bssid)['est_throughput']
+        if est != "780001":
+            raise Exception("Unexpected BSS est_throughput: " + est)
+
         sta = hapd.get_sta(dev[0].own_addr())
         if 'supp_op_classes' not in sta or len(sta['supp_op_classes']) < 2:
             raise Exception("No Supported Operating Classes information for STA")
@@ -779,6 +784,69 @@
         dev[0].request("DISCONNECT")
         clear_regdom(hapd, dev)
 
+def test_ap_vht_csa_vht80p80(dev, apdev):
+    """VHT CSA with VHT80+80 getting enabled"""
+    csa_supported(dev[0])
+    try:
+        hapd = None
+        params = {"ssid": "vht",
+                  "country_code": "US",
+                  "hw_mode": "a",
+                  "channel": "149",
+                  "ht_capab": "[HT40+]",
+                  "ieee80211n": "1",
+                  "ieee80211ac": "0"}
+        hapd = hostapd.add_ap(apdev[0], params)
+        bssid = hapd.own_addr()
+
+        dev[0].connect("vht", key_mgmt="NONE", scan_freq="5745")
+        hwsim_utils.test_connectivity(dev[0], hapd)
+
+        #if "OK" not in hapd.request("CHAN_SWITCH 5 5765 sec_channel_offset=-1 center_freq1=5775 center_freq2=5210 bandwidth=80 vht"):
+        if "OK" not in hapd.request("CHAN_SWITCH 5 5180 sec_channel_offset=1 center_freq1=5210 center_freq2=5775 bandwidth=80 vht"):
+            raise Exception("CHAN_SWITCH command failed")
+        ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
+        if ev is None:
+            raise Exception("CSA finished event timed out")
+        if "freq=5180" not in ev:
+            raise Exception("Unexpected channel in CSA finished event")
+        ev = dev[0].wait_event(["CTRL-EVENT-CHANNEL-SWITCH"], timeout=5)
+        if ev is None:
+            raise Exception("Channel switch event not seen")
+        if "freq=5180" not in ev:
+            raise Exception("Channel mismatch: " + ev)
+        ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
+        if ev is not None:
+            raise Exception("Unexpected disconnection event from station")
+        hwsim_utils.test_connectivity(dev[0], hapd)
+
+        dev[1].connect("vht", key_mgmt="NONE", scan_freq="5180")
+        hwsim_utils.test_connectivity(dev[1], hapd)
+
+        if dev[1].get_status_field("ieee80211ac") != '1':
+            raise Exception("VHT not enabled as part of channel switch")
+        sig = dev[1].request("SIGNAL_POLL").splitlines()
+        logger.info("SIGNAL_POLL(1): " + str(sig))
+        if "FREQUENCY=5180" not in sig:
+            raise Exception("Correct FREQUENCY missing from SIGNAL_POLL")
+        if "WIDTH=80+80 MHz" not in sig:
+            raise Exception("Correct WIDTH missing from SIGNAL_POLL")
+        if "CENTER_FRQ1=5210" not in sig:
+            raise Exception("Correct CENTER_FRQ1 missing from SIGNAL_POLL")
+        if "CENTER_FRQ2=5775" not in sig:
+            raise Exception("Correct CENTER_FRQ1 missing from SIGNAL_POLL")
+
+        sig = dev[0].request("SIGNAL_POLL").splitlines()
+        logger.info("SIGNAL_POLL(0): " + str(sig))
+    finally:
+        dev[0].request("DISCONNECT")
+        dev[1].request("DISCONNECT")
+        if hapd:
+            hapd.request("DISABLE")
+        subprocess.call(['iw', 'reg', 'set', '00'])
+        dev[0].flush_scan_cache()
+        dev[1].flush_scan_cache()
+
 def test_ap_vht_csa_vht40(dev, apdev):
     """VHT CSA with VHT40 getting enabled"""
     csa_supported(dev[0])
@@ -1218,3 +1286,53 @@
     finally:
         dev[0].request("DISCONNECT")
         clear_regdom(hapd, dev)
+
+def test_ap_vht_csa_invalid(dev, apdev):
+    """VHT CSA with invalid parameters"""
+    csa_supported(dev[0])
+    try:
+        hapd = None
+        params = {"ssid": "vht",
+                  "country_code": "US",
+                  "hw_mode": "a",
+                  "channel": "149",
+                  "ht_capab": "[HT40+]",
+                  "ieee80211n": "1",
+                  "ieee80211ac": "0"}
+        hapd = hostapd.add_ap(apdev[0], params)
+
+        tests = ["5 5765 center_freq1=5180",
+                 "5 5765 bandwidth=40",
+                 "5 5765 bandwidth=40 center_freq2=5180",
+                 "5 5765 bandwidth=40 sec_channel_offset=1 center_freq1=5180",
+                 "5 5765 bandwidth=40 sec_channel_offset=-1 center_freq1=5180",
+                 "5 5765 bandwidth=40 sec_channel_offset=2 center_freq1=5180",
+                 "5 5765 bandwidth=80",
+                 "5 5765 bandwidth=80 sec_channel_offset=-1",
+                 "5 5765 bandwidth=80 center_freq1=5755",
+                 "5 5765 bandwidth=80 sec_channel_offset=1 center_freq1=5180",
+                 "5 5765 bandwidth=80 sec_channel_offset=-1 center_freq1=5180",
+                 "5 5765 bandwidth=80 sec_channel_offset=2 center_freq1=5180",
+                 "5 5765 bandwidth=80 sec_channel_offset=-1 center_freq1=5775 center_freq2=5775",
+                 "5 5765 bandwidth=160",
+                 "5 5765 bandwidth=160 center_freq1=5755",
+                 "5 5765 bandwidth=160 center_freq1=5755 center_freq2=5755",
+                 "5 5765 bandwidth=160 center_freq1=5755 center_freq2=5755 sec_channel_offset=-1",
+                 "5 5765 bandwidth=160 center_freq1=5754 sec_channel_offset=1",
+                 "5 5765 bandwidth=160 center_freq1=5755 sec_channel_offset=2",
+                 "5 5765 sec_channel_offset=-1"]
+        for t in tests:
+            if "FAIL" not in hapd.request("CHAN_SWITCH " + t):
+                raise Exception("Invalid CHAN_SWITCH accepted: " + t)
+
+        hapd.request("CHAN_SWITCH 5 5765 bandwidth=160 center_freq1=5755 sec_channel_offset=1")
+        ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
+        if ev is None:
+            raise Exception("Timeout on AP-CSA-FINISHED")
+
+        hapd.request("CHAN_SWITCH 5 5765 bandwidth=160 center_freq1=5775 sec_channel_offset=-1")
+        time.sleep(1)
+    finally:
+        if hapd:
+            hapd.request("DISABLE")
+        subprocess.call(['iw', 'reg', 'set', '00'])
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_vlan.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_vlan.py
index 29f8f53..e4bfd68 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_vlan.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_vlan.py
@@ -378,41 +378,41 @@
         os.unlink(filename)
 
 def ap_vlan_iface_cleanup_multibss_cleanup():
-    subprocess.call(['ifconfig', 'dummy0', 'down'],
+    subprocess.call(['ifconfig', 'stub0', 'down'],
                     stderr=open('/dev/null', 'w'))
-    ifnames = ['wlan3.1', 'wlan3.2', 'wlan3-2.1', 'wlan3-2.2', 'dummy0.2',
-               'dummy0.1', 'dummy0', 'brvlan1', 'brvlan2']
+    ifnames = ['wlan3.1', 'wlan3.2', 'wlan3-2.1', 'wlan3-2.2', 'stub0.2',
+               'stub0.1', 'stub0', 'brvlan1', 'brvlan2']
     for ifname in ifnames:
         subprocess.call(['ip', 'link', 'del', ifname],
                         stderr=open('/dev/null', 'w'))
 
 def ap_vlan_iface_test_and_prepare_environ():
     ifaces = netifaces.interfaces()
-    if "dummy0" in ifaces:
-        raise Exception("dummy0 already exists before")
+    if "stub0" in ifaces:
+        raise Exception("stub0 already exists before")
     ifaces = netifaces.interfaces()
-    if "dummy0.1" in ifaces:
-        raise Exception("dummy0.1 already exists before")
+    if "stub0.1" in ifaces:
+        raise Exception("stub0.1 already exists before")
 
-    subprocess.call(['ip', 'link', 'add', 'dummy0', 'type', 'dummy'])
-    subprocess.call(['ifconfig', 'dummy0', 'up'])
+    subprocess.call(['ip', 'link', 'add', 'stub0', 'type', 'dummy'])
+    subprocess.call(['ifconfig', 'stub0', 'up'])
 
     ifaces = netifaces.interfaces()
-    if "dummy0" not in ifaces:
-        raise HwsimSkip("failed to add dummy0 - missing kernel config DUMMY ?")
+    if "stub0" not in ifaces:
+        raise HwsimSkip("failed to add stub0 - missing kernel config DUMMY ?")
 
-    subprocess.call(['ip', 'link', 'add', 'link', 'dummy0', 'name', 'dummy0.1',
+    subprocess.call(['ip', 'link', 'add', 'link', 'stub0', 'name', 'stub0.1',
                      'type', 'vlan', 'id', '1'])
 
     ifaces = netifaces.interfaces()
-    if "dummy0.1" not in ifaces:
-        raise HwsimSkip("failed to add dummy0.1 - missing kernel config VLAN_8021Q ?")
+    if "stub0.1" not in ifaces:
+        raise HwsimSkip("failed to add stub0.1 - missing kernel config VLAN_8021Q ?")
 
-    subprocess.call(['ip', 'link', 'del', 'dummy0.1'])
+    subprocess.call(['ip', 'link', 'del', 'stub0.1'])
 
     ifaces = netifaces.interfaces()
-    if "dummy0.1" in ifaces:
-        raise Exception("dummy0.1 was not removed before testing")
+    if "stub0.1" in ifaces:
+        raise Exception("stub0.1 was not removed before testing")
 
 def test_ap_vlan_iface_cleanup_multibss(dev, apdev):
     """AP VLAN operation in multi-BSS multi-VLAN case"""
@@ -464,8 +464,8 @@
             raise Exception("bridge brvlan1 was not created")
 
         hwsim_utils.test_connectivity_iface(dev[0], hapd, "brvlan1")
-        if not iface_is_in_bridge("brvlan1", "dummy0.1"):
-            raise Exception("dummy0.1 not in brvlan1")
+        if not iface_is_in_bridge("brvlan1", "stub0.1"):
+            raise Exception("stub0.1 not in brvlan1")
 
         dev[1].connect("bss-2", key_mgmt="WPA-EAP", eap="PAX",
                        identity="vlan1",
@@ -474,8 +474,8 @@
 
         hapd1.wait_sta()
         hwsim_utils.test_connectivity_iface(dev[1], hapd1, "brvlan1")
-        if not iface_is_in_bridge("brvlan1", "dummy0.1"):
-            raise Exception("dummy0.1 not in brvlan1")
+        if not iface_is_in_bridge("brvlan1", "stub0.1"):
+            raise Exception("stub0.1 not in brvlan1")
 
         authserv.disable()
         authserv.set('eap_user_file', "auth_serv/eap_user_vlan.conf")
@@ -502,13 +502,13 @@
         hwsim_utils.test_connectivity_iface(dev[0], hapd, "brvlan2",
                                             max_tries=5)
 
-        if not iface_is_in_bridge("brvlan2", "dummy0.2"):
-            raise Exception("dummy0.2 not in brvlan2")
+        if not iface_is_in_bridge("brvlan2", "stub0.2"):
+            raise Exception("stub0.2 not in brvlan2")
 
         logger.info("test wlan1 == VLAN 1")
         hwsim_utils.test_connectivity_iface(dev[1], hapd1, "brvlan1")
-        if not iface_is_in_bridge("brvlan1", "dummy0.1"):
-            raise Exception("dummy0.1 not in brvlan1")
+        if not iface_is_in_bridge("brvlan1", "stub0.1"):
+            raise Exception("stub0.1 not in brvlan1")
 
         logger.info("wlan1 -> VLAN 2")
 
@@ -530,8 +530,8 @@
         logger.info("test wlan0 == VLAN 2")
         hwsim_utils.test_connectivity_iface(dev[0], hapd, "brvlan2")
 
-        if not iface_is_in_bridge("brvlan2", "dummy0.2"):
-            raise Exception("dummy0.2 not in brvlan2")
+        if not iface_is_in_bridge("brvlan2", "stub0.2"):
+            raise Exception("stub0.2 not in brvlan2")
 
         ifaces = netifaces.interfaces()
         if "brvlan1" in ifaces:
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_wps.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_wps.py
index 0ecf296..62972ac 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_wps.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ap_wps.py
@@ -44,10 +44,12 @@
 from utils import *
 from test_ap_eap import int_eap_server_params
 
-def wps_start_ap(apdev, ssid="test-wps-conf"):
+def wps_start_ap(apdev, ssid="test-wps-conf", extra_cred=None):
     params = {"ssid": ssid, "eap_server": "1", "wps_state": "2",
               "wpa_passphrase": "12345678", "wpa": "2",
               "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"}
+    if extra_cred:
+        params['extra_cred'] = extra_cred
     return hostapd.add_ap(apdev, params)
 
 @remote_compatible
@@ -726,6 +728,8 @@
         raise Exception("Invalid WPS_AP_PIN accepted")
     if "FAIL" not in hapd.request("WPS_AP_PIN foo"):
         raise Exception("Invalid WPS_AP_PIN accepted")
+    if "FAIL" not in hapd.request("WPS_AP_PIN set " + 9*'1'):
+        raise Exception("Invalid WPS_AP_PIN accepted")
 
 def test_ap_wps_reg_config(dev, apdev):
     """WPS registrar configuring an AP using AP PIN"""
@@ -1052,6 +1056,11 @@
         raise Exception("PBC session overlap not correctly reported (dev1)")
     dev[1].request("WPS_CANCEL")
     dev[1].request("DISCONNECT")
+    ev = hapd.wait_event(["WPS-OVERLAP-DETECTED"], timeout=1)
+    if ev is None:
+        raise Exception("PBC session overlap not detected (AP)")
+    if "PBC Status: Overlap" not in hapd.request("WPS_GET_STATUS"):
+        raise Exception("PBC status not shown correctly")
     hapd.request("WPS_CANCEL")
     ret = hapd.request("WPS_PBC")
     if "FAIL" not in ret:
@@ -1060,6 +1069,43 @@
     dev[0].flush_scan_cache()
     dev[1].flush_scan_cache()
 
+def test_ap_wps_pbc_session_workaround(dev, apdev):
+    """WPS PBC session overlap workaround"""
+    ssid = "test-wps-pbc-overlap"
+    hapd = hostapd.add_ap(apdev[0],
+                          {"ssid": ssid, "eap_server": "1", "wps_state": "2",
+                           "wpa_passphrase": "12345678", "wpa": "2",
+                           "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
+    bssid = hapd.own_addr()
+    hapd.request("WPS_PBC")
+    dev[0].scan_for_bss(bssid, freq="2412")
+    dev[0].request("WPS_PBC " + bssid)
+    dev[0].wait_connected(timeout=30)
+
+    dev[0].request("REMOVE_NETWORK all")
+    dev[0].wait_disconnected(timeout=30)
+    dev[0].dump_monitor()
+    # Trigger AP/Registrar to ignore PBC activation immediately after
+    # successfully completed provisioning
+    dev[0].request("WPS_PBC " + bssid)
+    ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
+    if ev is None:
+        raise Exception("No scan results reported")
+    dev[0].request("WPS_CANCEL")
+    dev[0].dump_monitor()
+
+    # Verify that PBC session overlap does not prevent connection
+    hapd.request("WPS_PBC")
+    dev[1].scan_for_bss(bssid, freq="2412")
+    dev[1].request("WPS_PBC " + bssid)
+    dev[1].wait_connected()
+    dev[1].request("REMOVE_NETWORK all")
+    dev[1].wait_disconnected()
+
+    hapd.request("DISABLE")
+    dev[0].flush_scan_cache()
+    dev[1].flush_scan_cache()
+
 @remote_compatible
 def test_ap_wps_cancel(dev, apdev):
     """WPS AP cancelling enabled config method"""
@@ -4351,10 +4397,12 @@
             raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
     dev.request("WPS_ER_STOP")
 
-def run_wps_er_proto_test(dev, handler, no_event_url=False, location_url=None):
+def run_wps_er_proto_test(dev, handler, no_event_url=False, location_url=None,
+                          max_age=1):
     try:
         uuid = '27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'
-        server, sock = wps_er_start(dev, handler, location_url=location_url)
+        server, sock = wps_er_start(dev, handler, location_url=location_url,
+                                    max_age=max_age)
         global wps_event_url
         wps_event_url = None
         server.handle_request()
@@ -5018,14 +5066,14 @@
     sock.connect(addr)
     sock.send(b"G")
 
-    class DummyServer(StreamRequestHandler):
+    class StubServer(StreamRequestHandler):
         def handle(self):
-            logger.debug("DummyServer - start 31 sec wait")
+            logger.debug("StubServer - start 31 sec wait")
             time.sleep(31)
-            logger.debug("DummyServer - wait done")
+            logger.debug("StubServer - wait done")
 
     logger.debug("Start WPS ER")
-    server, sock2 = wps_er_start(dev[0], DummyServer, max_age=40,
+    server, sock2 = wps_er_start(dev[0], StubServer, max_age=40,
                                  wait_m_search=True)
 
     logger.debug("Start server to accept, but not complete, HTTP connection from WPS ER")
@@ -5098,6 +5146,15 @@
     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_req_as_resp,
                           no_event_url=True)
 
+def test_ap_wps_er_http_client_timeout(dev, apdev):
+    """WPS ER and HTTP client timeout"""
+    class WPSAPHTTPServer_timeout(WPSAPHTTPServer):
+        def handle_upnp_info(self):
+            time.sleep(31)
+            self.wfile.write(b"GET / HTTP/1.1\r\n\r\n")
+    run_wps_er_proto_test(dev[0], WPSAPHTTPServer_timeout,
+                          no_event_url=True, max_age=60)
+
 def test_ap_wps_init_oom(dev, apdev):
     """wps_init OOM cases"""
     ssid = "test-wps"
@@ -10074,8 +10131,8 @@
     if "FAIL" not in hapd.request("WPS_PBC"):
         raise Exception("WPS unexpectedly enabled")
 
-def test_ap_wps_conf_dummy_cred(dev, apdev):
-    """WPS PIN provisioning with configured AP using dummy cred"""
+def test_ap_wps_conf_stub_cred(dev, apdev):
+    """WPS PIN provisioning with configured AP using stub cred"""
     ssid = "test-wps-conf"
     hapd = hostapd.add_ap(apdev[0],
                           {"ssid": ssid, "eap_server": "1", "wps_state": "2",
@@ -10085,7 +10142,7 @@
     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
     dev[0].dump_monitor()
     try:
-        hapd.set("wps_testing_dummy_cred", "1")
+        hapd.set("wps_testing_stub_cred", "1")
         dev[0].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
         for i in range(1, 3):
             ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=15)
@@ -10093,7 +10150,7 @@
                 raise Exception("WPS credential %d not received" % i)
         dev[0].wait_connected(timeout=30)
     finally:
-        hapd.set("wps_testing_dummy_cred", "0")
+        hapd.set("wps_testing_stub_cred", "0")
 
 def test_ap_wps_rf_bands(dev, apdev):
     """WPS and wps_rf_bands configuration"""
@@ -10372,6 +10429,39 @@
     dev[1].connect(ssid, psk="12345678", scan_freq="2412", proto="WPA2",
                    key_mgmt="WPA-PSK", ieee80211w="0")
 
+def test_ap_wps_conf_and_sae_h2e(dev, apdev):
+    """WPS PIN provisioning with configured AP using PSK+SAE(H2E)"""
+    try:
+        run_ap_wps_conf_and_sae_h2e(dev, apdev)
+    finally:
+        dev[0].set("wps_cred_add_sae", "0")
+        dev[0].set("sae_pwe", "0")
+
+def run_ap_wps_conf_and_sae_h2e(dev, apdev):
+    check_sae_capab(dev[0])
+    ssid = "test-wps-conf-sae"
+    hapd = hostapd.add_ap(apdev[0],
+                          {"ssid": ssid, "eap_server": "1", "wps_state": "2",
+                           "wpa_passphrase": "12345678", "wpa": "2",
+                           "ieee80211w": "1", "sae_require_mfp": "1",
+                           "sae_pwe": "1",
+                           "wpa_key_mgmt": "WPA-PSK SAE",
+                           "rsn_pairwise": "CCMP"})
+
+    dev[0].set("wps_cred_add_sae", "1")
+    dev[0].set("sae_pwe", "1")
+    dev[0].request("SET sae_groups ")
+    dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
+    pin = dev[0].wps_read_pin()
+    hapd.request("WPS_PIN any " + pin)
+    dev[0].request("WPS_PIN " + apdev[0]['bssid'] + " " + pin)
+    dev[0].wait_connected(timeout=30)
+    status = dev[0].get_status()
+    if status['key_mgmt'] != "SAE":
+        raise Exception("SAE not used")
+    if 'pmf' not in status or status['pmf'] != "1":
+        raise Exception("PMF not enabled")
+
 def test_ap_wps_reg_config_and_sae(dev, apdev):
     """WPS registrar configuring an AP using AP PIN and using PSK+SAE"""
     try:
@@ -10446,6 +10536,10 @@
     ev = hapd.wait_event(["WPS-TIMEOUT"], timeout=130)
     if ev is None and "PBC" in cmd:
         raise Exception("WPS-TIMEOUT not reported")
+    if "PBC" in cmd and \
+       "PBC Status: Timed-out" not in hapd.request("WPS_GET_STATUS"):
+        raise Exception("PBC status not shown correctly")
+
     time.sleep(5)
     dev[0].flush_scan_cache()
     dev[0].scan_for_bss(bssid, freq="2412", force_scan=True)
@@ -10453,3 +10547,62 @@
     logger.info("BSS after timeout: " + str(bss))
     if bss['ie'].endswith("0106ffffffffffff"):
         raise Exception("Authorized MAC not removed")
+
+def test_ap_wps_er_unsubscribe_errors(dev, apdev):
+    """WPS ER and UNSUBSCRIBE errors"""
+    start_wps_ap(apdev[0])
+    tests = [(1, "http_client_url_parse;wps_er_ap_unsubscribe"),
+             (1, "wpabuf_alloc;wps_er_ap_unsubscribe"),
+             (1, "http_client_addr;wps_er_ap_unsubscribe")]
+    try:
+        for count, func in tests:
+            start_wps_er(dev[0])
+            with alloc_fail(dev[0], count, func):
+                dev[0].request("WPS_ER_STOP")
+            dev[0].request("REMOVE_NETWORK all")
+            dev[0].wait_disconnected()
+            dev[0].dump_monitor()
+    finally:
+        dev[0].request("WPS_ER_STOP")
+
+def start_wps_ap(apdev):
+    ssid = "wps-er-ap-config"
+    ap_pin = "12345670"
+    ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
+    params = {"ssid": ssid, "eap_server": "1", "wps_state": "2",
+              "wpa_passphrase": "12345678", "wpa": "2",
+              "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
+              "device_name": "Wireless AP", "manufacturer": "Company",
+              "model_name": "WAP", "model_number": "123",
+              "serial_number": "12345", "device_type": "6-0050F204-1",
+              "os_version": "01020300",
+              "config_methods": "label push_button",
+              "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"}
+    hostapd.add_ap(apdev, params)
+
+def start_wps_er(dev):
+    ssid = "wps-er-ap-config"
+    dev.connect(ssid, psk="12345678", scan_freq="2412")
+    dev.request("WPS_ER_START ifname=lo")
+    ev = dev.wait_event(["WPS-ER-AP-ADD"], timeout=15)
+    if ev is None:
+        raise Exception("AP discovery timed out")
+
+def test_ap_wps_registrar_init_errors(dev, apdev):
+    """WPS Registrar init errors"""
+    hapd = wps_start_ap(apdev[0], extra_cred="wps-mixed-cred")
+    hapd.disable()
+    tests = [(1, "wps_registrar_init"),
+             (1, "wpabuf_alloc_copy;wps_registrar_init"),
+             (1, "wps_set_ie;wps_registrar_init")]
+    for count, func in tests:
+        with alloc_fail(hapd, count, func):
+            if "FAIL" not in hapd.request("ENABLE"):
+                raise Exception("ENABLE succeeded unexpectedly")
+
+def test_ap_wps_config_without_wps(dev, apdev):
+    """AP configuration attempt using wps_config when WPS is disabled"""
+    ssid = "test-wps-init-config"
+    hapd = hostapd.add_ap(apdev[0], {"ssid": ssid})
+    if "FAIL" not in hapd.request("WPS_CONFIG " + binascii.hexlify(ssid.encode()).decode() + " WPA2PSK CCMP " + binascii.hexlify(b"12345678").decode()):
+        raise Exception("WPS_CONFIG command succeeded unexpectedly")
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_connect_cmd.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_connect_cmd.py
index 3c09851..d101ee7 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_connect_cmd.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_connect_cmd.py
@@ -191,6 +191,25 @@
     wpas.wait_disconnected()
     wpas.dump_monitor()
 
+def test_connect_cmd_wpa_psk_roam(dev, apdev):
+    """WPA2/WPA-PSK connection using cfg80211 connect command to trigger roam"""
+    params = hostapd.wpa2_params(ssid="sta-connect", passphrase="12345678")
+    hostapd.add_ap(apdev[0], params)
+
+    wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
+    wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
+    wpas.connect("sta-connect", psk="12345678", scan_freq="2412")
+    wpas.dump_monitor()
+
+    params = hostapd.wpa_params(ssid="sta-connect", passphrase="12345678")
+    hostapd.add_ap(apdev[1], params)
+    wpas.scan_for_bss(apdev[1]['bssid'], freq=2412, force_scan=True)
+    wpas.roam(apdev[1]['bssid'])
+    time.sleep(0.1)
+    wpas.request("DISCONNECT")
+    wpas.wait_disconnected()
+    wpas.dump_monitor()
+
 def test_connect_cmd_bssid_hint(dev, apdev):
     """cfg80211 connect command with bssid_hint"""
     params = {"ssid": "sta-connect"}
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_dbus.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_dbus.py
index 1143802..28fb050 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_dbus.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_dbus.py
@@ -6091,3 +6091,114 @@
     with TestDbusConnect(bus) as t:
         if not t.success():
             raise Exception("Expected signals not seen")
+
+def test_dbus_creds(dev, apdev):
+    "D-Bus interworking credentials"
+    (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
+    iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
+
+    args = {'domain': 'server.w1.fi',
+            'realm': 'server.w1.fi',
+            'roaming_consortium': '50a9bf',
+            'required_roaming_consortium': '23bf50',
+            'eap': 'TTLS',
+            'phase2': 'auth=MSCHAPV2',
+            'username': 'user',
+            'password': 'password',
+            'domain_suffix_match': 'server.w1.fi',
+            'ca_cert': 'auth_serv/ca.pem'}
+
+    path = iface.AddCred(dbus.Dictionary(args, signature='sv'))
+    for k, v in args.items():
+        if k == 'password':
+            continue
+        prop = dev[0].get_cred(0, k)
+        if prop != v:
+            raise Exception('Credential add failed: %s does not match %s' % (prop, v))
+
+    iface.RemoveCred(path)
+    if not "FAIL" in dev[0].get_cred(0, 'domain'):
+        raise Exception("Credential remove failed")
+
+    # Removal of multiple credentials
+    cred1 = {'domain': 'server1.w1.fi','realm': 'server1.w1.fi','eap': 'TTLS'}
+    iface.AddCred(dbus.Dictionary(cred1, signature='sv'))
+    if "FAIL" in dev[0].get_cred(0, 'domain'):
+        raise Exception("Failed to add credential")
+
+    cred2 = {'domain': 'server2.w1.fi','realm': 'server2.w1.fi','eap': 'TTLS'}
+    iface.AddCred(dbus.Dictionary(cred2, signature='sv'))
+    if "FAIL" in dev[0].get_cred(1, 'domain'):
+        raise Exception("Failed to add credential")
+
+    iface.RemoveAllCreds()
+    if not "FAIL" in dev[0].get_cred(0, 'domain'):
+        raise Exception("Credential remove failed")
+    if not "FAIL" in dev[0].get_cred(1, 'domain'):
+        raise Exception("Credential remove failed")
+
+def test_dbus_interworking(dev, apdev):
+    "D-Bus interworking selection"
+    (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
+    iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
+
+    params = {"ssid": "test-interworking", "wpa": "2",
+              "wpa_key_mgmt": "WPA-EAP", "rsn_pairwise": "CCMP",
+              "ieee8021x": "1", "eapol_version": "2",
+              "eap_server": "1", "eap_user_file": "auth_serv/eap_user.conf",
+              "ca_cert": "auth_serv/ca.pem",
+              "server_cert": "auth_serv/server.pem",
+              "private_key": "auth_serv/server.key",
+              "interworking": "1",
+              "domain_name": "server.w1.fi",
+              "nai_realm": "0,server.w1.fi,21[2:4][5:7]",
+              "roaming_consortium": "2233445566",
+              "hs20": "1", "anqp_domain_id": "1234"}
+
+    hapd = hostapd.add_ap(apdev[0], params)
+
+    class TestDbusInterworking(TestDbus):
+        def __init__(self, bus):
+            TestDbus.__init__(self, bus)
+            self.interworking_ap_seen = False
+            self.interworking_select_done = False
+
+        def __enter__(self):
+            gobject.timeout_add(1, self.run_select)
+            gobject.timeout_add(15000, self.timeout)
+            self.add_signal(self.interworkingAPAdded, WPAS_DBUS_IFACE,
+                            "InterworkingAPAdded")
+            self.add_signal(self.interworkingSelectDone, WPAS_DBUS_IFACE,
+                            "InterworkingSelectDone")
+            self.loop.run()
+            return self
+
+        def interworkingAPAdded(self, bss, cred, properties):
+            logger.debug("interworkingAPAdded: bss=%s cred=%s %s" % (bss, cred, str(properties)))
+            if self.cred == cred:
+                self.interworking_ap_seen = True
+
+        def interworkingSelectDone(self):
+            logger.debug("interworkingSelectDone")
+            self.interworking_select_done = True
+            self.loop.quit()
+
+        def run_select(self, *args):
+            args = {"domain": "server.w1.fi",
+                    "realm": "server.w1.fi",
+                    "eap": "TTLS",
+                    "phase2": "auth=MSCHAPV2",
+                    "username": "user",
+                    "password": "password",
+                    "domain_suffix_match": "server.w1.fi",
+                    "ca_cert": "auth_serv/ca.pem"}
+            self.cred = iface.AddCred(dbus.Dictionary(args, signature='sv'))
+            iface.InterworkingSelect()
+            return False
+
+        def success(self):
+            return self.interworking_ap_seen and self.interworking_select_done
+
+    with TestDbusInterworking(bus) as t:
+        if not t.success():
+            raise Exception("Expected signals not seen")
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_dfs.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_dfs.py
index 3efe6bb..c587653 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_dfs.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_dfs.py
@@ -652,3 +652,116 @@
         hwsim_utils.test_connectivity(dev[0], hapd)
     finally:
         clear_regdom(hapd, dev)
+
+@long_duration_test
+def test_dfs_no_available_channel(dev, apdev):
+    """DFS and no available channel after radar detection"""
+    try:
+        hapd = None
+        hapd = start_dfs_ap(apdev[0], chanlist="56")
+
+        ev = hapd.wait_event(["AP-ENABLED"], timeout=70)
+        if not ev:
+            raise Exception("AP2 setup timed out")
+
+        dfs_simulate_radar(hapd)
+        ev = wait_dfs_event(hapd, "DFS-RADAR-DETECTED", 5)
+        if "freq=5260 ht_enabled=1 chan_offset=0 chan_width=1" not in ev:
+            raise Exception("Unexpected DFS radar detection freq from AP")
+
+        ev = wait_dfs_event(hapd, "DFS-NEW-CHANNEL", 5)
+        if "freq=5280 chan=56" not in ev:
+            raise Exception("Unexpected DFS new freq: " + ev)
+        ev = wait_dfs_event(hapd, "DFS-CAC-START", 5)
+        if "freq=5280" not in ev:
+            raise Exception("Unexpected channel: " + ev)
+        ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70)
+        if "success=1" not in ev:
+            raise Exception("CAC failed")
+        if "freq=5280" not in ev:
+            raise Exception("Unexpected DFS freq result")
+        ev = hapd.wait_event(["AP-ENABLED"], timeout=5)
+        if not ev:
+            raise Exception("AP setup timed out")
+
+        dfs_simulate_radar(hapd)
+        ev = wait_dfs_event(hapd, "DFS-RADAR-DETECTED", 5)
+        if "freq=5280 ht_enabled=1 chan_offset=0 chan_width=1" not in ev:
+            raise Exception("Unexpected DFS radar detection freq from AP [2]")
+
+        ev = hapd.wait_event(["AP-DISABLED"], timeout=10)
+        if ev is None:
+            raise Exception("AP was not disabled")
+    finally:
+        clear_regdom(hapd, dev)
+
+def dfs_chan_switch_precac(dev, apdev, country):
+    """DFS channel switch pre CAC"""
+    try:
+        hapd = None
+
+        # Toggle regulatory - clean all preCAC
+        hostapd.cmd_execute(apdev[0], ['iw', 'reg', 'set', 'US'])
+
+        hapd = start_dfs_ap(apdev[0], country=country)
+
+        ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70)
+        if "success=1" not in ev:
+            raise Exception("CAC failed")
+        if "freq=5260" not in ev:
+            raise Exception("Unexpected DFS freq result")
+        ev = hapd.wait_event(["AP-ENABLED"], timeout=5)
+        if not ev:
+            raise Exception("AP setup timed out")
+        freq = hapd.get_status_field("freq")
+        if freq != "5260":
+            raise Exception("Unexpected frequency")
+
+        # TODO add/connect station here
+        # Today skip this step while dev[0].connect()
+        # for some reason toggle regulatory to US
+        # and clean preCAC
+
+        # Back to non DFS channel
+        if "OK" not in hapd.request("CHAN_SWITCH 5 5180 ht"):
+            raise Exception("CHAN_SWITCH 5180 failed")
+
+        ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=5)
+        if not ev:
+            raise Exception("No CSA finished event - 5180")
+        freq = hapd.get_status_field("freq")
+        if freq != "5180":
+            raise Exception("Unexpected frequency")
+
+        # Today cfg80211 first send AP-CSA-FINISHED and next
+        # DFS-PRE-CAC-EXPIRED
+        ev = hapd.wait_event(["DFS-PRE-CAC-EXPIRED"], timeout=3)
+        if not ev and country == 'US':
+            raise Exception("US - no CAC-EXPIRED event")
+
+	# Back again to DFS channel (CAC passed)
+        if "OK" not in hapd.request("CHAN_SWITCH 5 5260 ht"):
+            raise Exception("CHAN_SWITCH 5260 failed")
+
+        if country == 'US':
+            # For non EU we should start CAC again
+            ev = wait_dfs_event(hapd, "DFS-CAC-START", 5)
+            if not ev:
+                raise Exception("No DFS CAC start event")
+        else:
+            # For EU preCAC should be used
+            ev = wait_dfs_event(hapd, "AP-CSA-FINISHED", 5)
+            if not ev:
+                raise Exception("No CSA finished event - 5260")
+    finally:
+        clear_regdom(hapd, dev)
+
+@long_duration_test
+def test_dfs_eu_chan_switch_precac(dev, apdev):
+    """DFS channel switch pre CAC - ETSI domain"""
+    dfs_chan_switch_precac(dev, apdev, 'PL')
+
+@long_duration_test
+def test_dfs_us_chan_switch_precac(dev, apdev):
+    """DFS channel switch pre CAC - FCC domain"""
+    dfs_chan_switch_precac(dev, apdev, 'US')
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_dpp.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_dpp.py
index ff03814..339d729 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_dpp.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_dpp.py
@@ -15,6 +15,10 @@
 import struct
 import subprocess
 import time
+try:
+    from socketserver import StreamRequestHandler, TCPServer
+except ImportError:
+    from SocketServer import StreamRequestHandler, TCPServer
 
 import hostapd
 import hwsim_utils
@@ -122,8 +126,12 @@
     uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id1)
     info = dev[0].request("DPP_BOOTSTRAP_INFO %d" % id1)
     logger.info("Parsed URI info:\n" + info)
-    if "version=2" not in info.splitlines():
-        raise Exception("Unexpected version information (v2)")
+    capa = dev[0].request("GET_CAPABILITY dpp")
+    ver = 1
+    if capa.startswith("DPP="):
+        ver = int(capa[4:])
+    if "version=%d" % ver not in info.splitlines():
+        raise Exception("Unexpected version information (with indication)")
 
     dev[0].set("dpp_version_override", "1")
     id0 = dev[0].dpp_bootstrap_gen()
@@ -210,7 +218,8 @@
     """DPP QR Code and keygen failure"""
     check_dpp_capab(dev[0])
 
-    with alloc_fail(dev[0], 1, "dpp_bootstrap_key_der;dpp_keygen"):
+    with alloc_fail(dev[0], 1,
+                    "crypto_ec_key_get_subject_public_key;dpp_keygen"):
         if "FAIL" not in dev[0].request("DPP_BOOTSTRAP_GEN type=qrcode"):
             raise Exception("Failure not reported")
 
@@ -305,6 +314,7 @@
 
 def test_dpp_configurator_enroll_conf(dev, apdev):
     """DPP Configurator enrolling followed by use of the new Configurator"""
+    check_dpp_capab(dev[0], min_ver=2)
     try:
         dev[0].set("dpp_config_processing", "2")
         run_dpp_configurator_enroll_conf(dev, apdev)
@@ -364,8 +374,10 @@
                                  require_conf_failure=False,
                                  configurator=False, conf_curve=None,
                                  conf=None, qr=None, stop_responder=True):
-    check_dpp_capab(dev[0], curve and "brainpool" in curve)
-    check_dpp_capab(dev[1], curve and "brainpool" in curve)
+    brainpool = (curve and "brainpool" in curve) or \
+        (conf_curve and "brainpool" in conf_curve)
+    check_dpp_capab(dev[0], brainpool)
+    check_dpp_capab(dev[1], brainpool)
     if configurator:
         conf_id = dev[1].dpp_configurator_add(curve=conf_curve)
     else:
@@ -1482,6 +1494,11 @@
     except:
         raise HwsimSkip("DPP not supported")
 
+    conf = hapd.request("GET_CONFIG")
+    if "key_mgmt=DPP" not in conf.splitlines():
+        logger.info("GET_CONFIG:\n" + conf)
+        raise Exception("GET_CONFIG did not report correct key_mgmt")
+
     id = dev[0].connect("dpp", key_mgmt="DPP", ieee80211w="2", scan_freq="2412",
                         dpp_pfs="2", wait_connect=False)
     ev = dev[0].wait_event(["CTRL-EVENT-NETWORK-NOT-FOUND"], timeout=2)
@@ -1741,8 +1758,10 @@
 
 def run_dpp_ap_config(dev, apdev, curve=None, conf_curve=None,
                       reconf_configurator=False):
-    check_dpp_capab(dev[0])
-    check_dpp_capab(dev[1])
+    brainpool = (curve and "BP-" in curve) or \
+        (conf_curve and "BP-" in conf_curve)
+    check_dpp_capab(dev[0], brainpool)
+    check_dpp_capab(dev[1], brainpool)
     hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
     check_dpp_capab(hapd)
 
@@ -1862,7 +1881,7 @@
         dev[0].set("dpp_config_processing", "0", allow_fail=True)
 
 def run_dpp_auto_connect(dev, apdev, processing, ap_version=0, sta_version=0,
-                         sta1_version=0):
+                         sta1_version=0, stop_after_prov=False):
     check_dpp_capab(dev[0])
     check_dpp_capab(dev[1])
 
@@ -1901,6 +1920,8 @@
     if ev is None:
         raise Exception("DPP network profile not generated")
     id = ev.split(' ')[1]
+    if stop_after_prov:
+        return id, hapd
 
     if processing == 1:
         dev[0].select_network(id, freq=2412)
@@ -2115,6 +2136,25 @@
     wait_auth_success(dev[0], hapd, configurator=dev[0], enrollee=hapd,
                       stop_responder=True)
 
+def test_dpp_qr_code_hostapd_ignore_mismatch(dev, apdev):
+    """DPP QR Code and hostapd ignoring netaccessKey mismatch"""
+    check_dpp_capab(dev[0])
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
+                                     "channel": "6"})
+    check_dpp_capab(hapd)
+    conf_id = dev[0].dpp_configurator_add()
+    id0 = dev[0].dpp_bootstrap_gen(chan="81/6", mac=True)
+    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
+    dev[0].set("dpp_configurator_params",
+               "conf=ap-dpp configurator=%d" % conf_id)
+    conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{"akm":"dpp","signedConnector":"eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJUbkdLaklsTlphYXRyRUFZcmJiamlCNjdyamtMX0FHVldYTzZxOWhESktVIiwiYWxnIjoiRVMyNTYifQ.eyJncm91cHMiOlt7Imdyb3VwSWQiOiIqIiwibmV0Um9sZSI6InN0YSJ9XSwibmV0QWNjZXNzS2V5Ijp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoiYVRGNEpFR0lQS1NaMFh2OXpkQ01qbS10bjVYcE1zWUlWWjl3eVNBejFnSSIsInkiOiJRR2NIV0FfNnJiVTlYRFhBenRvWC1NNVEzc3VUbk1hcUVoVUx0bjdTU1h3In19._sm6YswxMf6hJLVTyYoU1uYUeY2VVkUNjrzjSiEhY42StD_RWowStEE-9CRsdCvLmsTptZ72_g40vTFwdId20A","csign":{"kty":"EC","crv":"P-256","x":"W4-Y5N1Pkos3UWb9A5qme0KUYRtY3CVUpekx_MapZ9s","y":"Et-M4NSF4NGjvh2VCh4B1sJ9eSCZ4RNzP2DBdP137VE","kid":"TnGKjIlNZaatrEAYrbbjiB67rjkL_AGVWXO6q9hDJKU"}}}'
+    dev[0].set("dpp_config_obj_override", conf)
+    dev[0].dpp_listen(2437, role="configurator")
+    hapd.set("dpp_ignore_netaccesskey_mismatch", "1")
+    hapd.dpp_auth_init(uri=uri0, role="enrollee")
+    wait_auth_success(dev[0], hapd, configurator=dev[0], enrollee=hapd,
+                      stop_responder=True)
+
 def test_dpp_test_vector_p_256(dev, apdev):
     """DPP P-256 test vector (mutual auth)"""
     check_dpp_capab(dev[0])
@@ -2185,7 +2225,7 @@
 def der_priv_key_p_521(priv):
     if len(priv) != 2 * 66:
         raise Exception("Unexpected der_priv_key_p_521 parameter: " + priv)
-    der_prefix = "3081500201010442"
+    der_prefix = "30500201010442"
     der_postfix = "a00706052b81040023"
     return der_prefix + priv + der_postfix
 
@@ -2228,6 +2268,10 @@
     """DPP and PKEX"""
     run_dpp_pkex(dev, apdev)
 
+def test_dpp_pkex_v2(dev, apdev):
+    """DPP and PKEXv2"""
+    run_dpp_pkex(dev, apdev, v2=True)
+
 def test_dpp_pkex_p256(dev, apdev):
     """DPP and PKEX (P-256)"""
     run_dpp_pkex(dev, apdev, "P-256")
@@ -2281,13 +2325,14 @@
 
 def run_dpp_pkex(dev, apdev, curve=None, init_extra=None, check_config=False,
                  identifier_i="test", identifier_r="test",
-                 expect_no_resp=False):
-    check_dpp_capab(dev[0], curve and "brainpool" in curve)
-    check_dpp_capab(dev[1], curve and "brainpool" in curve)
+                 expect_no_resp=False, v2=False):
+    min_ver = 3 if v2 else 1
+    check_dpp_capab(dev[0], curve and "brainpool" in curve, min_ver=min_ver)
+    check_dpp_capab(dev[1], curve and "brainpool" in curve, min_ver=min_ver)
     dev[0].dpp_pkex_resp(2437, identifier=identifier_r, code="secret",
                          curve=curve)
     dev[1].dpp_pkex_init(identifier=identifier_i, code="secret", curve=curve,
-                         extra=init_extra)
+                         extra=init_extra, v2=v2)
 
     if expect_no_resp:
         ev = dev[0].wait_event(["DPP-RX"], timeout=10)
@@ -2453,7 +2498,7 @@
     dev[0].dpp_pkex_resp(2437, identifier="test", code="secret")
 
     with alloc_fail(dev[0], 1,
-                    "dpp_get_pubkey_point;dpp_pkex_rx_commit_reveal_req"):
+                    "crypto_ec_key_get_pubkey_point;dpp_pkex_rx_commit_reveal_req"):
         dev[1].dpp_pkex_init(identifier="test", code="secret")
         wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
 
@@ -2511,6 +2556,19 @@
     wait_auth_success(hapd, dev[0], configurator=dev[0], enrollee=hapd,
                       stop_initiator=True)
 
+def test_dpp_pkex_v2_hostapd_responder(dev, apdev):
+    """DPP PKEXv2 with hostapd as responder"""
+    check_dpp_capab(dev[0], min_ver=3)
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
+                                     "channel": "6"})
+    check_dpp_capab(hapd, min_ver=3)
+    hapd.dpp_pkex_resp(2437, identifier="test", code="secret")
+    conf_id = dev[0].dpp_configurator_add()
+    dev[0].dpp_pkex_init(identifier="test", code="secret",
+                         extra="conf=ap-dpp configurator=%d" % conf_id, v2=True)
+    wait_auth_success(hapd, dev[0], configurator=dev[0], enrollee=hapd,
+                      stop_initiator=True)
+
 def test_dpp_pkex_hostapd_initiator(dev, apdev):
     """DPP PKEX with hostapd as initiator"""
     check_dpp_capab(dev[0])
@@ -2526,8 +2584,60 @@
     wait_auth_success(hapd, dev[0], configurator=dev[0], enrollee=hapd,
                       stop_initiator=True)
 
+def test_dpp_pkex_v2_hostapd_initiator(dev, apdev):
+    """DPP PKEXv2 with hostapd as initiator"""
+    check_dpp_capab(dev[0], min_ver=3)
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
+                                     "channel": "6"})
+    check_dpp_capab(hapd, min_ver=3)
+    conf_id = dev[0].dpp_configurator_add()
+    dev[0].set("dpp_configurator_params",
+               " conf=ap-dpp configurator=%d" % conf_id)
+    dev[0].dpp_pkex_resp(2437, identifier="test", code="secret",
+                         listen_role="configurator")
+    hapd.dpp_pkex_init(identifier="test", code="secret", role="enrollee",
+                       v2=True)
+    wait_auth_success(hapd, dev[0], configurator=dev[0], enrollee=hapd,
+                      stop_initiator=True)
+
+def test_dpp_pkex_hostapd_errors(dev, apdev):
+    """DPP PKEX errors with hostapd"""
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
+                                     "channel": "6"})
+    check_dpp_capab(hapd)
+    id0 = hapd.dpp_bootstrap_gen(type="pkex")
+    tests = ["own=%d" % id0,
+             "own=%d identifier=foo" % id0,
+             ""]
+    for t in tests:
+        if "FAIL" not in hapd.request("DPP_PKEX_ADD " + t):
+            raise Exception("Invalid DPP_PKEX_ADD accepted: " + t)
+
+    res = hapd.request("DPP_PKEX_ADD own=%d code=foo" % id0)
+    if "FAIL" in res:
+        raise Exception("Failed to add PKEX responder")
+    if "OK" not in hapd.request("DPP_PKEX_REMOVE " + res):
+        raise Exception("Failed to remove PKEX responder")
+    if "FAIL" not in hapd.request("DPP_PKEX_REMOVE " + res):
+        raise Exception("Unknown PKEX responder removal accepted")
+
+    res = hapd.request("DPP_PKEX_ADD own=%d code=foo" % id0)
+    if "FAIL" in res:
+        raise Exception("Failed to add PKEX responder")
+    if "OK" not in hapd.request("DPP_PKEX_REMOVE *"):
+        raise Exception("Failed to flush PKEX responders")
+    hapd.request("DPP_PKEX_REMOVE *")
+
 def test_dpp_hostapd_configurator(dev, apdev):
     """DPP with hostapd as configurator/initiator"""
+    run_dpp_hostapd_configurator(dev, apdev)
+
+def test_dpp_hostapd_configurator_enrollee_v1(dev, apdev):
+    """DPP with hostapd as configurator/initiator with v1 enrollee"""
+    dev[0].set("dpp_version_override", "1")
+    run_dpp_hostapd_configurator(dev, apdev)
+
+def run_dpp_hostapd_configurator(dev, apdev):
     check_dpp_capab(dev[0])
     hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
                                      "channel": "1"})
@@ -2587,6 +2697,362 @@
     wait_auth_success(dev[0], hapd, configurator=hapd, enrollee=dev[0],
                       stop_responder=True)
 
+def test_dpp_hostapd_enrollee_fragmentation(dev, apdev):
+    """DPP and hostapd as Enrollee with GAS fragmentation"""
+    check_dpp_capab(dev[0])
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
+                                     "channel": "6"})
+    check_dpp_capab(hapd)
+    conf_id = dev[0].dpp_configurator_add()
+    id0 = dev[0].dpp_bootstrap_gen(chan="81/6", mac=True)
+    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
+    conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"secret passphrase"}}' + 3000*' '
+    dev[0].set("dpp_config_obj_override", conf)
+    dev[0].set("dpp_configurator_params",
+               " conf=ap-dpp configurator=%d" % conf_id)
+    dev[0].dpp_listen(2437, role="configurator")
+    hapd.dpp_auth_init(uri=uri0, role="enrollee")
+    wait_auth_success(dev[0], hapd, configurator=dev[0], enrollee=hapd,
+                      stop_responder=True)
+
+def test_dpp_hostapd_enrollee_gas_timeout(dev, apdev):
+    """DPP and hostapd as Enrollee with GAS timeout"""
+    check_dpp_capab(dev[0])
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
+                                     "channel": "6"})
+    check_dpp_capab(hapd)
+    conf_id = dev[0].dpp_configurator_add()
+    id0 = dev[0].dpp_bootstrap_gen(chan="81/6", mac=True)
+    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
+    conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"secret passphrase"}}' + 3000*' '
+    dev[0].set("dpp_config_obj_override", conf)
+    dev[0].set("dpp_configurator_params",
+               "conf=ap-dpp configurator=%d" % conf_id)
+    dev[0].set("ext_mgmt_frame_handling", "1")
+    dev[0].dpp_listen(2437, role="configurator")
+    hapd.dpp_auth_init(uri=uri0, role="enrollee")
+    process_dpp_frames(dev[0])
+    ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
+    if "result=TIMEOUT" not in ev:
+        raise Exception("GAS timeout not reported")
+
+def test_dpp_hostapd_enrollee_gas_timeout_comeback(dev, apdev):
+    """DPP and hostapd as Enrollee with GAS timeout during comeback"""
+    check_dpp_capab(dev[0])
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
+                                     "channel": "6"})
+    check_dpp_capab(hapd)
+    conf_id = dev[0].dpp_configurator_add()
+    id0 = dev[0].dpp_bootstrap_gen(chan="81/6", mac=True)
+    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
+    conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"secret passphrase"}}' + 3000*' '
+    dev[0].set("dpp_config_obj_override", conf)
+    dev[0].set("dpp_configurator_params",
+               "conf=ap-dpp configurator=%d" % conf_id)
+    dev[0].set("ext_mgmt_frame_handling", "1")
+    dev[0].dpp_listen(2437, role="configurator")
+    hapd.dpp_auth_init(uri=uri0, role="enrollee")
+    process_dpp_frames(dev[0], count=4)
+    ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
+    if "result=TIMEOUT" not in ev:
+        raise Exception("GAS timeout not reported")
+
+def process_dpp_frames(dev, count=3):
+    for i in range(count):
+        msg = dev.mgmt_rx()
+        cmd = "MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], binascii.hexlify(msg['frame']).decode())
+        if "OK" not in dev.request(cmd):
+            raise Exception("MGMT_RX_PROCESS failed")
+
+def test_dpp_hostapd_enrollee_gas_errors(dev, apdev):
+    """DPP and hostapd as Enrollee with GAS query local errors"""
+    check_dpp_capab(dev[0])
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
+                                     "channel": "6"})
+    check_dpp_capab(hapd)
+    conf_id = dev[0].dpp_configurator_add()
+    id0 = dev[0].dpp_bootstrap_gen(chan="81/6", mac=True)
+    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
+    dev[0].set("dpp_configurator_params",
+               "conf=ap-dpp configurator=%d" % conf_id)
+    dev[0].set("ext_mgmt_frame_handling", "1")
+
+    # GAS without comeback
+    tests = [(1, "gas_query_append;gas_query_rx_initial", 3, True),
+             (1, "gas_query_rx_initial", 3, True),
+             (1, "gas_query_tx_initial_req", 2, True),
+             (1, "gas_query_ap_req", 2, False)]
+    for count, func, frame_count, wait_ev in tests:
+        dev[0].request("DPP_STOP_LISTEN")
+        dev[0].dpp_listen(2437, role="configurator")
+        dev[0].dump_monitor()
+        hapd.dump_monitor()
+        with alloc_fail(hapd, count, func):
+            hapd.dpp_auth_init(uri=uri0, role="enrollee")
+            process_dpp_frames(dev[0], count=frame_count)
+            if wait_ev:
+                ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
+                if not ev or "result=INTERNAL_ERROR" not in ev:
+                    raise Exception("Unexpect GAS query result: " + str(ev))
+
+    # GAS with comeback
+    conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"secret passphrase"}}' + 3000*' '
+    dev[0].set("dpp_config_obj_override", conf)
+
+    tests = [(1, "gas_query_append;gas_query_rx_comeback", 4),
+             (1, "wpabuf_alloc;gas_query_tx_comeback_req", 3),
+             (1, "hostapd_drv_send_action;gas_query_tx_comeback_req", 3)]
+    for count, func, frame_count in tests:
+        dev[0].request("DPP_STOP_LISTEN")
+        dev[0].dpp_listen(2437, role="configurator")
+        dev[0].dump_monitor()
+        hapd.dump_monitor()
+        with alloc_fail(hapd, count, func):
+            hapd.dpp_auth_init(uri=uri0, role="enrollee")
+            process_dpp_frames(dev[0], count=frame_count)
+            ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
+            if not ev or "result=INTERNAL_ERROR" not in ev:
+                raise Exception("Unexpect GAS query result: " + str(ev))
+
+def test_dpp_hostapd_enrollee_gas_proto(dev, apdev):
+    """DPP and hostapd as Enrollee with GAS query protocol testing"""
+    check_dpp_capab(dev[0])
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
+                                     "channel": "6"})
+    check_dpp_capab(hapd)
+    bssid = hapd.own_addr()
+    conf_id = dev[0].dpp_configurator_add()
+    id0 = dev[0].dpp_bootstrap_gen(chan="81/6", mac=True)
+    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
+    dev[0].set("dpp_configurator_params",
+               "conf=ap-dpp configurator=%d" % conf_id)
+    conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"secret passphrase"}}' + 3000*' '
+    dev[0].set("dpp_config_obj_override", conf)
+    dev[0].set("ext_mgmt_frame_handling", "1")
+    dev[0].dpp_listen(2437, role="configurator")
+    hapd.dpp_auth_init(uri=uri0, role="enrollee")
+    process_dpp_frames(dev[0], count=3)
+    msg = dev[0].mgmt_rx()
+    payload = msg['payload']
+    dialog_token, = struct.unpack('B', payload[2:3])
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x80, 0)
+    # GAS: Advertisement Protocol changed between initial and comeback response from 02:00:00:00:00:00
+    adv_proto = "6c087fdd05506f9a1a02"
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
+    if not ev or "result=PEER_ERROR" not in ev:
+        raise Exception("Unexpect GAS query result: " + str(ev))
+    dev[0].request("DPP_STOP_LISTEN")
+    hapd.dump_monitor()
+    dev[0].dump_monitor()
+
+    dev[0].dpp_listen(2437, role="configurator")
+    hapd.dpp_auth_init(uri=uri0, role="enrollee")
+    process_dpp_frames(dev[0], count=3)
+    msg = dev[0].mgmt_rx()
+    payload = msg['payload']
+    dialog_token, = struct.unpack('B', payload[2:3])
+    # Another comeback delay
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x80, 1)
+    adv_proto = "6c087fdd05506f9a1a01"
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    msg = dev[0].mgmt_rx()
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x81, 1)
+    # GAS: Invalid comeback response with non-zero frag_id and comeback_delay from 02:00:00:00:00:00
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
+    if not ev or "result=PEER_ERROR" not in ev:
+        raise Exception("Unexpect GAS query result: " + str(ev))
+    dev[0].request("DPP_STOP_LISTEN")
+    hapd.dump_monitor()
+    dev[0].dump_monitor()
+
+    dev[0].dpp_listen(2437, role="configurator")
+    hapd.dpp_auth_init(uri=uri0, role="enrollee")
+    process_dpp_frames(dev[0], count=3)
+    msg = dev[0].mgmt_rx()
+    payload = msg['payload']
+    dialog_token, = struct.unpack('B', payload[2:3])
+    # Valid comeback response
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x80, 0)
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    msg = dev[0].mgmt_rx()
+    # GAS: Drop frame as possible retry of previous fragment
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x80, 0)
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    # GAS: Unexpected frag_id in response from 02:00:00:00:00:00
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x82, 0)
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
+    if not ev or "result=PEER_ERROR" not in ev:
+        raise Exception("Unexpect GAS query result: " + str(ev))
+    dev[0].request("DPP_STOP_LISTEN")
+    hapd.dump_monitor()
+    dev[0].dump_monitor()
+
+    dev[0].dpp_listen(2437, role="configurator")
+    hapd.dpp_auth_init(uri=uri0, role="enrollee")
+    process_dpp_frames(dev[0], count=3)
+    msg = dev[0].mgmt_rx()
+    payload = msg['payload']
+    dialog_token, = struct.unpack('B', payload[2:3])
+    # GAS: Unexpected initial response from 02:00:00:00:00:00 dialog token 3 when waiting for comeback response
+    hdr = struct.pack('<BBBHBH', 4, 11, dialog_token, 0, 0x80, 0)
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    # GAS: Allow non-zero status for outstanding comeback response
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 95, 0x80, 0)
+    # GAS: Ignore 1 octets of extra data after Query Response from 02:00:00:00:00:00
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001" + "ff"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    # GAS: No pending query found for 02:00:00:00:00:00 dialog token 4
+    hdr = struct.pack('<BBBHBH', 4, 13, (dialog_token + 1) % 256, 0, 0x80, 0)
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    # GAS: Truncated Query Response in response from 02:00:00:00:00:00
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x81, 0)
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "0010"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    # GAS: No room for GAS Response Length
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x81, 0)
+    action = binascii.hexlify(hdr).decode() + adv_proto + "03"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    # GAS: Unexpected Advertisement Protocol element ID 0 in response from 02:00:00:00:00:00
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x81, 0)
+    adv_proto_broken = "0000"
+    action = binascii.hexlify(hdr).decode() + adv_proto_broken + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    # GAS: No room for Advertisement Protocol element in the response from 02:00:00:00:00:00
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x81, 0)
+    adv_proto_broken = "00ff"
+    action = binascii.hexlify(hdr).decode() + adv_proto_broken + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    # No room for Comeback Delay
+    hdr = struct.pack('<BBBHBB', 4, 13, dialog_token, 0, 0x81, 0)
+    action = binascii.hexlify(hdr).decode()
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    # No room for frag_id
+    hdr = struct.pack('<BBBH', 4, 13, dialog_token, 0)
+    action = binascii.hexlify(hdr).decode()
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    # GAS: Query to 02:00:00:00:00:00 dialog token 3 failed - status code 1
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 1, 0x81, 0)
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
+    if not ev or "result=FAILURE" not in ev:
+        raise Exception("Unexpect GAS query result: " + str(ev))
+    dev[0].request("DPP_STOP_LISTEN")
+    hapd.dump_monitor()
+    dev[0].dump_monitor()
+
+    dev[0].dpp_listen(2437, role="configurator")
+    hapd.dpp_auth_init(uri=uri0, role="enrollee")
+    process_dpp_frames(dev[0], count=2)
+    msg = dev[0].mgmt_rx()
+    payload = msg['payload']
+    dialog_token, = struct.unpack('B', payload[2:3])
+    # Unexpected comeback delay
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x80, 0)
+    adv_proto = "6c087fdd05506f9a1a01"
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    # GAS: Query to 02:00:00:00:00:00 dialog token 3 failed - status code 1
+    hdr = struct.pack('<BBBHBH', 4, 11, dialog_token, 1, 0x80, 0)
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
+    if not ev or "result=FAILURE" not in ev:
+        raise Exception("Unexpect GAS query result: " + str(ev))
+    dev[0].request("DPP_STOP_LISTEN")
+    hapd.dump_monitor()
+    dev[0].dump_monitor()
+
+def test_dpp_hostapd_enrollee_gas_tx_status_errors(dev, apdev):
+    """DPP and hostapd as Enrollee with GAS TX status errors"""
+    check_dpp_capab(dev[0])
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
+                                     "channel": "6"})
+    check_dpp_capab(hapd)
+    conf_id = dev[0].dpp_configurator_add()
+    id0 = dev[0].dpp_bootstrap_gen(chan="81/6", mac=True)
+    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
+    conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"secret passphrase"}}' + 3000*' '
+    dev[0].set("dpp_config_obj_override", conf)
+    dev[0].set("dpp_configurator_params",
+               "conf=ap-dpp configurator=%d" % conf_id)
+    dev[0].set("ext_mgmt_frame_handling", "1")
+    dev[0].dpp_listen(2437, role="configurator")
+    hapd.dpp_auth_init(uri=uri0, role="enrollee")
+    process_dpp_frames(dev[0], count=3)
+
+    hapd.set("ext_mgmt_frame_handling", "1")
+    # GAS: TX status for unexpected destination
+    frame = "d0003a01" + "222222222222"
+    frame += hapd.own_addr().replace(':', '') + "ffffffffffff"
+    frame += "5000" + "040a"
+    hapd.request("MGMT_TX_STATUS_PROCESS stype=13 ok=1 buf=" + frame)
+
+    # GAS: No ACK to GAS request
+    frame = "d0003a01" + dev[0].own_addr().replace(':', '')
+    frame += hapd.own_addr().replace(':', '') + "ffffffffffff"
+    frame += "5000" + "040a"
+    hapd.request("MGMT_TX_STATUS_PROCESS stype=13 ok=0 buf=" + frame)
+
+    ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
+    if "result=TIMEOUT" not in ev:
+        raise Exception("GAS timeout not reported")
+
+    # GAS: Unexpected TX status: dst=02:00:00:00:00:00 ok=1 - no query in progress
+    hapd.request("MGMT_TX_STATUS_PROCESS stype=13 ok=1 buf=" + frame)
+    hapd.set("ext_mgmt_frame_handling", "0")
+
+def test_dpp_hostapd_configurator_override_objects(dev, apdev):
+    """DPP with hostapd as configurator and override objects"""
+    check_dpp_capab(dev[0])
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
+                                     "channel": "1"})
+    check_dpp_capab(hapd)
+    conf_id = hapd.dpp_configurator_add()
+    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
+    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
+    id1 = hapd.dpp_qr_code(uri0)
+    res = hapd.request("DPP_BOOTSTRAP_INFO %d" % id1)
+    if "FAIL" in res:
+        raise Exception("DPP_BOOTSTRAP_INFO failed")
+    dev[0].dpp_listen(2412)
+    discovery = '{\n"ssid":"mywifi"\n}'
+    groups = '[\n  {"groupId":"home","netRole":"sta"},\n  {"groupId":"cottage","netRole":"sta"}\n]'
+    hapd.set("dpp_discovery_override", discovery)
+    hapd.set("dpp_groups_override", groups)
+    hapd.dpp_auth_init(peer=id1, configurator=conf_id, conf="sta-dpp")
+    wait_auth_success(dev[0], hapd, configurator=hapd, enrollee=dev[0],
+                      stop_responder=True)
+
 def test_dpp_own_config(dev, apdev):
     """DPP configurator signing own connector"""
     try:
@@ -2821,6 +3287,7 @@
         own = id1b
     dev[1].dpp_auth_init(uri=uri0, role=role, configurator=configurator,
                          conf=conf, own=own)
+    return uri0, role, configurator, conf, own
 
 def test_dpp_proto_after_wrapped_data_auth_req(dev, apdev):
     """DPP protocol testing - attribute after Wrapped Data in Auth Req"""
@@ -3249,7 +3716,7 @@
 
 def test_dpp_proto_stop_at_auth_resp(dev, apdev):
     """DPP protocol testing - stop when receiving Auth Resp"""
-    run_dpp_proto_init(dev, 1, 88)
+    uri0, role, configurator, conf, own = run_dpp_proto_init(dev, 1, 88)
 
     ev = dev[1].wait_event(["DPP-TX "], timeout=5)
     if ev is None:
@@ -3263,6 +3730,18 @@
     if ev is not None:
         raise Exception("Unexpected Auth Conf TX")
 
+    ev = dev[0].wait_event(["DPP-FAIL"], timeout=2)
+    if ev is None or "No Auth Confirm received" not in ev:
+        raise Exception("DPP-FAIL for missing Auth Confirm not reported")
+    time.sleep(0.1)
+
+    # Try again without special testing behavior to confirm Responder is able
+    # to accept a new provisioning attempt.
+    dev[1].set("dpp_test", "0")
+    dev[1].dpp_auth_init(uri=uri0, role=role, configurator=configurator,
+                         conf=conf, own=own)
+    wait_auth_success(dev[0], dev[1])
+
 def test_dpp_proto_stop_at_auth_conf(dev, apdev):
     """DPP protocol testing - stop when receiving Auth Conf"""
     run_dpp_proto_init(dev, 0, 89, init_enrollee=True)
@@ -3564,6 +4043,67 @@
                    dpp_csign=params1_csign, dpp_connector=params1_sta_connector,
                    dpp_netaccesskey=params1_sta_netaccesskey)
 
+def test_dpp_hostapd_auth_conf_timeout(dev, apdev):
+    """DPP Authentication Confirm timeout in hostapd"""
+    check_dpp_capab(dev[0])
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
+    check_dpp_capab(hapd)
+    id_h = hapd.dpp_bootstrap_gen(chan="81/1", mac=True)
+    uri_h = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id_h)
+    hapd.dpp_listen(2412)
+    dev[0].set("dpp_test", "88")
+    dev[0].dpp_auth_init(uri=uri_h)
+    ev = hapd.wait_event(["DPP-FAIL"], timeout=10)
+    if ev is None:
+        raise Exception("DPP-FAIL not reported")
+    if "No Auth Confirm received" not in ev:
+        raise Exception("Unexpected failure reason: " + ev)
+
+def test_dpp_hostapd_auth_resp_retries(dev, apdev):
+    """DPP Authentication Response retries in hostapd"""
+    check_dpp_capab(dev[0])
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
+    check_dpp_capab(hapd)
+
+    hapd.set("dpp_resp_max_tries", "3")
+    hapd.set("dpp_resp_retry_time", "100")
+
+    id_h = hapd.dpp_bootstrap_gen(chan="81/1", mac=True)
+    uri_h = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id_h)
+    id0b = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
+    uri0b = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0b)
+    hapd.dpp_listen(2412, qr="mutual")
+    dev[0].dpp_auth_init(uri=uri_h, own=id0b)
+
+    ev = dev[0].wait_event(["DPP-RESPONSE-PENDING"], timeout=5)
+    if ev is None:
+        raise Exception("Pending response not reported")
+    ev = hapd.wait_event(["DPP-SCAN-PEER-QR-CODE"], timeout=5)
+    if ev is None:
+        raise Exception("QR Code scan for mutual authentication not requested")
+
+    # Stop Initiator from listening to frames to force retransmission of the
+    # DPP Authentication Response frame with Status=0
+    dev[0].request("DPP_STOP_LISTEN")
+
+    hapd.dump_monitor()
+    dev[0].dump_monitor()
+
+    id0b = hapd.dpp_qr_code(uri0b)
+
+    ev = hapd.wait_event(["DPP-TX "], timeout=5)
+    if ev is None or "type=1" not in ev:
+        raise Exception("DPP Authentication Response not sent")
+    ev = hapd.wait_event(["DPP-TX-STATUS"], timeout=5)
+    if ev is None:
+        raise Exception("TX status for DPP Authentication Response not reported")
+    if "result=FAILED" not in ev:
+        raise Exception("Unexpected TX status for Authentication Response: " + ev)
+
+    ev = hapd.wait_event(["DPP-TX "], timeout=15)
+    if ev is None or "type=1" not in ev:
+        raise Exception("DPP Authentication Response retransmission not sent")
+
 def test_dpp_qr_code_no_chan_list_unicast(dev, apdev):
     """DPP QR Code and no channel list (unicast)"""
     run_dpp_qr_code_chan_list(dev, apdev, True, 2417, None)
@@ -3643,7 +4183,7 @@
     id1 = None
 
     # Local error cases on the Initiator
-    tests = [(1, "dpp_get_pubkey_point"),
+    tests = [(1, "crypto_ec_key_get_pubkey_point"),
              (1, "dpp_alloc_msg;dpp_pkex_build_exchange_req"),
              (1, "dpp_alloc_msg;dpp_pkex_build_commit_reveal_req"),
              (1, "dpp_alloc_msg;dpp_auth_build_req"),
@@ -3673,9 +4213,9 @@
              (3, "dpp_pkex_init"),
              (1, "dpp_pkex_derive_z"),
              (1, "=dpp_pkex_rx_commit_reveal_resp"),
-             (1, "dpp_get_pubkey_point;dpp_build_jwk"),
-             (2, "dpp_get_pubkey_point;dpp_build_jwk"),
-             (1, "dpp_get_pubkey_point;dpp_auth_init")]
+             (1, "crypto_ec_key_get_pubkey_point;dpp_build_jwk"),
+             (2, "crypto_ec_key_get_pubkey_point;dpp_build_jwk"),
+             (1, "crypto_ec_key_get_pubkey_point;dpp_auth_init")]
     for count, func in tests:
         dev[0].request("DPP_STOP_LISTEN")
         dev[1].request("DPP_STOP_LISTEN")
@@ -3696,11 +4236,11 @@
                 dev[0].wait_event(["GAS-QUERY-DONE"], timeout=3)
 
     # Local error cases on the Responder
-    tests = [(1, "dpp_get_pubkey_point"),
+    tests = [(1, "crypto_ec_key_get_pubkey_point"),
              (1, "dpp_alloc_msg;dpp_pkex_build_exchange_resp"),
              (1, "dpp_alloc_msg;dpp_pkex_build_commit_reveal_resp"),
              (1, "dpp_alloc_msg;dpp_auth_build_resp"),
-             (1, "dpp_get_pubkey_point;dpp_auth_build_resp_ok"),
+             (1, "crypto_ec_key_get_pubkey_point;dpp_auth_build_resp_ok"),
              (1, "dpp_alloc_auth"),
              (1, "=dpp_auth_req_rx"),
              (1, "=dpp_auth_conf_rx"),
@@ -3711,7 +4251,7 @@
              (1, "json_parse;dpp_parse_connector"),
              (1, "dpp_parse_jwk;dpp_parse_connector"),
              (1, "dpp_parse_jwk;dpp_parse_cred_dpp"),
-             (1, "dpp_get_pubkey_point;dpp_check_pubkey_match"),
+             (1, "crypto_ec_key_get_pubkey_point;dpp_check_pubkey_match"),
              (1, "base64_gen_decode;dpp_process_signed_connector"),
              (1, "dpp_parse_jws_prot_hdr;dpp_process_signed_connector"),
              (2, "base64_gen_decode;dpp_process_signed_connector"),
@@ -3724,7 +4264,7 @@
              (2, "=dpp_pkex_rx_exchange_req"),
              (3, "=dpp_pkex_rx_exchange_req"),
              (1, "=dpp_pkex_rx_commit_reveal_req"),
-             (1, "dpp_get_pubkey_point;dpp_pkex_rx_commit_reveal_req"),
+             (1, "crypto_ec_key_get_pubkey_point;dpp_pkex_rx_commit_reveal_req"),
              (1, "dpp_bootstrap_key_hash")]
     for count, func in tests:
         dev[0].request("DPP_STOP_LISTEN")
@@ -4155,7 +4695,8 @@
         if "FAIL" not in dev[0].request("DPP_CONFIGURATOR_ADD key=" + dpp_key_p256):
             raise Exception("Error not reported")
 
-    with alloc_fail(dev[0], 1, "dpp_get_pubkey_point;dpp_keygen_configurator"):
+    with alloc_fail(dev[0], 1,
+                    "crypto_ec_key_get_pubkey_point;dpp_keygen_configurator"):
         if "FAIL" not in dev[0].request("DPP_CONFIGURATOR_ADD key=" + dpp_key_p256):
             raise Exception("Error not reported")
 
@@ -4793,6 +5334,61 @@
     time.sleep(0.5)
     wt.close()
 
+class MyTCPServer(TCPServer):
+    def __init__(self, addr, handler):
+        self.allow_reuse_address = True
+        TCPServer.__init__(self, addr, handler)
+
+class DPPControllerServer(StreamRequestHandler):
+        def handle(self):
+            data = self.rfile.read()
+            # Do not reply
+
+def test_dpp_relay_incomplete_connections(dev, apdev):
+    """DPP Relay and incomplete connections"""
+    check_dpp_capab(dev[0], min_ver=2)
+    check_dpp_capab(dev[1], min_ver=2)
+
+    id_c = dev[1].dpp_bootstrap_gen()
+    uri_c = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id_c)
+    res = dev[1].request("DPP_BOOTSTRAP_INFO %d" % id_c)
+    pkhash = None
+    for line in res.splitlines():
+        name, value = line.split('=')
+        if name == "pkhash":
+            pkhash = value
+            break
+    if not pkhash:
+        raise Exception("Could not fetch public key hash from Controller")
+
+    params = {"ssid": "unconfigured",
+              "channel": "6",
+              "dpp_controller": "ipaddr=127.0.0.1 pkhash=" + pkhash}
+    hapd = hostapd.add_ap(apdev[0], params)
+    check_dpp_capab(hapd)
+
+    server = MyTCPServer(("127.0.0.1", 8908), DPPControllerServer)
+    server.timeout = 30
+
+    hapd.set("ext_mgmt_frame_handling", "1")
+    dev[0].dpp_auth_init(uri=uri_c, role="enrollee")
+    msg = hapd.mgmt_rx()
+    if msg is None:
+        raise Exception("MGMT RX wait timed out")
+    dev[0].request("DPP_STOP_LISTEN")
+    frame = msg['frame']
+    for i in range(20):
+        if i == 14:
+            time.sleep(20)
+        addr = struct.pack('6B', 0x02, 0, 0, 0, 0, i)
+        tmp = frame[0:10] + addr + frame[16:]
+        hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(tmp).decode())
+        ev = hapd.wait_event(["DPP-FAIL"], timeout=0.1)
+        if ev:
+            raise Exception("DPP relay failed [%d]: %s" % (i + 1, ev))
+
+    server.server_close()
+
 def test_dpp_tcp(dev, apdev, params):
     """DPP over TCP"""
     prefix = "dpp_tcp"
@@ -4926,6 +5522,51 @@
     time.sleep(0.5)
     wt.close()
 
+def test_dpp_tcp_controller_management_hostapd(dev, apdev, params):
+    """DPP Controller management in hostapd"""
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
+    check_dpp_capab(hapd)
+    conf_id = hapd.dpp_configurator_add()
+    if "OK" not in hapd.request("DPP_CONTROLLER_START"):
+        raise Exception("Failed to start Controller")
+    if "FAIL" not in hapd.request("DPP_CONTROLLER_START"):
+        raise Exception("DPP_CONTROLLER_START succeeded while already running Controller")
+    hapd.request("DPP_CONTROLLER_STOP")
+    hapd.dpp_configurator_remove(conf_id)
+    if "FAIL" not in hapd.request("DPP_CONFIGURATOR_REMOVE %d" % conf_id):
+        raise Exception("Removal of unknown Configurator accepted")
+
+def test_dpp_tcp_controller_management_hostapd2(dev, apdev, params):
+    """DPP Controller management in hostapd over interface addition/removal"""
+    check_dpp_capab(dev[0], min_ver=2)
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
+    check_dpp_capab(hapd, min_ver=2)
+    hapd2 = hostapd.add_ap(apdev[1], {"ssid": "unconfigured"})
+    check_dpp_capab(hapd2, min_ver=2)
+    id_c = hapd.dpp_bootstrap_gen()
+    uri_c = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id_c)
+    if "OK" not in hapd.request("DPP_CONTROLLER_START role=enrollee"):
+        raise Exception("Failed to start Controller")
+
+    conf_id = dev[0].dpp_configurator_add()
+    dev[0].dpp_auth_init(uri=uri_c, role="configurator", conf="sta-dpp",
+                       configurator=conf_id, tcp_addr="127.0.0.1")
+    ev = dev[0].wait_event(["DPP-AUTH-SUCCESS"], timeout=5)
+    if ev is None:
+        raise Exception("DPP Authentication did not succeed")
+    ev = dev[0].wait_event(["DPP-CONF-SENT"], timeout=5)
+    if ev is None:
+        raise Exception("DPP Configuration did not succeed")
+
+    hapd_global = hostapd.HostapdGlobal(apdev)
+    hapd_global.remove(apdev[0]['ifname'])
+
+    dev[0].dpp_auth_init(uri=uri_c, role="configurator", conf="sta-dpp",
+                       configurator=conf_id, tcp_addr="127.0.0.1")
+    ev = dev[0].wait_event(["DPP-AUTH-SUCCESS"], timeout=5)
+    if ev is not None:
+        raise Exception("Unexpected DPP Authentication success")
+
 def test_dpp_tcp_controller_start_failure(dev, apdev, params):
     """DPP Controller startup failure"""
     check_dpp_capab(dev[0])
@@ -5140,6 +5781,49 @@
     if result == 10 and "channel_list=" not in ev:
         raise Exception("Channel list not reported for no-AP")
 
+def test_dpp_conn_status_success_hostapd_configurator(dev, apdev):
+    """DPP connection status - success with hostapd as Configurator"""
+    try:
+        run_dpp_conn_status_hostapd_configurator(dev, apdev)
+    finally:
+        dev[0].set("dpp_config_processing", "0", allow_fail=True)
+
+def run_dpp_conn_status_hostapd_configurator(dev, apdev):
+    check_dpp_capab(dev[0])
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
+                                     "channel": "1"})
+    check_dpp_capab(hapd)
+    conf_id = hapd.dpp_configurator_add()
+
+    cmd = "DPP_CONFIGURATOR_SIGN conf=ap-dpp configurator=%d" % conf_id
+    res = hapd.request(cmd)
+    if "FAIL" in res:
+        raise Exception("Failed to generate own configuration")
+    update_hapd_config(hapd)
+
+    id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True)
+    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
+    id1 = hapd.dpp_qr_code(uri0)
+    res = hapd.request("DPP_BOOTSTRAP_INFO %d" % id1)
+    if "FAIL" in res:
+        raise Exception("DPP_BOOTSTRAP_INFO failed")
+    if "type=QRCODE" not in res:
+        raise Exception("DPP_BOOTSTRAP_INFO did not report correct type")
+    if "mac_addr=" + dev[0].own_addr() not in res:
+        raise Exception("DPP_BOOTSTRAP_INFO did not report correct mac_addr")
+    dev[0].set("dpp_config_processing", "2")
+    dev[0].dpp_listen(2412)
+    hapd.dpp_auth_init(peer=id1, configurator=conf_id, conf="sta-dpp",
+                       conn_status=True)
+    res = wait_auth_success(dev[0], hapd, configurator=hapd, enrollee=dev[0])
+    if 'wait_conn_status' not in res:
+        raise Exception("Configurator did not request connection status")
+    ev = hapd.wait_event(["DPP-CONN-STATUS-RESULT"], timeout=20)
+    if ev is None:
+        raise Exception("No connection status reported")
+    if "result=0" not in ev:
+        raise Exception("Unexpected connection status: " + ev)
+
 def test_dpp_mud_url(dev, apdev):
     """DPP MUD URL"""
     check_dpp_capab(dev[0])
@@ -5225,16 +5909,69 @@
     dev[1].dpp_auth_init(nfc_uri=uri, configurator=conf_id, conf="sta-dpp")
     wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0])
 
+def test_dpp_nfc_uri_hostapd(dev, apdev):
+    """DPP bootstrapping via NFC URI record (hostapd)"""
+    check_dpp_capab(dev[0])
+
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
+    check_dpp_capab(hapd)
+
+    id = hapd.dpp_bootstrap_gen(type="nfc-uri", chan="81/1", mac=True)
+    uri = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id)
+    logger.info("Generated URI: " + uri)
+    info = hapd.request("DPP_BOOTSTRAP_INFO %d" % id)
+    logger.info("Bootstrapping info:\n" + info)
+    if "type=NFC-URI" not in info:
+        raise Exception("Unexpected bootstrapping info contents")
+
+    hapd.dpp_listen(2412)
+    conf_id = dev[0].dpp_configurator_add()
+    dev[0].dpp_auth_init(nfc_uri=uri, configurator=conf_id, conf="ap-dpp")
+    wait_auth_success(hapd, dev[0], configurator=dev[0], enrollee=hapd)
+
+def test_dpp_nfc_uri_hostapd_tag_read(dev, apdev):
+    """DPP bootstrapping via NFC URI record (hostapd reading tag)"""
+    check_dpp_capab(dev[0])
+
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
+    check_dpp_capab(hapd)
+
+    id = dev[0].dpp_bootstrap_gen(type="nfc-uri", chan="81/1", mac=True)
+    uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id)
+    info = dev[0].request("DPP_BOOTSTRAP_INFO %d" % id)
+    conf_id = dev[0].dpp_configurator_add()
+    dev[0].set("dpp_configurator_params",
+               "conf=ap-dpp configurator=%d" % conf_id)
+    dev[0].dpp_listen(2412)
+
+    hapd.dpp_auth_init(nfc_uri=uri, role="enrollee")
+    wait_auth_success(dev[0], hapd, configurator=dev[0], enrollee=hapd)
+
 def test_dpp_nfc_negotiated_handover(dev, apdev):
     """DPP bootstrapping via NFC negotiated handover"""
-    run_dpp_nfc_negotiated_handover(dev, apdev)
+    run_dpp_nfc_negotiated_handover(dev)
 
 def test_dpp_nfc_negotiated_handover_diff_curve(dev, apdev):
     """DPP bootstrapping via NFC negotiated handover (different curve)"""
-    run_dpp_nfc_negotiated_handover(dev, apdev, curve0="prime256v1",
+    run_dpp_nfc_negotiated_handover(dev, curve0="prime256v1",
                                     curve1="secp384r1")
 
-def run_dpp_nfc_negotiated_handover(dev, apdev, curve0=None, curve1=None):
+def test_dpp_nfc_negotiated_handover_hostapd_sel(dev, apdev):
+    """DPP bootstrapping via NFC negotiated handover (hostapd as selector)"""
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
+                                     "channel": "6"})
+    check_dpp_capab(hapd)
+    run_dpp_nfc_negotiated_handover([dev[0], hapd], conf="ap-dpp")
+
+def test_dpp_nfc_negotiated_handover_hostapd_req(dev, apdev):
+    """DPP bootstrapping via NFC negotiated handover (hostapd as requestor)"""
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
+                                     "channel": "6"})
+    check_dpp_capab(hapd)
+    run_dpp_nfc_negotiated_handover([hapd, dev[0]])
+
+def run_dpp_nfc_negotiated_handover(dev, curve0=None, curve1=None,
+                                    conf="sta-dpp"):
     check_dpp_capab(dev[0])
     check_dpp_capab(dev[1])
 
@@ -5270,9 +6007,43 @@
 
     conf_id = dev[0].dpp_configurator_add()
     dev[0].dpp_auth_init(peer=peer, own=id0, configurator=conf_id,
-                         conf="sta-dpp")
+                         conf=conf)
     wait_auth_success(dev[1], dev[0], configurator=dev[0], enrollee=dev[1])
 
+def test_dpp_nfc_errors_hostapd(dev, apdev):
+    """DPP NFC operation failures in hostapd"""
+    check_dpp_capab(dev[0])
+    check_dpp_capab(dev[1])
+
+    id0 = dev[0].dpp_bootstrap_gen(type="nfc-uri", chan="81/11", mac=True,
+                                   curve="secp384r1")
+    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
+
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
+                                     "channel": "6"})
+    check_dpp_capab(hapd)
+
+    id_h = hapd.dpp_bootstrap_gen(type="nfc-uri", chan="81/6", mac=True)
+    uri_h = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id_h)
+
+    tests = ["",
+             "own=123456789",
+             "own=%d" % id_h,
+             "own=%d uri=%s" % (id_h, "foo")]
+    for t in tests:
+        if "FAIL" not in hapd.request("DPP_NFC_HANDOVER_REQ " + t):
+            raise Exception("Invalid DPP_NFC_HANDOVER_REQ accepted")
+        if "FAIL" not in hapd.request("DPP_NFC_HANDOVER_SEL " + t):
+            raise Exception("Invalid DPP_NFC_HANDOVER_SEL accepted")
+
+    # DPP: Peer (NFC Handover Selector) used different curve
+    if "FAIL" not in hapd.request("DPP_NFC_HANDOVER_SEL own=%d uri=%s" % (id_h, uri0)):
+        raise Exception("Invalid DPP_NFC_HANDOVER_SEL accepted")
+
+    # DPP: No common channel found
+    if "FAIL" not in hapd.request("DPP_NFC_HANDOVER_REQ own=%d uri=%s" % (id_h, uri0)):
+        raise Exception("DPP_NFC_HANDOVER_REQ with local error accepted")
+
 def test_dpp_with_p2p_device(dev, apdev):
     """DPP exchange when driver uses a separate P2P Device interface"""
     check_dpp_capab(dev[0])
@@ -5378,8 +6149,36 @@
     if "type=13" not in ev:
         raise Exception("Unexpected DPP frame received: " + ev)
 
+    ev = dev[1].wait_event(["DPP-TX"], timeout=10)
+    if ev is None:
+        raise Exception("Authentication Request TX not seen")
+    if "type=0" not in ev:
+        raise Exception("Unexpected DPP frame TX: " + ev)
+    if "dst=" + dev[0].own_addr() not in ev:
+        raise Exception("Unexpected Authentication Request destination: " + ev)
+
     wait_auth_success(dev[0], dev[1], dev[1], dev[0])
 
+def test_dpp_chirp_ap_as_configurator(dev, apdev):
+    """DPP chirp with an AP as a standalone Configurator"""
+    check_dpp_capab(dev[0], min_ver=2)
+
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"})
+    check_dpp_capab(hapd, min_ver=2)
+
+    id1 = dev[0].dpp_bootstrap_gen(chan="81/1")
+    uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id1)
+
+    conf_id = hapd.dpp_configurator_add()
+    idc = hapd.dpp_qr_code(uri)
+    hapd.dpp_bootstrap_set(idc, conf="sta-dpp", configurator=conf_id)
+    hapd.dpp_listen(2412)
+
+    if "OK" not in dev[0].request("DPP_CHIRP own=%d iter=2" % id1):
+        raise Exception("DPP_CHIRP failed")
+
+    wait_auth_success(dev[0], hapd, hapd, dev[0])
+
 def test_dpp_chirp_configurator_inits(dev, apdev):
     """DPP chirp with a standalone Configurator initiating"""
     check_dpp_capab(dev[0])
@@ -5422,6 +6221,94 @@
                       timeout=20)
     update_hapd_config(hapd)
 
+@long_duration_test
+def test_dpp_chirp_ap_5g(dev, apdev):
+    """DPP chirp by an AP on 5 GHz"""
+    check_dpp_capab(dev[0], min_ver=2)
+
+    try:
+        hapd = None
+        hapd2 = None
+
+        params = {"ssid": "unconfigured",
+                  "country_code": "US",
+                  "hw_mode": "a",
+                  "channel": "40",
+                  "dpp_configurator_connectivity": "1"}
+        hapd2 = hostapd.add_ap(apdev[1], params)
+        check_dpp_capab(hapd2, min_ver=2)
+
+        params = {"ssid": "unconfigured",
+                  "country_code": "US",
+                  "hw_mode": "a",
+                  "channel": "36",
+                  "start_disabled": "1"}
+        hapd = hostapd.add_ap(apdev[0], params)
+        check_dpp_capab(hapd, min_ver=2)
+
+        id_h = hapd.dpp_bootstrap_gen(chan="81/1", mac=True)
+        uri = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id_h)
+
+        # First, check chirping iteration and timeout
+        if "OK" not in hapd.request("DPP_CHIRP own=%d iter=2" % id_h):
+            raise Exception("DPP_CHIRP failed")
+        chan1 = 0
+        chan6 = 0
+        chan40 = 0
+        chan149 = 0
+        for i in range(30):
+            ev = hapd.wait_event(["DPP-CHIRP-STOPPED", "DPP-TX "], timeout=60)
+            if ev is None:
+                raise Exception("DPP chirp stop not reported")
+            if "DPP-CHIRP-STOPPED" in ev:
+                break
+            if "type=13" not in ev:
+                continue
+            freq = int(ev.split(' ')[2].split('=')[1])
+            if freq == 2412:
+                chan1 += 1
+            elif freq == 2437:
+                chan6 += 1
+            elif freq == 5200:
+                chan40 += 1
+            elif freq == 5745:
+                chan149 += 1
+        if not chan1 or not chan6 or not chan40 or not chan149:
+            raise Exception("Chirp not sent on all channels")
+
+        # Then, check successful chirping
+        conf_id = dev[0].dpp_configurator_add()
+        idc = dev[0].dpp_qr_code(uri)
+        dev[0].dpp_bootstrap_set(idc, conf="ap-dpp", configurator=conf_id)
+        dev[0].dpp_listen(5200)
+        if "OK" not in hapd.request("DPP_CHIRP own=%d iter=5" % id_h):
+            raise Exception("DPP_CHIRP failed")
+        wait_auth_success(hapd, dev[0], configurator=dev[0], enrollee=hapd,
+                          timeout=20)
+        update_hapd_config(hapd)
+    finally:
+        clear_regdom(hapd, dev)
+
+def test_dpp_chirp_ap_errors(dev, apdev):
+    """DPP chirp errors in hostapd"""
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
+                                     "start_disabled": "1"})
+    check_dpp_capab(hapd, min_ver=2)
+
+    id_h = hapd.dpp_bootstrap_gen(chan="81/1", mac=True)
+    uri = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id_h)
+    tests = ["",
+             "own=%d" % (id_h + 1),
+             "own=%d iter=-1" % id_h,
+             "own=%d listen=0" % id_h]
+    for t in tests:
+        if "FAIL" not in hapd.request("DPP_CHIRP " + t):
+            raise Exception("Invalid DPP_CHIRP accepted: " + t)
+    if "OK" not in hapd.request("DPP_CHIRP own=%d iter=5" % id_h):
+        raise Exception("DPP_CHIRP failed")
+
+    hapd.request("DPP_STOP_CHIRP")
+
 def start_dpp_pfs_ap(apdev, pfs, sae=False):
     params = {"ssid": "dpp",
               "wpa": "2",
@@ -5533,6 +6420,25 @@
     hapd = start_dpp_pfs_ap(apdev[0], 0)
     run_dpp_pfs_sta(dev[0], 0, pfs_expected=False)
 
+def test_dpp_pfs_errors(dev, apdev):
+    """DPP PFS error cases"""
+    check_dpp_capab(dev[0], min_ver=2)
+    hapd = start_dpp_pfs_ap(apdev[0], 1)
+    tests = [(1, "dpp_pfs_init"),
+             (1, "crypto_ecdh_init;dpp_pfs_init"),
+             (1, "wpabuf_alloc;dpp_pfs_init")]
+    for count, func in tests:
+        with alloc_fail(dev[0], count, func):
+            dev[0].connect("dpp", key_mgmt="DPP", scan_freq="2412",
+                           ieee80211w="2", dpp_pfs="1",
+                           dpp_csign=params1_csign,
+                           dpp_connector=params1_sta_connector,
+                           dpp_netaccesskey=params1_sta_netaccesskey)
+            dev[0].request("REMOVE_NETWORK all")
+            dev[0].wait_disconnected()
+            dev[0].dump_monitor()
+            hapd.dump_monitor()
+
 def test_dpp_reconfig_connector(dev, apdev):
     """DPP reconfiguration connector"""
     try:
@@ -5811,6 +6717,7 @@
 
 def test_dpp_enterprise(dev, apdev, params):
     """DPP and enterprise EAP-TLS provisioning"""
+    check_dpp_capab(dev[0], min_ver=2)
     try:
         dev[0].set("dpp_config_processing", "2")
         run_dpp_enterprise(dev, apdev, params)
@@ -5967,6 +6874,9 @@
 
 def test_dpp_enterprise_tcp(dev, apdev, params):
     """DPP over TCP for enterprise provisioning"""
+    if not openssl_imported:
+        raise HwsimSkip("OpenSSL python method not available")
+
     try:
         run_dpp_enterprise_tcp(dev, apdev, params)
     finally:
@@ -6054,6 +6964,9 @@
 
 def test_dpp_enterprise_tcp2(dev, apdev, params):
     """DPP over TCP for enterprise provisioning (Controller initiating)"""
+    if not openssl_imported:
+        raise HwsimSkip("OpenSSL python method not available")
+
     try:
         run_dpp_enterprise_tcp2(dev, apdev, params)
     finally:
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_dpp3.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_dpp3.py
new file mode 100755
index 0000000..e50f199
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_dpp3.py
@@ -0,0 +1,49 @@
+# Test cases for Device Provisioning Protocol (DPP) version 3
+# Copyright (c) 2021, Qualcomm Innovation Center, Inc.
+#
+# This software may be distributed under the terms of the BSD license.
+# See README for more details.
+
+from test_dpp import check_dpp_capab, run_dpp_auto_connect
+
+def test_dpp_network_intro_version(dev, apdev):
+    """DPP Network Introduction and protocol version"""
+    check_dpp_capab(dev[0], min_ver=3)
+
+    try:
+        id, hapd = run_dpp_auto_connect(dev, apdev, 1, stop_after_prov=True)
+        dev[0].select_network(id, freq=2412)
+        dev[0].wait_connected()
+    finally:
+        dev[0].set("dpp_config_processing", "0", allow_fail=True)
+
+def test_dpp_network_intro_version_change(dev, apdev):
+    """DPP Network Introduction and protocol version change"""
+    check_dpp_capab(dev[0], min_ver=3)
+
+    try:
+        dev[0].set("dpp_version_override", "2")
+        id, hapd = run_dpp_auto_connect(dev, apdev, 1, stop_after_prov=True)
+        dev[0].set("dpp_version_override", "3")
+        dev[0].select_network(id, freq=2412)
+        dev[0].wait_connected()
+    finally:
+        dev[0].set("dpp_config_processing", "0", allow_fail=True)
+
+def test_dpp_network_intro_version_missing_req(dev, apdev):
+    """DPP Network Introduction and protocol version missing from request"""
+    check_dpp_capab(dev[0], min_ver=3)
+
+    try:
+        dev[0].set("dpp_version_override", "2")
+        id, hapd = run_dpp_auto_connect(dev, apdev, 1, stop_after_prov=True)
+        dev[0].set("dpp_version_override", "3")
+        dev[0].set("dpp_test", "92")
+        dev[0].select_network(id, freq=2412)
+        ev = dev[0].wait_event(["DPP-INTRO"], timeout=10)
+        if ev is None:
+            raise Exception("DPP network introduction result not seen on STA")
+        if "status=8" not in ev:
+            raise Exception("Unexpected network introduction result on STA: " + ev)
+    finally:
+        dev[0].set("dpp_config_processing", "0", allow_fail=True)
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_dscp.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_dscp.py
new file mode 100755
index 0000000..e017938
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_dscp.py
@@ -0,0 +1,407 @@
+# Test cases for dscp policy
+# Copyright (c) 2021, Jouni Malinen <j@w1.fi>
+# Copyright (c) 2021, The Linux Foundation
+#
+# This software may be distributed under the terms of the BSD license.
+# See README for more details.
+
+import struct
+import time
+import sys
+import socket
+
+import hostapd
+from wpasupplicant import WpaSupplicant
+from utils import *
+
+def register_dscp_req(hapd):
+    type = 0x00d0
+    match = "7e506f9a1a"
+    if "OK" not in hapd.request("REGISTER_FRAME %04x %s" % (type, match)):
+        raise Exception("Could not register frame reception for Vendor specific protected type")
+
+def send_dscp_req(hapd, da, oui_subtype, dialog_token, req_control, qos_ie,
+                  truncate=False):
+    type = 0
+    subtype = 13
+    category = 126
+    oui_type = 0x506f9a1a
+    if truncate:
+        req = struct.pack('>BLBB', category, oui_type, oui_subtype,
+                          dialog_token)
+    else:
+        req = struct.pack('>BLBBB', category, oui_type, oui_subtype,
+                          dialog_token, req_control)
+        if qos_ie:
+            req += qos_ie
+
+    msg = {}
+    msg['fc'] = 0x00d0
+    msg['sa'] = hapd.own_addr()
+    msg['da'] = da
+    msg['bssid'] = hapd.own_addr()
+    msg['type'] = type
+    msg['subtype'] = subtype
+    msg['payload'] = req
+
+    hapd.mgmt_tx(msg)
+    ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
+    if ev is None or "stype=13 ok=1" not in ev:
+        raise Exception("No DSCP Policy Request sent")
+
+def prepare_qos_ie(policy_id, req_type, dscp, start_port=0, end_port=0,
+                   frame_classifier=None, frame_class_len=0, domain_name=None):
+    qos_elem_oui_type = 0x229a6f50
+    qos_elem_id = 221
+
+    if policy_id:
+        qos_attr = struct.pack('BBBBB', 2, 3, policy_id, req_type, dscp)
+        qos_attr_len = 5
+    else:
+        qos_attr = 0
+        qos_attr_len = 0
+
+    if start_port and end_port:
+        port_range_attr = struct.pack('>BBHH', 1, 4, start_port, end_port)
+        if qos_attr:
+            qos_attr += port_range_attr
+        else:
+            qos_attr = port_range_attr
+        qos_attr_len += 6
+
+    if frame_classifier and frame_class_len:
+        tclas_attr = struct.pack('>BB%ds' % (len(frame_classifier),), 3,
+                                 len(frame_classifier), frame_classifier)
+        if qos_attr:
+            qos_attr += tclas_attr
+        else:
+            qos_attr = tclas_attr
+        qos_attr_len += 2 + len(frame_classifier)
+
+    if domain_name:
+        s = bytes(domain_name, 'utf-8')
+        domain_name_attr = struct.pack('>BB%ds' % (len(s),), 4, len(s), s)
+        if qos_attr:
+            qos_attr += domain_name_attr
+        else:
+            qos_attr = domain_name_attr
+        qos_attr_len += 2 + len(s)
+
+    qos_attr_len += 4
+    qos_ie = struct.pack('<BBL', qos_elem_id, qos_attr_len,
+                         qos_elem_oui_type) + qos_attr
+
+    return qos_ie
+
+def validate_dscp_req_event(dev, event):
+    ev = dev.wait_event(["CTRL-EVENT-DSCP-POLICY"], timeout=2)
+    if ev is None:
+        raise Exception("No DSCP request reported")
+    if ev != event:
+        raise Exception("Invalid DSCP event received (%s; expected: %s)" % (ev, event))
+
+def handle_dscp_query(hapd, query):
+    msg = hapd.mgmt_rx()
+    if msg['payload'] != query:
+        raise Exception("Invalid DSCP Query received at AP")
+
+def handle_dscp_response(hapd, response):
+    msg = hapd.mgmt_rx()
+    if msg['payload'] != response:
+        raise Exception("Invalid DSCP Response received at AP")
+
+def ap_sta_connectivity(dev, apdev, params):
+    p = hostapd.wpa2_params(passphrase="12345678")
+    p["wpa_key_mgmt"] = "WPA-PSK"
+    p["ieee80211w"] = "1"
+    p.update(params)
+    hapd = hostapd.add_ap(apdev[0], p)
+    register_dscp_req(hapd)
+
+    dev[0].request("SET enable_dscp_policy_capa 1")
+    dev[0].connect("dscp", psk="12345678", ieee80211w="1",
+                   key_mgmt="WPA-PSK WPA-PSK-SHA256", scan_freq="2412")
+    hapd.wait_sta()
+
+    hapd.dump_monitor()
+    hapd.set("ext_mgmt_frame_handling", "1")
+    return hapd
+
+def test_dscp_query(dev, apdev):
+    """DSCP Policy Query"""
+
+    # Positive tests
+    #AP with DSCP Capabilities
+    params = {"ssid": "dscp",
+              "ext_capa": 6*"00" + "40",
+              "assocresp_elements": "dd06506f9a230101",
+              "vendor_elements": "dd06506f9a230101"}
+
+    hapd = ap_sta_connectivity(dev, apdev, params)
+    da = dev[0].own_addr()
+
+    # Query 1
+    cmd = "DSCP_QUERY wildcard"
+    if "OK" not in dev[0].request(cmd):
+        raise Exception("Sending DSCP Query failed")
+    query = b'\x7e\x50\x6f\x9a\x1a\x00\x01'
+    handle_dscp_query(hapd, query)
+
+    # Query 2
+    cmd = "DSCP_QUERY domain_name=example.com"
+    if "OK" not in dev[0].request(cmd):
+        raise Exception("Sending DSCP Query failed")
+    query = b'\x7e\x50\x6f\x9a\x1a\x00\x02\xdd\x11\x50\x6f\x9a\x22\x04\x0b\x65\x78\x61\x6d\x70\x6c\x65\x2e\x63\x6f\x6d'
+    handle_dscp_query(hapd, query)
+
+    # Negative tests
+
+    cmd = "DSCP_QUERY domain_name=" + 250*'a' + ".example.com"
+    if "FAIL" not in dev[0].request(cmd):
+        raise Exception("Invalid DSCP_QUERY accepted")
+
+    dev[0].disconnect_and_stop_scan()
+    # AP without DSCP Capabilities
+    params = {"ssid": "dscp",
+              "ext_capa": 6*"00" + "40"}
+    hapd = ap_sta_connectivity(dev, apdev, params)
+
+    # Query 3
+    cmd = "DSCP_QUERY wildcard"
+    if "FAIL" not in dev[0].request(cmd):
+        raise Exception("Able to send invalid DSCP Query")
+
+def test_dscp_request(dev, apdev):
+    """DSCP Policy Request"""
+
+    # Positive tests
+
+    #AP with DSCP Capabilities
+    params = {"ssid": "dscp",
+              "ext_capa": 6*"00" + "40",
+              "assocresp_elements": "dd06506f9a230101",
+              "vendor_elements": "dd06506f9a230101"}
+
+    hapd = ap_sta_connectivity(dev, apdev, params)
+    da = dev[0].own_addr()
+
+    # Request 1
+    dialog_token = 5
+    send_dscp_req(hapd, da, 1, dialog_token, 2, 0)
+    event = "<3>CTRL-EVENT-DSCP-POLICY request_start clear_all"
+    validate_dscp_req_event(dev[0], event)
+    event = "<3>CTRL-EVENT-DSCP-POLICY request_end"
+    validate_dscp_req_event(dev[0], event)
+
+    # DSCP Request with multiple QoS IEs
+    # QoS IE 1
+    dialog_token = 1
+    domain_name = "example.com"
+    ipv4_src_addr = socket.inet_pton(socket.AF_INET, "192.168.0.1")
+    ipv4_dest_addr = socket.inet_pton(socket.AF_INET, "192.168.0.2")
+    frame_classifier_start = [4, 91, 4]
+    frame_classifier_end = [12, 34, 12, 34, 0, 17, 0]
+    frame_classifier = bytes(frame_classifier_start) + ipv4_src_addr + ipv4_dest_addr + bytes(frame_classifier_end)
+    frame_len = len(frame_classifier)
+    qos_ie = prepare_qos_ie(1, 0, 22, 0, 0, frame_classifier, frame_len, domain_name)
+
+    # QoS IE 2
+    ipv6_src_addr = socket.inet_pton(socket.AF_INET6, "aaaa:bbbb:cccc::1")
+    ipv6_dest_addr = socket.inet_pton(socket.AF_INET6, "aaaa:bbbb:cccc::2")
+    frame_classifier_start = [4, 79, 6]
+    frame_classifier_end = [0, 12, 34, 0, 0, 17, 0, 0, 0]
+    frame_classifier = bytes(frame_classifier_start) + ipv6_src_addr + ipv6_dest_addr + bytes(frame_classifier_end)
+    frame_len = len(frame_classifier)
+    ie = prepare_qos_ie(5, 0, 48, 12345, 23456, frame_classifier, frame_len,
+                        None)
+    qos_ie += ie
+
+    # QoS IE 3
+    ie = prepare_qos_ie(4, 0, 32, 12345, 23456, 0, 0, domain_name)
+    qos_ie += ie
+    send_dscp_req(hapd, da, 1, dialog_token, 0, qos_ie)
+
+    event = "<3>CTRL-EVENT-DSCP-POLICY request_start"
+    validate_dscp_req_event(dev[0], event)
+    event = "<3>CTRL-EVENT-DSCP-POLICY add policy_id=1 dscp=22 ip_version=4 src_ip=192.168.0.1 src_port=3106 dst_port=3106 protocol=17 domain_name=example.com"
+    validate_dscp_req_event(dev[0], event)
+    event = "<3>CTRL-EVENT-DSCP-POLICY add policy_id=5 dscp=48 ip_version=6 src_ip=aaaa:bbbb:cccc::1 dst_ip=aaaa:bbbb:cccc::2 src_port=12 protocol=17 start_port=12345 end_port=23456"
+    validate_dscp_req_event(dev[0], event)
+    event = "<3>CTRL-EVENT-DSCP-POLICY add policy_id=4 dscp=32 ip_version=0 start_port=12345 end_port=23456 domain_name=example.com"
+    validate_dscp_req_event(dev[0], event)
+    event = "<3>CTRL-EVENT-DSCP-POLICY request_end"
+    validate_dscp_req_event(dev[0], event)
+
+    # Negative Tests
+
+    # No DSCP policy attribute
+    dialog_token = 4
+    domain_name = "example.com"
+    qos_ie = prepare_qos_ie(0, 0, 0, 12345, 23456, frame_classifier, frame_len,
+                            domain_name)
+    send_dscp_req(hapd, da, 1, dialog_token, 0, qos_ie)
+    event = "<3>CTRL-EVENT-DSCP-POLICY request_start"
+    validate_dscp_req_event(dev[0], event)
+    event = "<3>CTRL-EVENT-DSCP-POLICY request_end"
+    validate_dscp_req_event(dev[0], event)
+
+    # No DSCP stream classifier params
+    dialog_token = 6
+    qos_ie = prepare_qos_ie(1, 0, 32, 0, 0, 0, 0, None)
+    send_dscp_req(hapd, da, 1, dialog_token, 0, qos_ie)
+    event = "<3>CTRL-EVENT-DSCP-POLICY request_start"
+    validate_dscp_req_event(dev[0], event)
+    event = "<3>CTRL-EVENT-DSCP-POLICY reject policy_id=1"
+    validate_dscp_req_event(dev[0], event)
+    event = "<3>CTRL-EVENT-DSCP-POLICY request_end"
+    validate_dscp_req_event(dev[0], event)
+
+    # DSCP request with both destination and domain name
+    dialog_token = 7
+    domain_name = "example.com"
+    ipv4_src_addr = socket.inet_pton(socket.AF_INET, "192.168.0.1")
+    ipv4_dest_addr = socket.inet_pton(socket.AF_INET, "192.168.0.2")
+    frame_classifier_start = [4, 69, 4]
+    frame_classifier_end = [0, 0, 0, 0, 0, 17, 0]
+    frame_classifier = bytes(frame_classifier_start) + ipv4_src_addr + ipv4_dest_addr + bytes(frame_classifier_end)
+    frame_len = len(frame_classifier)
+    qos_ie = prepare_qos_ie(1, 0, 36, 0, 0, frame_classifier, frame_len,
+                            domain_name)
+    send_dscp_req(hapd, da, 1, dialog_token, 0, qos_ie)
+    event  = "<3>CTRL-EVENT-DSCP-POLICY request_start"
+    validate_dscp_req_event(dev[0], event)
+    event = "<3>CTRL-EVENT-DSCP-POLICY reject policy_id=1"
+    validate_dscp_req_event(dev[0], event)
+    event = "<3>CTRL-EVENT-DSCP-POLICY request_end"
+    validate_dscp_req_event(dev[0], event)
+
+    # DSCP request with both port range and destination port
+    frame_classifier_start = [4, 81, 4]
+    frame_classifier_end = [0, 0, 23, 45, 0, 17, 0]
+    frame_classifier = bytes(frame_classifier_start) + ipv4_src_addr + ipv4_dest_addr + bytes(frame_classifier_end)
+    frame_len = len(frame_classifier)
+    qos_ie = prepare_qos_ie(1, 0, 36, 12345, 23456, frame_classifier, frame_len,
+                            None)
+    send_dscp_req(hapd, da, 1, dialog_token, 0, qos_ie)
+    event = "<3>CTRL-EVENT-DSCP-POLICY request_start"
+    validate_dscp_req_event(dev[0], event)
+    event = "<3>CTRL-EVENT-DSCP-POLICY reject policy_id=1"
+    validate_dscp_req_event(dev[0], event)
+    event = "<3>CTRL-EVENT-DSCP-POLICY request_end"
+    validate_dscp_req_event(dev[0], event)
+
+    # Too short DSCP Policy Request frame
+    dialog_token += 1
+    send_dscp_req(hapd, da, 1, dialog_token, 0, None, truncate=True)
+
+    # Request Type: Remove
+    dialog_token += 1
+    qos_ie = prepare_qos_ie(1, 1, 36)
+    send_dscp_req(hapd, da, 1, dialog_token, 0, qos_ie)
+    validate_dscp_req_event(dev[0], "<3>CTRL-EVENT-DSCP-POLICY request_start")
+    validate_dscp_req_event(dev[0],
+                            "<3>CTRL-EVENT-DSCP-POLICY remove policy_id=1")
+    validate_dscp_req_event(dev[0], "<3>CTRL-EVENT-DSCP-POLICY request_end")
+
+    # Request Type: Reserved
+    dialog_token += 1
+    qos_ie = prepare_qos_ie(1, 2, 36)
+    send_dscp_req(hapd, da, 1, dialog_token, 0, qos_ie)
+    validate_dscp_req_event(dev[0], "<3>CTRL-EVENT-DSCP-POLICY request_start")
+    validate_dscp_req_event(dev[0],
+                            "<3>CTRL-EVENT-DSCP-POLICY reject policy_id=1")
+    validate_dscp_req_event(dev[0], "<3>CTRL-EVENT-DSCP-POLICY request_end")
+
+def test_dscp_response(dev, apdev):
+    """DSCP Policy Response"""
+
+    # Positive tests
+
+    # AP with DSCP Capabilities
+    params = {"ssid": "dscp",
+              "ext_capa": 6*"00" + "40",
+              "assocresp_elements": "dd06506f9a230101",
+              "vendor_elements": "dd06506f9a230101"}
+    hapd = ap_sta_connectivity(dev, apdev, params)
+    da = dev[0].own_addr()
+
+    # Sending solicited DSCP response after receiving DSCP request
+    dialog_token = 1
+    domain_name = "example.com"
+    ipv4_src_addr = socket.inet_pton(socket.AF_INET, "192.168.0.1")
+    ipv4_dest_addr = socket.inet_pton(socket.AF_INET, "192.168.0.2")
+    frame_classifier_start = [4,91,4]
+    frame_classifier_end = [12,34,12,34,0,17,0]
+    frame_classifier = bytes(frame_classifier_start) + ipv4_src_addr + ipv4_dest_addr + bytes(frame_classifier_end)
+    frame_len = len(frame_classifier)
+    qos_ie = prepare_qos_ie(1, 0, 22, 0, 0, frame_classifier, frame_len,
+                            domain_name)
+    ie = prepare_qos_ie(4, 0, 32, 12345, 23456, 0, 0, domain_name)
+    qos_ie += ie
+    send_dscp_req(hapd, da, 1, dialog_token, 0, qos_ie)
+
+    cmd = "DSCP_RESP solicited policy_id=1 status=0 policy_id=4 status=0"
+    if "OK" not in dev[0].request(cmd):
+        raise Exception("Sending DSCP Response failed")
+    response = b'\x7e\x50\x6f\x9a\x1a\x02\x01\x00\x02\x01\x00\x04\x00'
+    handle_dscp_response(hapd, response)
+
+    # Unsolicited DSCP Response without status duples
+    cmd = "DSCP_RESP reset more"
+    if "OK" not in dev[0].request(cmd):
+        raise Exception("Sending DSCP Response failed")
+    response = b'\x7e\x50\x6f\x9a\x1a\x02\x00\x03\x00'
+    handle_dscp_response(hapd, response)
+
+    # Unsolicited DSCP Response with one status duple
+    cmd = "DSCP_RESP policy_id=2 status=0"
+    if "OK" not in dev[0].request(cmd):
+        raise Exception("Sending DSCP Response failed")
+    response = b'\x7e\x50\x6f\x9a\x1a\x02\x00\x00\x01\x02\x00'
+    handle_dscp_response(hapd, response)
+
+    # Negative tests
+
+    # Send solicited DSCP Response without prior DSCP request
+    cmd = "DSCP_RESP solicited policy_id=1 status=0 policy_id=5 status=0"
+    if "FAIL" not in dev[0].request(cmd):
+        raise Exception("Able to send invalid DSCP response")
+
+def test_dscp_unsolicited_req_at_assoc(dev, apdev):
+    """DSCP Policy and unsolicited request at association"""
+    params = {"ssid": "dscp",
+              "ext_capa": 6*"00" + "40",
+              "assocresp_elements": "dd06506f9a230103",
+              "vendor_elements": "dd06506f9a230103"}
+    hapd = ap_sta_connectivity(dev, apdev, params)
+    da = dev[0].own_addr()
+
+    dialog_token = 1
+    qos_ie = prepare_qos_ie(1, 0, 36, 12345, 23456)
+    send_dscp_req(hapd, da, 1, dialog_token, 0, qos_ie)
+    validate_dscp_req_event(dev[0], "<3>CTRL-EVENT-DSCP-POLICY request_start")
+    validate_dscp_req_event(dev[0], "<3>CTRL-EVENT-DSCP-POLICY add policy_id=1 dscp=36 ip_version=0 start_port=12345 end_port=23456")
+    validate_dscp_req_event(dev[0], "<3>CTRL-EVENT-DSCP-POLICY request_end")
+
+    cmd = "DSCP_QUERY wildcard"
+    if "OK" not in dev[0].request(cmd):
+        raise Exception("Sending DSCP Query failed")
+
+def test_dscp_missing_unsolicited_req_at_assoc(dev, apdev):
+    """DSCP Policy and missing unsolicited request at association"""
+    params = {"ssid": "dscp",
+              "ext_capa": 6*"00" + "40",
+              "assocresp_elements": "dd06506f9a230103",
+              "vendor_elements": "dd06506f9a230103"}
+    hapd = ap_sta_connectivity(dev, apdev, params)
+    da = dev[0].own_addr()
+
+    cmd = "DSCP_QUERY wildcard"
+    if "FAIL" not in dev[0].request(cmd):
+        raise Exception("DSCP_QUERY accepted during wait for unsolicited requesdt")
+    time.sleep(5)
+    validate_dscp_req_event(dev[0], "<3>CTRL-EVENT-DSCP-POLICY request_wait end")
+
+    cmd = "DSCP_QUERY wildcard"
+    if "OK" not in dev[0].request(cmd):
+        raise Exception("Sending DSCP Query failed")
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_eap_proto.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_eap_proto.py
index 7494b42..60d2e90 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_eap_proto.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_eap_proto.py
@@ -16,9 +16,8 @@
 import time
 
 import hostapd
-from utils import HwsimSkip, alloc_fail, fail_test, wait_fail_trigger
+from utils import *
 from test_ap_eap import check_eap_capa, check_hlr_auc_gw_support, int_eap_server_params
-from test_erp import check_erp_capa
 
 try:
     import OpenSSL
@@ -984,7 +983,7 @@
     # Unknown session
     # --> EAP-SAKE: Session ID mismatch
     sess, = struct.unpack('B', binascii.unhexlify(resp[20:22]))
-    sess = binascii.hexlify(struct.pack('B', sess + 1)).decode()
+    sess = binascii.hexlify(struct.pack('B', (sess + 1) % 256)).decode()
     msg = resp[0:4] + "0008" + resp[8:12] + "0008" + "3002" + sess + "00"
     tx_msg(dev[0], hapd, msg)
     # Unknown subtype
@@ -2870,10 +2869,10 @@
              (1, "os_get_random;eap_eke_dhcomp", None),
              (1, "aes_128_cbc_encrypt;eap_eke_dhcomp", None),
              (1, "aes_128_cbc_decrypt;eap_eke_shared_secret", None),
-             (1, "eap_eke_prf;eap_eke_shared_secret", None),
-             (1, "eap_eke_prfplus;eap_eke_derive_ke_ki", None),
-             (1, "eap_eke_prfplus;eap_eke_derive_ka", None),
-             (1, "eap_eke_prfplus;eap_eke_derive_msk", None),
+             (1, "hmac_sha256_vector;eap_eke_shared_secret", None),
+             (1, "eap_eke_prf_hmac_sha256;eap_eke_derive_ke_ki", None),
+             (1, "eap_eke_prf_hmac_sha256;eap_eke_derive_ka", None),
+             (1, "eap_eke_prf_hmac_sha256;eap_eke_derive_msk", None),
              (1, "os_get_random;eap_eke_prot", None),
              (1, "aes_128_cbc_decrypt;eap_eke_decrypt_prot", None),
              (1, "eap_eke_derive_key;eap_eke_process_commit", None),
@@ -5629,8 +5628,7 @@
     tests = [(1, "=eap_aka_learn_ids"),
              (2, "=eap_aka_learn_ids"),
              (1, "eap_sim_parse_encr;eap_aka_process_challenge"),
-             (1, "wpabuf_dup;eap_aka_add_id_msg"),
-             (1, "wpabuf_resize;eap_aka_add_id_msg"),
+             (1, "wpabuf_alloc;eap_aka_add_id_msg"),
              (1, "eap_aka_getKey"),
              (1, "eap_aka_get_emsk"),
              (1, "eap_aka_get_session_id")]
@@ -8160,7 +8158,6 @@
              (3, "crypto_bignum_init_set;compute_password_element"),
              (1, "crypto_bignum_to_bin;compute_password_element"),
              (1, "crypto_ec_point_compute_y_sqr;compute_password_element"),
-             (1, "crypto_ec_point_solve_y_coord;compute_password_element"),
              (1, "crypto_bignum_rand;compute_password_element"),
              (1, "crypto_bignum_sub;compute_password_element")]
     for count, func in funcs:
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_erp.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_erp.py
index 40fbf2b..50cec8d 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_erp.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_erp.py
@@ -11,15 +11,10 @@
 import time
 
 import hostapd
-from utils import HwsimSkip, alloc_fail, fail_test, wait_fail_trigger
-from test_ap_eap import int_eap_server_params
+from utils import *
+from test_ap_eap import int_eap_server_params, check_tls13_support
 from test_ap_psk import find_wpas_process, read_process_memory, verify_not_present, get_key_locations
 
-def check_erp_capa(dev):
-    capab = dev.get_capability("erp")
-    if not capab or 'ERP' not in capab:
-        raise HwsimSkip("ERP not supported in the build")
-
 def test_erp_initiate_reauth_start(dev, apdev):
     """Authenticator sending EAP-Initiate/Re-auth-Start, but ERP disabled on peer"""
     params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
@@ -334,9 +329,7 @@
 def test_erp_radius_eap_tls_v13(dev, apdev):
     """ERP enabled on RADIUS server and peer using EAP-TLS v1.3"""
     check_erp_capa(dev[0])
-    tls = dev[0].request("GET tls_library")
-    if "run=OpenSSL 1.1.1" not in tls:
-        raise HwsimSkip("No TLS v1.3 support in TLS library")
+    check_tls13_support(dev[0])
 
     eap_methods = dev[0].get_capability("eap")
     start_erp_as(tls13=True)
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ext_password.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ext_password.py
index dfaf3ea..789b673 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ext_password.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ext_password.py
@@ -7,6 +7,8 @@
 from remotehost import remote_compatible
 import logging
 logger = logging.getLogger()
+import os
+import tempfile
 
 import hostapd
 from utils import skip_with_fips
@@ -79,3 +81,32 @@
     dev[0].set_cred(id, "password", "ext:pw1")
     interworking_select(dev[0], bssid, freq="2412")
     interworking_connect(dev[0], bssid, "TTLS")
+
+def test_ext_password_file_psk(dev, apdev):
+    """External password (file) storage for PSK"""
+    params = hostapd.wpa2_params(ssid="ext-pw-psk", passphrase="12345678")
+    hostapd.add_ap(apdev[0], params)
+    fd, fn = tempfile.mkstemp()
+    with open(fn, "w") as f:
+        f.write("psk1=12345678\n")
+    os.close(fd)
+    dev[0].request("SET ext_password_backend file:%s" % fn)
+    dev[0].connect("ext-pw-psk", raw_psk="ext:psk1", scan_freq="2412")
+    for i in range(2):
+        dev[0].request("REMOVE_NETWORK all")
+        if i == 0:
+            dev[0].wait_disconnected()
+            dev[0].connect("ext-pw-psk", raw_psk="ext:psk2", scan_freq="2412",
+                           wait_connect=False)
+        else:
+            dev[0].connect("ext-pw-psk", raw_psk="ext:psk1", scan_freq="2412",
+                           wait_connect=False)
+        ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
+                                "EXT PW: No PSK found from external storage"],
+                               timeout=10)
+        if i == 0:
+            os.unlink(fn)
+        if ev is None:
+            raise Exception("No connection result reported")
+        if "CTRL-EVENT-CONNECTED" in ev:
+            raise Exception("Unexpected connection")
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_fils.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_fils.py
index 8e4df65..4dcbcf6 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_fils.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_fils.py
@@ -18,19 +18,9 @@
 from wpasupplicant import WpaSupplicant
 import hwsim_utils
 from utils import *
-from test_erp import check_erp_capa, start_erp_as
+from test_erp import start_erp_as
 from test_ap_hs20 import ip_checksum
 
-def check_fils_capa(dev):
-    capa = dev.get_capability("fils")
-    if capa is None or "FILS" not in capa:
-        raise HwsimSkip("FILS not supported")
-
-def check_fils_sk_pfs_capa(dev):
-    capa = dev.get_capability("fils")
-    if capa is None or "FILS-SK-PFS" not in capa:
-        raise HwsimSkip("FILS-SK-PFS not supported")
-
 def test_fils_sk_full_auth(dev, apdev, params):
     """FILS SK full authentication"""
     check_fils_capa(dev[0])
@@ -1430,10 +1420,10 @@
 
     tls = dev[0].request("GET tls_library")
     if int(group) in [25]:
-        if not (tls.startswith("OpenSSL") and ("build=OpenSSL 1.0.2" in tls or "build=OpenSSL 1.1" in tls) and ("run=OpenSSL 1.0.2" in tls or "run=OpenSSL 1.1" in tls)):
+        if not (tls.startswith("OpenSSL") and ("build=OpenSSL 1.0.2" in tls or "build=OpenSSL 1.1" in tls or "build=OpenSSL 3.0" in tls) and ("run=OpenSSL 1.0.2" in tls or "run=OpenSSL 1.1" in tls or "run=OpenSSL 3.0" in tls)):
             raise HwsimSkip("EC group not supported")
     if int(group) in [27, 28, 29, 30]:
-        if not (tls.startswith("OpenSSL") and ("build=OpenSSL 1.0.2" in tls or "build=OpenSSL 1.1" in tls) and ("run=OpenSSL 1.0.2" in tls or "run=OpenSSL 1.1" in tls)):
+        if not (tls.startswith("OpenSSL") and ("build=OpenSSL 1.0.2" in tls or "build=OpenSSL 1.1" in tls or "build=OpenSSL 3.0" in tls) and ("run=OpenSSL 1.0.2" in tls or "run=OpenSSL 1.1" in tls or "run=OpenSSL 3.0" in tls)):
             raise HwsimSkip("Brainpool EC group not supported")
 
     start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
@@ -1838,6 +1828,10 @@
 
 def run_fils_and_ft_over_air(dev, apdev, params, key_mgmt):
     hapd, hapd2 = run_fils_and_ft_setup(dev, apdev, params, key_mgmt)
+    conf = hapd.request("GET_CONFIG")
+    if "key_mgmt=" + key_mgmt not in conf.splitlines():
+        logger.info("GET_CONFIG:\n" + conf)
+        raise Exception("GET_CONFIG did not report correct key_mgmt")
 
     logger.info("FT protocol using FT key hierarchy established during FILS authentication")
     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412", force_scan=True)
@@ -2330,3 +2324,137 @@
         hwsim_utils.test_connectivity(dev[0], hapd)
     finally:
         dev[0].set("extended_key_id", "0")
+
+def test_fils_discovery_frame(dev, apdev, params):
+    """FILS Discovery frame generation"""
+    check_fils_capa(dev[0])
+    check_erp_capa(dev[0])
+
+    start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
+
+    bssid = apdev[0]['bssid']
+    params = hostapd.wpa2_eap_params(ssid="fils")
+    params['wpa_key_mgmt'] = "FILS-SHA256"
+    params['auth_server_port'] = "18128"
+    params['erp_send_reauth_start'] = '1'
+    params['erp_domain'] = 'example.com'
+    params['fils_realm'] = 'example.com'
+    params['wpa_group_rekey'] = '1'
+    params['fils_discovery_min_interval'] = '20'
+    params['fils_discovery_max_interval'] = '20'
+    hapd = hostapd.add_ap(apdev[0]['ifname'], params, no_enable=True)
+
+    if "OK" not in hapd.request("ENABLE"):
+        raise HwsimSkip("FILS Discovery frame transmission not supported")
+
+    ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=5)
+    if ev is None:
+        raise Exception("AP startup timed out")
+    if "AP-ENABLED" not in ev:
+        raise Exception("AP startup failed")
+
+    dev[0].request("ERP_FLUSH")
+    dev[0].connect("fils", key_mgmt="FILS-SHA256",
+                   eap="PSK", identity="psk.user@example.com",
+                   password_hex="0123456789abcdef0123456789abcdef",
+                   erp="1", scan_freq="2412")
+
+def test_fils_offload_to_driver(dev, apdev, params):
+    """FILS offload to driver"""
+    check_fils_capa(dev[0])
+    check_erp_capa(dev[0])
+    run_fils_offload_to_driver(dev[0], apdev, params)
+
+def test_fils_offload_to_driver2(dev, apdev, params):
+    """FILS offload to driver"""
+    wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
+    wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
+    run_fils_offload_to_driver(wpas, apdev, params)
+
+def run_fils_offload_to_driver(dev, apdev, params):
+    start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
+
+    bssid = apdev[0]['bssid']
+    params = hostapd.wpa2_eap_params(ssid="fils")
+    params['wpa_key_mgmt'] = "FILS-SHA256"
+    params['auth_server_port'] = "18128"
+    params['erp_send_reauth_start'] = '1'
+    params['erp_domain'] = 'example.com'
+    params['fils_realm'] = 'example.com'
+    params['disable_pmksa_caching'] = '1'
+    hapd = hostapd.add_ap(apdev[0]['ifname'], params)
+
+    dev.request("ERP_FLUSH")
+    id = dev.connect("fils", key_mgmt="FILS-SHA256",
+                     eap="PSK", identity="psk.user@example.com",
+                     password_hex="0123456789abcdef0123456789abcdef",
+                     erp="1", scan_freq="2412")
+
+    p = "freq=2412 authorized=1 fils_erp_next_seq_num=4"
+    if "OK" not in dev.request("DRIVER_EVENT ASSOC " + p):
+        raise Exception("DRIVER_EVENT ASSOC did not succeed")
+    dev.wait_connected()
+
+    dev.request("DISCONNECT")
+    dev.wait_disconnected()
+    dev.dump_monitor()
+
+    dev.select_network(id, freq=2412)
+    dev.wait_connected()
+    dev.dump_monitor()
+
+    # This does not really work properly with SME-in-wpa_supplicant case
+    p = "freq=2412 authorized=1 fils_erp_next_seq_num=4"
+    if "OK" not in dev.request("DRIVER_EVENT ASSOC " + p):
+        raise Exception("DRIVER_EVENT ASSOC did not succeed")
+
+    dev.wait_connected()
+
+def test_fils_sk_okc(dev, apdev, params):
+    """FILS SK and opportunistic key caching"""
+    check_fils_capa(dev[0])
+    check_erp_capa(dev[0])
+
+    start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
+
+    bssid = apdev[0]['bssid']
+    params = hostapd.wpa2_eap_params(ssid="fils")
+    params['wpa_key_mgmt'] = "FILS-SHA256"
+    params['okc'] = '1'
+    params['auth_server_port'] = "18128"
+    params['erp_domain'] = 'example.com'
+    params['fils_realm'] = 'example.com'
+    hapd = hostapd.add_ap(apdev[0]['ifname'], params)
+
+    dev[0].scan_for_bss(bssid, freq=2412)
+    dev[0].request("ERP_FLUSH")
+    id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
+                        eap="PSK", identity="psk.user@example.com",
+                        password_hex="0123456789abcdef0123456789abcdef",
+                        erp="1", okc=True, scan_freq="2412")
+    pmksa = dev[0].get_pmksa(bssid)
+    if pmksa is None:
+        raise Exception("No PMKSA cache entry created")
+    hapd.wait_sta()
+
+    hapd2 = hostapd.add_ap(apdev[1], params)
+    bssid2 = hapd2.own_addr()
+
+    dev[0].scan_for_bss(bssid2, freq=2412)
+    if "OK" not in dev[0].request("ROAM " + bssid2):
+        raise Exception("ROAM failed")
+    ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
+                            "CTRL-EVENT-CONNECTED"], timeout=10)
+    if ev is None:
+        raise Exception("Connection using OKC/PMKSA caching timed out")
+    if "CTRL-EVENT-EAP-STARTED" in ev:
+        raise Exception("Unexpected EAP exchange")
+    hapd2.wait_sta()
+    hwsim_utils.test_connectivity(dev[0], hapd2)
+    pmksa2 = dev[0].get_pmksa(bssid2)
+    if pmksa2 is None:
+        raise Exception("No PMKSA cache entry found")
+    if 'opportunistic' not in pmksa2 or pmksa2['opportunistic'] != '1':
+        raise Exception("OKC not indicated in PMKSA entry")
+    if pmksa['pmkid'] != pmksa2['pmkid']:
+        raise Exception("Unexpected PMKID change")
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_fst_config.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_fst_config.py
index 9813401..c28786d 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_fst_config.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_fst_config.py
@@ -111,7 +111,10 @@
         self.reg_ctrl = fst_test_common.HapdRegCtrl()
         self.test_is_supported()
 
-    def __del__(self):
+    def __enter__(self):
+        return self
+
+    def __exit__(self, type, value, traceback):
         self.cleanup()
 
     @staticmethod
@@ -269,7 +272,7 @@
     iel = [iehex[i:i + 2] for i in range(0, len(iehex), 2)]
     for i in range(0, len(iel)):
          iel[i] = int(iel[i], 16)
-    # Sanity check
+    # Validity check
     i = 0
     res = []
     while i < len(iel):
@@ -303,19 +306,19 @@
     0 - no errors discovered, an error otherwise. The function is used for
     simplek "bad configuration" tests."""
     logdir = test_params['logdir']
-    fst_launcher = FstLauncher(logdir)
-    ap1 = FstLauncherConfigAP(apdev[0]['ifname'], 'fst_goodconf', 'a',
-                              fst_test_common.fst_test_def_chan_a,
-                              fst_test_common.fst_test_def_group,
-                              fst_test_common.fst_test_def_prio_low,
-                              fst_test_common.fst_test_def_llt)
-    ap2 = FstLauncherConfigAP(apdev[1]['ifname'], 'fst_badconf', 'b',
-                              fst_test_common.fst_test_def_chan_g, fst_group,
-                              fst_pri, fst_llt)
-    fst_launcher.add_cfg(ap1)
-    fst_launcher.add_cfg(ap2)
-    res = fst_launcher.run_hostapd()
-    return res
+    with FstLauncher(logdir) as fst_launcher:
+        ap1 = FstLauncherConfigAP(apdev[0]['ifname'], 'fst_goodconf', 'a',
+                                  fst_test_common.fst_test_def_chan_a,
+                                  fst_test_common.fst_test_def_group,
+                                  fst_test_common.fst_test_def_prio_low,
+                                  fst_test_common.fst_test_def_llt)
+        ap2 = FstLauncherConfigAP(apdev[1]['ifname'], 'fst_badconf', 'b',
+                                  fst_test_common.fst_test_def_chan_g, fst_group,
+                                  fst_pri, fst_llt)
+        fst_launcher.add_cfg(ap1)
+        fst_launcher.add_cfg(ap2)
+        res = fst_launcher.run_hostapd()
+        return res
 
 def run_test_sta_configuration(test_params,
                                fst_group=fst_test_common.fst_test_def_group,
@@ -326,16 +329,16 @@
     the run: 0 - no errors discovered, an error otherwise. The function is used
     for simple "bad configuration" tests."""
     logdir = test_params['logdir']
-    fst_launcher = FstLauncher(logdir)
-    sta1 = FstLauncherConfigSTA('wlan5',
-                                fst_test_common.fst_test_def_group,
-                                fst_test_common.fst_test_def_prio_low,
-                                fst_test_common.fst_test_def_llt)
-    sta2 = FstLauncherConfigSTA('wlan6', fst_group, fst_pri, fst_llt)
-    fst_launcher.add_cfg(sta1)
-    fst_launcher.add_cfg(sta2)
-    res = fst_launcher.run_wpa_supplicant()
-    return res
+    with FstLauncher(logdir) as fst_launcher:
+        sta1 = FstLauncherConfigSTA('wlan5',
+                                    fst_test_common.fst_test_def_group,
+                                    fst_test_common.fst_test_def_prio_low,
+                                    fst_test_common.fst_test_def_llt)
+        sta2 = FstLauncherConfigSTA('wlan6', fst_group, fst_pri, fst_llt)
+        fst_launcher.add_cfg(sta1)
+        fst_launcher.add_cfg(sta2)
+        res = fst_launcher.run_wpa_supplicant()
+        return res
 
 def test_fst_ap_config_llt_neg(dev, apdev, test_params):
     """FST AP configuration negative LLT"""
@@ -481,21 +484,21 @@
     logdir = test_params['logdir']
 
     # Test valid MB IE in scan results
-    fst_launcher = FstLauncher(logdir)
-    ap1 = FstLauncherConfigAP(apdev[0]['ifname'], 'fst_11a', 'a',
-                              fst_test_common.fst_test_def_chan_a,
-                              fst_test_common.fst_test_def_group,
-                              fst_test_common.fst_test_def_prio_high)
-    ap2 = FstLauncherConfigAP(apdev[1]['ifname'], 'fst_11g', 'b',
-                              fst_test_common.fst_test_def_chan_g,
-                              fst_test_common.fst_test_def_group,
-                              fst_test_common.fst_test_def_prio_low)
-    fst_launcher.add_cfg(ap1)
-    fst_launcher.add_cfg(ap2)
-    res = fst_launcher.run_hostapd()
-    if res != 0:
-        raise Exception("hostapd didn't start properly")
-    try:
+    with FstLauncher(logdir) as fst_launcher:
+        ap1 = FstLauncherConfigAP(apdev[0]['ifname'], 'fst_11a', 'a',
+                                  fst_test_common.fst_test_def_chan_a,
+                                  fst_test_common.fst_test_def_group,
+                                  fst_test_common.fst_test_def_prio_high)
+        ap2 = FstLauncherConfigAP(apdev[1]['ifname'], 'fst_11g', 'b',
+                                  fst_test_common.fst_test_def_chan_g,
+                                  fst_test_common.fst_test_def_group,
+                                  fst_test_common.fst_test_def_prio_low)
+        fst_launcher.add_cfg(ap1)
+        fst_launcher.add_cfg(ap2)
+        res = fst_launcher.run_hostapd()
+        if res != 0:
+            raise Exception("hostapd didn't start properly")
+
         mbie1 = []
         flags1 = ''
         mbie2 = []
@@ -514,8 +517,6 @@
                 mbie2 = parse_ies(vals2['ie'], 0x9e)
             if 'flags' in vals2:
                 flags2 = vals2['flags']
-    finally:
-         fst_launcher.cleanup()
 
     if len(mbie1) == 0:
         raise Exception("No MB IE created by 1st AP")
@@ -527,16 +528,16 @@
     logdir = test_params['logdir']
 
     # Test valid MB IE in scan results
-    fst_launcher = FstLauncher(logdir)
-    ap1 = FstLauncherConfigAP(apdev[0]['ifname'], 'fst_11a', 'a',
-                              fst_test_common.fst_test_def_chan_a,
-                              fst_test_common.fst_test_def_group,
-                              fst_test_common.fst_test_def_prio_high)
-    fst_launcher.add_cfg(ap1)
-    res = fst_launcher.run_hostapd()
-    if res != 0:
-        raise Exception("Hostapd didn't start properly")
-    try:
+    with FstLauncher(logdir) as fst_launcher:
+        ap1 = FstLauncherConfigAP(apdev[0]['ifname'], 'fst_11a', 'a',
+                                  fst_test_common.fst_test_def_chan_a,
+                                  fst_test_common.fst_test_def_group,
+                                  fst_test_common.fst_test_def_prio_high)
+        fst_launcher.add_cfg(ap1)
+        res = fst_launcher.run_hostapd()
+        if res != 0:
+            raise Exception("Hostapd didn't start properly")
+
         time.sleep(2)
         mbie1 = []
         flags1 = ''
@@ -546,8 +547,6 @@
                 mbie1 = parse_ies(vals1['ie'], 0x9e)
             if 'flags' in vals1:
                 flags1 = vals1['flags']
-    finally:
-        fst_launcher.cleanup()
 
     if len(mbie1) != 0:
         raise Exception("MB IE exists with 1 AP")
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_hapd_ctrl.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_hapd_ctrl.py
index 0d8c10a..9cf8ac7 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_hapd_ctrl.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_hapd_ctrl.py
@@ -856,6 +856,7 @@
     tests = ["MGMT_TX 1",
              "MGMT_TX 1q",
              "MGMT_RX_PROCESS freq=2412",
+             "MGMT_TX_STATUS_PROCESS style=1 ok=0 buf=12345678",
              "EAPOL_RX foo",
              "EAPOL_RX 00:11:22:33:44:55 1",
              "EAPOL_RX 00:11:22:33:44:55 1q"]
@@ -873,7 +874,10 @@
     tests = ["MGMT_RX_PROCESS freq=2412",
              "MGMT_RX_PROCESS freq=2412 ssi_signal=0",
              "MGMT_RX_PROCESS freq=2412 frame=1",
-             "MGMT_RX_PROCESS freq=2412 frame=1q"]
+             "MGMT_RX_PROCESS freq=2412 frame=1q",
+             "MGMT_TX_STATUS_PROCESS style=1 ok=0",
+             "MGMT_TX_STATUS_PROCESS style=1 ok=0 buf=1234567",
+             "MGMT_TX_STATUS_PROCESS style=1 ok=0 buf=1234567q"]
     for t in tests:
         if "FAIL" not in hapd.request(t):
             raise Exception("Invalid command accepted: " + t)
@@ -907,6 +911,36 @@
         if "FAIL" not in hapd.request("DATA_TEST_FRAME 112233445566778899aabbccddeeff"):
             raise Exception("DATA_TEST_FRAME accepted during OOM")
 
+def test_hapd_ctrl_vendor_test(dev, apdev):
+    """hostapd and VENDOR test command"""
+    ssid = "hapd-ctrl"
+    params = {"ssid": ssid}
+    hapd = hostapd.add_ap(apdev[0], params)
+
+    OUI_QCA = 0x001374
+    QCA_NL80211_VENDOR_SUBCMD_TEST = 1
+    QCA_WLAN_VENDOR_ATTR_TEST = 8
+    attr = struct.pack("@HHI", 4 + 4, QCA_WLAN_VENDOR_ATTR_TEST, 123)
+    cmd = "VENDOR %x %d %s" % (OUI_QCA, QCA_NL80211_VENDOR_SUBCMD_TEST, binascii.hexlify(attr).decode())
+
+    res = hapd.request(cmd)
+    if "FAIL" in res:
+        raise Exception("VENDOR command failed")
+    val, = struct.unpack("@I", binascii.unhexlify(res))
+    if val != 125:
+        raise Exception("Incorrect response value")
+
+    res = hapd.request(cmd + " nested=1")
+    if "FAIL" in res:
+        raise Exception("VENDOR command failed")
+    val, = struct.unpack("@I", binascii.unhexlify(res))
+    if val != 125:
+        raise Exception("Incorrect response value")
+
+    res = hapd.request(cmd + " nested=0")
+    if "FAIL" not in res:
+        raise Exception("VENDOR command with invalid (not nested) data accepted")
+
 def test_hapd_ctrl_vendor_errors(dev, apdev):
     """hostapd and VENDOR errors"""
     ssid = "hapd-ctrl"
@@ -968,6 +1002,12 @@
         if "FAIL" not in hapd.request("UPDATE_BEACON"):
             raise Exception("UPDATE_BEACON succeeded unexpectedly")
     dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412")
+    dev[0].request("DISCONNECT")
+    if "OK" not in hapd.request("UPDATE_BEACON"):
+        raise Exception("UPDATE_BEACON failed")
+    hapd.disable()
+    if "FAIL" not in hapd.request("UPDATE_BEACON"):
+        raise Exception("UPDATE_BEACON did not indicate failure when disabled")
 
 def test_hapd_ctrl_test_fail(dev, apdev):
     """hostapd and TEST_ALLOC_FAIL/TEST_FAIL"""
@@ -980,3 +1020,58 @@
         raise Exception("TEST_ALLOC_FAIL clearing failed")
     if "OK" not in hapd.request("TEST_FAIL "):
         raise Exception("TEST_FAIL clearing failed")
+
+def test_hapd_ctrl_setband(dev, apdev):
+    """hostapd and setband"""
+    ssid = "hapd-ctrl"
+    params = {"ssid": ssid}
+    hapd = hostapd.add_ap(apdev[0], params)
+    # The actual setband driver operations are not supported without vendor
+    # commands, so only check minimal parsing items here.
+    if "FAIL" not in hapd.request("SET setband foo"):
+        raise Exception("Invalid setband value accepted")
+    vals = ["5G", "6G", "2G", "2G,6G", "2G,5G,6G", "AUTO"]
+    for val in vals:
+        if "OK" not in hapd.request("SET setband " + val):
+            raise Exception("SET setband %s failed" % val)
+
+def test_hapd_ctrl_get_capability(dev, apdev):
+    """hostapd GET_CAPABILITY"""
+    ssid = "hapd-ctrl"
+    params = {"ssid": ssid}
+    hapd = hostapd.add_ap(apdev[0], params)
+    if "FAIL" not in hapd.request("GET_CAPABILITY "):
+        raise Exception("Invalid GET_CAPABILITY accepted")
+    res = hapd.request("GET_CAPABILITY dpp")
+    logger.info("DPP capability: " + res)
+
+def test_hapd_ctrl_pmksa_add_failures(dev, apdev):
+    """hostapd PMKSA_ADD failures"""
+    ssid = "hapd-ctrl"
+    params = {"ssid": ssid}
+    hapd = hostapd.add_ap(apdev[0], params)
+    tests = ["q",
+             "22:22:22:22:22:22",
+             "22:22:22:22:22:22 q",
+             "22:22:22:22:22:22 " + 16*'00',
+             "22:22:22:22:22:22 " + 16*"00" + " " + 10*"00",
+             "22:22:22:22:22:22 " + 16*"00" + " q",
+             "22:22:22:22:22:22 " + 16*"00" + " " + 200*"00",
+             "22:22:22:22:22:22 " + 16*"00" + " " + 32*"00" + " 12345",
+             "22:22:22:22:22:22 " + 16*"00" + " " + 32*"00" + " 12345 1",
+             ""]
+    for t in tests:
+        if "FAIL" not in hapd.request("PMKSA_ADD " + t):
+            raise Exception("Invalid PMKSA_ADD accepted: " + t)
+
+def test_hapd_ctrl_attach_errors(dev, apdev):
+    """hostapd ATTACH errors"""
+    params = {"ssid": "hapd-ctrl"}
+    hapd = hostapd.add_ap(apdev[0], params)
+    hglobal = hostapd.HostapdGlobal(apdev[0])
+    with alloc_fail(hapd, 1, "ctrl_iface_attach"):
+        if "FAIL" not in hapd.request("ATTACH foo"):
+            raise Exception("Invalid ATTACH accepted")
+    with alloc_fail(hapd, 1, "ctrl_iface_attach"):
+        if "FAIL" not in hglobal.request("ATTACH foo"):
+            raise Exception("Invalid ATTACH accepted")
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_he.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_he.py
index 28123e8..43dfa5e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_he.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_he.py
@@ -24,8 +24,24 @@
               "he_mu_edca_ac_be_ecwmax": "15"}
     hapd = hostapd.add_ap(apdev[0], params)
     if hapd.get_status_field("ieee80211ax") != "1":
-        raise Exception("STATUS did not indicate ieee80211ac=1")
+        raise Exception("STATUS did not indicate ieee80211ax=1")
     dev[0].connect("he", key_mgmt="NONE", scan_freq="2412")
+    sta = hapd.get_sta(dev[0].own_addr())
+    if "[HE]" not in sta['flags']:
+        raise Exception("Missing STA flag: HE")
+
+def test_he_disabled_on_sta(dev, apdev):
+    """HE AP and HE disabled on STA"""
+    params = {"ssid": "he",
+              "ieee80211ax": "1",
+              "he_bss_color": "42",
+              "he_mu_edca_ac_be_ecwmin": "7",
+              "he_mu_edca_ac_be_ecwmax": "15"}
+    hapd = hostapd.add_ap(apdev[0], params)
+    dev[0].connect("he", key_mgmt="NONE", scan_freq="2412", disable_he="1")
+    sta = hapd.get_sta(dev[0].own_addr())
+    if "[HE]" in sta['flags']:
+        raise Exception("Unexpected STA flag: HE")
 
 def test_he_params(dev, apdev):
     """HE AP parameters"""
@@ -67,12 +83,36 @@
               "he_spr_non_srg_obss_pd_max_offset": "0",
               "he_spr_srg_obss_pd_min_offset": "0",
               "he_spr_srg_obss_pd_max_offset": "0",
+              "he_spr_srg_bss_colors": "1 2 10 63",
+              "he_spr_srg_partial_bssid": "0 1 3 63",
+              "he_6ghz_max_ampdu_len_exp": "7",
+              "he_6ghz_rx_ant_pat": "1",
+              "he_6ghz_tx_ant_pat": "1",
+              "he_6ghz_max_mpdu": "2",
               "he_oper_chwidth": "0",
               "he_oper_centr_freq_seg0_idx": "1",
               "he_oper_centr_freq_seg1_idx": "0"}
     hapd = hostapd.add_ap(apdev[0], params)
     if hapd.get_status_field("ieee80211ax") != "1":
-        raise Exception("STATUS did not indicate ieee80211ac=1")
+        raise Exception("STATUS did not indicate ieee80211ax=1")
+    dev[0].connect("he", key_mgmt="NONE", scan_freq="2412")
+
+def test_he_spr_params(dev, apdev):
+    """HE AP spatial reuse parameters"""
+    params = {"ssid": "he",
+              "ieee80211ax": "1",
+              "he_spr_sr_control": "12",
+              "he_spr_non_srg_obss_pd_max_offset": "1",
+              "he_spr_srg_obss_pd_min_offset": "2",
+              "he_spr_srg_obss_pd_max_offset": "3",
+              "he_spr_srg_bss_colors": "1 2 10 63",
+              "he_spr_srg_partial_bssid": "0 1 3 63",
+              "he_oper_chwidth": "0",
+              "he_oper_centr_freq_seg0_idx": "1",
+              "he_oper_centr_freq_seg1_idx": "0"}
+    hapd = hostapd.add_ap(apdev[0], params)
+    if hapd.get_status_field("ieee80211ax") != "1":
+        raise Exception("STATUS did not indicate ieee80211ax=1")
     dev[0].connect("he", key_mgmt="NONE", scan_freq="2412")
 
 def he_supported():
@@ -110,7 +150,7 @@
         if "WIDTH=80 MHz" not in sig:
             raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
         est = dev[0].get_bss(bssid)['est_throughput']
-        if est != "390001":
+        if est != "600502":
             raise Exception("Unexpected BSS est_throughput: " + est)
         status = dev[0].get_status()
         if status["ieee80211ac"] != "1":
@@ -154,27 +194,19 @@
         dev[0].request("DISCONNECT")
         clear_regdom(hapd, dev)
 
-def test_he_wifi_generation(dev, apdev):
+def _test_he_wifi_generation(dev, apdev, conf, scan_freq):
     """HE and wifi_generation"""
     try:
         hapd = None
         params = {"ssid": "he",
                   "country_code": "FI",
-                  "hw_mode": "a",
-                  "channel": "36",
-                  "ht_capab": "[HT40+]",
                   "ieee80211n": "1",
-                  "ieee80211ac": "1",
-                  "ieee80211ax": "1",
-                  "vht_oper_chwidth": "1",
-                  "vht_capab": "[MAX-MPDU-11454]",
-                  "vht_oper_centr_freq_seg0_idx": "42",
-                  "he_oper_chwidth": "1",
-                  "he_oper_centr_freq_seg0_idx": "42"}
+                  "ieee80211ax": "1"}
+        params.update(conf)
         hapd = hostapd.add_ap(apdev[0], params)
         bssid = apdev[0]['bssid']
 
-        dev[0].connect("he", key_mgmt="NONE", scan_freq="5180")
+        dev[0].connect("he", key_mgmt="NONE", scan_freq=scan_freq)
         status = dev[0].get_status()
         if 'wifi_generation' not in status:
             # For now, assume this is because of missing kernel support
@@ -185,7 +217,7 @@
 
         wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
         wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
-        wpas.connect("he", key_mgmt="NONE", scan_freq="5180")
+        wpas.connect("he", key_mgmt="NONE", scan_freq=scan_freq)
         status = wpas.get_status()
         if 'wifi_generation' not in status:
             # For now, assume this is because of missing kernel support
@@ -202,6 +234,27 @@
         dev[0].request("DISCONNECT")
         clear_regdom(hapd, dev)
 
+def test_he_wifi_generation(dev, apdev):
+    conf = {
+        "vht_oper_chwidth": "1",
+        "hw_mode": "a",
+        "channel": "36",
+        "ht_capab": "[HT40+]",
+        "vht_oper_centr_freq_seg0_idx": "42",
+        "he_oper_chwidth": "1",
+        "he_oper_centr_freq_seg0_idx": "42",
+        "vht_capab": "[MAX-MPDU-11454]",
+        "ieee80211ac": "1",
+    }
+    _test_he_wifi_generation(dev, apdev, conf, "5180")
+
+def test_he_wifi_generation_24(dev, apdev):
+    conf = {
+        "hw_mode": "g",
+        "channel": "1",
+    }
+    _test_he_wifi_generation(dev, apdev, conf, "2412")
+
 def he80_test(apdev, dev, channel, ht_capab):
     clear_scan_cache(apdev)
     try:
@@ -439,6 +492,7 @@
                   'ieee80211d': '1',
                   'ieee80211h': '1'}
         hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
+        bssid = apdev[0]['bssid']
 
         ev = wait_dfs_event(hapd, "DFS-CAC-START", 5)
         if "DFS-CAC-START" not in ev:
@@ -477,6 +531,9 @@
             raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
         if "WIDTH=160 MHz" not in sig:
             raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
+        est = dev[0].get_bss(bssid)['est_throughput']
+        if est != "1201002":
+            raise Exception("Unexpected BSS est_throughput: " + est)
     except Exception as e:
         if isinstance(e, Exception) and str(e) == "AP startup failed":
             if not he_supported():
@@ -992,7 +1049,7 @@
             raise Exception("Unexpected STATUS ieee80211n value")
         if status["ieee80211ac"] != "0":
             raise Exception("Unexpected STATUS ieee80211ac value")
-        if status["ieee80211ax"] != "1":
+        if status["ieee80211ax"] != "0":
             raise Exception("Unexpected STATUS ieee80211ax value")
         if status["secondary_channel"] != "0":
             raise Exception("Unexpected STATUS secondary_channel value")
@@ -1075,3 +1132,90 @@
     finally:
         dev[0].request("DISCONNECT")
         clear_regdom(hapd, dev)
+
+def test_he_twt(dev, apdev):
+    """HE and TWT"""
+    params = {"ssid": "he",
+              "ieee80211ax": "1",
+              "he_bss_color": "42",
+              "he_twt_required":"1"}
+    hapd = hostapd.add_ap(apdev[0], params)
+
+    dev[0].connect("he", key_mgmt="NONE", scan_freq="2412")
+    if "OK" not in dev[0].request("TWT_SETUP"):
+        raise Exception("TWT_SETUP failed")
+    if "OK" not in dev[0].request("TWT_TEARDOWN"):
+        raise Exception("TWT_SETUP failed")
+    if "OK" not in dev[0].request("TWT_SETUP dialog=123 exponent=9 mantissa=10 min_twt=254 setup_cmd=1 twt=1234567890 requestor=1 trigger=0 implicit=0 flow_type=0 flow_id=2 protection=1 twt_channel=3 control=16"):
+        raise Exception("TWT_SETUP failed")
+    if "OK" not in dev[0].request("TWT_TEARDOWN flags=255"):
+        raise Exception("TWT_SETUP failed")
+
+def test_he_6ghz_security(dev, apdev):
+    """HE AP and 6 GHz security parameter validation"""
+    params = {"ssid": "he",
+              "ieee80211ax": "1",
+              "op_class": "131",
+              "channel": "1"}
+    hapd = hostapd.add_ap(apdev[0], params, no_enable=True)
+
+    # Pre-RSNA security methods are not allowed in 6 GHz
+    if "FAIL" not in hapd.request("ENABLE"):
+        raise Exception("Invalid configuration accepted(1)")
+
+    # Management frame protection is required in 6 GHz"
+    hapd.set("wpa", "2")
+    hapd.set("wpa_passphrase", "12345678")
+    hapd.set("wpa_key_mgmt", "SAE")
+    hapd.set("rsn_pairwise", "CCMP")
+    hapd.set("ieee80211w", "1")
+    if "FAIL" not in hapd.request("ENABLE"):
+        raise Exception("Invalid configuration accepted(2)")
+
+    # Invalid AKM suite for 6 GHz
+    hapd.set("ieee80211w", "2")
+    hapd.set("wpa_key_mgmt", "SAE WPA-PSK")
+    if "FAIL" not in hapd.request("ENABLE"):
+        raise Exception("Invalid configuration accepted(3)")
+
+    # Invalid pairwise cipher suite for 6 GHz
+    hapd.set("wpa_key_mgmt", "SAE")
+    hapd.set("rsn_pairwise", "CCMP TKIP")
+    if "FAIL" not in hapd.request("ENABLE"):
+        raise Exception("Invalid configuration accepted(4)")
+
+    # Invalid group cipher suite for 6 GHz
+    hapd.set("wpa_key_mgmt", "SAE")
+    hapd.set("rsn_pairwise", "CCMP")
+    hapd.set("group_cipher", "TKIP")
+    if "FAIL" not in hapd.request("ENABLE"):
+        raise Exception("Invalid configuration accepted(5)")
+
+def test_he_prefer_he20(dev, apdev):
+    """Preference on HE20 over HT20"""
+    params = {"ssid": "he",
+              "channel": "1",
+              "ieee80211ax": "0",
+              "ieee80211n": "1"}
+    hapd = hostapd.add_ap(apdev[0], params)
+    bssid = apdev[0]['bssid']
+    params = {"ssid": "test",
+              "channel": "1",
+              "ieee80211ax": "1",
+              "ieee80211n": "1"}
+    hapd2 = hostapd.add_ap(apdev[1], params)
+    bssid2 = apdev[1]['bssid']
+
+    dev[0].scan_for_bss(bssid, freq=2412)
+    dev[0].scan_for_bss(bssid2, freq=2412)
+    dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
+    if dev[0].get_status_field('bssid') != bssid2:
+        raise Exception("Unexpected BSS selected")
+
+    est = dev[0].get_bss(bssid)['est_throughput']
+    if est != "65000":
+        raise Exception("Unexpected BSS0 est_throughput: " + est)
+
+    est = dev[0].get_bss(bssid2)['est_throughput']
+    if est != "143402":
+        raise Exception("Unexpected BSS1 est_throughput: " + est)
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ieee8021x.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ieee8021x.py
index 89c282b..630d6d0 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ieee8021x.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ieee8021x.py
@@ -245,6 +245,23 @@
         dev[0].request("SET EAPOL::maxStart 3")
         dev[0].request("SET EAPOL::heldPeriod 60")
 
+def test_ieee8021x_force_unauth(dev, apdev):
+    """IEEE 802.1X and FORCE_UNAUTH state"""
+    params = hostapd.radius_params()
+    params["ssid"] = "ieee8021x-open"
+    params["ieee8021x"] = "1"
+    hapd = hostapd.add_ap(apdev[0], params)
+    bssid = apdev[0]['bssid']
+
+    dev[0].connect("ieee8021x-open", key_mgmt="IEEE8021X", eapol_flags="0",
+                   eap="PSK", identity="psk.user@example.com",
+                   password_hex="0123456789abcdef0123456789abcdef",
+                   scan_freq="2412")
+    dev[0].request("SET EAPOL::portControl ForceUnauthorized")
+    pae = dev[0].get_status_field('Supplicant PAE state')
+    dev[0].wait_disconnected()
+    dev[0].request("SET EAPOL::portControl Auto")
+
 def send_eapol_key(dev, bssid, signkey, frame_start, frame_end):
     zero_sign = "00000000000000000000000000000000"
     frame = frame_start + zero_sign + frame_end
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_mbo.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_mbo.py
index 65d446b..d4426ac 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_mbo.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_mbo.py
@@ -203,8 +203,8 @@
     hapd2 = hostapd.add_ap(apdev[1], {"ssid": "MBO", "mbo": "1"})
 
     logger.debug("Set mbo_assoc_disallow with invalid value")
-    if "FAIL" not in hapd1.request("SET mbo_assoc_disallow 2"):
-        raise Exception("Set mbo_assoc_disallow for AP1 succeeded unexpectedly with value 2")
+    if "FAIL" not in hapd1.request("SET mbo_assoc_disallow 6"):
+        raise Exception("Set mbo_assoc_disallow for AP1 succeeded unexpectedly with value 6")
 
     logger.debug("Disallow associations to AP1 and allow association to AP2")
     if "OK" not in hapd1.request("SET mbo_assoc_disallow 1"):
@@ -543,15 +543,32 @@
 def test_mbo_without_pmf_workaround(dev, apdev):
     """MBO and WPA2 without PMF on misbehaving AP"""
     ssid = "test-wnm-mbo"
-    params = {'ssid': ssid, "wpa": '2',
-              "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
-              "wpa_passphrase": "12345678",
-              "vendor_elements": "dd07506f9a16010100"}
-    hapd = hostapd.add_ap(apdev[0], params)
+    params0 = {'ssid': ssid, "wpa": '2',
+               "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
+               "wpa_passphrase": "12345678",
+               "vendor_elements": "dd07506f9a16010100"}
+    params1 = {'ssid': ssid, "mbo": '1', "wpa": '2',
+               "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
+               "wpa_passphrase": "12345678", "ieee80211w": "1"}
+    hapd0 = hostapd.add_ap(apdev[0], params0)
     dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK",
                    proto="WPA2", ieee80211w="1", scan_freq="2412")
-    hapd.wait_sta()
-    sta = hapd.get_sta(dev[0].own_addr())
+    hapd0.wait_sta()
+    sta = hapd0.get_sta(dev[0].own_addr())
+    ext_capab = bytearray(binascii.unhexlify(sta['ext_capab']))
+    if ext_capab[2] & 0x08:
+        raise Exception("STA did not disable BSS Transition capability")
+    hapd1 = hostapd.add_ap(apdev[1], params1)
+    dev[0].scan_for_bss(hapd1.own_addr(), 2412, force_scan=True)
+    dev[0].roam(hapd1.own_addr())
+    hapd1.wait_sta()
+    sta = hapd1.get_sta(dev[0].own_addr())
+    ext_capab = bytearray(binascii.unhexlify(sta['ext_capab']))
+    if not ext_capab[2] & 0x08:
+        raise Exception("STA disabled BSS Transition capability")
+    dev[0].roam(hapd0.own_addr())
+    hapd0.wait_sta()
+    sta = hapd0.get_sta(dev[0].own_addr())
     ext_capab = bytearray(binascii.unhexlify(sta['ext_capab']))
     if ext_capab[2] & 0x08:
         raise Exception("STA did not disable BSS Transition capability")
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_mscs.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_mscs.py
new file mode 100755
index 0000000..b200550
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_mscs.py
@@ -0,0 +1,231 @@
+# Test cases for MSCS
+# Copyright (c) 2021, Jouni Malinen <j@w1.fi>
+#
+# This software may be distributed under the terms of the BSD license.
+# See README for more details.
+
+import struct
+import time
+
+import hostapd
+from utils import *
+
+def register_mcsc_req(hapd):
+    type = 0x00d0
+    match = "1304"
+    if "OK" not in hapd.request("REGISTER_FRAME %04x %s" % (type, match)):
+        raise Exception("Could not register frame reception for Robust AV Streaming")
+
+def handle_mscs_req(hapd, wrong_dialog=False, status_code=0):
+    msg = hapd.mgmt_rx()
+    if msg['subtype'] != 13:
+        logger.info("RX:" + str(msg))
+        raise Exception("Received unexpected Management frame")
+    categ, act, dialog_token = struct.unpack('BBB', msg['payload'][0:3])
+    if categ != 19 or act != 4:
+        logger.info("RX:" + str(msg))
+        raise Exception("Received unexpected Action frame")
+
+    if wrong_dialog:
+        dialog_token = (dialog_token + 1) % 256
+    msg['da'] = msg['sa']
+    msg['sa'] = hapd.own_addr()
+    msg['payload'] = struct.pack('<BBBH', 19, 5, dialog_token, status_code)
+    hapd.mgmt_tx(msg)
+    ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
+    if ev is None or "stype=13 ok=1" not in ev:
+        raise Exception("No TX status reported")
+
+def wait_mscs_result(dev, expect_status=0):
+    ev = dev.wait_event(["CTRL-EVENT-MSCS-RESULT"], timeout=1)
+    if ev is None:
+        raise Exception("No MSCS result reported")
+    if "status_code=%d" % expect_status not in ev:
+        raise Exception("Unexpected MSCS result: " + ev)
+
+def test_mscs_invalid_params(dev, apdev):
+    """MSCS command invalid parameters"""
+    tests = ["",
+             "add Xp_bitmap=F0 up_limit=7 stream_timeout=12345 frame_classifier=045F",
+             "add up_bitmap=F0 Xp_limit=7 stream_timeout=12345 frame_classifier=045F",
+             "add up_bitmap=F0 up_limit=7 Xtream_timeout=12345 frame_classifier=045F",
+             "add up_bitmap=F0 up_limit=7 stream_timeout=12345 Xrame_classifier=045F",
+             "add up_bitmap=X0 up_limit=7 stream_timeout=12345 frame_classifier=045F",
+             "add up_bitmap=F0 up_limit=7 stream_timeout=0 frame_classifier=045F",
+             "add up_bitmap=F0 up_limit=7 stream_timeout=12345 frame_classifier=X45F",
+             "change "]
+    for t in tests:
+        if "FAIL" not in dev[0].request("MSCS " + t):
+            raise Exception("Invalid MSCS parameters accepted: " + t)
+
+def test_mscs_without_ap_support(dev, apdev):
+    """MSCS without AP support"""
+    try:
+        run_mscs_without_ap_support(dev, apdev)
+    finally:
+        dev[0].request("MSCS remove")
+
+def run_mscs_without_ap_support(dev, apdev):
+    params = {"ssid": "mscs",
+              "ext_capa_mask": 10*"00" + "20"}
+    hapd = hostapd.add_ap(apdev[0], params)
+
+    cmd = "MSCS add up_bitmap=F0 up_limit=7 stream_timeout=12345 frame_classifier=045F"
+    if "OK" not in dev[0].request(cmd):
+        raise Exception("Failed to configure MSCS")
+
+    dev[0].connect("mscs", key_mgmt="NONE", scan_freq="2412")
+
+    cmd = "MSCS change up_bitmap=F0 up_limit=7 stream_timeout=12345 frame_classifier=045F"
+    if "FAIL" not in dev[0].request(cmd):
+        raise Exception("MSCS change accepted unexpectedly")
+
+    cmd = "MSCS add up_bitmap=F0 up_limit=7 stream_timeout=12345 frame_classifier=045F"
+    if "FAIL" not in dev[0].request(cmd):
+        raise Exception("MSCS add accepted unexpectedly")
+
+def test_mscs_post_assoc(dev, apdev):
+    """MSCS configuration post-association"""
+    try:
+        run_mscs_post_assoc(dev, apdev)
+    finally:
+        dev[0].request("MSCS remove")
+
+def run_mscs_post_assoc(dev, apdev):
+    params = {"ssid": "mscs",
+              "ext_capa": 10*"00" + "20"}
+    hapd = hostapd.add_ap(apdev[0], params)
+    register_mcsc_req(hapd)
+
+    dev[0].connect("mscs", key_mgmt="NONE", scan_freq="2412")
+
+    hapd.dump_monitor()
+    hapd.set("ext_mgmt_frame_handling", "1")
+
+    cmd = "MSCS change up_bitmap=F0 up_limit=7 stream_timeout=12345 frame_classifier=045F"
+    if "FAIL" not in dev[0].request(cmd):
+        raise Exception("MSCS change accepted unexpectedly")
+
+    cmd = "MSCS add up_bitmap=F0 up_limit=7 stream_timeout=12345 frame_classifier=045F"
+    if "OK" not in dev[0].request(cmd):
+        raise Exception("MSCS add failed")
+
+    handle_mscs_req(hapd)
+    wait_mscs_result(dev[0])
+
+    cmd = "MSCS change up_bitmap=F0 up_limit=7 stream_timeout=12345 frame_classifier=045F"
+    if "OK" not in dev[0].request(cmd):
+        raise Exception("MSCS change failed")
+
+    handle_mscs_req(hapd)
+    wait_mscs_result(dev[0])
+
+    cmd = "MSCS change up_bitmap=F0 up_limit=7 stream_timeout=12345 frame_classifier=045F"
+    if "OK" not in dev[0].request(cmd):
+        raise Exception("MSCS change failed")
+
+    handle_mscs_req(hapd, status_code=23456)
+    wait_mscs_result(dev[0], expect_status=23456)
+
+def test_mscs_pre_assoc(dev, apdev):
+    """MSCS configuration pre-association"""
+    try:
+        run_mscs_pre_assoc(dev, apdev)
+    finally:
+        dev[0].request("MSCS remove")
+
+def run_mscs_pre_assoc(dev, apdev):
+    params = {"ssid": "mscs",
+              "ext_capa": 10*"00" + "20",
+              "assocresp_elements": "ff0c5800000000000000" + "01020000"}
+    hapd = hostapd.add_ap(apdev[0], params)
+    register_mcsc_req(hapd)
+
+    cmd = "MSCS add up_bitmap=F0 up_limit=7 stream_timeout=12345 frame_classifier=045F"
+    if "OK" not in dev[0].request(cmd):
+        raise Exception("MSCS add failed")
+
+    dev[0].connect("mscs", key_mgmt="NONE", scan_freq="2412",
+                   wait_connect=False)
+    wait_mscs_result(dev[0])
+    dev[0].wait_connected()
+
+    hapd.set("ext_mgmt_frame_handling", "1")
+
+    cmd = "MSCS change up_bitmap=F0 up_limit=7 stream_timeout=12345 frame_classifier=045F"
+    if "OK" not in dev[0].request(cmd):
+        raise Exception("MSCS change failed")
+
+    handle_mscs_req(hapd)
+    wait_mscs_result(dev[0])
+
+    cmd = "MSCS change up_bitmap=F0 up_limit=7 stream_timeout=12345 frame_classifier=045F"
+    if "OK" not in dev[0].request(cmd):
+        raise Exception("MSCS change failed")
+
+    handle_mscs_req(hapd, wrong_dialog=True)
+
+    ev = dev[0].wait_event(["CTRL-EVENT-MSCS-RESULT"], timeout=1)
+    if ev is not None:
+        raise Exception("Unexpected MSCS result reported")
+
+def test_mscs_assoc_failure(dev, apdev):
+    """MSCS configuration failure during association exchange"""
+    try:
+        run_mscs_assoc_failure(dev, apdev)
+    finally:
+        dev[0].request("MSCS remove")
+
+def run_mscs_assoc_failure(dev, apdev):
+    params = {"ssid": "mscs",
+              "ext_capa": 10*"00" + "20",
+              "assocresp_elements": "ff0c5800000000000000" + "01020001"}
+    hapd = hostapd.add_ap(apdev[0], params)
+    register_mcsc_req(hapd)
+
+    cmd = "MSCS add up_bitmap=F0 up_limit=7 stream_timeout=12345 frame_classifier=045F"
+    if "OK" not in dev[0].request(cmd):
+        raise Exception("MSCS add failed")
+
+    dev[0].connect("mscs", key_mgmt="NONE", scan_freq="2412",
+                   wait_connect=False)
+    wait_mscs_result(dev[0], expect_status=256)
+    dev[0].wait_connected()
+    dev[0].request("REMOVE_NETWORK all")
+    dev[0].wait_disconnected()
+
+    hapd.dump_monitor()
+    # No MSCS Status subelement
+    hapd.set("assocresp_elements", "ff085800000000000000")
+    dev[0].connect("mscs", key_mgmt="NONE", scan_freq="2412",
+                   wait_connect=False)
+    ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", "CTRL-EVENT-MSCS-RESULT"],
+                           timeout=10)
+    if ev is None:
+        raise Exception("No connection event")
+    if "CTRL-EVENT-MSCS-RESULT" in ev:
+        raise Exception("Unexpected MSCS result")
+
+def test_mscs_local_errors(dev, apdev):
+    """MSCS configuration local errors"""
+    try:
+        run_mscs_local_errors(dev, apdev)
+    finally:
+        dev[0].request("MSCS remove")
+
+def run_mscs_local_errors(dev, apdev):
+    params = {"ssid": "mscs",
+              "ext_capa": 10*"00" + "20"}
+    hapd = hostapd.add_ap(apdev[0], params)
+    register_mcsc_req(hapd)
+
+    dev[0].connect("mscs", key_mgmt="NONE", scan_freq="2412")
+
+    hapd.dump_monitor()
+    hapd.set("ext_mgmt_frame_handling", "1")
+
+    for count in range(1, 3):
+        with alloc_fail(dev[0], count, "wpas_send_mscs_req"):
+            cmd = "MSCS add up_bitmap=F0 up_limit=7 stream_timeout=12345 frame_classifier=045F"
+            if "FAIL" not in dev[0].request(cmd):
+                raise Exception("MSCS add succeeded in error case")
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_multi_ap.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_multi_ap.py
index 4070d3e..99db14e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_multi_ap.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_multi_ap.py
@@ -5,6 +5,7 @@
 # See README for more details.
 
 import hostapd
+from wpasupplicant import WpaSupplicant
 from utils import *
 
 def test_multi_ap_association(dev, apdev):
@@ -38,6 +39,42 @@
     dev[0].connect("multi-ap", psk="12345678", scan_freq="2412",
                    multi_ap_backhaul_sta="1", wait_connect=wait_connect)
 
+def test_multi_ap_backhaul_roam_with_bridge(dev, apdev):
+    """Multi-AP backhaul BSS reassociation to another BSS with bridge"""
+    br_ifname = 'sta-br0'
+    ifname = 'wlan5'
+    try:
+        run_multi_ap_backhaul_roam_with_bridge(dev, apdev)
+    finally:
+        subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'down'])
+        subprocess.call(['brctl', 'delif', br_ifname, ifname])
+        subprocess.call(['brctl', 'delbr', br_ifname])
+        subprocess.call(['iw', ifname, 'set', '4addr', 'off'])
+
+def run_multi_ap_backhaul_roam_with_bridge(dev, apdev):
+    br_ifname = 'sta-br0'
+    ifname = 'wlan5'
+    wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
+    subprocess.call(['brctl', 'addbr', br_ifname])
+    subprocess.call(['brctl', 'setfd', br_ifname, '0'])
+    subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'up'])
+    subprocess.call(['iw', ifname, 'set', '4addr', 'on'])
+    subprocess.check_call(['brctl', 'addif', br_ifname, ifname])
+    wpas.interface_add(ifname, br_ifname=br_ifname)
+    wpas.flush_scan_cache()
+
+    params = hostapd.wpa2_params(ssid="multi-ap", passphrase="12345678")
+    params["multi_ap"] = "1"
+    hapd = hostapd.add_ap(apdev[0], params)
+
+    wpas.connect("multi-ap", psk="12345678", scan_freq="2412",
+                 multi_ap_backhaul_sta="1")
+
+    hapd2 = hostapd.add_ap(apdev[1], params)
+    bssid2 = hapd2.own_addr()
+    wpas.scan_for_bss(bssid2, freq="2412", force_scan=True)
+    wpas.roam(bssid2)
+
 def test_multi_ap_disabled_on_ap(dev, apdev):
     """Multi-AP association attempt when disabled on AP"""
     run_multi_ap_association(dev, apdev, 0, wait_connect=False)
@@ -63,7 +100,13 @@
     if "CTRL-EVENT-DISCONNECTED" not in ev:
         raise Exception("Unexpected connection result")
 
-def run_multi_ap_wps(dev, apdev, params, multi_ap_bssid=None):
+def remove_apdev(dev, ifname):
+    hglobal = hostapd.HostapdGlobal()
+    hglobal.remove(ifname)
+    dev.cmd_execute(['iw', ifname, 'del'])
+
+def run_multi_ap_wps(dev, apdev, params, params_backhaul=None, add_apdev=False,
+                     run_csa=False, allow_csa_fail=False):
     """Helper for running Multi-AP WPS tests
 
     dev[0] does multi_ap WPS, dev[1] does normal WPS. apdev[0] is the fronthaul
@@ -72,12 +115,33 @@
     the WPS parameters. multi_ap_bssid must be given if it is not equal to the
     fronthaul BSSID."""
 
-    if multi_ap_bssid is None:
+    wpas_apdev = None
+
+    if params_backhaul:
+        hapd_backhaul = hostapd.add_ap(apdev[1], params_backhaul)
+        multi_ap_bssid =  hapd_backhaul.own_addr()
+    else:
         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)
+    conf = hapd.request("GET_CONFIG").splitlines()
+    if "ssid=" + params['ssid'] not in conf:
+        raise Exception("GET_CONFIG did not show correct ssid entry")
+    if "multi_ap" in params and \
+       "multi_ap=" + params["multi_ap"] not in conf:
+        raise Exception("GET_CONFIG did not show correct multi_ap entry")
+    if "multi_ap_backhaul_ssid" in params and \
+       "multi_ap_backhaul_ssid=" + params["multi_ap_backhaul_ssid"].strip('"') not in conf:
+        raise Exception("GET_CONFIG did not show correct multi_ap_backhaul_ssid entry")
+    if "wpa" in params and "multi_ap_backhaul_wpa_passphrase" in params and \
+       "multi_ap_backhaul_wpa_passphrase=" + params["multi_ap_backhaul_wpa_passphrase"] not in conf:
+        raise Exception("GET_CONFIG did not show correct multi_ap_backhaul_wpa_passphrase entry")
+    if "multi_ap_backhaul_wpa_psk" in params and \
+       "multi_ap_backhaul_wpa_psk=" + params["multi_ap_backhaul_wpa_psk"] not in conf:
+        raise Exception("GET_CONFIG did not show correct multi_ap_backhaul_wpa_psk entry")
     hapd.request("WPS_PBC")
     if "PBC Status: Active" not in hapd.request("WPS_GET_STATUS"):
         raise Exception("PBC status not shown correctly")
@@ -130,6 +194,44 @@
     if len(dev[1].list_networks()) != 1:
         raise Exception("Unexpected number of network blocks")
 
+    try:
+        # Add apdev to the same phy that dev[0]
+        if add_apdev:
+            wpas_apdev = {}
+            wpas_apdev['ifname'] = dev[0].ifname + "_ap"
+            status, buf = dev[0].cmd_execute(['iw', dev[0].ifname,
+                                              'interface', 'add',
+                                              wpas_apdev['ifname'],
+                                              'type', 'managed'])
+            if status != 0:
+                raise Exception("iw interface add failed")
+            wpas_hapd = hostapd.add_ap(wpas_apdev, params)
+
+        if run_csa:
+            if 'OK' not in hapd.request("CHAN_SWITCH 5 2462 ht"):
+                raise Exception("chan switch request failed")
+
+            ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=5)
+            if not ev:
+                raise Exception("chan switch failed")
+
+            # now check station
+            ev = dev[0].wait_event(["CTRL-EVENT-CHANNEL-SWITCH",
+                                    "CTRL-EVENT-DISCONNECTED"], timeout=5)
+            if not ev:
+                raise Exception("sta - no chanswitch event")
+            if "CTRL-EVENT-CHANNEL-SWITCH" not in ev and not allow_csa_fail:
+                raise Exception("Received disconnection event instead of channel switch event")
+
+        if add_apdev:
+            remove_apdev(dev[0], wpas_apdev['ifname'])
+    except:
+        if wpas_apdev:
+            remove_apdev(dev[0], wpas_apdev['ifname'])
+        raise
+
+    return hapd
+
 def test_multi_ap_wps_shared(dev, apdev):
     """WPS on shared fronthaul/backhaul AP"""
     ssid = "multi-ap-wps"
@@ -138,7 +240,39 @@
     params.update({"multi_ap": "3",
                    "multi_ap_backhaul_ssid": '"%s"' % ssid,
                    "multi_ap_backhaul_wpa_passphrase": passphrase})
-    run_multi_ap_wps(dev, apdev, params)
+    hapd = run_multi_ap_wps(dev, apdev, params)
+    # Verify WPS parameter update with Multi-AP
+    if "OK" not in hapd.request("RELOAD"):
+        raise Exception("hostapd RELOAD failed")
+    dev[0].wait_disconnected()
+    dev[0].request("REMOVE_NETWORK all")
+    hapd.request("WPS_PBC")
+    dev[0].request("WPS_PBC multi_ap=1")
+    dev[0].wait_connected(timeout=20)
+
+def test_multi_ap_wps_shared_csa(dev, apdev):
+    """WPS on shared fronthaul/backhaul AP, run CSA"""
+    ssid = "multi-ap-wps-csa"
+    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, run_csa=True)
+
+def test_multi_ap_wps_shared_apdev_csa(dev, apdev):
+    """WPS on shared fronthaul/backhaul AP add apdev on same phy and run CSA"""
+    ssid = "multi-ap-wps-apdev-csa"
+    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})
+    # This case is currently failing toc omplete CSA on the station interface.
+    # For the time being, ignore that to avoid always failing tests. Full
+    # validation can be enabled once the issue behind this is fixed.
+    run_multi_ap_wps(dev, apdev, params, add_apdev=True, run_csa=True,
+                     allow_csa_fail=True)
 
 def test_multi_ap_wps_shared_psk(dev, apdev):
     """WPS on shared fronthaul/backhaul AP using PSK"""
@@ -163,9 +297,8 @@
     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())
+    run_multi_ap_wps(dev, apdev, params, params_backhaul)
 
 def test_multi_ap_wps_split_psk(dev, apdev):
     """WPS on split fronthaul and backhaul AP"""
@@ -178,9 +311,8 @@
                    "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())
+    run_multi_ap_wps(dev, apdev, params, params_backhaul)
 
 def test_multi_ap_wps_split_mixed(dev, apdev):
     """WPS on split fronthaul and backhaul AP with mixed-mode fronthaul"""
@@ -195,9 +327,8 @@
     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())
+    run_multi_ap_wps(dev, apdev, params, params_backhaul)
 
 def test_multi_ap_wps_split_open(dev, apdev):
     """WPS on split fronthaul and backhaul AP with open fronthaul"""
@@ -209,9 +340,8 @@
     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())
+    run_multi_ap_wps(dev, apdev, params, params_backhaul)
 
 def test_multi_ap_wps_fail_non_multi_ap(dev, apdev):
     """Multi-AP WPS on non-WPS AP fails"""
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ocv.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ocv.py
index 802e678..e93cea6 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ocv.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_ocv.py
@@ -13,7 +13,8 @@
 from wpasupplicant import WpaSupplicant
 import hwsim_utils
 from utils import *
-
+from test_erp import start_erp_as
+from test_ap_ft import ft_params1, ft_params2
 from test_ap_psk import parse_eapol, build_eapol, pmk_to_ptk, eapol_key_mic, recv_eapol, send_eapol, reply_eapol, build_eapol_key_3_4, aes_wrap, pad_key_data
 
 #TODO: Refuse setting up AP with OCV but without MFP support
@@ -981,12 +982,22 @@
 
 def test_wpa2_ocv_ap_override_eapol_m3(dev, apdev):
     """OCV on 2.4 GHz and AP override EAPOL-Key msg 3/4"""
+    run_wpa2_ocv_ap_override_eapol_m3(dev, apdev)
+
+def test_wpa2_ocv_ap_override_eapol_m3_post_enable(dev, apdev):
+    """OCV on 2.4 GHz and AP override EAPOL-Key msg 3/4 (post enable)"""
+    run_wpa2_ocv_ap_override_eapol_m3(dev, apdev, True)
+
+def run_wpa2_ocv_ap_override_eapol_m3(dev, apdev, post_enable=False):
     params = {"channel": "1",
               "ieee80211w": "2",
-              "ocv": "1",
-              "oci_freq_override_eapol_m3": "2462"}
+              "ocv": "1"}
+    if not post_enable:
+        params["oci_freq_override_eapol_m3"] = "2462"
     hapd, ssid, passphrase = ocv_setup_ap(apdev[0], params)
     bssid = hapd.own_addr()
+    if post_enable:
+        hapd.set("oci_freq_override_eapol_m3", "2462")
     dev[0].connect(ssid, psk=passphrase, scan_freq="2412", ocv="1",
                    ieee80211w="2", wait_connect=False)
 
@@ -998,15 +1009,25 @@
 
 def test_wpa2_ocv_ap_override_eapol_g1(dev, apdev):
     """OCV on 2.4 GHz and AP override EAPOL-Key group msg 1/2"""
+    run_wpa2_ocv_ap_override_eapol_g1(dev, apdev)
+
+def test_wpa2_ocv_ap_override_eapol_g1_post_enable(dev, apdev):
+    """OCV on 2.4 GHz and AP override EAPOL-Key group msg 1/2 (post enable)"""
+    run_wpa2_ocv_ap_override_eapol_g1(dev, apdev, True)
+
+def run_wpa2_ocv_ap_override_eapol_g1(dev, apdev, post_enable=False):
     params = {"channel": "1",
               "ieee80211w": "2",
-              "ocv": "1",
-              "oci_freq_override_eapol_g1": "2462"}
+              "ocv": "1"}
+    if not post_enable:
+        params["oci_freq_override_eapol_g1"] = "2462"
     hapd, ssid, passphrase = ocv_setup_ap(apdev[0], params)
     bssid = hapd.own_addr()
     dev[0].connect(ssid, psk=passphrase, scan_freq="2412", ocv="1",
                    ieee80211w="2")
 
+    if post_enable:
+        hapd.set("oci_freq_override_eapol_g1", "2462")
     if "OK" not in hapd.request("REKEY_GTK"):
         raise Exception("REKEY_GTK failed")
     check_ocv_failure(dev[0], "EAPOL-Key group msg 1/2", "eapol-key-g1", bssid)
@@ -1041,6 +1062,105 @@
         raise Exception("Triggering SA Query from the STA failed")
     check_ocv_failure(dev[0], "SA Query Response", "saqueryresp", bssid)
 
+def test_wpa2_ocv_ap_override_fils_assoc(dev, apdev, params):
+    """OCV on 2.4 GHz and AP override FILS association"""
+    run_wpa2_ocv_ap_override_fils_assoc(dev, apdev, params)
+
+def test_wpa2_ocv_ap_override_fils_assoc_post_enable(dev, apdev, params):
+    """OCV on 2.4 GHz and AP override FILS association (post enable)"""
+    run_wpa2_ocv_ap_override_fils_assoc(dev, apdev, params, True)
+
+def run_wpa2_ocv_ap_override_fils_assoc(dev, apdev, params, post_enable=False):
+    check_fils_capa(dev[0])
+    check_erp_capa(dev[0])
+
+    start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
+
+    bssid = apdev[0]['bssid']
+    ssid = "test-wpa2-ocv"
+    params = hostapd.wpa2_eap_params(ssid=ssid)
+    params['wpa_key_mgmt'] = "FILS-SHA256"
+    params['auth_server_port'] = "18128"
+    params['erp_send_reauth_start'] = '1'
+    params['erp_domain'] = 'example.com'
+    params['fils_realm'] = 'example.com'
+    params['wpa_group_rekey'] = '1'
+    params["ieee80211w"] = "2"
+    params["ocv"] = "1"
+    if not post_enable:
+        params["oci_freq_override_fils_assoc"] = "2462"
+    try:
+        hapd = hostapd.add_ap(apdev[0], params)
+    except Exception as e:
+        if "Failed to set hostapd parameter ocv" in str(e):
+            raise HwsimSkip("OCV not supported")
+        raise
+    bssid = hapd.own_addr()
+    if post_enable:
+        hapd.set("oci_freq_override_fils_assoc", "2462")
+    dev[0].request("ERP_FLUSH")
+    id = dev[0].connect(ssid, key_mgmt="FILS-SHA256",
+                        eap="PSK", identity="psk.user@example.com",
+                        password_hex="0123456789abcdef0123456789abcdef",
+                        erp="1", scan_freq="2412", ocv="1", ieee80211w="2")
+
+    dev[0].request("DISCONNECT")
+    dev[0].wait_disconnected()
+
+    dev[0].dump_monitor()
+    dev[0].select_network(id, freq=2412)
+
+    check_ocv_failure(dev[0], "FILS Association Response", "fils-assoc", bssid)
+    dev[0].request("DISCONNECT")
+
+def test_wpa2_ocv_ap_override_ft_assoc(dev, apdev):
+    """OCV on 2.4 GHz and AP override FT reassociation"""
+    run_wpa2_ocv_ap_override_ft_assoc(dev, apdev)
+
+def test_wpa2_ocv_ap_override_ft_assoc_post_enable(dev, apdev):
+    """OCV on 2.4 GHz and AP override FT reassociation (post enable)"""
+    run_wpa2_ocv_ap_override_ft_assoc(dev, apdev, True)
+
+def run_wpa2_ocv_ap_override_ft_assoc(dev, apdev, post_enable=False):
+    ssid = "test-wpa2-ocv"
+    passphrase = "qwertyuiop"
+    params = ft_params1(ssid=ssid, passphrase=passphrase)
+    params["ieee80211w"] = "2"
+    params["ocv"] = "1"
+    if not post_enable:
+        params["oci_freq_override_ft_assoc"] = "2462"
+    try:
+        hapd0 = hostapd.add_ap(apdev[0], params)
+    except Exception as e:
+        if "Failed to set hostapd parameter ocv" in str(e):
+            raise HwsimSkip("OCV not supported")
+        raise
+    params = ft_params2(ssid=ssid, passphrase=passphrase)
+    params["ieee80211w"] = "2"
+    params["ocv"] = "1"
+    if not post_enable:
+        params["oci_freq_override_ft_assoc"] = "2462"
+    hapd1 = hostapd.add_ap(apdev[1], params)
+
+    if post_enable:
+        hapd0.set("oci_freq_override_ft_assoc", "2462")
+        hapd1.set("oci_freq_override_ft_assoc", "2462")
+
+    dev[0].connect(ssid, key_mgmt="FT-PSK", psk=passphrase,
+                   scan_freq="2412", ocv="1", ieee80211w="2")
+
+    bssid = dev[0].get_status_field("bssid")
+    bssid0 = hapd0.own_addr()
+    bssid1 = hapd1.own_addr()
+    target = bssid0 if bssid == bssid1 else bssid1
+
+    dev[0].scan_for_bss(target, freq="2412")
+    if "OK" not in dev[0].request("ROAM " + target):
+        raise Exception("ROAM failed")
+
+    check_ocv_failure(dev[0], "FT Reassociation Response", "ft-assoc", target)
+    dev[0].request("DISCONNECT")
+
 @remote_compatible
 def test_wpa2_ocv_no_pmf(dev, apdev):
     """OCV on 2.4 GHz and no PMF on STA"""
@@ -1113,3 +1233,15 @@
         raise Exception("Could not set TEST_ASSOC_IE")
     dev[0].connect(ssid, psk=passphrase, scan_freq="2412", ocv="0",
                    ieee80211w="1")
+
+def test_wpa2_ocv_without_pmf(dev, apdev):
+    """OCV without PMF"""
+    params = {"channel": "6",
+              "ieee80211n": "1",
+              "ieee80211w": "1",
+              "ocv": "1"}
+    hapd, ssid, passphrase = ocv_setup_ap(apdev[0], params)
+    hapd.disable()
+    hapd.set("ieee80211w", "0")
+    if "FAIL" not in hapd.request("ENABLE"):
+        raise Exception("OCV without PMF accepted")
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_owe.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_owe.py
index 95c6b19..f72c606 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_owe.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_owe.py
@@ -29,6 +29,10 @@
               "rsn_pairwise": "CCMP"}
     hapd = hostapd.add_ap(apdev[0], params)
     bssid = hapd.own_addr()
+    conf = hapd.request("GET_CONFIG")
+    if "key_mgmt=OWE" not in conf.splitlines():
+        logger.info("GET_CONFIG:\n" + conf)
+        raise Exception("GET_CONFIG did not report correct key_mgmt")
 
     dev[0].scan_for_bss(bssid, freq="2412")
     bss = dev[0].get_bss(bssid)
@@ -60,10 +64,12 @@
     dev[0].scan_for_bss(bssid, freq="2412")
     for group in [19, 20, 21]:
         dev[0].connect("owe", key_mgmt="OWE", owe_group=str(group))
+        hapd.wait_sta()
         hwsim_utils.test_connectivity(dev[0], hapd)
         dev[0].request("REMOVE_NETWORK all")
         dev[0].wait_disconnected()
         dev[0].dump_monitor()
+        hapd.dump_monitor()
 
 def test_owe_pmksa_caching(dev, apdev):
     """Opportunistic Wireless Encryption and PMKSA caching"""
@@ -146,10 +152,12 @@
 
     dev[0].scan_for_bss(bssid, freq="2412")
     dev[0].connect("owe+psk", psk="12345678")
+    hapd.wait_sta()
     hwsim_utils.test_connectivity(dev[0], hapd)
 
     dev[1].scan_for_bss(bssid, freq="2412")
     dev[1].connect("owe+psk", key_mgmt="OWE")
+    hapd.wait_sta()
     hwsim_utils.test_connectivity(dev[1], hapd)
 
 def test_owe_transition_mode(dev, apdev):
@@ -213,6 +221,7 @@
 
     id = dev[0].connect("owe-test", key_mgmt="OWE", ieee80211w="2",
                         scan_freq="2412")
+    hapd.wait_sta()
     hwsim_utils.test_connectivity(dev[0], hapd)
     val = dev[0].get_status_field("key_mgmt")
     if val != "OWE":
@@ -235,6 +244,7 @@
     dev[0].scan_for_bss(bssid, freq="2412")
     dev[0].select_network(id, 2412)
     dev[0].wait_connected()
+    hapd.wait_sta()
     hwsim_utils.test_connectivity(dev[0], hapd)
 
 def test_owe_transition_mode_ifname(dev, apdev):
@@ -916,3 +926,28 @@
     dev[0].wait_disconnected()
     dev[0].request("RECONNECT")
     dev[0].wait_connected()
+
+def test_owe_sa_query(dev, apdev):
+    """Opportunistic Wireless Encryption - SA Query"""
+    if "OWE" not in dev[0].get_capability("key_mgmt"):
+        raise HwsimSkip("OWE not supported")
+    params = {"ssid": "owe",
+              "wpa": "2",
+              "ieee80211w": "2",
+              "wpa_key_mgmt": "OWE",
+              "rsn_pairwise": "CCMP"}
+    hapd = hostapd.add_ap(apdev[0], params)
+    bssid = hapd.own_addr()
+
+    dev[0].scan_for_bss(bssid, freq="2412")
+    dev[0].connect("owe", key_mgmt="OWE", owe_group="19", ieee80211w="2",
+                   scan_freq="2412")
+    hapd.wait_sta()
+
+    hapd.set("ext_mgmt_frame_handling", "1")
+    dev[0].request("DISCONNECT")
+    dev[0].wait_disconnected(timeout=10)
+    hapd.set("ext_mgmt_frame_handling", "0")
+    dev[0].request("PMKSA_FLUSH")
+    dev[0].request("REASSOCIATE")
+    dev[0].wait_connected(timeout=10, error="Timeout on re-connection")
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_p2p_autogo.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_p2p_autogo.py
index 91d68ea..d857c90 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_p2p_autogo.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_p2p_autogo.py
@@ -378,7 +378,7 @@
 @remote_compatible
 def test_autogo_extra_cred(dev):
     """P2P autonomous GO sending two WPS credentials"""
-    if "FAIL" in dev[0].request("SET wps_testing_dummy_cred 1"):
+    if "FAIL" in dev[0].request("SET wps_testing_stub_cred 1"):
         raise Exception("Failed to enable test mode")
     autogo(dev[0], freq=2412)
     connect_cli(dev[0], dev[1], social=True, freq=2412)
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_p2p_channel.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_p2p_channel.py
index 87a1a24..d57234d 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_p2p_channel.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_p2p_channel.py
@@ -17,7 +17,7 @@
 from wpasupplicant import WpaSupplicant
 from hwsim import HWSimRadio
 from p2p_utils import *
-from utils import clear_regdom_dev
+from utils import *
 
 def set_country(country, dev=None):
     subprocess.call(['iw', 'reg', 'set', country])
@@ -226,6 +226,7 @@
 def test_p2p_channel_avoid3(dev):
     """P2P and avoid frequencies driver event on 5 GHz"""
     try:
+        dev[0].global_request("SET p2p_pref_chan 128:44")
         set_country("CN", dev[0])
         form(dev[0], dev[1])
         set_country("CN", dev[0])
@@ -251,6 +252,7 @@
     finally:
         set_country("00")
         dev[0].request("DRIVER_EVENT AVOID_FREQUENCIES")
+        dev[0].global_request("SET p2p_pref_chan ")
         dev[1].flush_scan_cache()
 
 @remote_compatible
@@ -603,7 +605,7 @@
             raise Exception("Unexpected number of network blocks: " + str(netw))
         id = netw[0]['id']
 
-        set_country("SE", dev[0])
+        set_country("JP", dev[0])
         res = autogo(dev[0], persistent=id)
         if res['freq'] == "5745":
             raise Exception("Unexpected channel selected(2): " + res['freq'])
@@ -950,7 +952,8 @@
         dev[0].remove_group()
     finally:
         dev[0].global_request("SET p2p_go_freq_change_policy 2")
-        set_country("00")
+        disable_hapd(hapd)
+        clear_regdom_dev(dev, 1)
 
 def test_p2p_go_move_scm_peer_does_not_support(dev, apdev):
     """No P2P GO move due to SCM operation (peer does not supports)"""
@@ -996,6 +999,7 @@
     finally:
         dev[0].global_request("SET p2p_go_freq_change_policy 2")
         dev[1].request("DRIVER_EVENT AVOID_FREQUENCIES")
+        disable_hapd(hapd)
         clear_regdom_dev(dev, 2)
 
 def test_p2p_go_move_scm_multi(dev, apdev):
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_p2p_discovery.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_p2p_discovery.py
index f4353e8..0537f02 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_p2p_discovery.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_p2p_discovery.py
@@ -7,9 +7,12 @@
 from remotehost import remote_compatible
 import logging
 logger = logging.getLogger()
+import binascii
 import os
+import struct
 import time
 
+import hostapd
 import hwsim_utils
 from wpasupplicant import WpaSupplicant
 from p2p_utils import *
@@ -776,3 +779,93 @@
         raise Exception("Unexpected device name(2): " + ev)
     wpas.p2p_stop_find()
     dev[0].p2p_stop_find()
+
+def test_p2p_group_cli_invalid(dev, apdev):
+    """P2P device discovery with invalid group client info"""
+    attr = struct.pack('<BHBB', 2, 2, 0x25, 0x09)
+
+    attr += struct.pack('<BH', 3, 6) + "\x02\x02\x02\x02\x02\x00".encode()
+
+    cli = bytes()
+    cli += "\x02\x02\x02\x02\x02\x03".encode()
+    cli += "\x02\x02\x02\x02\x02\x04".encode()
+    cli += struct.pack('>BH', 0, 0x3148)
+    dev_type = "\x00\x00\x00\x00\x00\x00\x00\x01".encode()
+    cli += dev_type
+    num_sec = 25
+    cli += struct.pack('B', num_sec)
+    cli += num_sec * dev_type
+    name = "TEST".encode()
+    cli += struct.pack('>HH', 0x1011, len(name)) + name
+    desc = struct.pack('B', len(cli)) + cli
+    attr += struct.pack('<BH', 14, len(desc)) + desc
+
+    p2p_ie = struct.pack('>BBL', 0xdd, 4 + len(attr), 0x506f9a09) + attr
+    ie = binascii.hexlify(p2p_ie).decode()
+
+    params = {"ssid": "DIRECT-test",
+              "eap_server": "1",
+              "wps_state": "2",
+              "wpa_passphrase": "12345678",
+              "wpa": "2",
+              "wpa_key_mgmt": "WPA-PSK",
+              "rsn_pairwise": "CCMP",
+              "vendor_elements": ie}
+    hapd = hostapd.add_ap(apdev[0], params)
+
+    for i in range(2):
+        dev[i].p2p_find(social=True)
+        ev = dev[i].wait_global_event(["P2P-DEVICE-FOUND"], timeout=5)
+        if not ev:
+            raise Exception("P2P device not found")
+
+def test_discovery_max_peers(dev):
+    """P2P device discovery and maximum peer limit exceeded"""
+    dev[0].p2p_listen()
+    dev[0].request("SET ext_mgmt_frame_handling 1")
+    probereq1 = "40000000ffffffffffff"
+    probereq2 = "ffffffffffff000000074449524543542d01080c1218243048606c0301012d1afe131bffff000000000000000000000100000000000000000000ff16230178c812400000bfce0000000000000000fafffaffdd730050f204104a000110103a00010110080002314810470010572cf82fc95756539b16b5cfb298abf1105400080000000000000000103c0001031002000200001009000200001012000200001021000120102300012010240001201011000844657669636520421049000900372a000120030101dd11506f9a0902020025000605005858045106"
+
+    # Fill the P2P peer table with max+1 entries based on Probe Request frames
+    # to verify correct behavior on# removing the oldest entry when running out
+    # of room.
+    for i in range(101):
+        addr = "0202020202%02x" % i
+        probereq = probereq1 + addr + probereq2
+        if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=60 ssi_signal=-30 frame=" + probereq):
+            raise Exception("MGMT_RX_PROCESS failed")
+
+    res = dev[0].global_request("P2P_PEER FIRST")
+    addr = res.splitlines()[0]
+    peers = [addr]
+    limit = 200
+    while limit > 0:
+        res = dev[0].global_request("P2P_PEER NEXT-" + addr)
+        addr = res.splitlines()[0]
+        if addr == "FAIL":
+            break
+        peers.append(addr)
+        limit -= 1
+    logger.info("Peers: " + str(peers))
+
+    if len(peers) != 100:
+        raise Exception("Unexpected number of peer entries")
+    oldest = "02:02:02:02:02:00"
+    if oldest in peers:
+        raise Exception("Oldest entry is still present")
+    for i in range(101):
+        addr = "02:02:02:02:02:%02x" % i
+        if addr == oldest:
+            continue
+        if addr not in peers:
+            raise Exception("Peer missing from table: " + addr)
+
+    # Provision Discovery Request from the oldest peer (SA) using internally
+    # different P2P Device Address as a regression test for incorrect processing
+    # for this corner case.
+    dst = dev[0].own_addr().replace(':', '')
+    src = peers[99].replace(':', '')
+    devaddr = "0202020202ff"
+    pdreq = "d0004000" + dst + src + dst + "d0000409506f9a090701dd29506f9a0902020025000d1d00" + devaddr + "1108000000000000000000101100084465766963652041dd0a0050f204100800020008"
+    if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=60 ssi_signal=-30 frame=" + pdreq):
+        raise Exception("MGMT_RX_PROCESS failed")
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_pasn.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_pasn.py
new file mode 100755
index 0000000..6f7a806
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_pasn.py
@@ -0,0 +1,854 @@
+# Test cases for PASN
+# Copyright (C) 2019 Intel Corporation
+#
+# This software may be distributed under the terms of the BSD license.
+# See README for more details.
+
+from remotehost import remote_compatible
+import binascii
+import os
+import time
+import logging
+logger = logging.getLogger()
+import socket
+import struct
+import subprocess
+import re
+
+import hwsim_utils
+import hostapd
+from wpasupplicant import WpaSupplicant
+from utils import *
+from hwsim import HWSimRadio
+from test_erp import start_erp_as
+from test_ap_ft import run_roams, ft_params1, ft_params2
+
+def check_pasn_capab(dev):
+    if "PASN" not in dev.get_capability("auth_alg"):
+        raise HwsimSkip("PASN not supported")
+
+def pasn_ap_params(akmp="PASN", cipher="CCMP", group="19"):
+    params = {"ssid": "test-wpa2-pasn",
+              "wpa_passphrase": "12345678",
+              "wpa": "2",
+              "ieee80211w": "2",
+              "wpa_key_mgmt": "WPA-PSK " + akmp,
+              "rsn_pairwise": cipher,
+              "pasn_groups" : group}
+
+    return params
+
+def start_pasn_ap(apdev, params):
+    try:
+        return hostapd.add_ap(apdev, params)
+    except Exception as e:
+        if "Failed to set hostapd parameter wpa_key_mgmt" in str(e) or \
+           "Failed to set hostapd parameter force_kdk_derivation" in str(e):
+            raise HwsimSkip("PASN not supported")
+        raise
+
+def check_pasn_ptk(dev, hapd, cipher, fail_ptk=False, clear_keys=True):
+    sta_ptksa = dev.get_ptksa(hapd.own_addr(), cipher)
+    ap_ptksa = hapd.get_ptksa(dev.own_addr(), cipher)
+
+    if not (sta_ptksa and ap_ptksa):
+        if fail_ptk:
+            return
+        raise Exception("Could not get PTKSA entry")
+
+    logger.info("sta: TK: %s KDK: %s" % (sta_ptksa['tk'], sta_ptksa['kdk']))
+    logger.info("ap : TK: %s KDK: %s" % (ap_ptksa['tk'], ap_ptksa['kdk']))
+
+    if sta_ptksa['tk'] != ap_ptksa['tk'] or sta_ptksa['kdk'] != ap_ptksa['kdk']:
+        raise Exception("TK/KDK mismatch")
+    elif fail_ptk:
+        raise Exception("TK/KDK match although key derivation should have failed")
+    elif clear_keys:
+        cmd = "PASN_DEAUTH bssid=%s" % hapd.own_addr()
+        dev.request(cmd)
+
+        # Wait a little to let the AP process the deauth
+        time.sleep(0.2)
+
+        sta_ptksa = dev.get_ptksa(hapd.own_addr(), cipher)
+        ap_ptksa = hapd.get_ptksa(dev.own_addr(), cipher)
+        if sta_ptksa or ap_ptksa:
+            raise Exception("TK/KDK not deleted as expected")
+
+def check_pasn_akmp_cipher(dev, hapd, akmp="PASN", cipher="CCMP",
+                           group="19", status=0, fail=0, nid="",
+                           fail_ptk=False):
+    dev.flush_scan_cache()
+    dev.scan(type="ONLY", freq=2412)
+
+    cmd = "PASN_START bssid=%s akmp=%s cipher=%s group=%s" % (hapd.own_addr(), akmp, cipher, group)
+
+    if nid != "":
+        cmd += " nid=%s" % nid
+
+    resp = dev.request(cmd)
+
+    if fail:
+        if "OK" in resp:
+            raise Exception("Unexpected success to start PASN authentication")
+        return
+
+    if "OK" not in resp:
+        raise Exception("Failed to start PASN authentication")
+
+    ev = dev.wait_event(["PASN-AUTH-STATUS"], 3)
+    if not ev:
+        raise Exception("PASN: PASN-AUTH-STATUS not seen")
+
+    if hapd.own_addr() + " akmp=" + akmp + ", status=" + str(status) not in ev:
+        raise Exception("PASN: unexpected status")
+
+    if status:
+        return
+
+    check_pasn_ptk(dev, hapd, cipher, fail_ptk)
+
+@remote_compatible
+def test_pasn_ccmp(dev, apdev):
+    """PASN authentication with WPA2/CCMP AP"""
+    check_pasn_capab(dev[0])
+
+    params = pasn_ap_params("PASN", "CCMP", "19")
+    hapd = start_pasn_ap(apdev[0], params)
+
+    check_pasn_akmp_cipher(dev[0], hapd, "PASN", "CCMP")
+
+@remote_compatible
+def test_pasn_gcmp(dev, apdev):
+    """PASN authentication with WPA2/GCMP AP"""
+    check_pasn_capab(dev[0])
+
+    params = pasn_ap_params("PASN", "GCMP", "19")
+    hapd = start_pasn_ap(apdev[0], params)
+
+    check_pasn_akmp_cipher(dev[0], hapd, "PASN", "GCMP")
+
+@remote_compatible
+def test_pasn_ccmp_256(dev, apdev):
+    """PASN authentication with WPA2/CCMP256 AP"""
+    check_pasn_capab(dev[0])
+
+    params = pasn_ap_params("PASN", "CCMP-256", "19")
+    hapd = start_pasn_ap(apdev[0], params)
+
+    check_pasn_akmp_cipher(dev[0], hapd, "PASN", "CCMP-256")
+
+@remote_compatible
+def test_pasn_gcmp_256(dev, apdev):
+    """PASN authentication with WPA2/GCMP-256 AP"""
+    check_pasn_capab(dev[0])
+
+    params = pasn_ap_params("PASN", "GCMP-256", "19")
+    hapd = start_pasn_ap(apdev[0], params)
+
+    check_pasn_akmp_cipher(dev[0], hapd, "PASN", "GCMP-256")
+
+@remote_compatible
+def test_pasn_group_mismatch(dev, apdev):
+    """PASN authentication with WPA2/CCMP AP with group mismatch"""
+    check_pasn_capab(dev[0])
+
+    params = pasn_ap_params("PASN", "CCMP", "20")
+    hapd = start_pasn_ap(apdev[0], params)
+
+    check_pasn_akmp_cipher(dev[0], hapd, "PASN", "CCMP", status=77)
+
+@remote_compatible
+def test_pasn_channel_mismatch(dev, apdev):
+    """PASN authentication with WPA2/CCMP AP with channel mismatch"""
+    check_pasn_capab(dev[0])
+
+    params = pasn_ap_params("PASN", "CCMP")
+    params['channel'] = "6"
+    hapd = start_pasn_ap(apdev[0], params)
+
+    check_pasn_akmp_cipher(dev[0], hapd, "PASN", "CCMP", fail=1)
+
+@remote_compatible
+def test_pasn_while_connected_same_channel(dev, apdev):
+    """PASN authentication with WPA2/CCMP AP while connected same channel"""
+    check_pasn_capab(dev[0])
+
+    ssid = "test-wpa2-psk"
+    psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
+    params = hostapd.wpa2_params(ssid=ssid)
+    params['wpa_psk'] = psk
+    hapd = start_pasn_ap(apdev[0], params)
+
+    dev[0].connect(ssid, raw_psk=psk, scan_freq="2412")
+
+    params = pasn_ap_params("PASN", "CCMP")
+    hapd = start_pasn_ap(apdev[1], params)
+
+    check_pasn_akmp_cipher(dev[0], hapd, "PASN", "CCMP")
+
+@remote_compatible
+def test_pasn_while_connected_same_ap(dev, apdev):
+    """PASN authentication with WPA2/CCMP AP while connected to it"""
+    check_pasn_capab(dev[0])
+
+    params = hostapd.wpa2_params(ssid="test-wpa2-psk",
+                                 passphrase="12345678")
+    hapd = start_pasn_ap(apdev[0], params)
+
+    dev[0].connect("test-wpa2-psk", psk="12345678", scan_freq="2412")
+
+    check_pasn_akmp_cipher(dev[0], hapd, "PASN", "CCMP", fail=1)
+
+@remote_compatible
+def test_pasn_while_connected_diff_channel(dev, apdev):
+    """PASN authentication with WPA2/CCMP AP while connected diff channel"""
+    check_pasn_capab(dev[0])
+
+    with HWSimRadio(n_channels=2) as (radio, iface):
+        wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
+        wpas.interface_add(iface)
+
+        if wpas.get_mcc() < 2:
+            raise HwsimSkip("PASN: New radio does not support MCC")
+
+        params = hostapd.wpa2_params(ssid="test-wpa2-psk",
+                                     passphrase="12345678")
+        params['channel'] = "6"
+        hapd = start_pasn_ap(apdev[0], params)
+        wpas.connect("test-wpa2-psk", psk="12345678", scan_freq="2437")
+
+        params = pasn_ap_params("PASN", "CCMP")
+        hapd2 = start_pasn_ap(apdev[1], params)
+
+        check_pasn_akmp_cipher(wpas, hapd2, "PASN", "CCMP")
+
+@remote_compatible
+def test_pasn_sae_pmksa_cache(dev, apdev):
+    """PASN authentication with SAE AP with PMKSA caching"""
+    check_pasn_capab(dev[0])
+    check_sae_capab(dev[0])
+
+    params = hostapd.wpa2_params(ssid="test-sae",
+                                 passphrase="12345678")
+    params['wpa_key_mgmt'] = 'SAE PASN'
+    params['sae_pwe'] = "2"
+    hapd = start_pasn_ap(apdev[0], params)
+
+    try:
+        dev[0].set("sae_groups", "19")
+        dev[0].set("sae_pwe", "2")
+        dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE", scan_freq="2412")
+
+        hapd.wait_sta()
+        hwsim_utils.test_connectivity(dev[0], hapd)
+
+        dev[0].request("DISCONNECT")
+        dev[0].wait_disconnected()
+
+        check_pasn_akmp_cipher(dev[0], hapd, "SAE", "CCMP")
+    finally:
+        dev[0].set("sae_pwe", "0")
+
+def check_pasn_fils_pmksa_cache(dev, apdev, params, key_mgmt):
+    check_fils_capa(dev[0])
+    check_erp_capa(dev[0])
+    check_pasn_capab(dev[0])
+
+    start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
+
+    bssid = apdev[0]['bssid']
+    params = hostapd.wpa2_eap_params(ssid="fils")
+    params['wpa_key_mgmt'] = key_mgmt + " PASN"
+    params['auth_server_port'] = "18128"
+    params['erp_domain'] = 'example.com'
+    params['fils_realm'] = 'example.com'
+    hapd = start_pasn_ap(apdev[0], params)
+
+    dev[0].scan_for_bss(bssid, freq=2412)
+    dev[0].request("ERP_FLUSH")
+
+    id = dev[0].connect("fils", key_mgmt=key_mgmt,
+                        eap="PSK", identity="psk.user@example.com",
+                        password_hex="0123456789abcdef0123456789abcdef",
+                        erp="1", scan_freq="2412")
+    pmksa = dev[0].get_pmksa(bssid)
+    if pmksa is None:
+        raise Exception("No PMKSA cache entry created")
+
+    hapd.wait_sta()
+    hwsim_utils.test_connectivity(dev[0], hapd)
+
+    dev[0].request("DISCONNECT")
+    dev[0].wait_disconnected()
+
+    check_pasn_akmp_cipher(dev[0], hapd, key_mgmt, "CCMP")
+
+@remote_compatible
+def test_pasn_fils_sha256_pmksa_cache(dev, apdev, params):
+    """PASN authentication with FILS-SHA256 with PMKSA caching"""
+    check_pasn_fils_pmksa_cache(dev, apdev, params, "FILS-SHA256")
+
+@remote_compatible
+def test_pasn_fils_sha384_pmksa_cache(dev, apdev, params):
+    """PASN authentication with FILS-SHA384 with PMKSA caching"""
+    check_pasn_fils_pmksa_cache(dev, apdev, params, "FILS-SHA384")
+
+@remote_compatible
+def test_pasn_sae_kdk(dev, apdev):
+    """Station authentication with SAE AP with KDK derivation during connection"""
+    check_pasn_capab(dev[0])
+    check_sae_capab(dev[0])
+
+    try:
+        params = hostapd.wpa2_params(ssid="test-sae",
+                                     passphrase="12345678")
+        params['wpa_key_mgmt'] = 'SAE PASN'
+        params['sae_pwe'] = "2"
+        params['force_kdk_derivation'] = "1"
+        hapd = start_pasn_ap(apdev[0], params)
+
+        dev[0].set("force_kdk_derivation", "1")
+        dev[0].set("sae_pwe", "2")
+        dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
+                       scan_freq="2412")
+
+        check_pasn_ptk(dev[0], hapd, "CCMP", clear_keys=False)
+    finally:
+        dev[0].set("force_kdk_derivation", "0")
+        dev[0].set("sae_pwe", "0")
+
+
+def check_pasn_fils_kdk(dev, apdev, params, key_mgmt):
+    check_fils_capa(dev[0])
+    check_erp_capa(dev[0])
+    check_pasn_capab(dev[0])
+
+    start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
+
+    try:
+        bssid = apdev[0]['bssid']
+        params = hostapd.wpa2_eap_params(ssid="fils")
+        params['wpa_key_mgmt'] = key_mgmt
+        params['auth_server_port'] = "18128"
+        params['erp_domain'] = 'example.com'
+        params['fils_realm'] = 'example.com'
+        params['disable_pmksa_caching'] = '1'
+        params['force_kdk_derivation'] = "1"
+        hapd = start_pasn_ap(apdev[0], params)
+
+        dev[0].scan_for_bss(bssid, freq=2412)
+        dev[0].request("ERP_FLUSH")
+        dev[0].set("force_kdk_derivation", "1")
+
+        id = dev[0].connect("fils", key_mgmt=key_mgmt,
+                            eap="PSK", identity="psk.user@example.com",
+                            password_hex="0123456789abcdef0123456789abcdef",
+                            erp="1", scan_freq="2412")
+
+        hapd.wait_sta()
+        hwsim_utils.test_connectivity(dev[0], hapd)
+
+        check_pasn_ptk(dev[0], hapd, "CCMP", clear_keys=False)
+
+        dev[0].request("DISCONNECT")
+        dev[0].wait_disconnected()
+
+        dev[0].dump_monitor()
+        dev[0].select_network(id, freq=2412)
+        ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
+                                "EVENT-ASSOC-REJECT",
+                                "CTRL-EVENT-CONNECTED"], timeout=10)
+        if ev is None:
+            raise Exception("Connection using FILS/ERP timed out")
+        if "CTRL-EVENT-EAP-STARTED" in ev:
+            raise Exception("Unexpected EAP exchange")
+        if "EVENT-ASSOC-REJECT" in ev:
+            raise Exception("Association failed")
+
+        hapd.wait_sta()
+        hwsim_utils.test_connectivity(dev[0], hapd)
+
+        check_pasn_ptk(dev[0], hapd, "CCMP", clear_keys=False)
+    finally:
+        dev[0].set("force_kdk_derivation", "0")
+
+@remote_compatible
+def test_pasn_fils_sha256_kdk(dev, apdev, params):
+    """Station authentication with FILS-SHA256 with KDK derivation during connection"""
+    check_pasn_fils_kdk(dev, apdev, params, "FILS-SHA256")
+
+@remote_compatible
+def test_pasn_fils_sha384_kdk(dev, apdev, params):
+    """Station authentication with FILS-SHA384 with KDK derivation during connection"""
+    check_pasn_fils_kdk(dev, apdev, params, "FILS-SHA384")
+
+@remote_compatible
+def test_pasn_sae(dev, apdev):
+    """PASN authentication with SAE AP with PMK derivation + PMKSA caching"""
+    check_pasn_capab(dev[0])
+    check_sae_capab(dev[0])
+
+    params = hostapd.wpa2_params(ssid="test-pasn-sae",
+                                 passphrase="12345678")
+    params['wpa_key_mgmt'] = 'SAE PASN'
+    params['sae_pwe'] = "2"
+    hapd = start_pasn_ap(apdev[0], params)
+
+    try:
+        dev[0].set("sae_pwe", "2")
+        dev[0].connect("test-pasn-sae", psk="12345678", key_mgmt="SAE",
+                       scan_freq="2412", only_add_network=True)
+
+        # first test with a valid PSK
+        check_pasn_akmp_cipher(dev[0], hapd, "SAE", "CCMP", nid="0")
+
+        # And now with PMKSA caching
+        check_pasn_akmp_cipher(dev[0], hapd, "SAE", "CCMP")
+
+        # And now with a wrong passphrase
+        if "FAIL" in dev[0].request("PMKSA_FLUSH"):
+            raise Exception("PMKSA_FLUSH failed")
+
+        dev[0].set_network_quoted(0, "psk", "12345678787")
+        check_pasn_akmp_cipher(dev[0], hapd, "SAE", "CCMP", status=1, nid="0")
+    finally:
+        dev[0].set("sae_pwe", "0")
+
+@remote_compatible
+def test_pasn_sae_while_connected_same_channel(dev, apdev):
+    """PASN SAE authentication while connected same channel"""
+    check_pasn_capab(dev[0])
+    check_sae_capab(dev[0])
+
+    params = hostapd.wpa2_params(ssid="test-pasn-wpa2-psk",
+                                 passphrase="12345678")
+    hapd = hostapd.add_ap(apdev[0], params)
+
+    try:
+        dev[0].set("sae_pwe", "2")
+        dev[0].connect("test-pasn-wpa2-psk", psk="12345678", scan_freq="2412")
+
+        params = hostapd.wpa2_params(ssid="test-pasn-sae",
+                                     passphrase="12345678")
+
+        params['wpa_key_mgmt'] = 'SAE PASN'
+        params['sae_pwe'] = "2"
+        hapd = start_pasn_ap(apdev[1], params)
+
+        dev[0].connect("test-pasn-sae", psk="12345678", key_mgmt="SAE",
+                       scan_freq="2412", only_add_network=True)
+
+        check_pasn_akmp_cipher(dev[0], hapd, "SAE", "CCMP", nid="1")
+    finally:
+        dev[0].set("sae_pwe", "0")
+
+@remote_compatible
+def test_pasn_sae_while_connected_diff_channel(dev, apdev):
+    """PASN SAE authentication while connected diff channel"""
+    check_pasn_capab(dev[0])
+    check_sae_capab(dev[0])
+
+    with HWSimRadio(n_channels=2) as (radio, iface):
+        wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
+        wpas.interface_add(iface)
+
+        if wpas.get_mcc() < 2:
+            raise HwsimSkip("PASN: New radio does not support MCC")
+
+        params = hostapd.wpa2_params(ssid="test-pasn-wpa2-psk",
+                                     passphrase="12345678")
+        params['channel'] = "6"
+        hapd = hostapd.add_ap(apdev[0], params)
+
+        try:
+            wpas.set("sae_pwe", "2")
+            wpas.connect("test-pasn-wpa2-psk", psk="12345678", scan_freq="2437")
+
+            params = hostapd.wpa2_params(ssid="test-pasn-sae",
+                                         passphrase="12345678")
+
+            params['wpa_key_mgmt'] = 'SAE PASN'
+            params['sae_pwe'] = "2"
+            hapd = start_pasn_ap(apdev[1], params)
+
+            wpas.connect("test-pasn-sae", psk="12345678", key_mgmt="SAE",
+                           scan_freq="2412", only_add_network=True)
+
+            check_pasn_akmp_cipher(wpas, hapd, "SAE", "CCMP", nid="1")
+        finally:
+            wpas.set("sae_pwe", "0")
+
+def pasn_fils_setup(wpas, apdev, params, key_mgmt):
+    check_fils_capa(wpas)
+    check_erp_capa(wpas)
+
+    wpas.flush_scan_cache()
+
+    start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
+
+    bssid = apdev[0]['bssid']
+    params = hostapd.wpa2_eap_params(ssid="fils")
+    params['wpa_key_mgmt'] = key_mgmt + " PASN"
+    params['auth_server_port'] = "18128"
+    params['erp_domain'] = 'example.com'
+    params['fils_realm'] = 'example.com'
+    params['disable_pmksa_caching'] = '1'
+    hapd = hostapd.add_ap(apdev[0]['ifname'], params)
+
+    id = wpas.connect("fils", key_mgmt=key_mgmt,
+                      eap="PSK", identity="psk.user@example.com",
+                      password_hex="0123456789abcdef0123456789abcdef",
+                      erp="1", scan_freq="2412")
+
+    wpas.request("DISCONNECT")
+    wpas.wait_disconnected()
+    wpas.dump_monitor()
+
+    if "FAIL" in wpas.request("PMKSA_FLUSH"):
+        raise Exception("PMKSA_FLUSH failed")
+
+    return hapd
+
+def check_pasn_fils(dev, apdev, params, key_mgmt):
+    check_pasn_capab(dev[0])
+
+    hapd = pasn_fils_setup(dev[0], apdev, params, key_mgmt);
+    check_pasn_akmp_cipher(dev[0], hapd, key_mgmt, "CCMP", nid="0")
+
+@remote_compatible
+def test_pasn_fils_sha256(dev, apdev, params):
+    """PASN FILS authentication using SHA-256"""
+    check_pasn_fils(dev, apdev, params, "FILS-SHA256")
+
+@remote_compatible
+def test_pasn_fils_sha384(dev, apdev, params):
+    """PASN FILS authentication using SHA-384"""
+    check_pasn_fils(dev, apdev, params, "FILS-SHA384")
+
+def check_pasn_fils_connected_same_channel(dev, apdev, params, key_mgmt):
+    check_pasn_capab(dev[0])
+
+    hapd = pasn_fils_setup(dev[0], apdev, params, key_mgmt);
+
+    # Connect to another AP on the same channel
+    hapd1 = hostapd.add_ap(apdev[1], {"ssid": "open"})
+    dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
+                   bg_scan_period="0")
+
+    hwsim_utils.test_connectivity(dev[0], hapd1)
+
+    # And perform the PASN authentication with FILS
+    check_pasn_akmp_cipher(dev[0], hapd, key_mgmt, "CCMP", nid="0")
+
+@remote_compatible
+def test_pasn_fils_sha256_connected_same_channel(dev, apdev, params):
+    """PASN FILS authentication using SHA-256 while connected same channel"""
+    check_pasn_fils_connected_same_channel(dev, apdev, params, "FILS-SHA256")
+
+@remote_compatible
+def test_pasn_fils_sha384_connected_same_channel(dev, apdev, params):
+    """PASN FILS authentication using SHA-384 while connected same channel"""
+    check_pasn_fils_connected_same_channel(dev, apdev, params, "FILS-SHA384")
+
+def check_pasn_fils_connected_diff_channel(dev, apdev, params, key_mgmt):
+    check_pasn_capab(dev[0])
+
+    with HWSimRadio(n_channels=2) as (radio, iface):
+        wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
+        wpas.interface_add(iface)
+        if wpas.get_mcc() < 2:
+           raise Exception("New radio does not support MCC")
+
+        hapd = pasn_fils_setup(wpas, apdev, params, key_mgmt);
+
+        # Connect to another AP on a different channel
+        hapd1 = hostapd.add_ap(apdev[1], {"ssid": "open", "channel" : "6"})
+        wpas.connect("open", key_mgmt="NONE", scan_freq="2437",
+                bg_scan_period="0")
+
+        hwsim_utils.test_connectivity(wpas, hapd1)
+
+        # And perform the PASN authentication with FILS
+        check_pasn_akmp_cipher(wpas, hapd, key_mgmt, "CCMP", nid="0")
+
+@remote_compatible
+def test_pasn_fils_sha256_connected_diff_channel(dev, apdev, params):
+    """PASN FILS authentication using SHA-256 while connected diff channel"""
+    check_pasn_fils_connected_diff_channel(dev, apdev, params, "FILS-SHA256")
+
+@remote_compatible
+def test_pasn_fils_sha384_connected_diff_channel(dev, apdev, params):
+    """PASN FILS authentication using SHA-384 while connected diff channel"""
+    check_pasn_fils_connected_diff_channel(dev, apdev, params, "FILS-SHA384")
+
+def test_pasn_ft_psk(dev, apdev):
+    """PASN authentication with FT-PSK"""
+    check_pasn_capab(dev[0])
+
+    ssid = "test-pasn-ft-psk"
+    passphrase = "12345678"
+
+    params = ft_params1(ssid=ssid, passphrase=passphrase)
+    params['wpa_key_mgmt'] += " PASN"
+    hapd0 = hostapd.add_ap(apdev[0], params)
+    params = ft_params2(ssid=ssid, passphrase=passphrase)
+    params['wpa_key_mgmt'] += " PASN"
+    hapd1 = hostapd.add_ap(apdev[1], params)
+
+    run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase)
+
+    if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
+        pasn_hapd = hapd1
+    else:
+        pasn_hapd = hapd0
+
+    check_pasn_akmp_cipher(dev[0], pasn_hapd, "FT-PSK", "CCMP")
+
+    run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, only_one_way=1)
+
+    if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
+        pasn_hapd = hapd1
+    else:
+        pasn_hapd = hapd0
+
+    check_pasn_akmp_cipher(dev[0], pasn_hapd, "FT-PSK", "CCMP")
+
+def test_pasn_ft_eap(dev, apdev):
+    """PASN authentication with FT-EAP"""
+    check_pasn_capab(dev[0])
+
+    ssid = "test-pasn-ft-psk"
+    passphrase = "12345678"
+    identity = "gpsk user"
+
+    radius = hostapd.radius_params()
+    params = ft_params1(ssid=ssid, passphrase=passphrase)
+    params['wpa_key_mgmt'] = "FT-EAP PASN"
+    params["ieee8021x"] = "1"
+    params = dict(list(radius.items()) + list(params.items()))
+    hapd0 = hostapd.add_ap(apdev[0], params)
+
+    params = ft_params2(ssid=ssid, passphrase=passphrase)
+    params['wpa_key_mgmt'] = "FT-EAP PASN"
+    params["ieee8021x"] = "1"
+    params = dict(list(radius.items()) + list(params.items()))
+    hapd1 = hostapd.add_ap(apdev[1], params)
+
+    run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, eap=True,
+              eap_identity=identity)
+
+    if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
+        pasn_hapd = hapd1
+    else:
+        pasn_hapd = hapd0
+
+    check_pasn_akmp_cipher(dev[0], pasn_hapd, "FT-EAP", "CCMP")
+
+def test_pasn_ft_eap_sha384(dev, apdev):
+    """PASN authentication with FT-EAP-SHA-384"""
+    check_pasn_capab(dev[0])
+
+    ssid = "test-pasn-ft-psk"
+    passphrase = "12345678"
+    identity = "gpsk user"
+
+    radius = hostapd.radius_params()
+    params = ft_params1(ssid=ssid, passphrase=passphrase)
+    params["ieee80211w"] = "2"
+    params['wpa_key_mgmt'] = "FT-EAP-SHA384 PASN"
+    params["ieee8021x"] = "1"
+    params = dict(list(radius.items()) + list(params.items()))
+    hapd0 = hostapd.add_ap(apdev[0], params)
+
+    params = ft_params2(ssid=ssid, passphrase=passphrase)
+    params["ieee80211w"] = "2"
+    params['wpa_key_mgmt'] = "FT-EAP-SHA384 PASN"
+    params["ieee8021x"] = "1"
+    params = dict(list(radius.items()) + list(params.items()))
+    hapd1 = hostapd.add_ap(apdev[1], params)
+
+    run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, eap=True,
+              sha384=True)
+
+    if dev[0].get_status_field('bssid') == apdev[0]['bssid']:
+        pasn_hapd = hapd1
+    else:
+        pasn_hapd = hapd0
+
+    check_pasn_akmp_cipher(dev[0], pasn_hapd, "FT-EAP-SHA384", "CCMP")
+
+def test_pasn_sta_mic_error(dev, apdev):
+    """PASN authentication with WPA2/CCMP AP with corrupted MIC on station"""
+    check_pasn_capab(dev[0])
+
+    params = pasn_ap_params("PASN", "CCMP", "19")
+    hapd = hostapd.add_ap(apdev[0], params)
+
+    try:
+        # When forcing MIC corruption, the exchange would be still successful
+        # on the station side, but the AP would fail the exchange and would not
+        # store the keys.
+        dev[0].set("pasn_corrupt_mic", "1")
+        check_pasn_akmp_cipher(dev[0], hapd, "PASN", "CCMP", fail_ptk=True)
+    finally:
+        dev[0].set("pasn_corrupt_mic", "0")
+
+    # Now verify the successful case
+    check_pasn_akmp_cipher(dev[0], hapd, "PASN", "CCMP")
+
+def test_pasn_ap_mic_error(dev, apdev):
+    """PASN authentication with WPA2/CCMP AP with corrupted MIC on AP"""
+    check_pasn_capab(dev[0])
+
+    params = pasn_ap_params("PASN", "CCMP", "19")
+    hapd0 = hostapd.add_ap(apdev[0], params)
+
+    params['pasn_corrupt_mic'] = "1"
+    hapd1 = hostapd.add_ap(apdev[1], params)
+
+    check_pasn_akmp_cipher(dev[0], hapd1, "PASN", "CCMP", status=1)
+    check_pasn_akmp_cipher(dev[0], hapd0, "PASN", "CCMP")
+
+@remote_compatible
+def test_pasn_comeback(dev, apdev, params):
+    """PASN authentication with comeback flow"""
+    check_pasn_capab(dev[0])
+
+    params = pasn_ap_params("PASN", "CCMP", "19")
+    params['sae_anti_clogging_threshold'] = '0'
+    hapd = hostapd.add_ap(apdev[0], params)
+    bssid = hapd.own_addr()
+
+    dev[0].scan(type="ONLY", freq=2412)
+    cmd = "PASN_START bssid=%s akmp=PASN cipher=CCMP group=19" % bssid
+
+    resp = dev[0].request(cmd)
+    if "OK" not in resp:
+        raise Exception("Failed to start PASN authentication")
+
+    ev = dev[0].wait_event(["PASN-AUTH-STATUS"], 3)
+    if not ev:
+        raise Exception("PASN: PASN-AUTH-STATUS not seen")
+
+    if bssid + " akmp=PASN, status=30 comeback_after=" not in ev:
+        raise Exception("PASN: unexpected status")
+
+    comeback = re.split("comeback=", ev)[1]
+
+    cmd = "PASN_START bssid=%s akmp=PASN cipher=CCMP group=19 comeback=%s" % \
+            (bssid, comeback)
+
+    resp = dev[0].request(cmd)
+    if "OK" not in resp:
+        raise Exception("Failed to start PASN authentication")
+
+    ev = dev[0].wait_event(["PASN-AUTH-STATUS"], 3)
+    if not ev:
+        raise Exception("PASN: PASN-AUTH-STATUS not seen")
+
+    if bssid + " akmp=PASN, status=0" not in ev:
+        raise Exception("PASN: unexpected status with comeback token")
+
+    check_pasn_ptk(dev[0], hapd, "CCMP")
+
+@remote_compatible
+def test_pasn_comeback_after_0(dev, apdev, params):
+    """PASN authentication with comeback flow with comeback after set to 0"""
+    check_pasn_capab(dev[0])
+
+    params = pasn_ap_params("PASN", "CCMP", "19")
+    params['anti_clogging_threshold'] = '0'
+    params['pasn_comeback_after'] = '0'
+    hapd = start_pasn_ap(apdev[0], params)
+
+    check_pasn_akmp_cipher(dev[0], hapd, "PASN", "CCMP")
+
+@remote_compatible
+def test_pasn_comeback_after_0_sae(dev, apdev):
+    """PASN authentication with SAE, with comeback flow where comeback after is set to 0"""
+    check_pasn_capab(dev[0])
+    check_sae_capab(dev[0])
+
+    params = hostapd.wpa2_params(ssid="test-pasn-sae",
+                                 passphrase="12345678")
+    params['wpa_key_mgmt'] = 'SAE PASN'
+    params['anti_clogging_threshold'] = '0'
+    params['pasn_comeback_after'] = '0'
+    params['sae_pwe'] = "2"
+    hapd = start_pasn_ap(apdev[0], params)
+
+    try:
+        dev[0].set("sae_pwe", "2")
+        dev[0].connect("test-pasn-sae", psk="12345678", key_mgmt="SAE",
+                       scan_freq="2412", only_add_network=True)
+
+        # first test with a valid PSK
+        check_pasn_akmp_cipher(dev[0], hapd, "SAE", "CCMP", nid="0")
+
+        # And now with PMKSA caching
+        check_pasn_akmp_cipher(dev[0], hapd, "SAE", "CCMP")
+
+        # And now with a wrong passphrase
+        if "FAIL" in dev[0].request("PMKSA_FLUSH"):
+            raise Exception("PMKSA_FLUSH failed")
+
+        dev[0].set_network_quoted(0, "psk", "12345678787")
+        check_pasn_akmp_cipher(dev[0], hapd, "SAE", "CCMP", status=1, nid="0")
+    finally:
+        dev[0].set("sae_pwe", "0")
+
+@remote_compatible
+def test_pasn_comeback_multi(dev, apdev):
+    """PASN authentication with SAE, with multiple stations with comeback"""
+    check_pasn_capab(dev[0])
+    check_sae_capab(dev[0])
+
+    params = hostapd.wpa2_params(ssid="test-pasn-sae",
+                                 passphrase="12345678")
+    params['wpa_key_mgmt'] = 'SAE PASN'
+    params['anti_clogging_threshold'] = '1'
+    params['pasn_comeback_after'] = '0'
+    hapd = start_pasn_ap(apdev[0], params)
+    bssid = hapd.own_addr()
+
+    id = {}
+    for i in range(0, 2):
+        dev[i].flush_scan_cache()
+        dev[i].scan(type="ONLY", freq=2412)
+        id[i] = dev[i].connect("test-pasn-sae", psk="12345678", key_mgmt="SAE",
+                               scan_freq="2412", only_add_network=True)
+
+    for i in range(0, 2):
+        cmd = "PASN_START bssid=%s akmp=PASN cipher=CCMP group=19, nid=%s" % (bssid, id[i])
+        resp = dev[i].request(cmd)
+
+        if "OK" not in resp:
+            raise Exception("Failed to start pasn authentication")
+
+    for i in range(0, 2):
+        ev = dev[i].wait_event(["PASN-AUTH-STATUS"], 3)
+        if not ev:
+            raise Exception("PASN: PASN-AUTH-STATUS not seen")
+
+        if bssid + " akmp=PASN, status=0" not in ev:
+            raise Exception("PASN: unexpected status")
+
+        check_pasn_ptk(dev[i], hapd, "CCMP")
+
+def test_pasn_kdk_derivation(dev, apdev):
+    """PASN authentication with forced KDK derivation"""
+    check_pasn_capab(dev[0])
+
+    params = pasn_ap_params("PASN", "CCMP", "19")
+    hapd0 = start_pasn_ap(apdev[0], params)
+
+    params['force_kdk_derivation'] = "1"
+    hapd1 = start_pasn_ap(apdev[1], params)
+
+    try:
+        check_pasn_akmp_cipher(dev[0], hapd0, "PASN", "CCMP")
+        dev[0].set("force_kdk_derivation", "1")
+        check_pasn_akmp_cipher(dev[0], hapd1, "PASN", "CCMP")
+    finally:
+        dev[0].set("force_kdk_derivation", "0")
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_pmksa_cache.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_pmksa_cache.py
index 526f7f4..10d76a3 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_pmksa_cache.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_pmksa_cache.py
@@ -1251,3 +1251,17 @@
         raise Exception("ENABLE failed")
     sock.send(_bssid + foreign + proto + struct.pack('>BBH', 2, 1, 0))
     sock.send(_bssid + foreign2 + proto + struct.pack('>BBH', 2, 1, 0))
+
+def test_pmksa_cache_add_failure(dev, apdev):
+    """PMKSA cache add failure"""
+    params = hostapd.wpa2_eap_params(ssid="test-pmksa-cache")
+    hostapd.add_ap(apdev[0], params)
+    bssid = apdev[0]['bssid']
+    with alloc_fail(dev[0], 1, "pmksa_cache_add"):
+        dev[0].connect("test-pmksa-cache", proto="RSN", key_mgmt="WPA-EAP",
+                       eap="GPSK", identity="gpsk user",
+                       password="abcdefghijklmnop0123456789abcdef",
+                       scan_freq="2412")
+    pmksa = dev[0].get_pmksa(bssid)
+    if pmksa is None:
+        raise Exception("No PMKSA cache entry created")
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_radius.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_radius.py
index 16a29ec..ca96c97 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_radius.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_radius.py
@@ -313,6 +313,20 @@
     req_e = int(as_mib_end['radiusAccServTotalRequests'])
     if req_e < req_s + 3:
         raise Exception("Unexpected RADIUS server acct MIB value (req_e=%d req_s=%d)" % (req_e, req_s))
+    # Disable Accounting server and wait for interim update retries to fail and
+    # expire.
+    as_hapd.disable()
+    time.sleep(15)
+    as_hapd.enable()
+    ok = False
+    for i in range(10):
+        time.sleep(1)
+        as_mib = as_hapd.get_mib(param="radius_server")
+        if int(as_mib['radiusAccServTotalRequests']) > 0:
+            ok = True
+            break
+    if not ok:
+        raise Exception("Accounting updates did not seen after server restart")
 
 def test_radius_acct_interim_unreachable(dev, apdev):
     """RADIUS Accounting interim update with unreachable server"""
@@ -1372,6 +1386,13 @@
     hapd = hostapd.add_ap(apdev[0], params)
     connect(dev[0], "radius-auth")
 
+def test_radius_auth_force_client_dev(dev, apdev):
+    """RADIUS client device specified"""
+    params = hostapd.wpa2_eap_params(ssid="radius-auth")
+    params['radius_client_dev'] = "lo"
+    hapd = hostapd.add_ap(apdev[0], params)
+    connect(dev[0], "radius-auth")
+
 @remote_compatible
 def test_radius_auth_force_invalid_client_addr(dev, apdev):
     """RADIUS client address specified and invalid address"""
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_rrm.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_rrm.py
index 73782c9..db67131 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_rrm.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_rrm.py
@@ -90,6 +90,10 @@
     if "FAIL" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=test1 nr=" + nr):
         raise Exception("Set neighbor succeeded unexpectedly")
 
+    # Bad SSID end
+    if "FAIL" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1 nr=" + nr):
+        raise Exception("Set neighbor succeeded unexpectedly")
+
     # No SSID
     if "FAIL" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 nr=" + nr):
         raise Exception("Set neighbor succeeded unexpectedly")
@@ -208,6 +212,27 @@
     if apdev[0]['bssid'] not in res:
         raise Exception("Own BSS not visible in SHOW_NEIGHBOR output")
 
+def test_rrm_neighbor_db_failures(dev, apdev):
+    """hostapd ctrl_iface SET_NEIGHBOR failures"""
+    params = {"ssid": "test", "rrm_neighbor_report": "1"}
+    hapd = hostapd.add_ap(apdev[0]['ifname'], params)
+    cmd = "SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1\" nr=" + nr + " lci=" + lci + " civic=" + civic
+    tests = [(1, "hostapd_neighbor_add"),
+             (1, "wpabuf_dup;hostapd_neighbor_set"),
+             (2, "wpabuf_dup;hostapd_neighbor_set"),
+             (3, "wpabuf_dup;hostapd_neighbor_set")]
+    for count, func in tests:
+        with alloc_fail(hapd, count, func):
+            if "FAIL" not in hapd.request(cmd):
+                raise Exception("Set neighbor succeeded")
+
+def test_rrm_neighbor_db_disabled(dev, apdev):
+    """hostapd ctrl_iface SHOW_NEIGHBOR while neighbor report disabled"""
+    params = {"ssid": "test"}
+    hapd = hostapd.add_ap(apdev[0]['ifname'], params)
+    if "FAIL" not in hapd.request("SHOW_NEIGHBOR"):
+        raise Exception("SHOW_NEIGHBOR accepted")
+
 def test_rrm_neighbor_rep_req(dev, apdev):
     """wpa_supplicant ctrl_iface NEIGHBOR_REP_REQUEST"""
     check_rrm_support(dev[0])
@@ -216,9 +241,9 @@
     nr2 = "00112233445600000000510107"
     nr3 = "dd112233445500000000510107"
 
-    params = {"ssid": "test"}
+    params = {"ssid": "test", "rnr": "1"}
     hostapd.add_ap(apdev[0]['ifname'], params)
-    params = {"ssid": "test2", "rrm_neighbor_report": "1"}
+    params = {"ssid": "test2", "rrm_neighbor_report": "1", "rnr": "1"}
     hapd = hostapd.add_ap(apdev[1]['ifname'], params)
 
     bssid1 = apdev[1]['bssid']
@@ -312,6 +337,11 @@
         raise Exception("Request failed")
     check_nr_results(dev[0], ["dd:11:22:33:44:55"], lci=True)
 
+    if "OK" not in hapd.request("UPDATE_BEACON"):
+        raise Exception("UPDATE_BEACON failed")
+    time.sleep(0.2)
+    dev[1].connect("test2", key_mgmt="NONE", scan_freq="2412")
+
 def test_rrm_neighbor_rep_oom(dev, apdev):
     """hostapd neighbor report OOM"""
     check_rrm_support(dev[0])
@@ -811,6 +841,9 @@
 
     tests = ["REQ_BEACON ",
              "REQ_BEACON q",
+             "REQ_BEACON 11:22:33:44:55:66",
+             "REQ_BEACON 11:22:33:44:55:66 req_mode=q",
+             "REQ_BEACON 11:22:33:44:55:66 req_mode=11",
              "REQ_BEACON 11:22:33:44:55:66 1",
              "REQ_BEACON 11:22:33:44:55:66 1q",
              "REQ_BEACON 11:22:33:44:55:66 11223344556677889900aabbccddeeff"]
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_sae.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_sae.py
index 9276e51..abadc30 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_sae.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_sae.py
@@ -52,6 +52,15 @@
     pmk_w = dev[0].get_pmk(id)
     if pmk_h != pmk_w:
         raise Exception("Fetched PMK does not match: hostapd %s, wpa_supplicant %s" % (pmk_h, pmk_w))
+    dev[0].request("DISCONNECT")
+    dev[0].wait_disconnected()
+    pmk_h2 = hapd.request("GET_PMK " + dev[0].own_addr())
+    if pmk_h != pmk_h2:
+        raise Exception("Fetched PMK from PMKSA cache does not match: %s, %s" % (pmk_h, pmk_h2))
+    if "FAIL" not in hapd.request("GET_PMK foo"):
+        raise Exception("Invalid GET_PMK did not return failure")
+    if "FAIL" not in hapd.request("GET_PMK 02:ff:ff:ff:ff:ff"):
+        raise Exception("GET_PMK for unknown STA did not return failure")
 
 @remote_compatible
 def test_sae_password_ecc(dev, apdev):
@@ -225,7 +234,7 @@
     params['sae_groups'] = '19'
     hostapd.add_ap(apdev[0], params)
 
-    dev[0].request("SET sae_groups 25 26 20 19")
+    dev[0].request("SET sae_groups 25 20 19")
     dev[0].connect("test-sae-group-nego", psk="12345678", key_mgmt="SAE",
                    scan_freq="2412")
     if dev[0].get_status_field('sae_group') != '19':
@@ -327,6 +336,61 @@
     dev[0].connect("test-psk", psk="12345678", key_mgmt="SAE WPA-PSK",
                    scan_freq="2412")
 
+def test_sae_wpa3_roam(dev, apdev):
+    """SAE and WPA3-Personal transition mode roaming"""
+    check_sae_capab(dev[0])
+
+    # WPA3-Personal only AP
+    params = hostapd.wpa2_params(ssid="test", passphrase="12345678")
+    params['ieee80211w'] = '2'
+    params['wpa_key_mgmt'] = 'SAE'
+    hapd0 = hostapd.add_ap(apdev[0], params)
+
+    # WPA2-Personal only AP
+    params = hostapd.wpa2_params(ssid="test", passphrase="12345678")
+    hapd1 = hostapd.add_ap(apdev[1], params)
+
+    dev[0].set("sae_groups", "")
+    dev[0].connect("test", psk="12345678", key_mgmt="SAE WPA-PSK",
+                   ieee80211w="1", scan_freq="2412")
+    bssid = dev[0].get_status_field('bssid')
+
+    # Disable the current AP to force roam to the other one
+    if bssid == apdev[0]['bssid']:
+        hapd0.disable()
+    else:
+        hapd1.disable()
+    dev[0].wait_connected()
+
+    # Disable the current AP to force roam to the other (previous) one
+    if bssid == apdev[0]['bssid']:
+        hapd0.enable()
+        hapd1.disable()
+    else:
+        hapd1.enable()
+        hapd0.disable()
+    dev[0].wait_connected()
+
+    # Force roam to an AP in WPA3-Personal transition mode
+    if bssid == apdev[0]['bssid']:
+        hapd1.set("ieee80211w", "1")
+        hapd1.set("sae_require_mfp", "1")
+        hapd1.set("wpa_key_mgmt", "SAE WPA-PSK")
+        hapd1.enable()
+        hapd0.disable()
+    else:
+        hapd0.set("ieee80211w", "1")
+        hapd0.set("sae_require_mfp", "1")
+        hapd0.set("wpa_key_mgmt", "SAE WPA-PSK")
+        hapd0.enable()
+        hapd1.disable()
+    dev[0].wait_connected()
+    status = dev[0].get_status()
+    if status['key_mgmt'] != "SAE":
+        raise Exception("Did not use SAE with WPA3-Personal transition mode AP")
+    if status['pmf'] != "1":
+        raise Exception("Did not use PMF with WPA3-Personal transition mode AP")
+
 def test_sae_mixed_mfp(dev, apdev):
     """Mixed SAE and non-SAE network and MFP required with SAE"""
     check_sae_capab(dev[0])
@@ -1426,8 +1490,7 @@
              (1, "crypto_bignum_init_set;sae_test_pwd_seed_ecc"),
              (1, "crypto_ec_point_compute_y_sqr;sae_test_pwd_seed_ecc"),
              (1, "crypto_bignum_to_bin;sae_derive_pwe_ecc"),
-             (1, "crypto_ec_point_init;sae_derive_pwe_ecc"),
-             (1, "crypto_ec_point_solve_y_coord;sae_derive_pwe_ecc"),
+             (1, "crypto_ec_point_compute_y_sqr;sae_derive_pwe_ecc"),
              (1, "crypto_ec_point_init;sae_derive_commit_element_ecc"),
              (1, "crypto_ec_point_mul;sae_derive_commit_element_ecc"),
              (1, "crypto_ec_point_invert;sae_derive_commit_element_ecc"),
@@ -2052,7 +2115,7 @@
     check_sae_capab(dev[0])
     tls = dev[0].request("GET tls_library")
     if group in [27, 28, 29, 30]:
-        if tls.startswith("OpenSSL") and "run=OpenSSL 1." in tls:
+        if tls.startswith("OpenSSL") and ("run=OpenSSL 1." in tls or "run=OpenSSL 3." in tls):
             logger.info("Add Brainpool EC groups since OpenSSL is new enough")
         else:
             raise HwsimSkip("Brainpool curve not supported")
@@ -2524,7 +2587,7 @@
         raise Exception("SAE authentication not used during roam to AP2 after reauth threshold")
 
 def test_sae_pmk_lifetime(dev, apdev):
-    """SAE and opportunistic key caching and PMK lifetime"""
+    """SAE and PMK lifetime"""
     check_sae_capab(dev[0])
     params = hostapd.wpa2_params(ssid="test-sae", passphrase="12345678")
     params['wpa_key_mgmt'] = 'SAE'
@@ -2568,19 +2631,8 @@
     ev = dev[0].wait_event(["PMKSA-CACHE-REMOVED"], 11)
     if ev is None:
         raise Exception("PMKSA cache entry did not expire")
-    if bssid2 not in ev:
-        ev = dev[0].wait_event(["PMKSA-CACHE-REMOVED"], 11)
-        if ev is None:
-            raise Exception("PMKSA cache entry did not expire")
-        if bssid2 not in ev:
-            raise Exception("PMKSA cache entry for the current AP did not expire")
-    ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], 1)
-    if ev is None:
-        raise Exception("Disconnection not reported after PMKSA cache entry expiration")
-
-    dev[0].wait_connected()
-    if "sae_group" not in dev[0].get_status():
-        raise Exception("SAE authentication not used after PMKSA cache entry expiration")
+    if bssid2 in ev:
+        raise Exception("Unexpected expiration of the current SAE PMKSA cache entry")
 
 def test_sae_and_psk_multiple_passwords(dev, apdev, params):
     """SAE and PSK with multiple passwords/passphrases"""
@@ -2711,3 +2763,19 @@
         raise Exception("hostapd did not report correct PMK after disconnection")
     if pmk_w2 != pmk_w:
         raise Exception("wpa_supplicant did not report correct PMK after disconnection")
+
+def test_sae_reject(dev, apdev):
+    """SAE and AP rejecting connection"""
+    check_sae_capab(dev[0])
+    params = hostapd.wpa2_params(ssid="test-sae",
+                                 passphrase="12345678")
+    params['wpa_key_mgmt'] = 'SAE'
+    params['max_num_sta'] = '0'
+    hapd = hostapd.add_ap(apdev[0], params)
+    dev[0].set("sae_groups", "")
+    id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
+                        scan_freq="2412", wait_connect=False)
+    if not dev[0].wait_event(["CTRL-EVENT-AUTH-REJECT"], timeout=10):
+        raise Exception("Authentication rejection not reported")
+    dev[0].request("REMOVE_NETWORK all")
+    dev[0].dump_monitor()
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_scan.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_scan.py
index 2e64cee..24a7903 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_scan.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_scan.py
@@ -654,6 +654,10 @@
 
 def test_scan_setband(dev, apdev):
     """Band selection for scan operations"""
+    wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
+    wpas.interface_add("wlan5")
+    devs = [ dev[0], dev[1], dev[2], wpas ]
+
     try:
         hapd = None
         hapd2 = None
@@ -678,21 +682,26 @@
             raise Exception("Failed to set setband")
         if "OK" not in dev[2].request("SET setband 2G"):
             raise Exception("Failed to set setband")
+        if "OK" not in wpas.request("SET setband 2G,5G"):
+            raise Exception("Failed to set setband")
 
         # Allow a retry to avoid reporting errors during heavy load
         for j in range(5):
-            for i in range(3):
-                dev[i].request("SCAN only_new=1")
+            for d in devs:
+                d.request("SCAN only_new=1")
 
-            for i in range(3):
-                ev = dev[i].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 15)
+            for d in devs:
+                ev = d.wait_event(["CTRL-EVENT-SCAN-RESULTS"], 15)
                 if ev is None:
                     raise Exception("Scan timed out")
 
             res0 = dev[0].request("SCAN_RESULTS")
             res1 = dev[1].request("SCAN_RESULTS")
             res2 = dev[2].request("SCAN_RESULTS")
-            if bssid in res0 and bssid2 in res0 and bssid in res1 and bssid2 in res2:
+            res3 = wpas.request("SCAN_RESULTS")
+            if bssid in res0 and bssid2 in res0 and \
+               bssid in res1 and bssid2 in res2 and \
+               bssid in res3 and bssid2 in res3:
                 break
 
         res = dev[0].request("SCAN_RESULTS")
@@ -710,15 +719,19 @@
             raise Exception("Missing scan result(2)")
         if bssid in res:
             raise Exception("Unexpected scan result(2)")
+
+        res = wpas.request("SCAN_RESULTS")
+        if bssid not in res or bssid2 not in res:
+            raise Exception("Missing scan result(3)")
     finally:
         if hapd:
             hapd.request("DISABLE")
         if hapd2:
             hapd2.request("DISABLE")
         subprocess.call(['iw', 'reg', 'set', '00'])
-        for i in range(3):
-            dev[i].request("SET setband AUTO")
-            dev[i].flush_scan_cache()
+        for d in devs:
+            d.request("SET setband AUTO")
+            d.flush_scan_cache()
 
 @remote_compatible
 def test_scan_hidden_many(dev, apdev):
@@ -1137,7 +1150,7 @@
     try:
         if "OK" not in dev[0].request("SET setband 2G"):
             raise Exception("SET setband failed")
-        with alloc_fail(dev[0], 1, "=wpa_setband_scan_freqs_list"):
+        with alloc_fail(dev[0], 1, "=wpa_add_scan_freqs_list"):
             # While the frequency list cannot be created due to memory
             # allocation failure, this scan is expected to be completed without
             # frequency filtering.
@@ -1976,6 +1989,9 @@
                 break
     finally:
         dev[0].request("VENDOR_ELEM_REMOVE 14 *")
+        hapd.disable()
+        dev[0].flush_scan_cache(freq=2432)
+        dev[0].flush_scan_cache()
 
     if not found:
         raise Exception("AP not found in scan results")
@@ -2001,6 +2017,9 @@
                 break
     finally:
         dev[0].request("VENDOR_ELEM_REMOVE 14 *")
+        hapd.disable()
+        dev[0].flush_scan_cache(freq=2432)
+        dev[0].flush_scan_cache()
 
     if not found:
         raise Exception("AP not found in scan results")
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_scs.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_scs.py
new file mode 100755
index 0000000..df63cbf
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_scs.py
@@ -0,0 +1,196 @@
+# Test cases for SCS
+# Copyright (c) 2021, Jouni Malinen <j@w1.fi>
+# Copyright (c) 2021, The Linux Foundation
+#
+# This software may be distributed under the terms of the BSD license.
+# See README for more details.
+
+import struct
+import time
+
+import hostapd
+from utils import *
+
+def register_scs_req(hapd):
+    type = 0x00d0
+    match = "1300"
+    if "OK" not in hapd.request("REGISTER_FRAME %04x %s" % (type, match)):
+        raise Exception("Could not register frame reception for Robust AV Streaming")
+
+def handle_scs_req(hapd, wrong_dialog=False, status_code=0, twice=False,
+                   short=False, scsid=1):
+    msg = hapd.mgmt_rx()
+    if msg['subtype'] != 13:
+        logger.info("RX:" + str(msg))
+        raise Exception("Received unexpected Management frame")
+    categ, act, dialog_token = struct.unpack('BBB', msg['payload'][0:3])
+    if categ != 19 or act != 0:
+        logger.info("RX:" + str(msg))
+        raise Exception("Received unexpected Action frame")
+
+    if wrong_dialog:
+        dialog_token = (dialog_token + 1) % 256
+    msg['da'] = msg['sa']
+    msg['sa'] = hapd.own_addr()
+    count = 1
+    if short:
+        resp = struct.pack('BBB', 19, 1, dialog_token)
+    else:
+        resp = struct.pack('BBBB', 19, 1, dialog_token, count)
+        resp += struct.pack('<BH', scsid, status_code)
+    msg['payload'] = resp
+    hapd.mgmt_tx(msg)
+    ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
+    if ev is None or "stype=13 ok=1" not in ev:
+        raise Exception("No TX status reported")
+    if twice:
+        hapd.mgmt_tx(msg)
+        ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
+        if ev is None or "stype=13 ok=1" not in ev:
+            raise Exception("No TX status reported")
+
+def wait_scs_result(dev, expect_status="0"):
+    ev = dev.wait_event(["CTRL-EVENT-SCS-RESULT"], timeout=2)
+    if ev is None:
+        raise Exception("No SCS result reported")
+    if "status_code=%s" % expect_status not in ev:
+        raise Exception("Unexpected SCS result: " + ev)
+
+def test_scs_invalid_params(dev, apdev):
+    """SCS command invalid parameters"""
+    tests = ["",
+             "scs_id=1",
+             "scs_id=1 foo",
+             "scs_id=1 add ",
+             "scs_id=1 add scs_up=8",
+             "scs_id=1 add scs_up=7",
+             "scs_id=1 add scs_up=7 classifier_type=1",
+             "scs_id=1 add scs_up=7 classifier_type=4",
+             "scs_id=1 add scs_up=7 classifier_type=4 ip_version=ipv4",
+             "scs_id=1 add scs_up=7 classifier_type=4 ip_version=ipv4 src_ip=q",
+             "scs_id=1 add scs_up=7 classifier_type=4 ip_version=ipv4 dst_ip=q",
+             "scs_id=1 add scs_up=7 classifier_type=4 ip_version=ipv4 src_port=q",
+             "scs_id=1 add scs_up=7 classifier_type=4 ip_version=ipv4 dst_port=q",
+             "scs_id=1 add scs_up=7 classifier_type=4 ip_version=ipv4 protocol=foo",
+             "scs_id=1 add scs_up=7 classifier_type=4 ip_version=ipv6 protocol=foo",
+             "scs_id=1 add scs_up=7 classifier_type=4 ip_version=ipv6 next_header=foo",
+             "scs_id=1 add scs_up=7 classifier_type=4 ip_version=ipv6 flow_label=ffffff",
+             "scs_id=1 add scs_up=7 classifier_type=10",
+             "scs_id=1 add scs_up=7 classifier_type=10 prot_instance=1",
+             "scs_id=1 add scs_up=7 classifier_type=10 prot_instance=1 prot_number=udp",
+             "scs_id=1 add scs_up=7 classifier_type=10 prot_instance=1 prot_number=udp filter_value=11223344",
+             "scs_id=1 add scs_up=7 classifier_type=10 prot_instance=1 prot_number=udp filter_value=qq",
+             "scs_id=1 add scs_up=7 classifier_type=10 prot_instance=1 prot_number=udp filter_value=11223344 filter_mask=ffffff",
+             "scs_id=1 add scs_up=7 classifier_type=10 prot_instance=1 prot_number=udp filter_value=11223344 filter_mask=qqqqqqqq",
+             "scs_id=1 add scs_up=7 classifier_type=10 prot_instance=1 prot_number=udp filter_value=11223344 filter_mask=ffffffff",
+             "scs_id=1 add scs_up=7 classifier_type=10 prot_instance=1 prot_number=foo filter_value=11223344 filter_mask=ffffffff",
+             "scs_id=1 add scs_up=7 classifier_type=10 prot_instance=1 prot_number=udp filter_value=11 filter_mask=ee classifier_type=10 prot_instance=2 prot_number=udp filter_value=22 filter_mask=ff",
+             "scs_id=1 add scs_up=7 classifier_type=10 prot_instance=1 prot_number=udp filter_value=11 filter_mask=ee classifier_type=10 prot_instance=2 prot_number=udp filter_value=22 filter_mask=ff tclas_processing=2",
+             "scs_id=1 add scs_up=7 classifier_type=10 prot_instance=1 prot_number=udp filter_value=11 filter_mask=ee classifier_type=10 prot_instance=2 prot_number=udp filter_value=22 filter_mask=ff tclas_processing=0",
+             "scs_id=1 add scs_up=6 classifier_type=4 ip_version=ipv4 src_ip=1.2.3.4 dst_ip=5.6.7.8 src_port=12345 dst_port=23456 dscp=5 protocol=udp scs_id=1 add scs_up=6 classifier_type=4 ip_version=ipv4 src_ip=1.2.3.4 dst_ip=5.6.7.8 src_port=12345 dst_port=23456 dscp=5 protocol=tcp"
+             "scs_id=1 remove",
+             "scs_id=1 change "]
+    for t in tests:
+        if "FAIL" not in dev[0].request("SCS " + t):
+            raise Exception("Invalid SCS parameters accepted: " + t)
+
+def test_scs_request(dev, apdev):
+    """SCS Request"""
+    params = {"ssid": "scs",
+              "ext_capa": 6*"00" + "40"}
+    hapd = hostapd.add_ap(apdev[0], params)
+    register_scs_req(hapd)
+
+    dev[0].connect("scs", key_mgmt="NONE", scan_freq="2412")
+
+    hapd.dump_monitor()
+    hapd.set("ext_mgmt_frame_handling", "1")
+
+    cmd = "SCS scs_id=1 add scs_up=7 classifier_type=10 prot_instance=1 prot_number=udp filter_value=11223344 filter_mask=ffffffff"
+    if "OK" not in dev[0].request(cmd):
+        raise Exception("SCS add failed")
+
+    handle_scs_req(hapd)
+    wait_scs_result(dev[0])
+
+    cmd = "SCS scs_id=2 add scs_up=5 classifier_type=10 prot_instance=1 prot_number=udp filter_value=11223344 filter_mask=ffffffff"
+    if "OK" not in dev[0].request(cmd):
+        raise Exception("SCS add failed")
+
+    handle_scs_req(hapd, wrong_dialog=True)
+    ev = dev[0].wait_event(["CTRL-EVENT-SCS-RESULT"], timeout=2)
+    if ev is None:
+        raise Exception("No SCS result reported")
+    if "status_code=timedout" not in ev:
+        raise Exception("Timeout not reported: " + ev)
+
+    cmd = "SCS scs_id=1 add scs_up=5 classifier_type=10 prot_instance=1 prot_number=udp filter_value=11223344 filter_mask=ffffffff"
+    if "FAIL" not in dev[0].request(cmd):
+        raise Exception("SCS add for already configured scs_id did not fail")
+
+    cmd = "SCS scs_id=1 remove"
+    if "OK" not in dev[0].request(cmd):
+        raise Exception("SCS remove failed")
+    handle_scs_req(hapd)
+    wait_scs_result(dev[0])
+
+    tests = ["scs_up=6 classifier_type=4 ip_version=ipv4 src_ip=1.2.3.4 dst_ip=5.6.7.8 src_port=12345 dst_port=23456 dscp=5 protocol=udp",
+             "scs_up=6 classifier_type=4 ip_version=ipv4 src_ip=1.2.3.4 dst_ip=5.6.7.8 src_port=12345 dst_port=23456 dscp=5 protocol=tcp",
+             "scs_up=6 classifier_type=4 ip_version=ipv4 src_ip=1.2.3.4 dst_ip=5.6.7.8 src_port=12345 dst_port=23456 dscp=5 protocol=esp",
+             "scs_up=6 classifier_type=4 ip_version=ipv6 src_ip=::1 dst_ip=::1 src_port=12345 dst_port=23456 dscp=5 next_header=udp",
+             "scs_up=6 classifier_type=4 ip_version=ipv6 src_ip=::1 dst_ip=::1 src_port=12345 dst_port=23456 dscp=5 next_header=tcp",
+             "scs_up=6 classifier_type=4 ip_version=ipv6 src_ip=::1 dst_ip=::1 src_port=12345 dst_port=23456 dscp=5 next_header=esp flow_label=012345",
+             "scs_up=6 classifier_type=10 prot_instance=1 prot_number=tcp filter_value=11223344 filter_mask=ffffffff",
+             "scs_up=6 classifier_type=10 prot_instance=1 prot_number=esp filter_value=11223344 filter_mask=ffffffff",
+             "scs_up=6 classifier_type=10 prot_instance=1 prot_number=udp filter_value=11223344 filter_mask=ffffffff",
+             "scs_up=6 classifier_type=4 ip_version=ipv4 src_ip=1.2.3.4 dst_ip=5.6.7.8 src_port=12345 dst_port=23456 dscp=5 protocol=udp classifier_type=4 ip_version=ipv4 src_ip=1.2.3.4 dst_ip=5.6.7.8 src_port=12345 dst_port=23456 dscp=5 protocol=tcp tclas_processing=1",
+             "scs_up=6 classifier_type=4 ip_version=ipv4 src_ip=1.2.3.4 dst_ip=5.6.7.8 src_port=12345 dst_port=23456 dscp=5 protocol=udp scs_id=10 add scs_up=6 classifier_type=4 ip_version=ipv4 src_ip=1.2.3.4 dst_ip=5.6.7.8 src_port=12345 dst_port=23456 dscp=5 protocol=tcp"]
+    for t in tests:
+        cmd = "SCS scs_id=1 change " + t
+        if "OK" not in dev[0].request(cmd):
+            raise Exception("SCS change failed: " + t)
+        handle_scs_req(hapd)
+        wait_scs_result(dev[0])
+        if "scs_id=" in t:
+            wait_scs_result(dev[0], expect_status="response_not_received")
+
+    cmd = "SCS scs_id=1 change scs_up=6 classifier_type=4 ip_version=ipv4 src_ip=1.2.3.4 dst_ip=5.6.7.8 src_port=12345 dst_port=23456 dscp=5 protocol=udp"
+    if "OK" not in dev[0].request(cmd):
+        raise Exception("SCS change failed: " + t)
+    if "FAIL" not in dev[0].request(cmd):
+        raise Exception("SCS change failed: " + t)
+    handle_scs_req(hapd, twice=True)
+    wait_scs_result(dev[0])
+    ev = dev[0].wait_event(["CTRL-EVENT-SCS-RESULT"], timeout=0.1)
+    if ev is not None:
+        raise Exception("Unexpected SCS result reported(1)")
+
+    if "OK" not in dev[0].request(cmd):
+        raise Exception("SCS change failed: " + t)
+    handle_scs_req(hapd, short=True)
+    ev = dev[0].wait_event(["CTRL-EVENT-SCS-RESULT"], timeout=3)
+    if ev is not None:
+        raise Exception("Unexpected SCS result reported(2)")
+
+    cmd = "SCS scs_id=123 add scs_up=6 classifier_type=4 ip_version=ipv4 src_ip=1.2.3.4 dst_ip=5.6.7.8 src_port=12345 dst_port=23456 dscp=5 protocol=udp"
+    if "OK" not in dev[0].request(cmd):
+        raise Exception("SCS add failed: " + t)
+    handle_scs_req(hapd, scsid=34)
+    wait_scs_result(dev[0], expect_status="response_not_received")
+
+    cmd = "SCS scs_id=33 add scs_up=6 classifier_type=4 ip_version=ipv4 src_ip=1.2.3.4 dst_ip=5.6.7.8 src_port=12345 dst_port=23456 dscp=5 protocol=udp"
+    if "OK" not in dev[0].request(cmd):
+        raise Exception("SCS add failed: " + t)
+    handle_scs_req(hapd, scsid=33, status_code=123)
+    wait_scs_result(dev[0], expect_status="123")
+
+def test_scs_request_without_ap_capa(dev, apdev):
+    """SCS Request without AP capability"""
+    params = {"ssid": "scs"}
+    hapd = hostapd.add_ap(apdev[0], params)
+
+    dev[0].connect("scs", key_mgmt="NONE", scan_freq="2412")
+
+    cmd = "SCS scs_id=1 add scs_up=7 classifier_type=10 prot_instance=1 prot_number=udp filter_value=11223344 filter_mask=ffffffff"
+    if "FAIL" not in dev[0].request(cmd):
+        raise Exception("SCS add accepted")
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_sigma_dut.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_sigma_dut.py
index e2151cf..5450c33 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_sigma_dut.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_sigma_dut.py
@@ -2240,7 +2240,7 @@
             dev[1].dpp_listen(2437)
             dev[0].dpp_auth_init(uri=uri, conf="sta-dpp", ssid="DPPNET01",
                                  configurator=conf_id)
-            dev[1].wait_connected()
+            dev[1].wait_connected(timeout=20)
 
             sigma_dut_cmd_check("ap_reset_default,program,DPP")
         finally:
@@ -2334,7 +2334,7 @@
             cmd = "DPP_AUTH_INIT peer=%d conf=%s %s configurator=%d" % (id0b, sta_conf, extra, conf_id)
             if "OK" not in dev[0].request(cmd):
                 raise Exception("Failed to initiate DPP Authentication")
-            dev[1].wait_connected()
+            dev[1].wait_connected(timeout=20)
 
             sigma_dut_cmd_check("ap_reset_default")
         finally:
@@ -2389,7 +2389,7 @@
             cmd = "DPP_AUTH_INIT peer=%d conf=sta-dpp ssid=%s configurator=%d" % (id0b, to_hex("DPPNET01"), conf_id)
             if "OK" not in dev[0].request(cmd):
                 raise Exception("Failed to initiate DPP Authentication")
-            dev[1].wait_connected()
+            dev[1].wait_connected(timeout=20)
 
             sigma_dut_cmd_check("ap_reset_default")
         finally:
@@ -2914,7 +2914,7 @@
     res = sigma_dut_cmd(cmd)
     if "BootstrapResult,OK,AuthResult,OK,ConfResult,OK" not in res:
         raise Exception("Unexpected result: " + res)
-    dev[0].wait_connected()
+    dev[0].wait_connected(timeout=20)
     dev[0].request("DISCONNECT")
     dev[0].wait_disconnected()
     sigma_dut_cmd_check("ap_reset_default")
@@ -3114,6 +3114,7 @@
     res = sigma_dut_cmd(cmd, timeout=10)
     if "BootstrapResult,OK,AuthResult,OK,ConfResult,OK" not in res:
         raise Exception("Unexpected result: " + res)
+    sigma_dut_cmd_check("ap_reset_default")
 
 def test_sigma_dut_dpp_tcp_enrollee_init_mutual(dev, apdev):
     """sigma_dut DPP TCP Enrollee as initiator with mutual authentication"""
@@ -3391,7 +3392,7 @@
         if ev is None:
             raise Exception("DPP Config Response (reconfig) not transmitted")
 
-        dev[0].wait_connected()
+        dev[0].wait_connected(timeout=20)
         ev = dev[1].wait_event(["DPP-CONN-STATUS-RESULT"], timeout=20)
         if ev is None:
             raise Exception("No connection status reported")
@@ -3413,7 +3414,7 @@
         if ev is None:
             raise Exception("DPP Config Response (reconfig) not transmitted [2]")
 
-        dev[0].wait_connected()
+        dev[0].wait_connected(timeout=20)
     finally:
         dev[0].set("dpp_config_processing", "0")
         stop_sigma_dut(sigma)
@@ -4661,6 +4662,7 @@
 
 def test_sigma_dut_ap_transition_disable(dev, apdev, params):
     """sigma_dut controlled AP and transition disabled indication"""
+    check_sae_capab(dev[0])
     logdir = params['prefix'] + ".sigma-hostapd"
 
     with HWSimRadio() as (radio, iface):
@@ -4686,6 +4688,7 @@
 
 def test_sigma_dut_ap_transition_disable_change(dev, apdev, params):
     """sigma_dut controlled AP and transition disabled indication change"""
+    check_sae_capab(dev[0])
     logdir = params['prefix'] + ".sigma-hostapd"
 
     with HWSimRadio() as (radio, iface):
@@ -5214,11 +5217,12 @@
         sigma_dut_cmd_check("sta_reset_default,interface," + ifname)
     finally:
         stop_sigma_dut(sigma)
-        dev[1].set("mac_addr", "0", allow_fail=True)
-        dev[1].set("rand_addr_lifetime", "60", allow_fail=True)
-        dev[1].set("preassoc_mac_addr", "0", allow_fail=True)
-        dev[1].set("gas_rand_mac_addr", "0", allow_fail=True)
-        dev[1].set("gas_rand_addr_lifetime", "60", allow_fail=True)
+        dev[0].set("mac_addr", "0", allow_fail=True)
+        dev[0].set("rand_addr_lifetime", "60", allow_fail=True)
+        dev[0].request("MAC_RAND_SCAN enable=0 all")
+        dev[0].set("preassoc_mac_addr", "0", allow_fail=True)
+        dev[0].set("gas_rand_mac_addr", "0", allow_fail=True)
+        dev[0].set("gas_rand_addr_lifetime", "60", allow_fail=True)
 
     out = run_tshark(os.path.join(logdir, "hwsim0.pcapng"),
                      "wlan.addr == " + addr,
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_suite_b.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_suite_b.py
index 7065b18..2b3c30f 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_suite_b.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_suite_b.py
@@ -27,7 +27,7 @@
     if not tls.startswith("OpenSSL"):
         raise HwsimSkip("TLS library not supported for Suite B: " + tls)
     supported = False
-    for ver in ['1.0.2', '1.1.0', '1.1.1']:
+    for ver in ['1.0.2', '1.1.0', '1.1.1', '3.0']:
         if "build=OpenSSL " + ver in tls and "run=OpenSSL " + ver in tls:
             supported = True
             break
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wep.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wep.py
index 6df9ef8..5c1fc9a 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wep.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wep.py
@@ -130,6 +130,22 @@
         dev[0].request("DISCONNECT")
         clear_regdom(hapd, dev)
 
+def test_wep_he(dev, apdev):
+    """WEP and HE"""
+    check_wep_capa(dev[0])
+    dev[0].flush_scan_cache()
+    params = {"ssid": "test-he-wep",
+              "ieee80211ax": "1",
+              "wep_key0": '"hello"'}
+    hapd = hostapd.add_ap(apdev[0], params)
+    dev[0].connect("test-he-wep", scan_freq="2412", key_mgmt="NONE",
+                   wep_key0='"hello"')
+    hwsim_utils.test_connectivity(dev[0], hapd)
+    status = hapd.get_status()
+    logger.info("hostapd STATUS: " + str(status))
+    if status["ieee80211ax"] != "0":
+        raise Exception("Unexpected STATUS ieee80211ax value")
+
 def test_wep_ifdown(dev, apdev):
     """AP with WEP and external ifconfig down"""
     check_wep_capa(dev[0])
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wmediumd.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wmediumd.py
index ad38f03..8243e7c 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wmediumd.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wmediumd.py
@@ -1,4 +1,4 @@
-# wmediumd sanity checks
+# wmediumd validity checks
 # Copyright (c) 2015, Intel Deutschland GmbH
 #
 # This software may be distributed under the terms of the BSD license.
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wnm.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wnm.py
index c9a1609..88cb082 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wnm.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wnm.py
@@ -37,7 +37,8 @@
                  wnm_sleep_mode=False, wnm_sleep_mode_no_keys=False, rsn=False,
                  ocv=False, ap_max_inactivity=0, coloc_intf_reporting=False,
                  hw_mode=None, channel=None, country_code=None, country3=None,
-                 pmf=True, passphrase=None, ht=True, vht=False, mbo=False):
+                 pmf=True, passphrase=None, ht=True, vht=False, mbo=False,
+                 beacon_prot=False):
     if rsn:
         if not ssid:
             ssid = "test-wnm-rsn"
@@ -47,6 +48,8 @@
         if pmf:
             params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
             params["ieee80211w"] = "2"
+            if beacon_prot:
+                params["beacon_prot"] = "1"
     else:
         params = {"ssid": "test-wnm"}
     if bss_transition:
@@ -195,7 +198,8 @@
     if ev is None:
         raise Exception("Timeout while waiting for re-connection scan")
 
-def check_wnm_sleep_mode_enter_exit(hapd, dev, interval=None, tfs_req=None):
+def check_wnm_sleep_mode_enter_exit(hapd, dev, interval=None, tfs_req=None,
+                                    rekey=False):
     addr = dev.p2p_interface_addr()
     sta = hapd.get_sta(addr)
     if "[WNM_SLEEP_MODE]" in sta['flags']:
@@ -219,6 +223,14 @@
     if not ok:
         raise Exception("Station failed to enter WNM-Sleep Mode")
 
+    if rekey:
+        time.sleep(0.1)
+        if "OK" not in hapd.request("REKEY_GTK"):
+            raise Exception("REKEY_GTK failed")
+        ev = dev.wait_event(["WPA: Group rekeying completed"], timeout=0.1)
+        if ev is not None:
+                raise Exception("Unexpected report of GTK rekey during WNM-Sleep Mode")
+
     logger.info("Waking up from WNM Sleep Mode")
     ok = False
     dev.request("WNM_SLEEP exit")
@@ -231,6 +243,14 @@
     if not ok:
         raise Exception("Station failed to exit WNM-Sleep Mode")
 
+    if rekey:
+        time.sleep(0.1)
+        if "OK" not in hapd.request("REKEY_GTK"):
+            raise Exception("REKEY_GTK failed")
+        ev = dev.wait_event(["WPA: Group rekeying completed"], timeout=2)
+        if ev is None:
+                raise Exception("GTK rekey timed out")
+
 @remote_compatible
 def test_wnm_sleep_mode_open(dev, apdev):
     """WNM Sleep Mode - open"""
@@ -303,6 +323,19 @@
         raise Exception("No connection event received from hostapd")
     check_wnm_sleep_mode_enter_exit(hapd, dev[0])
 
+def test_wnm_sleep_mode_rsn_beacon_prot(dev, apdev):
+    """WNM Sleep Mode - RSN with PMF and beacon protection"""
+    hapd = start_wnm_ap(apdev[0], rsn=True, wnm_sleep_mode=True, time_adv=True,
+                        beacon_prot=True)
+    dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2",
+                   beacon_prot="1",
+                   key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412")
+    ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=5)
+    if ev is None:
+        raise Exception("No connection event received from hostapd")
+    check_wnm_sleep_mode_enter_exit(hapd, dev[0])
+    check_wnm_sleep_mode_enter_exit(hapd, dev[0], rekey=True)
+
 @remote_compatible
 def test_wnm_sleep_mode_rsn_ocv(dev, apdev):
     """WNM Sleep Mode - RSN with OCV"""
@@ -764,7 +797,7 @@
         dev[0].dump_monitor()
 
         logger.info("Neighbor list entry, but not claimed as Preferred Candidate List")
-        if "OK" not in hapd.request("BSS_TM_REQ " + addr + " neighbor=11:22:33:44:55:66,0x0000,81,3,7"):
+        if "OK" not in hapd.request("BSS_TM_REQ " + addr + " dialog_token=123 neighbor=11:22:33:44:55:66,0x0000,81,3,7"):
             raise Exception("BSS_TM_REQ command failed")
         ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
         if ev is None:
@@ -1895,6 +1928,15 @@
             raise Exception("No Collocated Interference Report frame seen")
         if addr + " 0 " + binascii.hexlify(no_intf).decode() not in ev:
             raise Exception("Unexpected report values: " + ev)
+
+        if "FAIL" not in hapd.request("COLOC_INTF_REQ foo 1 5"):
+            raise Exception("Invalid COLOC_INTF_REQ accepted")
+        if "FAIL" not in hapd.request("COLOC_INTF_REQ 02:ff:ff:ff:ff:ff 1 5"):
+            raise Exception("COLOC_INTF_REQ for unknown STA accepted")
+        if "FAIL" not in hapd.request("COLOC_INTF_REQ %s 1" % addr):
+            raise Exception("Invalid COLOC_INTF_REQ accepted")
+        if "FAIL" not in hapd.request("COLOC_INTF_REQ %s" % addr):
+            raise Exception("Invalid COLOC_INTF_REQ accepted")
     finally:
         dev[0].set("coloc_intf_reporting", "0")
         dev[0].set("coloc_intf_elems", "")
@@ -1933,3 +1975,10 @@
             raise Exception("Unexpected BSS Transition Management Response")
     finally:
         dev[0].set("disable_btm", "0")
+
+def test_wnm_time_adv_restart(dev, apdev):
+    """WNM time advertisement and interface restart"""
+    hapd = start_wnm_ap(apdev[0], time_adv=True)
+    hapd.disable()
+    hapd.enable()
+    dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wpas_ap.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wpas_ap.py
index b5b4311..fb70cd3 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wpas_ap.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wpas_ap.py
@@ -903,3 +903,25 @@
     dev[1].wait_disconnected()
     dev[1].request("RECONNECT")
     dev[1].wait_connected()
+
+def test_wpas_ap_vendor_elems(dev):
+    """wpa_supplicant AP mode - vendor elements"""
+    id = dev[0].add_network()
+    dev[0].set_network(id, "mode", "2")
+    dev[0].set_network_quoted(id, "ssid", "wpas-ap-open")
+    dev[0].set_network(id, "key_mgmt", "NONE")
+    dev[0].set_network(id, "frequency", "2412")
+    dev[0].set_network(id, "scan_freq", "2412")
+    dev[0].select_network(id)
+    wait_ap_ready(dev[0])
+
+    beacon_elems = "dd0411223301"
+    dev[0].set("ap_vendor_elements", beacon_elems)
+    dev[0].set("ap_assocresp_elements", "dd0411223302")
+    if "OK" not in dev[0].request("UPDATE_BEACON"):
+        raise Exception("UPDATE_BEACON failed")
+
+    dev[1].connect("wpas-ap-open", key_mgmt="NONE", scan_freq="2412")
+    bss = dev[1].get_bss(dev[0].own_addr())
+    if beacon_elems not in bss['ie']:
+        raise Exception("Vendor element not visible in scan results")
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wpas_config.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wpas_config.py
index 6bf62d0..3cd7dfc 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wpas_config.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wpas_config.py
@@ -191,6 +191,11 @@
                 f.write("                    ")
             f.write("foo\n")
             f.write("device_name=name#foo\n")
+            f.write("network={\n")
+            f.write("\tkey_mgmt=NONE\n")
+            f.write('\tssid="hello"\n')
+            f.write('\tgroup=GCMP # "foo"\n')
+            f.write("}\n")
 
         wpas.interface_add("wlan5", config=config)
         capa = {}
@@ -242,9 +247,11 @@
 
         wpas.interface_remove("wlan5")
         data1 = check_config(capa, config)
+        if "group=GCMP" not in data1:
+            raise Exception("Network block group parameter with a comment not present")
 
         wpas.interface_add("wlan5", config=config)
-        if len(wpas.list_networks()) != 1:
+        if len(wpas.list_networks()) != 2:
             raise Exception("Unexpected number of networks")
         if len(wpas.request("LIST_CREDS").splitlines()) != 2:
             raise Exception("Unexpected number of credentials")
@@ -284,6 +291,8 @@
             os.rmdir(config)
         except:
             pass
+        if not wpas.ifname:
+            wpas.interface_add("wlan5")
         wpas.dump_monitor()
         wpas.request("SET country 00")
         wpas.wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=1)
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wpas_ctrl.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wpas_ctrl.py
index 04418f0..210c119 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wpas_ctrl.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wpas_ctrl.py
@@ -266,14 +266,14 @@
              "f2:99:88:77:66:55 02:11:22:33:44:55/ff:00:ff:00:ff:00 12:34:56:78:90:ab",
              "02:11:22:33:44:55/ff:ff:ff:00:00:00 02:ae:be:ce:53:77/00:00:00:00:00:ff"]
     for val in tests:
-        dev[0].set_network(id, "bssid_blacklist", val)
-        res = dev[0].get_network(id, "bssid_blacklist")
+        dev[0].set_network(id, "bssid_ignore", val)
+        res = dev[0].get_network(id, "bssid_ignore")
         if res != val:
-            raise Exception("Unexpected bssid_blacklist value: %s != %s" % (res, val))
-        dev[0].set_network(id, "bssid_whitelist", val)
-        res = dev[0].get_network(id, "bssid_whitelist")
+            raise Exception("Unexpected bssid_ignore value: %s != %s" % (res, val))
+        dev[0].set_network(id, "bssid_accept", val)
+        res = dev[0].get_network(id, "bssid_accept")
         if res != val:
-            raise Exception("Unexpected bssid_whitelist value: %s != %s" % (res, val))
+            raise Exception("Unexpected bssid_accept value: %s != %s" % (res, val))
 
     tests = ["foo",
              "00:11:22:33:44:5",
@@ -281,8 +281,8 @@
              "00:11:22:33:44:55/",
              "00:11:22:33:44:55/66:77:88:99:aa:b"]
     for val in tests:
-        if "FAIL" not in dev[0].request("SET_NETWORK %d bssid_blacklist %s" % (id, val)):
-            raise Exception("Invalid bssid_blacklist value accepted")
+        if "FAIL" not in dev[0].request("SET_NETWORK %d bssid_ignore %s" % (id, val)):
+            raise Exception("Invalid bssid_ignore value accepted")
 
 @remote_compatible
 def test_wpas_ctrl_network_oom(dev):
@@ -687,8 +687,8 @@
         raise Exception("Unexpected success on invalid WPS_REG")
     if "FAIL" not in dev[0].request("IBSS_RSN 00:11:22:33:44"):
         raise Exception("Unexpected success on invalid IBSS_RSN")
-    if "FAIL" not in dev[0].request("BLACKLIST 00:11:22:33:44"):
-        raise Exception("Unexpected success on invalid BLACKLIST")
+    if "FAIL" not in dev[0].request("BSSID_IGNORE 00:11:22:33:44"):
+        raise Exception("Unexpected success on invalid BSSID_IGNORE")
 
 @remote_compatible
 def test_wpas_ctrl_wps_errors(dev):
@@ -1078,43 +1078,43 @@
         if "FAIL" in dev[0].request("NFC_GET_HANDOVER_SEL " + v):
             raise Exception("Unexpected NFC_GET_HANDOVER_SEL failure for " + v)
 
-def get_blacklist(dev):
-    return dev.request("BLACKLIST").splitlines()
+def get_bssid_ignore_list(dev):
+    return dev.request("BSSID_IGNORE").splitlines()
 
 @remote_compatible
-def test_wpas_ctrl_blacklist(dev):
-    """wpa_supplicant ctrl_iface BLACKLIST"""
-    if "OK" not in dev[0].request("BLACKLIST clear"):
-        raise Exception("BLACKLIST clear failed")
-    b = get_blacklist(dev[0])
+def test_wpas_ctrl_bssid_ignore(dev):
+    """wpa_supplicant ctrl_iface BSSID_IGNORE"""
+    if "OK" not in dev[0].request("BSSID_IGNORE clear"):
+        raise Exception("BSSID_IGNORE clear failed")
+    b = get_bssid_ignore_list(dev[0])
     if len(b) != 0:
-        raise Exception("Unexpected blacklist contents: " + str(b))
-    if "OK" not in dev[0].request("BLACKLIST 00:11:22:33:44:55"):
-        raise Exception("BLACKLIST add failed")
-    b = get_blacklist(dev[0])
+        raise Exception("Unexpected BSSID ignore list contents: " + str(b))
+    if "OK" not in dev[0].request("BSSID_IGNORE 00:11:22:33:44:55"):
+        raise Exception("BSSID_IGNORE add failed")
+    b = get_bssid_ignore_list(dev[0])
     if "00:11:22:33:44:55" not in b:
-        raise Exception("Unexpected blacklist contents: " + str(b))
-    if "OK" not in dev[0].request("BLACKLIST 00:11:22:33:44:56"):
-        raise Exception("BLACKLIST add failed")
-    b = get_blacklist(dev[0])
+        raise Exception("Unexpected BSSID ignore list contents: " + str(b))
+    if "OK" not in dev[0].request("BSSID_IGNORE 00:11:22:33:44:56"):
+        raise Exception("BSSID_IGNORE add failed")
+    b = get_bssid_ignore_list(dev[0])
     if "00:11:22:33:44:55" not in b or "00:11:22:33:44:56" not in b:
-        raise Exception("Unexpected blacklist contents: " + str(b))
-    if "OK" not in dev[0].request("BLACKLIST 00:11:22:33:44:56"):
-        raise Exception("BLACKLIST add failed")
-    b = get_blacklist(dev[0])
+        raise Exception("Unexpected BSSID ignore list contents: " + str(b))
+    if "OK" not in dev[0].request("BSSID_IGNORE 00:11:22:33:44:56"):
+        raise Exception("BSSID_IGNORE add failed")
+    b = get_bssid_ignore_list(dev[0])
     if "00:11:22:33:44:55" not in b or "00:11:22:33:44:56" not in b or len(b) != 2:
-        raise Exception("Unexpected blacklist contents: " + str(b))
+        raise Exception("Unexpected BSSID ignore list contents: " + str(b))
 
-    if "OK" not in dev[0].request("BLACKLIST clear"):
-        raise Exception("BLACKLIST clear failed")
-    if dev[0].request("BLACKLIST") != "":
-        raise Exception("Unexpected blacklist contents")
+    if "OK" not in dev[0].request("BSSID_IGNORE clear"):
+        raise Exception("BSSID_IGNORE clear failed")
+    if dev[0].request("BSSID_IGNORE") != "":
+        raise Exception("Unexpected BSSID ignore list contents")
 
 @remote_compatible
-def test_wpas_ctrl_blacklist_oom(dev):
-    """wpa_supplicant ctrl_iface BLACKLIST and out-of-memory"""
-    with alloc_fail(dev[0], 1, "wpa_blacklist_add"):
-        if "FAIL" not in dev[0].request("BLACKLIST aa:bb:cc:dd:ee:ff"):
+def test_wpas_ctrl_bssid_ignore_oom(dev):
+    """wpa_supplicant ctrl_iface BSSID_IGNORE and out-of-memory"""
+    with alloc_fail(dev[0], 1, "wpa_bssid_ignore_add"):
+        if "FAIL" not in dev[0].request("BSSID_IGNORE aa:bb:cc:dd:ee:ff"):
             raise Exception("Unexpected success with allocation failure")
 
 def test_wpas_ctrl_log_level(dev):
@@ -1344,6 +1344,32 @@
         if "OK" not in dev[0].request("CTRL-RSP-%s-%d:" % (req, id)):
             raise Exception("Request failed unexpectedly")
 
+def test_wpas_ctrl_vendor_test(dev, apdev):
+    """wpas_supplicant and VENDOR test command"""
+    OUI_QCA = 0x001374
+    QCA_NL80211_VENDOR_SUBCMD_TEST = 1
+    QCA_WLAN_VENDOR_ATTR_TEST = 8
+    attr = struct.pack("@HHI", 4 + 4, QCA_WLAN_VENDOR_ATTR_TEST, 123)
+    cmd = "VENDOR %x %d %s" % (OUI_QCA, QCA_NL80211_VENDOR_SUBCMD_TEST, binascii.hexlify(attr).decode())
+
+    res = dev[0].request(cmd)
+    if "FAIL" in res:
+        raise Exception("VENDOR command failed")
+    val, = struct.unpack("@I", binascii.unhexlify(res))
+    if val != 125:
+        raise Exception("Incorrect response value")
+
+    res = dev[0].request(cmd + " nested=1")
+    if "FAIL" in res:
+        raise Exception("VENDOR command failed")
+    val, = struct.unpack("@I", binascii.unhexlify(res))
+    if val != 125:
+        raise Exception("Incorrect response value")
+
+    res = dev[0].request(cmd + " nested=0")
+    if "FAIL" not in res:
+        raise Exception("VENDOR command with invalid (not nested) data accepted")
+
 @remote_compatible
 def test_wpas_ctrl_vendor(dev, apdev):
     """wpa_supplicant ctrl_iface VENDOR"""
@@ -1376,6 +1402,8 @@
     """wpa_supplicant ctrl_iface DRIVER_EVENT"""
     if "FAIL" not in dev[0].request("DRIVER_EVENT foo"):
         raise Exception("Invalid DRIVER_EVENT accepted")
+    if "OK" not in dev[0].request("DRIVER_EVENT ASSOC reassoc=1 req_ies=0000 resp_ies=0000 resp_frame=0000 beacon_ies=0000 freq=2412 wmm::info_bitmap=0 wmm::uapsd_queues=0 addr=02:02:02:02:02:02 authorized=0 key_replay_ctr=00 ptk_kck=00 ptk_kek=00 subnet_status=0 fils_erp_next_seq_num=0 fils_pmk=00 fils_pmkid=" + 16*"00"):
+        raise Exception("DRIVER_EVENT ASSOC did not succeed")
 
 @remote_compatible
 def test_wpas_ctrl_eapol_rx(dev, apdev):
@@ -2121,3 +2149,11 @@
     dev[0].set("get_pref_freq_list_override", "")
     res = dev[0].request("GET_PREF_FREQ_LIST STATION").strip()
     logger.info("STATION (without override): " + res)
+
+def test_wpas_ctrl_interface_add_driver_init_failure(dev, apdev):
+    """wpa_supplicant INTERFACE_ADD and driver init failing"""
+    for i in range(1000):
+        res = dev[0].global_request("INTERFACE_ADD FOO")
+        if "FAIL" not in res:
+            raise Exception("Unexpected result: " + res)
+    dev[0].dump_monitor()
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wpas_mesh.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wpas_mesh.py
index b7f9846..71825dc 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wpas_mesh.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/test_wpas_mesh.py
@@ -80,8 +80,24 @@
     if '[MESH]' not in bss['flags']:
         raise Exception("BSS output did not include MESH flag")
 
-def check_mesh_group_added(dev):
-    ev = dev.wait_event(["MESH-GROUP-STARTED"])
+def check_dfs_started(dev, timeout=10):
+    ev = dev.wait_event(["DFS-CAC-START"], timeout=timeout)
+    if ev is None:
+        raise Exception("Test exception: CAC did not start")
+
+def check_dfs_finished(dev, timeout=70):
+    ev = dev.wait_event(["DFS-CAC-COMPLETED"], timeout=timeout)
+    if ev is None:
+        raise Exception("Test exception: CAC did not finish")
+
+def check_mesh_radar_handling_finished(dev, timeout=75):
+    ev = dev.wait_event(["CTRL-EVENT-CHANNEL-SWITCH", "MESH-GROUP-STARTED"],
+                        timeout=timeout)
+    if ev is None:
+        raise Exception("Test exception: Couldn't join mesh")
+
+def check_mesh_group_added(dev, timeout=10):
+    ev = dev.wait_event(["MESH-GROUP-STARTED"], timeout=timeout)
     if ev is None:
         raise Exception("Test exception: Couldn't join mesh")
 
@@ -91,6 +107,10 @@
     if ev is None:
         raise Exception("Test exception: Couldn't leave mesh")
 
+def check_regdom_change(dev, timeout=10):
+    ev = dev.wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=timeout)
+    if ev is None:
+        raise Exception("Test exception: No regdom change happened.")
 
 def check_mesh_peer_connected(dev, timeout=10):
     ev = dev.wait_event(["MESH-PEER-CONNECTED"], timeout=timeout)
@@ -167,6 +187,39 @@
     check_mesh_group_removed(dev[0])
     dev[0].mesh_group_remove()
 
+def dfs_simulate_radar(dev):
+    logger.info("Trigger a simulated radar event")
+    phyname = dev.get_driver_status_field("phyname")
+    radar_file = '/sys/kernel/debug/ieee80211/' + phyname + '/hwsim/dfs_simulate_radar'
+    with open(radar_file, 'w') as f:
+        f.write('1')
+
+@long_duration_test
+def test_mesh_peer_connected_dfs(dev):
+    """Mesh peer connected (DFS)"""
+    dev[0].set("country", "DE")
+    dev[1].set("country", "DE")
+
+    check_regdom_change(dev[0])
+    check_regdom_change(dev[1])
+
+    check_mesh_support(dev[0])
+    add_open_mesh_network(dev[0], freq="5500", beacon_int=160)
+    add_open_mesh_network(dev[1], freq="5500", beacon_int=160)
+    check_dfs_started(dev[0])
+    check_dfs_finished(dev[0])
+    check_mesh_joined_connected(dev, timeout0=10)
+
+    dfs_simulate_radar(dev[0])
+
+    check_mesh_radar_handling_finished(dev[0], timeout=75)
+
+    dev[0].set("country", "00")
+    dev[1].set("country", "00")
+
+    check_regdom_change(dev[0])
+    check_regdom_change(dev[1])
+
 def test_wpas_mesh_peer_connected(dev):
     """wpa_supplicant MESH peer connected"""
     check_mesh_support(dev[0])
@@ -217,6 +270,9 @@
     if mode != "mesh":
         raise Exception("Unexpected mode: " + mode)
 
+    peer = dev[1].own_addr()
+    sta1 = dev[0].get_sta(peer)
+
     dev[0].scan(freq="2462")
     bss = dev[0].get_bss(dev[1].own_addr())
     if bss and 'ie' in bss and "ff0724" in bss['ie']:
@@ -227,6 +283,15 @@
         if "[VHT]" in sta:
             raise Exception("Unexpected STA VHT flag")
 
+    time.sleep(1.1)
+    sta2 = dev[0].get_sta(peer)
+    if 'connected_time' not in sta1 or 'connected_time' not in sta2:
+        raise Exception("connected_time not reported for peer")
+    ct1 = int(sta1['connected_time'])
+    ct2 = int(sta2['connected_time'])
+    if ct2 <= ct1:
+        raise Exception("connected_time did not increment")
+
 def test_wpas_mesh_open_no_auto(dev, apdev):
     """wpa_supplicant open MESH network connectivity"""
     check_mesh_support(dev[0])
@@ -548,7 +613,7 @@
     id = add_mesh_secure_net(dev[1])
     dev[1].mesh_group_add(id)
 
-    dev[2].request("SET sae_groups 26")
+    dev[2].request("SET sae_groups 20")
     id = add_mesh_secure_net(dev[2])
     dev[2].mesh_group_add(id)
 
@@ -591,11 +656,11 @@
     addr1 = dev[1].own_addr()
 
     #dev[0].request("SET sae_groups 21 20 25 26")
-    dev[0].request("SET sae_groups 26")
+    dev[0].request("SET sae_groups 25")
     id = add_mesh_secure_net(dev[0])
     dev[0].mesh_group_add(id)
 
-    dev[1].request("SET sae_groups 19 26")
+    dev[1].request("SET sae_groups 19 25")
     id = add_mesh_secure_net(dev[1])
     dev[1].mesh_group_add(id)
 
@@ -1762,7 +1827,7 @@
     """Mesh with invalid SAE group configuration"""
     check_mesh_support(dev[0], secure=True)
 
-    dev[0].request("SET sae_groups 26")
+    dev[0].request("SET sae_groups 25")
     id = add_mesh_secure_net(dev[0])
     dev[0].mesh_group_add(id)
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/tshark.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/tshark.py
index d6a57f0..32cdf47 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/tshark.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/tshark.py
@@ -12,6 +12,8 @@
 import logging
 logger = logging.getLogger()
 
+from utils import *
+
 class UnknownFieldsException(Exception):
     def __init__(self, fields):
         Exception.__init__(self, "unknown tshark fields %s" % ','.join(fields))
@@ -41,6 +43,8 @@
                                stderr=subprocess.PIPE)
     except Exception as e:
         logger.info("Could run run tshark check: " + str(e))
+        if "No such file or directory: 'tshark'" in str(e):
+            raise HwsimSkip("No tshark available")
         cmd = None
         return None
 
@@ -111,6 +115,8 @@
                                stderr=subprocess.PIPE)
     except Exception as e:
         logger.info("Could run run tshark: " + str(e))
+        if "No such file or directory: 'tshark'" in str(e):
+            raise HwsimSkip("No tshark available")
         return None
     output = cmd.communicate()
     out = output[0].decode()
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/utils.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/utils.py
index 3aa7c44..4e88626 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/utils.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/utils.py
@@ -114,9 +114,25 @@
         raise HwsimSkip("SAE not supported")
 
 def check_sae_pk_capab(dev):
-    if "PK" not in dev.get_capability("sae"):
+    capab = dev.get_capability("sae")
+    if capab is None or "PK" not in capab:
         raise HwsimSkip("SAE-PK not supported")
 
+def check_erp_capa(dev):
+    capab = dev.get_capability("erp")
+    if not capab or 'ERP' not in capab:
+        raise HwsimSkip("ERP not supported in the build")
+
+def check_fils_capa(dev):
+    capa = dev.get_capability("fils")
+    if capa is None or "FILS" not in capa:
+        raise HwsimSkip("FILS not supported")
+
+def check_fils_sk_pfs_capa(dev):
+    capa = dev.get_capability("fils")
+    if capa is None or "FILS-SK-PFS" not in capa:
+        raise HwsimSkip("FILS-SK-PFS not supported")
+
 def check_tls_tod(dev):
     tls = dev.request("GET tls_library")
     if not tls.startswith("OpenSSL") and not tls.startswith("internal"):
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/vm/inside.sh b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/vm/inside.sh
index 6ccad4b..bfcbda6 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/vm/inside.sh
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/vm/inside.sh
@@ -15,11 +15,16 @@
 # needed for tracing
 mount debugfs -t debugfs /sys/kernel/debug
 
+mkdir /tmp/wireshark-share
+mount --bind /usr/share/wireshark /tmp/wireshark-share
+mount tmpfs -t tmpfs /usr/share/wireshark
+
 # for inside telnet
 mkdir /dev/pts
 mount devpts -t devpts /dev/pts
 
 export PATH=/usr/sbin:$PATH
+export HOME=/tmp
 
 # reboot on any sort of crash
 sysctl kernel.panic_on_oops=1
@@ -33,6 +38,8 @@
 ARGS=$(sed 's/.*ARGS=\([^ ]*\)\( \|$\).*/\1/' /proc/cmdline)
 LOGDIR=$(sed 's/.*LOGDIR=\([^ ]*\)\( \|$\).*/\1/' /proc/cmdline)
 
+mount --bind "$TESTDIR/vm/regdb/" /lib/firmware
+
 # create /dev entries we need
 mknod -m 660 /dev/ttyS0 c 4 64
 mknod -m 666 /dev/ptmx c 5 2
@@ -48,7 +55,7 @@
 
 echo "VM has started up" > /dev/ttyS0
 
-# create dummy sudo - everything runs as uid 0
+# create stub sudo - everything runs as uid 0
 mkdir /tmp/bin
 cat > /tmp/bin/sudo << EOF
 #!/bin/bash
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/vm/parallel-vm.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/vm/parallel-vm.py
index c451e8a..86565c6 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/vm/parallel-vm.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/vm/parallel-vm.py
@@ -344,6 +344,23 @@
     scr.refresh()
     time.sleep(0.3)
 
+def known_output(tests, line):
+    if not line:
+        return True
+    if line in tests:
+        return True
+    known = ["START ", "PASS ", "FAIL ", "SKIP ", "REASON ", "ALL-PASSED",
+             "READY",
+             "  ", "Exception: ", "Traceback (most recent call last):",
+             "./run-all.sh: running",
+             "./run-all.sh: passing",
+             "Test run completed", "Logfiles are at", "Starting test run",
+             "passed all", "skipped ", "failed tests:"]
+    for k in known:
+        if line.startswith(k):
+            return True
+    return False
+
 def main():
     import argparse
     import os
@@ -617,6 +634,16 @@
     if other_reasons:
         print("Other skip reasons:", other_reasons)
 
+    for i in range(num_servers):
+        unknown = ""
+        for line in vm[i]['out'].splitlines():
+            if not known_output(tests, line):
+                unknown += line + "\n"
+        if unknown:
+            print("\nVM %d - unexpected stdout output:\n%s" % (i, unknown))
+        if vm[i]['err']:
+            print("\nVM %d - unexpected stderr output:\n%s\n" % (i, vm[i]['err']))
+
     if codecov:
         print("Code coverage - preparing report")
         for i in range(num_servers):
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/vm/regdb/regulatory.db b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/vm/regdb/regulatory.db
new file mode 100755
index 0000000..e0db5f8
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/vm/regdb/regulatory.db
Binary files differ
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/vm/regdb/regulatory.db.p7s b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/vm/regdb/regulatory.db.p7s
new file mode 100755
index 0000000..730aef4
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/vm/regdb/regulatory.db.p7s
Binary files differ
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/wlantest.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/wlantest.py
index 6d4343b..16765d2 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/wlantest.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/wlantest.py
@@ -29,7 +29,7 @@
             return
 
         cls.remote_host.execute(["killall", "-9", "wlantest"])
-        cls.remote_host.wait_execute_complete(cls.exe_thread, 5)
+        cls.remote_host.thread_wait(cls.exe_thread, 5)
         cls.exe_thread = None
         cls.exe_res = []
 
@@ -64,7 +64,7 @@
                                                     pcap_file, log_file)
         cls.remote_host.add_log(log_file)
         cls.remote_host.add_log(pcap_file)
-        cls.exe_thread = cls.remote_host.execute_run(cmd.split(), cls.exe_res)
+        cls.exe_thread = cls.remote_host.thread_run(cmd.split(), cls.exe_res)
         # Give wlantest a chance to start working
         time.sleep(1)
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/wpasupplicant.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/wpasupplicant.py
index 92c8552..160aa3e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/wpasupplicant.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/hwsim/wpasupplicant.py
@@ -1092,11 +1092,12 @@
                       "wep_tx_keyidx", "scan_freq", "freq_list", "eap",
                       "eapol_flags", "fragment_size", "scan_ssid", "auth_alg",
                       "wpa_ptk_rekey", "disable_ht", "disable_vht", "bssid",
+                      "disable_he",
                       "disable_max_amsdu", "ampdu_factor", "ampdu_density",
                       "disable_ht40", "disable_sgi", "disable_ldpc",
                       "ht40_intolerant", "update_identifier", "mac_addr",
-                      "erp", "bg_scan_period", "bssid_blacklist",
-                      "bssid_whitelist", "mem_only_psk", "eap_workaround",
+                      "erp", "bg_scan_period", "bssid_ignore",
+                      "bssid_accept", "mem_only_psk", "eap_workaround",
                       "engine", "fils_dh_group", "bssid_hint",
                       "dpp_csign", "dpp_csign_expiry",
                       "dpp_netaccesskey", "dpp_netaccesskey_expiry", "dpp_pfs",
@@ -1576,7 +1577,7 @@
         return int(peer)
 
     def dpp_pkex_init(self, identifier, code, role=None, key=None, curve=None,
-                      extra=None, use_id=None, allow_fail=False):
+                      extra=None, use_id=None, allow_fail=False, v2=False):
         if use_id is None:
             id1 = self.dpp_bootstrap_gen(type="pkex", key=key, curve=curve)
         else:
@@ -1584,7 +1585,10 @@
         cmd = "own=%d " % id1
         if identifier:
             cmd += "identifier=%s " % identifier
-        cmd += "init=1 "
+        if v2:
+            cmd += "init=2 "
+        else:
+            cmd += "init=1 "
         if role:
             cmd += "role=%s " % role
         if extra:
@@ -1628,3 +1632,21 @@
         res = self.request("DPP_CONFIGURATOR_REMOVE %d" % conf_id)
         if "OK" not in res:
             raise Exception("DPP_CONFIGURATOR_REMOVE failed")
+
+    def get_ptksa(self, bssid, cipher):
+        res = self.request("PTKSA_CACHE_LIST")
+        lines = res.splitlines()
+        for l in lines:
+            if bssid not in l or cipher not in l:
+                continue
+
+            vals = dict()
+            [index, addr, cipher, expiration, tk, kdk] = l.split(' ', 5)
+            vals['index'] = index
+            vals['addr'] = addr
+            vals['cipher'] = cipher
+            vals['expiration'] = expiration
+            vals['tk'] = tk
+            vals['kdk'] = kdk
+            return vals
+        return None
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/remote/monitor.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/remote/monitor.py
index 5bd801c..0f77d50 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/remote/monitor.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/remote/monitor.py
@@ -110,7 +110,7 @@
 
     log = log_dir + tc_name + "_" + host.name + log_monitor + ".pcap"
     host.add_log(log)
-    thread = host.execute_run([tshark, "-w", log], monitor_res)
+    thread = host.thread_run([tshark, "-w", log], monitor_res)
     host.thread = thread
 
 
@@ -122,7 +122,7 @@
     if host.thread is None:
         return
 
-    host.execute_stop(host.thread)
+    host.thread_stop(host.thread)
     host.thread = None
 
 # Add monitor to existing interface
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/remote/run-tests.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/remote/run-tests.py
index e26e348..67993a3 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/remote/run-tests.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/remote/run-tests.py
@@ -13,6 +13,7 @@
 import traceback
 import getopt
 from datetime import datetime
+from random import shuffle
 
 import logging
 logger = logging.getLogger()
@@ -32,7 +33,7 @@
 def usage():
     print("USAGE: " + sys.argv[0] + " -t devices")
     print("USAGE: " + sys.argv[0] + " -t check_devices")
-    print("USAGE: " + sys.argv[0] + " -d <dut_name> -t <all|sanity|tests_to_run> [-r <ref_name>] [-c <cfg_file.py>] [-m <all|monitor_name>] [-h hwsim_tests] [-f hwsim_modules][-R][-T][-P][-v]")
+    print("USAGE: " + sys.argv[0] + " -d <dut_name> -t <all|sanity|tests_to_run> [-r <ref_name>] [-c <cfg_file.py>] [-m <all|monitor_name>] [-h hwsim_tests] [-f hwsim_modules][-R][-T][-P][-S][-v]")
     print("USAGE: " + sys.argv[0])
 
 def get_devices(devices, duts, refs, monitors):
@@ -79,10 +80,11 @@
     trace = False
     restart = False
     perf = False
+    shuffle_tests = False
 
     # parse input parameters
     try:
-        opts, args = getopt.getopt(sys.argv[1:], "d:f:r:t:l:k:c:m:h:vRPT",
+        opts, args = getopt.getopt(sys.argv[1:], "d:f:r:t:l:k:c:m:h:vRPTS",
                                    ["dut=", "modules=", "ref=", "tests=",
                                     "log-dir=",
                                     "cfg=", "key=", "monitor=", "hwsim="])
@@ -100,6 +102,8 @@
             trace = True
         elif option == "-P":
             perf = True
+        elif option == "-S":
+            shuffle_tests = True
         elif option in ("-d", "--dut"):
             duts.append(argument)
         elif option in ("-r", "--ref"):
@@ -283,6 +287,10 @@
                 continue
             tests_to_run.append(t)
 
+    if shuffle_tests:
+        shuffle(tests_to_run)
+        shuffle(hwsim_tests_to_run)
+
     # lock devices
     try:
         get_devices(devices, duts, refs, monitors)
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/remote/rutils.py b/src/lynq/packages/thirdpart/lynq-wg870/tests/remote/rutils.py
index e80901b..6902991 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/remote/rutils.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/remote/rutils.py
@@ -342,12 +342,12 @@
 
     flush_arp_cache(host)
 
-    thread = host.execute_run(ping, result)
+    thread = host.thread_run(ping, result)
     return thread
 
 def ping_wait(host, thread, timeout=None):
-    host.wait_execute_complete(thread, timeout)
-    if thread.isAlive():
+    host.thread_wait(thread, timeout)
+    if thread.is_alive():
         raise Exception("ping thread still alive")
 
 def flush_arp_cache(host):
@@ -496,24 +496,24 @@
     flush_arp_cache(server)
     flush_arp_cache(client)
 
-    server_thread = server.execute_run(iperf_server, server_res)
+    server_thread = server.thread_run(iperf_server, server_res)
     time.sleep(1)
-    client_thread = client.execute_run(iperf_client, client_res)
+    client_thread = client.thread_run(iperf_client, client_res)
 
     return server_thread, client_thread
 
 def iperf_wait(server, client, server_thread, client_thread, timeout=None, iperf="iperf"):
-    client.wait_execute_complete(client_thread, timeout)
-    if client_thread.isAlive():
+    client.thread_wait(client_thread, timeout)
+    if client_thread.is_alive():
         raise Exception("iperf client thread still alive")
 
-    server.wait_execute_complete(server_thread, 5)
-    if server_thread.isAlive():
+    server.thread_wait(server_thread, 5)
+    if server_thread.is_alive():
         server.execute(["killall", "-s", "INT", iperf])
         time.sleep(1)
 
-    server.wait_execute_complete(server_thread, 5)
-    if server_thread.isAlive():
+    server.thread_wait(server_thread, 5)
+    if server_thread.is_alive():
         raise Exception("iperf server thread still alive")
 
     return
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/test-aes.c b/src/lynq/packages/thirdpart/lynq-wg870/tests/test-aes.c
index 9d76c07..ab39b78 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/test-aes.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/test-aes.c
@@ -16,38 +16,6 @@
 
 static void test_aes_perf(void)
 {
-#if 0 /* this did not seem to work with new compiler?! */
-#ifdef __i386__
-#define rdtscll(val) \
-     __asm__ __volatile__("rdtsc" : "=A" (val))
-	const int num_iters = 10;
-	int i;
-	unsigned int start, end;
-	u8 key[16], pt[16], ct[16];
-	void *ctx;
-
-	printf("keySetupEnc:");
-	for (i = 0; i < num_iters; i++) {
-		rdtscll(start);
-		ctx = aes_encrypt_init(key, 16);
-		rdtscll(end);
-		aes_encrypt_deinit(ctx);
-		printf(" %d", end - start);
-	}
-	printf("\n");
-
-	printf("Encrypt:");
-	ctx = aes_encrypt_init(key, 16);
-	for (i = 0; i < num_iters; i++) {
-		rdtscll(start);
-		aes_encrypt(ctx, pt, ct);
-		rdtscll(end);
-		printf(" %d", end - start);
-	}
-	aes_encrypt_deinit(ctx);
-	printf("\n");
-#endif /* __i386__ */
-#endif
 }
 
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/tests/test-rsa-sig-ver.c b/src/lynq/packages/thirdpart/lynq-wg870/tests/test-rsa-sig-ver.c
index 6fad5b1..0cb398a 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/tests/test-rsa-sig-ver.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/tests/test-rsa-sig-ver.c
@@ -187,12 +187,19 @@
 int main(int argc, char *argv[])
 {
 	int ret = 0;
+	int i;
 
 	wpa_debug_level = 0;
+	wpa_debug_show_keys = 1;
 
-	if (cavp_rsa_sig_ver("CAVP/SigVer15_186-3.rsp"))
+	for (i = 1; i < argc; i++) {
+		if (cavp_rsa_sig_ver(argv[i]))
+			ret++;
+	}
+
+	if (argc < 2 && cavp_rsa_sig_ver("CAVP/SigVer15_186-3.rsp"))
 		ret++;
-	if (cavp_rsa_sig_ver("CAVP/SigVer15EMTest.txt"))
+	if (argc < 2 && cavp_rsa_sig_ver("CAVP/SigVer15EMTest.txt"))
 		ret++;
 
 	return ret;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/Makefile b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/Makefile
index 6023751..1eba3ce 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/Makefile
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/Makefile
@@ -25,6 +25,7 @@
 CFLAGS += -DCONFIG_OWE
 CFLAGS += -DCONFIG_DPP
 CFLAGS += -DCONFIG_SHA384
+CFLAGS += -DCONFIG_PASN
 
 OBJS += ../src/common/ieee802_11_common.o
 OBJS += ../src/common/wpa_common.o
@@ -63,6 +64,7 @@
 
 
 OBJS_cli = wlantest_cli.o
+OBJS_cli += ../src/common/cli.o
 
 _OBJS_VAR := OBJS
 include ../src/objs.mk
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/bss.c b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/bss.c
index 3208e65..4fc0b17 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/bss.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/bss.c
@@ -102,6 +102,7 @@
 		   " based on passphrase '%s'",
 		   MAC2STR(bss->bssid), passphrase);
 	wpa_hexdump(MSG_DEBUG, "Possible PMK", pmk->pmk, PMK_LEN);
+	pmk->pmk_len = PMK_LEN;
 	dl_list_add(&bss->pmk, &pmk->list);
 
 	return 0;
@@ -178,14 +179,18 @@
 			  elems->osen_len + 2);
 	}
 
-	if (elems->rsn_ie == NULL) {
+	/* S1G does not include RSNE in beacon, so only clear it from
+	 * Probe Response frames. Note this assumes short beacons were dropped
+	 * due to missing SSID above.
+	 */
+	if (!elems->rsn_ie && (!elems->s1g_capab || beacon != 1)) {
 		if (bss->rsnie[0]) {
 			add_note(wt, MSG_INFO, "BSS " MACSTR
 				 " - RSN IE removed", MAC2STR(bss->bssid));
 			bss->rsnie[0] = 0;
 			update = 1;
 		}
-	} else {
+	} else if (elems->rsn_ie) {
 		if (bss->rsnie[0] == 0 ||
 		    os_memcmp(bss->rsnie, elems->rsn_ie - 2,
 			      elems->rsn_ie_len + 2) != 0) {
@@ -223,6 +228,8 @@
 	if (elems->mdie)
 		os_memcpy(bss->mdid, elems->mdie, 2);
 
+	bss->mesh = elems->mesh_id != NULL;
+
 	if (!update)
 		return;
 
@@ -289,8 +296,8 @@
 		   "pairwise=%s%s%s%s%s%s%s"
 		   "group=%s%s%s%s%s%s%s%s%s"
 		   "mgmt_group_cipher=%s%s%s%s%s"
-		   "key_mgmt=%s%s%s%s%s%s%s%s%s"
-		   "rsn_capab=%s%s%s%s%s%s%s",
+		   "key_mgmt=%s%s%s%s%s%s%s%s%s%s%s%s%s%s"
+		   "rsn_capab=%s%s%s%s%s%s%s%s%s%s",
 		   MAC2STR(bss->bssid),
 		   bss->proto == 0 ? "OPEN " : "",
 		   bss->proto & WPA_PROTO_WPA ? "WPA " : "",
@@ -333,7 +340,14 @@
 		   "EAP-SHA256 " : "",
 		   bss->key_mgmt & WPA_KEY_MGMT_PSK_SHA256 ?
 		   "PSK-SHA256 " : "",
+		   bss->key_mgmt & WPA_KEY_MGMT_OWE ? "OWE " : "",
+		   bss->key_mgmt & WPA_KEY_MGMT_PASN ? "PASN " : "",
 		   bss->key_mgmt & WPA_KEY_MGMT_OSEN ? "OSEN " : "",
+		   bss->key_mgmt & WPA_KEY_MGMT_DPP ? "DPP " : "",
+		   bss->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B ?
+		   "EAP-SUITE-B " : "",
+		   bss->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192 ?
+		   "EAP-SUITE-B-192 " : "",
 		   bss->rsn_capab & WPA_CAPABILITY_PREAUTH ? "PREAUTH " : "",
 		   bss->rsn_capab & WPA_CAPABILITY_NO_PAIRWISE ?
 		   "NO_PAIRWISE " : "",
@@ -341,6 +355,11 @@
 		   bss->rsn_capab & WPA_CAPABILITY_MFPC ? "MFPC " : "",
 		   bss->rsn_capab & WPA_CAPABILITY_PEERKEY_ENABLED ?
 		   "PEERKEY " : "",
+		   bss->rsn_capab & WPA_CAPABILITY_SPP_A_MSDU_CAPABLE ?
+		   "SPP-A-MSDU-CAPAB " : "",
+		   bss->rsn_capab & WPA_CAPABILITY_SPP_A_MSDU_REQUIRED ?
+		   "SPP-A-MSDU-REQUIRED " : "",
+		   bss->rsn_capab & WPA_CAPABILITY_PBAC ? "PBAC " : "",
 		   bss->rsn_capab & WPA_CAPABILITY_OCVC ? "OCVC " : "",
 		   bss->rsn_capab & WPA_CAPABILITY_EXT_KEY_ID_FOR_UNICAST ?
 		   "ExtKeyID " : "");
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/ccmp.c b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/ccmp.c
index 2a1ad83..5d393d4 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/ccmp.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/ccmp.c
@@ -35,7 +35,7 @@
 		if (stype & 0x08) {
 			const u8 *qc;
 			qos = 1;
-			fc &= ~WLAN_FC_ORDER;
+			fc &= ~WLAN_FC_HTC;
 			qc = (const u8 *) (hdr + 1);
 			if (addr4)
 				qc += ETH_ALEN;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/gcmp.c b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/gcmp.c
index d92f4ed..f9f95b2 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/gcmp.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/gcmp.c
@@ -33,7 +33,7 @@
 		if (stype & 0x08) {
 			const u8 *qc;
 			qos = 1;
-			fc &= ~WLAN_FC_ORDER;
+			fc &= ~WLAN_FC_HTC;
 			qc = (const u8 *) (hdr + 1);
 			if (addr4)
 				qc += ETH_ALEN;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/inject.c b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/inject.c
index 54a0554..b177bcf 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/inject.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/inject.c
@@ -68,7 +68,8 @@
 	stype = WLAN_FC_GET_STYPE(fc);
 	if (stype == WLAN_FC_STYPE_DEAUTH || stype == WLAN_FC_STYPE_DISASSOC)
 		return 1;
-	if (stype == WLAN_FC_STYPE_ACTION) {
+	if (stype == WLAN_FC_STYPE_ACTION ||
+	    stype == WLAN_FC_STYPE_ACTION_NO_ACK) {
 		if (len < 25)
 			return 0;
 		if (mgmt->u.action.category != WLAN_ACTION_PUBLIC)
@@ -82,17 +83,17 @@
 			       u8 *frame, size_t len, int incorrect_key)
 {
 	u8 *prot;
-	u8 dummy[32];
+	u8 stub[32];
 	int ret;
 	size_t plen;
 
 	if (!bss->igtk_len[bss->igtk_idx])
 		return -1;
 
-	os_memset(dummy, 0x11, sizeof(dummy));
+	os_memset(stub, 0x11, sizeof(stub));
 	inc_byte_array(bss->ipn[bss->igtk_idx], 6);
 
-	prot = bip_protect(incorrect_key ? dummy : bss->igtk[bss->igtk_idx],
+	prot = bip_protect(incorrect_key ? stub : bss->igtk[bss->igtk_idx],
 			   bss->igtk_len[bss->igtk_idx],
 			   frame, len, bss->ipn[bss->igtk_idx],
 			   bss->igtk_idx, &plen);
@@ -114,7 +115,7 @@
 	u8 *crypt;
 	size_t crypt_len;
 	int ret;
-	u8 dummy[64];
+	u8 stub[64];
 	u8 *pn;
 	struct ieee80211_hdr *hdr;
 	u16 fc;
@@ -133,14 +134,14 @@
 	pn = bss->rsc[bss->gtk_idx];
 	inc_byte_array(pn, 6);
 
-	os_memset(dummy, 0x11, sizeof(dummy));
+	os_memset(stub, 0x11, sizeof(stub));
 	if (bss->group_cipher == WPA_CIPHER_TKIP)
-		crypt = tkip_encrypt(incorrect_key ? dummy :
+		crypt = tkip_encrypt(incorrect_key ? stub :
 				     bss->gtk[bss->gtk_idx],
 				     frame, len, hdrlen, NULL, pn,
 				     bss->gtk_idx, &crypt_len);
 	else
-		crypt = ccmp_encrypt(incorrect_key ? dummy :
+		crypt = ccmp_encrypt(incorrect_key ? stub :
 				     bss->gtk[bss->gtk_idx],
 				     frame, len, hdrlen, NULL, pn,
 				     bss->gtk_idx, &crypt_len);
@@ -162,7 +163,7 @@
 	u8 *crypt;
 	size_t crypt_len;
 	int ret;
-	u8 dummy[64];
+	u8 stub[64];
 	u8 *pn;
 	struct ieee80211_hdr *hdr;
 	u16 fc;
@@ -242,17 +243,17 @@
 		pn = sta->rsc_tods[tid];
 	inc_byte_array(pn, 6);
 
-	os_memset(dummy, 0x11, sizeof(dummy));
+	os_memset(stub, 0x11, sizeof(stub));
 	if (tk)
-		crypt = ccmp_encrypt(incorrect_key ? dummy : tk,
+		crypt = ccmp_encrypt(incorrect_key ? stub : tk,
 				     frame, len, hdrlen, qos, pn, 0,
 				     &crypt_len);
 	else if (sta->pairwise_cipher == WPA_CIPHER_TKIP)
-		crypt = tkip_encrypt(incorrect_key ? dummy : sta->ptk.tk,
+		crypt = tkip_encrypt(incorrect_key ? stub : sta->ptk.tk,
 				     frame, len, hdrlen, qos, pn, 0,
 				     &crypt_len);
 	else
-		crypt = ccmp_encrypt(incorrect_key ? dummy : sta->ptk.tk,
+		crypt = ccmp_encrypt(incorrect_key ? stub : sta->ptk.tk,
 				     frame, len, hdrlen, qos, pn, 0,
 				     &crypt_len);
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/rx_data.c b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/rx_data.c
index b632013..16e0f53 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/rx_data.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/rx_data.c
@@ -99,15 +99,46 @@
 }
 
 
-static void rx_data_process(struct wlantest *wt, const u8 *bssid,
+static void rx_data_process(struct wlantest *wt, struct wlantest_bss *bss,
+			    const u8 *bssid,
 			    const u8 *sta_addr,
 			    const u8 *dst, const u8 *src,
 			    const u8 *data, size_t len, int prot,
-			    const u8 *peer_addr)
+			    const u8 *peer_addr, const u8 *qos)
 {
 	if (len == 0)
 		return;
 
+	if (bss && bss->mesh && qos && !(qos[0] & BIT(7)) &&
+	    (qos[1] & BIT(0))) {
+		u8 addr_ext_mode;
+		size_t mesh_control_len = 6;
+
+		/* Skip Mesh Control field if this is not an A-MSDU */
+		if (len < mesh_control_len) {
+			wpa_printf(MSG_DEBUG,
+				   "Not enough room for Mesh Control field");
+			return;
+		}
+
+		addr_ext_mode = data[0] & 0x03;
+		if (addr_ext_mode == 3) {
+			wpa_printf(MSG_DEBUG,
+				   "Reserved Mesh Control :: Address Extension Mode");
+			return;
+		}
+
+		mesh_control_len += addr_ext_mode * ETH_ALEN;
+		if (len < mesh_control_len) {
+			wpa_printf(MSG_DEBUG,
+				   "Not enough room for Mesh Address Extension");
+			return;
+		}
+
+		len -= mesh_control_len;
+		data += mesh_control_len;
+	}
+
 	if (len >= 8 && os_memcmp(data, "\xaa\xaa\x03\x00\x00\x00", 6) == 0) {
 		rx_data_eth(wt, bssid, sta_addr, dst, src,
 			    WPA_GET_BE16(data + 6), data + 8, len - 8, prot,
@@ -119,21 +150,8 @@
 }
 
 
-static void write_decrypted_note(struct wlantest *wt, const u8 *decrypted,
-				 const u8 *tk, size_t tk_len, int keyid)
-{
-	char tk_hex[65];
-
-	if (!decrypted)
-		return;
-
-	wpa_snprintf_hex(tk_hex, sizeof(tk_hex), tk, tk_len);
-	add_note(wt, MSG_EXCESSIVE, "TK[%d] %s", keyid, tk_hex);
-}
-
-
-static u8 * try_ptk(int pairwise_cipher, struct wpa_ptk *ptk,
-		    const struct ieee80211_hdr *hdr,
+static u8 * try_ptk(struct wlantest *wt, int pairwise_cipher,
+		    struct wpa_ptk *ptk, const struct ieee80211_hdr *hdr,
 		    const u8 *data, size_t data_len, size_t *decrypted_len)
 {
 	u8 *decrypted;
@@ -156,8 +174,15 @@
 					 data, data_len, decrypted_len);
 	} else if ((pairwise_cipher == WPA_CIPHER_TKIP ||
 		    pairwise_cipher == 0) && tk_len == 32) {
+		enum michael_mic_result mic_res;
+
 		decrypted = tkip_decrypt(ptk->tk, hdr, data, data_len,
-					 decrypted_len);
+					 decrypted_len, &mic_res,
+					 &wt->tkip_frag);
+		if (decrypted && mic_res == MICHAEL_MIC_INCORRECT)
+			add_note(wt, MSG_INFO, "Invalid Michael MIC");
+		else if (decrypted && mic_res == MICHAEL_MIC_NOT_VERIFIED)
+			add_note(wt, MSG_DEBUG, "Michael MIC not verified");
 	}
 
 	return decrypted;
@@ -174,7 +199,7 @@
 
 	wpa_debug_level = MSG_WARNING;
 	dl_list_for_each(ptk, &wt->ptk, struct wlantest_ptk, list) {
-		decrypted = try_ptk(pairwise_cipher, &ptk->ptk, hdr,
+		decrypted = try_ptk(wt, pairwise_cipher, &ptk->ptk, hdr,
 				    data, data_len, decrypted_len);
 		if (decrypted) {
 			wpa_debug_level = prev_level;
@@ -263,8 +288,13 @@
 	if (bss->gtk_len[keyid] == 0 &&
 	    (bss->group_cipher != WPA_CIPHER_WEP40 ||
 	     dl_list_empty(&wt->wep))) {
-		add_note(wt, MSG_MSGDUMP, "No GTK known to decrypt the frame "
-			 "(A2=" MACSTR " KeyID=%d)",
+		decrypted = try_all_ptk(wt, bss->group_cipher, hdr, keyid,
+					data, len, &dlen);
+		if (decrypted)
+			goto process;
+		add_note(wt, MSG_MSGDUMP,
+			 "No GTK known to decrypt the frame (A2=" MACSTR
+			 " KeyID=%d)",
 			 MAC2STR(hdr->addr2), keyid);
 		return;
 	}
@@ -295,21 +325,28 @@
 	}
 
 skip_replay_det:
-	if (bss->group_cipher == WPA_CIPHER_TKIP)
+	if (bss->group_cipher == WPA_CIPHER_TKIP) {
+		enum michael_mic_result mic_res;
+
 		decrypted = tkip_decrypt(bss->gtk[keyid], hdr, data, len,
-					 &dlen);
-	else if (bss->group_cipher == WPA_CIPHER_WEP40)
+					 &dlen, &mic_res, &wt->tkip_frag);
+		if (decrypted && mic_res == MICHAEL_MIC_INCORRECT)
+			add_note(wt, MSG_INFO, "Invalid Michael MIC");
+		else if (decrypted && mic_res == MICHAEL_MIC_NOT_VERIFIED)
+			add_note(wt, MSG_DEBUG, "Michael MIC not verified");
+	} else if (bss->group_cipher == WPA_CIPHER_WEP40) {
 		decrypted = wep_decrypt(wt, hdr, data, len, &dlen);
-	else if (bss->group_cipher == WPA_CIPHER_CCMP)
+	} else if (bss->group_cipher == WPA_CIPHER_CCMP) {
 		decrypted = ccmp_decrypt(bss->gtk[keyid], hdr, data, len,
 					 &dlen);
-	else if (bss->group_cipher == WPA_CIPHER_CCMP_256)
+	} else if (bss->group_cipher == WPA_CIPHER_CCMP_256) {
 		decrypted = ccmp_256_decrypt(bss->gtk[keyid], hdr, data, len,
 					     &dlen);
-	else if (bss->group_cipher == WPA_CIPHER_GCMP ||
-		 bss->group_cipher == WPA_CIPHER_GCMP_256)
+	} else if (bss->group_cipher == WPA_CIPHER_GCMP ||
+		   bss->group_cipher == WPA_CIPHER_GCMP_256) {
 		decrypted = gcmp_decrypt(bss->gtk[keyid], bss->gtk_len[keyid],
 					 hdr, data, len, &dlen);
+	}
 
 	if (decrypted) {
 		char gtk[65];
@@ -317,8 +354,9 @@
 		wpa_snprintf_hex(gtk, sizeof(gtk), bss->gtk[keyid],
 				 bss->gtk_len[keyid]);
 		add_note(wt, MSG_EXCESSIVE, "GTK[%d] %s", keyid, gtk);
-		rx_data_process(wt, bss->bssid, NULL, dst, src, decrypted,
-				dlen, 1, NULL);
+	process:
+		rx_data_process(wt, bss, bss->bssid, NULL, dst, src, decrypted,
+				dlen, 1, NULL, qos);
 		if (!replay)
 			os_memcpy(bss->rsc[keyid], pn, 6);
 		write_pcap_decrypted(wt, (const u8 *) hdr, hdrlen,
@@ -579,7 +617,14 @@
 			write_decrypted_note(wt, decrypted, tk, 16, keyid);
 		}
 	} else if (sta->pairwise_cipher == WPA_CIPHER_TKIP) {
-		decrypted = tkip_decrypt(sta->ptk.tk, hdr, data, len, &dlen);
+		enum michael_mic_result mic_res;
+
+		decrypted = tkip_decrypt(sta->ptk.tk, hdr, data, len, &dlen,
+					 &mic_res, &wt->tkip_frag);
+		if (decrypted && mic_res == MICHAEL_MIC_INCORRECT)
+			add_note(wt, MSG_INFO, "Invalid Michael MIC");
+		else if (decrypted && mic_res == MICHAEL_MIC_NOT_VERIFIED)
+			add_note(wt, MSG_DEBUG, "Michael MIC not verified");
 		write_decrypted_note(wt, decrypted, sta->ptk.tk, 32, keyid);
 	} else if (sta->pairwise_cipher == WPA_CIPHER_WEP40) {
 		decrypted = wep_decrypt(wt, hdr, data, len, &dlen);
@@ -607,7 +652,7 @@
 		os_memset(&zero_ptk, 0, sizeof(zero_ptk));
 		zero_ptk.tk_len = wpa_cipher_key_len(sta->pairwise_cipher);
 		wpa_debug_level = MSG_ERROR;
-		decrypted = try_ptk(sta->pairwise_cipher, &zero_ptk, hdr,
+		decrypted = try_ptk(wt, sta->pairwise_cipher, &zero_ptk, hdr,
 				    data, len, &dlen);
 		wpa_debug_level = old_debug_level;
 		if (decrypted) {
@@ -629,8 +674,8 @@
 			peer_addr = hdr->addr1;
 		if (!replay && rsc)
 			os_memcpy(rsc, pn, 6);
-		rx_data_process(wt, bss->bssid, sta->addr, dst, src, decrypted,
-				dlen, 1, peer_addr);
+		rx_data_process(wt, bss, bss->bssid, sta->addr, dst, src,
+				decrypted, dlen, 1, peer_addr, qos);
 		write_pcap_decrypted(wt, (const u8 *) hdr, hdrlen,
 				     decrypted, dlen);
 	} else if (sta->tptk_set) {
@@ -733,8 +778,8 @@
 			}
 		}
 
-		rx_data_process(wt, bssid, sta_addr, dst, src, data, len, 0,
-				peer_addr);
+		rx_data_process(wt, bss, bssid, sta_addr, dst, src, data, len,
+				0, peer_addr, qos);
 	}
 }
 
@@ -823,6 +868,8 @@
 		qos = data + hdrlen;
 		hdrlen += 2;
 	}
+	if ((fc & WLAN_FC_HTC) && (stype & 0x08))
+		hdrlen += 4; /* HT Control field */
 	if (len < hdrlen)
 		return;
 	wt->rx_data++;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/rx_eapol.c b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/rx_eapol.c
index 1e5d667..967d521 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/rx_eapol.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/rx_eapol.c
@@ -120,15 +120,15 @@
 				      sta->snonce, sta->anonce, sta->addr,
 				      bss->bssid, sta->pmk_r1_name,
 				      &ptk, ptk_name, sta->key_mgmt,
-				      sta->pairwise_cipher) < 0 ||
+				      sta->pairwise_cipher, 0) < 0 ||
 		    check_mic(ptk.kck, ptk.kck_len, sta->key_mgmt, ver, data,
 			      len) < 0)
 			return -1;
-	} else if (wpa_pmk_to_ptk(pmk->pmk, PMK_LEN,
+	} else if (wpa_pmk_to_ptk(pmk->pmk, pmk->pmk_len,
 				  "Pairwise key expansion",
 				  bss->bssid, sta->addr, sta->anonce,
 				  sta->snonce, &ptk, sta->key_mgmt,
-				  sta->pairwise_cipher, NULL, 0) < 0 ||
+				  sta->pairwise_cipher, NULL, 0, 0) < 0 ||
 		   check_mic(ptk.kck, ptk.kck_len, sta->key_mgmt, ver, data,
 			     len) < 0) {
 		return -1;
@@ -703,7 +703,7 @@
 			    decrypted, decrypted_len);
 	}
 	if ((wt->write_pcap_dumper || wt->pcapng) && decrypted != key_data) {
-		/* Fill in a dummy Data frame header */
+		/* Fill in a stub Data frame header */
 		u8 buf[24 + 8 + sizeof(*eapol) + sizeof(*hdr) + 64];
 		struct ieee80211_hdr *h;
 		struct wpa_eapol_key *k;
@@ -926,7 +926,7 @@
 	wpa_hexdump(MSG_DEBUG, "Decrypted EAPOL-Key Key Data",
 		    decrypted, decrypted_len);
 	if (wt->write_pcap_dumper || wt->pcapng) {
-		/* Fill in a dummy Data frame header */
+		/* Fill in a stub Data frame header */
 		u8 buf[24 + 8 + sizeof(*eapol) + sizeof(*hdr) + 64];
 		struct ieee80211_hdr *h;
 		struct wpa_eapol_key *k;
@@ -1056,7 +1056,10 @@
 
 	bss = bss_get(wt, bssid);
 	if (bss) {
-		sta = sta_get(bss, sta_addr);
+		if (sta_addr)
+			sta = sta_get(bss, sta_addr);
+		else
+			sta = NULL;
 		if (sta)
 			mic_len = wpa_mic_len(sta->key_mgmt, PMK_LEN);
 	}
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/rx_ip.c b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/rx_ip.c
index fdf80b7..b0fdd20 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/rx_ip.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/rx_ip.c
@@ -120,63 +120,64 @@
 		const u8 *dst, const u8 *src, const u8 *data, size_t len,
 		const u8 *peer_addr)
 {
-	const struct ip *ip;
+	struct ip ip;
 	const u8 *payload;
 	size_t plen;
 	uint16_t frag_off, ip_len;
 
-	ip = (const struct ip *) data;
-	if (len < sizeof(*ip))
+	if (len < sizeof(ip))
 		return;
-	if (ip->ip_v != 4) {
+	os_memcpy(&ip, data, sizeof(ip));
+
+	if (ip.ip_v != 4) {
 		if (hwsim_test_packet(data, len)) {
 			add_note(wt, MSG_INFO, "hwsim_test package");
 			return;
 		}
 		add_note(wt, MSG_DEBUG, "Unexpected IP protocol version %u in "
 			 "IPv4 packet (bssid=" MACSTR " str=" MACSTR
-			 " dst=" MACSTR ")", ip->ip_v, MAC2STR(bssid),
+			 " dst=" MACSTR ")", ip.ip_v, MAC2STR(bssid),
 			 MAC2STR(src), MAC2STR(dst));
 		return;
 	}
-	if (ip->ip_hl * 4 < sizeof(*ip)) {
+	if (ip.ip_hl * 4 < sizeof(ip)) {
 		add_note(wt, MSG_DEBUG, "Unexpected IP header length %u in "
 			 "IPv4 packet (bssid=" MACSTR " str=" MACSTR
-			 " dst=" MACSTR ")", ip->ip_hl, MAC2STR(bssid),
+			 " dst=" MACSTR ")", ip.ip_hl, MAC2STR(bssid),
 			 MAC2STR(src), MAC2STR(dst));
 		return;
 	}
-	if (ip->ip_hl * 4 > len) {
+	if (ip.ip_hl * 4 > len) {
 		add_note(wt, MSG_DEBUG, "Truncated IP header (ihl=%u len=%u) "
 			 "in IPv4 packet (bssid=" MACSTR " str=" MACSTR
-			 " dst=" MACSTR ")", ip->ip_hl, (unsigned) len,
+			 " dst=" MACSTR ")", ip.ip_hl, (unsigned) len,
 			 MAC2STR(bssid), MAC2STR(src), MAC2STR(dst));
 		return;
 	}
 
-	/* TODO: check header checksum in ip->ip_sum */
+	/* TODO: check header checksum in ip.ip_sum */
 
-	frag_off = be_to_host16(ip->ip_off);
+	frag_off = be_to_host16(ip.ip_off);
 	if (frag_off & 0x1fff) {
 		wpa_printf(MSG_EXCESSIVE, "IP fragment reassembly not yet "
 			   "supported");
 		return;
 	}
 
-	ip_len = be_to_host16(ip->ip_len);
+	ip_len = be_to_host16(ip.ip_len);
 	if (ip_len > len)
 		return;
 	if (ip_len < len)
 		len = ip_len;
 
-	payload = data + 4 * ip->ip_hl;
-	plen = len - 4 * ip->ip_hl;
+	payload = data + 4 * ip.ip_hl;
+	plen = len - 4 * ip.ip_hl;
 
-	switch (ip->ip_p) {
+	switch (ip.ip_p) {
 #ifndef __APPLE__
 	case IPPROTO_ICMP:
-		rx_data_icmp(wt, bssid, sta_addr, ip->ip_dst.s_addr,
-			     ip->ip_src.s_addr, payload, plen, peer_addr);
+		rx_data_icmp(wt, bssid, sta_addr, ip.ip_dst.s_addr,
+			     ip.ip_src.s_addr, payload, plen, peer_addr);
 		break;
 #endif /* __APPLE__ */
 	}
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/rx_mgmt.c b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/rx_mgmt.c
index 0bc7eb2..f7690e0 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/rx_mgmt.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/rx_mgmt.c
@@ -51,6 +51,8 @@
 		return "DEAUTH";
 	case WLAN_FC_STYPE_ACTION:
 		return "ACTION";
+	case WLAN_FC_STYPE_ACTION_NO_ACK:
+		return "ACTION-NO-ACK";
 	}
 	return "??";
 }
@@ -290,7 +292,7 @@
 	    wpa_pmk_r1_to_ptk(sta->pmk_r1, sta->pmk_r1_len, parse.fte_snonce,
 			      parse.fte_anonce, sta->addr, bss->bssid,
 			      sta->pmk_r1_name, &ptk, ptk_name, sta->key_mgmt,
-			      sta->pairwise_cipher) < 0)
+			      sta->pairwise_cipher, 0) < 0)
 		return;
 
 	add_note(wt, MSG_DEBUG, "Derived new PTK");
@@ -494,7 +496,7 @@
 			    sta->snonce, sta->anonce, NULL, 0,
 			    &ptk, ick, &ick_len,
 			    sta->key_mgmt, sta->pairwise_cipher,
-			    NULL, NULL) < 0)
+			    NULL, NULL, 0) < 0)
 		return -1;
 
 	/* Check AES-SIV decryption with the derived key */
@@ -1779,7 +1781,8 @@
 	    wpa_pmk_r1_to_ptk(sta->pmk_r1, sta->pmk_r1_len, parse.fte_snonce,
 			      parse.fte_anonce, new_sta->addr, bss->bssid,
 			      sta->pmk_r1_name, &ptk, ptk_name,
-			      new_sta->key_mgmt, new_sta->pairwise_cipher) < 0)
+			      new_sta->key_mgmt, new_sta->pairwise_cipher,
+			      0) < 0)
 		return;
 
 	add_note(wt, MSG_DEBUG, "Derived new PTK");
@@ -1913,8 +1916,126 @@
 }
 
 
+static void
+rx_mgmt_location_measurement_report(struct wlantest *wt,
+				    const struct ieee80211_mgmt *mgmt,
+				    size_t len, bool no_ack)
+{
+	const u8 *pos = mgmt->u.action.u.public_action.variable;
+	const u8 *end = ((const u8 *) mgmt) + len;
+
+	if (end - pos < 1) {
+		add_note(wt, MSG_INFO,
+			 "Too short Location Measurement Report frame from "
+			 MACSTR, MAC2STR(mgmt->sa));
+		return;
+	}
+
+	wpa_printf(MSG_DEBUG, "Location Measurement Report " MACSTR " --> "
+		   MACSTR " (dialog token %u)",
+		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da), *pos);
+	pos++;
+
+	if (!no_ack)
+		add_note(wt, MSG_INFO,
+			 "Protected Fine Timing Measurement Report incorrectly as an Action frame from "
+			 MACSTR, MAC2STR(mgmt->sa));
+
+	wpa_hexdump(MSG_MSGDUMP, "Location Measurement Report contents",
+		    pos, end - pos);
+}
+
+
+static void rx_mgmt_action_no_bss_public(struct wlantest *wt,
+					 const struct ieee80211_mgmt *mgmt,
+					 size_t len, bool no_ack)
+{
+	switch (mgmt->u.action.u.public_action.action) {
+	case WLAN_PA_LOCATION_MEASUREMENT_REPORT:
+		rx_mgmt_location_measurement_report(wt, mgmt, len, no_ack);
+		break;
+	}
+}
+
+
+static void rx_mgmt_prot_ftm_request(struct wlantest *wt,
+				     const struct ieee80211_mgmt *mgmt,
+				     size_t len, bool no_ack)
+{
+	wpa_printf(MSG_DEBUG, "Protected Fine Timing Measurement Request "
+		   MACSTR " --> " MACSTR,
+		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da));
+	if (no_ack)
+		add_note(wt, MSG_INFO,
+			 "Protected Fine Timing Measurement Request incorrectly as an Action No Ack frame from "
+			 MACSTR, MAC2STR(mgmt->sa));
+}
+
+
+static void rx_mgmt_prot_ftm(struct wlantest *wt,
+			     const struct ieee80211_mgmt *mgmt,
+			     size_t len, bool no_ack)
+{
+	wpa_printf(MSG_DEBUG, "Protected Fine Timing Measurement "
+		   MACSTR " --> " MACSTR,
+		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da));
+	if (no_ack)
+		add_note(wt, MSG_INFO,
+			 "Protected Fine Timing Measurement incorrectly as an Action No Ack frame from "
+			 MACSTR, MAC2STR(mgmt->sa));
+}
+
+
+static void rx_mgmt_prot_ftm_report(struct wlantest *wt,
+				     const struct ieee80211_mgmt *mgmt,
+				     size_t len, bool no_ack)
+{
+	wpa_printf(MSG_DEBUG, "Protected Fine Timing Measurement Report "
+		   MACSTR " --> " MACSTR,
+		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da));
+	if (!no_ack)
+		add_note(wt, MSG_INFO,
+			 "Protected Fine Timing Measurement Report incorrectly as an Action frame from "
+			 MACSTR, MAC2STR(mgmt->sa));
+}
+
+
+static void
+rx_mgmt_action_no_bss_protected_ftm(struct wlantest *wt,
+				    const struct ieee80211_mgmt *mgmt,
+				    size_t len, bool no_ack)
+{
+	switch (mgmt->u.action.u.public_action.action) {
+	case WLAN_PROT_FTM_REQUEST:
+		rx_mgmt_prot_ftm_request(wt, mgmt, len, no_ack);
+		break;
+	case WLAN_PROT_FTM:
+		rx_mgmt_prot_ftm(wt, mgmt, len, no_ack);
+		break;
+	case WLAN_PROT_FTM_REPORT:
+		rx_mgmt_prot_ftm_report(wt, mgmt, len, no_ack);
+		break;
+	}
+}
+
+
+static void rx_mgmt_action_no_bss(struct wlantest *wt,
+				  const struct ieee80211_mgmt *mgmt, size_t len,
+				  bool no_ack)
+{
+	switch (mgmt->u.action.category) {
+	case WLAN_ACTION_PUBLIC:
+		rx_mgmt_action_no_bss_public(wt, mgmt, len, no_ack);
+		break;
+	case WLAN_ACTION_PROTECTED_FTM:
+		rx_mgmt_action_no_bss_protected_ftm(wt, mgmt, len, no_ack);
+		break;
+	}
+}
+
+
 static void rx_mgmt_action(struct wlantest *wt, const u8 *data, size_t len,
-			   int valid)
+			   int valid, bool no_ack)
 {
 	const struct ieee80211_mgmt *mgmt;
 	struct wlantest_bss *bss;
@@ -1929,6 +2050,24 @@
 			 MAC2STR(mgmt->bssid), mgmt->u.action.category);
 		return; /* Ignore group addressed Action frames for now */
 	}
+
+	if (len < 24 + 2) {
+		add_note(wt, MSG_INFO, "Too short Action frame from " MACSTR,
+			 MAC2STR(mgmt->sa));
+		return;
+	}
+
+	wpa_printf(MSG_DEBUG, "ACTION%s " MACSTR " -> " MACSTR
+		   " BSSID=" MACSTR " (category=%u) (valid=%d)",
+		   no_ack ? "-NO-ACK" : "",
+		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da), MAC2STR(mgmt->bssid),
+		   mgmt->u.action.category, valid);
+	wpa_hexdump(MSG_MSGDUMP, "ACTION payload", data + 24, len - 24);
+
+	if (is_broadcast_ether_addr(mgmt->bssid)) {
+		rx_mgmt_action_no_bss(wt, mgmt, len, no_ack);
+		return;
+	}
 	bss = bss_get(wt, mgmt->bssid);
 	if (bss == NULL)
 		return;
@@ -1939,18 +2078,6 @@
 	if (sta == NULL)
 		return;
 
-	if (len < 24 + 1) {
-		add_note(wt, MSG_INFO, "Too short Action frame from " MACSTR,
-			 MAC2STR(mgmt->sa));
-		return;
-	}
-
-	wpa_printf(MSG_DEBUG, "ACTION " MACSTR " -> " MACSTR
-		   " (category=%u) (valid=%d)",
-		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da),
-		   mgmt->u.action.category, valid);
-	wpa_hexdump(MSG_MSGDUMP, "ACTION payload", data + 24, len - 24);
-
 	if (mgmt->u.action.category != WLAN_ACTION_PUBLIC &&
 	    sta->state < STATE3) {
 		add_note(wt, MSG_INFO, "Action frame sent when STA is not in "
@@ -2061,7 +2188,8 @@
 	fc = le_to_host16(mgmt->frame_control);
 	stype = WLAN_FC_GET_STYPE(fc);
 
-	if (stype == WLAN_FC_STYPE_ACTION) {
+	if (stype == WLAN_FC_STYPE_ACTION ||
+	    stype == WLAN_FC_STYPE_ACTION_NO_ACK) {
 		if (len < 24 + 1)
 			return 0;
 		if (mgmt->u.action.category == WLAN_ACTION_PUBLIC)
@@ -2138,6 +2266,56 @@
 }
 
 
+static u8 * try_tk(struct wpa_ptk *ptk, const u8 *data, size_t len,
+		   size_t *dlen)
+{
+	const struct ieee80211_hdr *hdr;
+	u8 *decrypted, *frame;
+
+	hdr = (const struct ieee80211_hdr *) data;
+	decrypted = ccmp_decrypt(ptk->tk, hdr, data + 24, len - 24, dlen);
+	if (!decrypted)
+		return NULL;
+
+	frame = os_malloc(24 + *dlen);
+	if (frame) {
+		os_memcpy(frame, data, 24);
+		os_memcpy(frame + 24, decrypted, *dlen);
+		*dlen += 24;
+	}
+	os_free(decrypted);
+	return frame;
+}
+
+
+static u8 * mgmt_ccmp_decrypt_tk(struct wlantest *wt, const u8 *data,
+				 size_t len, size_t *dlen)
+{
+	struct wlantest_ptk *ptk;
+	u8 *decrypted;
+	int prev_level = wpa_debug_level;
+	int keyid;
+
+	keyid = data[24 + 3] >> 6;
+
+	wpa_debug_level = MSG_WARNING;
+	dl_list_for_each(ptk, &wt->ptk, struct wlantest_ptk, list) {
+		decrypted = try_tk(&ptk->ptk, data, len, dlen);
+		if (decrypted) {
+			wpa_debug_level = prev_level;
+			add_note(wt, MSG_DEBUG,
+				 "Found TK match from the list of all known TKs");
+			write_decrypted_note(wt, decrypted, ptk->ptk.tk,
+					     ptk->ptk.tk_len, keyid);
+			return decrypted;
+		}
+	}
+	wpa_debug_level = prev_level;
+
+	return NULL;
+}
+
+
 static u8 * mgmt_ccmp_decrypt(struct wlantest *wt, const u8 *data, size_t len,
 			      size_t *dlen)
 {
@@ -2147,19 +2325,11 @@
 	int keyid;
 	u8 *decrypted, *frame = NULL;
 	u8 pn[6], *rsc;
+	u16 fc;
+	u8 mask;
 
 	hdr = (const struct ieee80211_hdr *) data;
-	bss = bss_get(wt, hdr->addr3);
-	if (bss == NULL)
-		return NULL;
-	if (os_memcmp(hdr->addr1, hdr->addr3, ETH_ALEN) == 0)
-		sta = sta_get(bss, hdr->addr2);
-	else
-		sta = sta_get(bss, hdr->addr1);
-	if (sta == NULL || !sta->ptk_set) {
-		add_note(wt, MSG_MSGDUMP, "No PTK known to decrypt the frame");
-		return NULL;
-	}
+	fc = le_to_host16(hdr->frame_control);
 
 	if (len < 24 + 4)
 		return NULL;
@@ -2171,7 +2341,11 @@
 		return NULL;
 	}
 
-	if (data[24 + 2] != 0 || (data[24 + 3] & 0x1f) != 0) {
+	mask = 0x1f;
+	if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION ||
+	    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION_NO_ACK)
+		mask &= ~0x10; /* FTM */
+	if (data[24 + 2] != 0 || (data[24 + 3] & mask) != 0) {
 		add_note(wt, MSG_INFO, "CCMP mgmt frame from " MACSTR " used "
 			 "non-zero reserved bit", MAC2STR(hdr->addr2));
 	}
@@ -2183,6 +2357,21 @@
 			 MACSTR, keyid, MAC2STR(hdr->addr2));
 	}
 
+	bss = bss_get(wt, hdr->addr3);
+	if (bss == NULL)
+		return mgmt_ccmp_decrypt_tk(wt, data, len, dlen);
+	if (os_memcmp(hdr->addr1, hdr->addr3, ETH_ALEN) == 0)
+		sta = sta_get(bss, hdr->addr2);
+	else
+		sta = sta_get(bss, hdr->addr1);
+	if (sta == NULL || !sta->ptk_set) {
+		decrypted = mgmt_ccmp_decrypt_tk(wt, data, len, dlen);
+		if (!decrypted)
+			add_note(wt, MSG_MSGDUMP,
+				 "No PTK known to decrypt the frame");
+		return decrypted;
+	}
+
 	if (os_memcmp(hdr->addr1, hdr->addr3, ETH_ALEN) == 0)
 		rsc = sta->rsc_tods[16];
 	else
@@ -2236,7 +2425,8 @@
 	mgmt = (const struct ieee80211_mgmt *) data;
 	fc = le_to_host16(mgmt->frame_control);
 
-	if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION) {
+	if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION ||
+	    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION_NO_ACK) {
 		if (len > 24 &&
 		    mgmt->u.action.category == WLAN_ACTION_PUBLIC)
 			return 0; /* Not a robust management frame */
@@ -2255,7 +2445,8 @@
 	if ((bss->rsn_capab & WPA_CAPABILITY_MFPC) &&
 	    (sta->rsn_capab & WPA_CAPABILITY_MFPC) &&
 	    (sta->state == STATE3 ||
-	     WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION)) {
+	     WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION ||
+	     WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION_NO_ACK)) {
 		add_note(wt, MSG_INFO, "Robust individually-addressed "
 			 "management frame sent without CCMP by "
 			 MACSTR, MAC2STR(mgmt->sa));
@@ -2285,7 +2476,8 @@
 	if ((hdr->addr1[0] & 0x01) &&
 	    (stype == WLAN_FC_STYPE_DEAUTH ||
 	     stype == WLAN_FC_STYPE_DISASSOC ||
-	     stype == WLAN_FC_STYPE_ACTION)) {
+	     stype == WLAN_FC_STYPE_ACTION ||
+	     stype == WLAN_FC_STYPE_ACTION_NO_ACK)) {
 		if (check_bip(wt, data, len) < 0)
 			valid = 0;
 	}
@@ -2305,7 +2497,8 @@
 	    !(hdr->addr1[0] & 0x01) &&
 	    (stype == WLAN_FC_STYPE_DEAUTH ||
 	     stype == WLAN_FC_STYPE_DISASSOC ||
-	     stype == WLAN_FC_STYPE_ACTION)) {
+	     stype == WLAN_FC_STYPE_ACTION ||
+	     stype == WLAN_FC_STYPE_ACTION_NO_ACK)) {
 		decrypted = mgmt_ccmp_decrypt(wt, data, len, &dlen);
 		if (decrypted) {
 			write_pcap_decrypted(wt, decrypted, dlen, NULL, 0);
@@ -2319,7 +2512,8 @@
 	    !(hdr->addr1[0] & 0x01) &&
 	    (stype == WLAN_FC_STYPE_DEAUTH ||
 	     stype == WLAN_FC_STYPE_DISASSOC ||
-	     stype == WLAN_FC_STYPE_ACTION)) {
+	     stype == WLAN_FC_STYPE_ACTION ||
+	     stype == WLAN_FC_STYPE_ACTION_NO_ACK)) {
 		if (check_mgmt_ccmp(wt, data, len) < 0)
 			valid = 0;
 	}
@@ -2353,7 +2547,10 @@
 		rx_mgmt_disassoc(wt, data, len, valid);
 		break;
 	case WLAN_FC_STYPE_ACTION:
-		rx_mgmt_action(wt, data, len, valid);
+		rx_mgmt_action(wt, data, len, valid, false);
+		break;
+	case WLAN_FC_STYPE_ACTION_NO_ACK:
+		rx_mgmt_action(wt, data, len, valid, true);
 		break;
 	}
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/sta.c b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/sta.c
index 62dae07..02ecb78 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/sta.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/sta.c
@@ -180,8 +180,8 @@
 	wpa_printf(MSG_INFO, "STA " MACSTR
 		   " proto=%s%s%s%s"
 		   "pairwise=%s%s%s%s%s%s%s"
-		   "key_mgmt=%s%s%s%s%s%s%s%s%s%s%s"
-		   "rsn_capab=%s%s%s%s%s%s",
+		   "key_mgmt=%s%s%s%s%s%s%s%s%s%s%s%s%s%s"
+		   "rsn_capab=%s%s%s%s%s%s%s%s%s%s",
 		   MAC2STR(sta->addr),
 		   sta->proto == 0 ? "OPEN " : "",
 		   sta->proto & WPA_PROTO_WPA ? "WPA " : "",
@@ -206,7 +206,10 @@
 		   "EAP-SHA256 " : "",
 		   sta->key_mgmt & WPA_KEY_MGMT_PSK_SHA256 ?
 		   "PSK-SHA256 " : "",
+		   sta->key_mgmt & WPA_KEY_MGMT_OWE ? "OWE " : "",
+		   sta->key_mgmt & WPA_KEY_MGMT_PASN ? "PASN " : "",
 		   sta->key_mgmt & WPA_KEY_MGMT_OSEN ? "OSEN " : "",
+		   sta->key_mgmt & WPA_KEY_MGMT_DPP ? "DPP " : "",
 		   sta->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B ?
 		   "EAP-SUITE-B " : "",
 		   sta->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192 ?
@@ -218,5 +221,12 @@
 		   sta->rsn_capab & WPA_CAPABILITY_MFPC ? "MFPC " : "",
 		   sta->rsn_capab & WPA_CAPABILITY_PEERKEY_ENABLED ?
 		   "PEERKEY " : "",
-		   sta->rsn_capab & WPA_CAPABILITY_OCVC ? "OCVC " : "");
+		   sta->rsn_capab & WPA_CAPABILITY_SPP_A_MSDU_CAPABLE ?
+		   "SPP-A-MSDU-CAPAB " : "",
+		   sta->rsn_capab & WPA_CAPABILITY_SPP_A_MSDU_REQUIRED ?
+		   "SPP-A-MSDU-REQUIRED " : "",
+		   sta->rsn_capab & WPA_CAPABILITY_PBAC ? "PBAC " : "",
+		   sta->rsn_capab & WPA_CAPABILITY_OCVC ? "OCVC " : "",
+		   sta->rsn_capab & WPA_CAPABILITY_EXT_KEY_ID_FOR_UNICAST ?
+		   "ExtKeyID " : "");
 }
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/test_vectors.c b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/test_vectors.c
index ab9c0a3..7f39c42 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/test_vectors.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/test_vectors.c
@@ -63,7 +63,7 @@
 
 	wpa_debug_level = MSG_INFO;
 	plain = tkip_decrypt(tk, (const struct ieee80211_hdr *) enc,
-			     enc + 24, enc_len - 24, &plain_len);
+			     enc + 24, enc_len - 24, &plain_len, NULL, NULL);
 	wpa_debug_level = MSG_EXCESSIVE;
 	os_free(enc);
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/tkip.c b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/tkip.c
index d616d43..843f651 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/tkip.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/tkip.c
@@ -1,5 +1,5 @@
 /*
- * Temporal Key Integrity Protocol (CCMP)
+ * Temporal Key Integrity Protocol (TKIP)
  * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
@@ -290,7 +290,8 @@
 
 
 u8 * tkip_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr,
-		  const u8 *data, size_t data_len, size_t *decrypted_len)
+		  const u8 *data, size_t data_len, size_t *decrypted_len,
+		  enum michael_mic_result *mic_res, struct tkip_frag *frag)
 {
 	u16 iv16;
 	u32 iv32;
@@ -303,6 +304,11 @@
 	u8 michael_hdr[16];
 	u8 mic[8];
 	u16 fc = le_to_host16(hdr->frame_control);
+	const u8 *full_payload;
+	size_t full_payload_len;
+	u16 sc = le_to_host16(hdr->seq_ctrl);
+	u16 sn;
+	u8 fn;
 
 	if (data_len < 8 + 4)
 		return NULL;
@@ -335,9 +341,57 @@
 	}
 	plain_len -= 4;
 
-	/* TODO: MSDU reassembly */
+	full_payload = plain;
+	full_payload_len = plain_len;
 
-	if (plain_len < 8) {
+	sn = WLAN_GET_SEQ_SEQ(sc);
+	fn = WLAN_GET_SEQ_FRAG(sc);
+
+	if (frag) {
+		/* MSDU reassembly for Michael MIC validation */
+		if (fn == 0 && (fc & WLAN_FC_MOREFRAG)) {
+			/* Start of a new fragmented MSDU */
+			wpabuf_free(frag->buf);
+			frag->buf = NULL;
+			frag->buf = wpabuf_alloc_copy(plain, plain_len);
+			os_memcpy(frag->ra, hdr->addr1, ETH_ALEN);
+			os_memcpy(frag->ta, hdr->addr2, ETH_ALEN);
+			frag->sn = sn;
+			frag->fn = 0;
+		}
+
+		if (frag->buf && (fn || (fc & WLAN_FC_MOREFRAG)) &&
+		    sn == frag->sn && fn == frag->fn + 1 &&
+		    os_memcmp(frag->ra, hdr->addr1, ETH_ALEN) == 0 &&
+		    os_memcmp(frag->ta, hdr->addr2, ETH_ALEN) == 0) {
+			/* Add the next fragment */
+			if (wpabuf_resize(&frag->buf, plain_len) == 0) {
+				wpabuf_put_data(frag->buf, plain, plain_len);
+				frag->fn = fn;
+				if (!(fc & WLAN_FC_MOREFRAG)) {
+					full_payload = wpabuf_head(frag->buf);
+					full_payload_len =
+						wpabuf_len(frag->buf);
+					wpa_hexdump(MSG_MSGDUMP,
+						    "TKIP reassembled full payload",
+						    full_payload,
+						    full_payload_len);
+				}
+			}
+		}
+	}
+
+	if ((fc & WLAN_FC_MOREFRAG) || (fn > 0 && full_payload == plain)) {
+		/* Return the decrypted fragment and do not check the
+		 * Michael MIC value since no reassembled frame is available. */
+		*decrypted_len = plain_len;
+		if (mic_res) {
+			*mic_res = MICHAEL_MIC_NOT_VERIFIED;
+			return plain;
+		}
+	}
+
+	if (full_payload_len < 8) {
 		wpa_printf(MSG_INFO, "TKIP: Not enough room for Michael MIC "
 			   "in a frame from " MACSTR, MAC2STR(hdr->addr2));
 		os_free(plain);
@@ -346,15 +400,23 @@
 
 	michael_mic_hdr(hdr, michael_hdr);
 	mic_key = tk + ((fc & WLAN_FC_FROMDS) ? 16 : 24);
-	michael_mic(mic_key, michael_hdr, plain, plain_len - 8, mic);
-	if (os_memcmp(mic, plain + plain_len - 8, 8) != 0) {
+	michael_mic(mic_key, michael_hdr, full_payload, full_payload_len - 8,
+		    mic);
+	if (os_memcmp(mic, full_payload + full_payload_len - 8, 8) != 0) {
 		wpa_printf(MSG_INFO, "TKIP: Michael MIC mismatch in a frame "
 			   "from " MACSTR, MAC2STR(hdr->addr2));
 		wpa_hexdump(MSG_DEBUG, "TKIP: Calculated MIC", mic, 8);
 		wpa_hexdump(MSG_DEBUG, "TKIP: Received MIC",
-			    plain + plain_len - 8, 8);
+			    full_payload + full_payload_len - 8, 8);
+		if (mic_res) {
+			*decrypted_len = plain_len - 8;
+			*mic_res = MICHAEL_MIC_INCORRECT;
+			return plain;
+		}
 		os_free(plain);
 		return NULL;
+	} else if (mic_res) {
+		*mic_res = MICHAEL_MIC_OK;
 	}
 
 	*decrypted_len = plain_len - 8;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/wlantest.c b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/wlantest.c
index 1b8d714..fd6dc20 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/wlantest.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/wlantest.c
@@ -27,7 +27,7 @@
 	       "[-P<RADIUS shared secret>]\n"
 	       "         [-n<write pcapng file>]\n"
 	       "         [-w<write pcap file>] [-f<MSK/PMK file>]\n"
-	       "         [-L<log file>] [-T<PTK file>]\n");
+	       "         [-L<log file>] [-T<PTK file>] [-W<WEP key>]\n");
 }
 
 
@@ -77,6 +77,13 @@
 }
 
 
+static void wep_deinit(struct wlantest_wep *wep)
+{
+	dl_list_del(&wep->list);
+	os_free(wep);
+}
+
+
 static void wlantest_deinit(struct wlantest *wt)
 {
 	struct wlantest_passphrase *p, *pn;
@@ -104,12 +111,14 @@
 	dl_list_for_each_safe(ptk, npt, &wt->ptk, struct wlantest_ptk, list)
 		ptk_deinit(ptk);
 	dl_list_for_each_safe(wep, nw, &wt->wep, struct wlantest_wep, list)
-		os_free(wep);
+		wep_deinit(wep);
 	write_pcap_deinit(wt);
 	write_pcapng_deinit(wt);
 	clear_notes(wt);
 	os_free(wt->decrypted);
 	wt->decrypted = NULL;
+	wpabuf_free(wt->tkip_frag.buf);
+	wt->tkip_frag.buf = NULL;
 }
 
 
@@ -323,6 +332,19 @@
 }
 
 
+void write_decrypted_note(struct wlantest *wt, const u8 *decrypted,
+			  const u8 *tk, size_t tk_len, int keyid)
+{
+	char tk_hex[65];
+
+	if (!decrypted)
+		return;
+
+	wpa_snprintf_hex(tk_hex, sizeof(tk_hex), tk, tk_len);
+	add_note(wt, MSG_EXCESSIVE, "TK[%d] %s", keyid, tk_hex);
+}
+
+
 int wlantest_relog(struct wlantest *wt)
 {
 	int ret = 0;
@@ -349,7 +371,7 @@
 
 int main(int argc, char *argv[])
 {
-	int c;
+	int c, ret = 0;
 	const char *read_file = NULL;
 	const char *read_wired_file = NULL;
 	const char *ifname = NULL;
@@ -357,6 +379,7 @@
 	const char *logfile = NULL;
 	struct wlantest wt;
 	int ctrl_iface = 0;
+	bool eloop_init_done = false;
 
 	wpa_debug_level = MSG_INFO;
 	wpa_debug_show_keys = 1;
@@ -382,15 +405,18 @@
 			wt.ethernet = 1;
 			break;
 		case 'f':
-			if (add_pmk_file(&wt, optarg) < 0)
-				return -1;
+			if (add_pmk_file(&wt, optarg) < 0) {
+				ret = -1;
+				goto deinit;
+			}
 			break;
 		case 'F':
 			wt.assume_fcs = 1;
 			break;
 		case 'h':
 			usage();
-			return 0;
+			ret = 0;
+			goto deinit;
 		case 'i':
 			ifname = optarg;
 			break;
@@ -425,54 +451,54 @@
 			wpa_debug_timestamp = 1;
 			break;
 		case 'T':
-			if (add_ptk_file(&wt, optarg) < 0)
-				return -1;
+			if (add_ptk_file(&wt, optarg) < 0) {
+				ret = -1;
+				goto deinit;
+			}
 			break;
 		case 'w':
 			wt.write_file = optarg;
 			break;
 		case 'W':
-			if (add_wep(&wt, optarg) < 0)
-				return -1;
+			if (add_wep(&wt, optarg) < 0) {
+				ret = -1;
+				goto deinit;
+			}
 			break;
 		default:
 			usage();
-			return -1;
+			ret = -1;
+			goto deinit;
 		}
 	}
 
 	if (ifname == NULL && ifname_wired == NULL &&
 	    read_file == NULL && read_wired_file == NULL) {
 		usage();
-		return 0;
+		ret = 0;
+		goto deinit;
 	}
 
-	if (eloop_init())
-		return -1;
+	if (eloop_init()) {
+		ret = -1;
+		goto deinit;
+	}
+	eloop_init_done = true;
 
 	if (logfile)
 		wpa_debug_open_file(logfile);
 
-	if (wt.write_file && write_pcap_init(&wt, wt.write_file) < 0)
-		return -1;
-
-	if (wt.pcapng_file && write_pcapng_init(&wt, wt.pcapng_file) < 0)
-		return -1;
-
-	if (read_wired_file && read_wired_cap_file(&wt, read_wired_file) < 0)
-		return -1;
-
-	if (read_file && read_cap_file(&wt, read_file) < 0)
-		return -1;
-
-	if (ifname && monitor_init(&wt, ifname) < 0)
-		return -1;
-
-	if (ifname_wired && monitor_init_wired(&wt, ifname_wired) < 0)
-		return -1;
-
-	if (ctrl_iface && ctrl_init(&wt) < 0)
-		return -1;
+	if ((wt.write_file && write_pcap_init(&wt, wt.write_file) < 0) ||
+	    (wt.pcapng_file && write_pcapng_init(&wt, wt.pcapng_file) < 0) ||
+	    (read_wired_file &&
+	     read_wired_cap_file(&wt, read_wired_file) < 0) ||
+	    (read_file && read_cap_file(&wt, read_file) < 0) ||
+	    (ifname && monitor_init(&wt, ifname) < 0) ||
+	    (ifname_wired && monitor_init_wired(&wt, ifname_wired) < 0) ||
+	    (ctrl_iface && ctrl_init(&wt) < 0)) {
+		ret = -1;
+		goto deinit;
+	}
 
 	eloop_register_signal_terminate(wlantest_terminate, &wt);
 
@@ -482,11 +508,13 @@
 		   "fcs_error=%u",
 		   wt.rx_mgmt, wt.rx_ctrl, wt.rx_data, wt.fcs_error);
 
+deinit:
 	wlantest_deinit(&wt);
 
 	wpa_debug_close_file();
-	eloop_destroy();
+	if (eloop_init_done)
+		eloop_destroy();
 	os_program_deinit();
 
-	return 0;
+	return ret;
 }
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/wlantest.h b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/wlantest.h
index 0c266f4..33ab422 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/wlantest.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/wlantest.h
@@ -170,6 +170,7 @@
 	u8 r0kh_id[FT_R0KH_ID_MAX_LEN];
 	size_t r0kh_id_len;
 	u8 r1kh_id[FT_R1KH_ID_LEN];
+	bool mesh;
 };
 
 struct wlantest_radius {
@@ -183,6 +184,14 @@
 #define MAX_CTRL_CONNECTIONS 10
 #define MAX_NOTES 10
 
+struct tkip_frag {
+	struct wpabuf *buf;
+	u8 ra[ETH_ALEN];
+	u8 ta[ETH_ALEN];
+	u16 sn;
+	u8 fn;
+};
+
 struct wlantest {
 	int monitor_sock;
 	int monitor_wired;
@@ -226,12 +235,16 @@
 
 	const char *write_file;
 	const char *pcapng_file;
+
+	struct tkip_frag tkip_frag;
 };
 
 void add_note(struct wlantest *wt, int level, const char *fmt, ...)
 PRINTF_FORMAT(3, 4);
 void clear_notes(struct wlantest *wt);
 size_t notes_len(struct wlantest *wt, size_t hdrlen);
+void write_decrypted_note(struct wlantest *wt, const u8 *decrypted,
+			  const u8 *tk, size_t tk_len, int keyid);
 
 int add_wep(struct wlantest *wt, const char *key);
 int read_cap_file(struct wlantest *wt, const char *fname);
@@ -301,8 +314,14 @@
 u8 * ccmp_256_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen,
 		      u8 *qos, u8 *pn, int keyid, size_t *encrypted_len);
 
+enum michael_mic_result {
+	MICHAEL_MIC_OK,
+	MICHAEL_MIC_INCORRECT,
+	MICHAEL_MIC_NOT_VERIFIED
+};
 u8 * tkip_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr,
-		  const u8 *data, size_t data_len, size_t *decrypted_len);
+		  const u8 *data, size_t data_len, size_t *decrypted_len,
+		  enum michael_mic_result *mic_res, struct tkip_frag *frag);
 u8 * tkip_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, u8 *qos,
 		  u8 *pn, int keyid, size_t *encrypted_len);
 void tkip_get_pn(u8 *pn, const u8 *data);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/wlantest_cli.c b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/wlantest_cli.c
index ad5a48d..0a1384e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wlantest/wlantest_cli.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wlantest/wlantest_cli.c
@@ -12,25 +12,11 @@
 #include "utils/common.h"
 #include "utils/eloop.h"
 #include "utils/edit.h"
+#include "common/cli.h"
 #include "wlantest_ctrl.h"
 
-
-static int get_cmd_arg_num(const char *str, int pos)
-{
-	int arg = 0, i;
-
-	for (i = 0; i <= pos; i++) {
-		if (str[i] != ' ') {
-			arg++;
-			while (i <= pos && str[i] != ' ')
-				i++;
-		}
-	}
-
-	if (arg > 0)
-		arg--;
-	return arg;
-}
+static void print_help(FILE *stream, const char *cmd);
+static char ** wlantest_cli_cmd_list(void);
 
 
 static int get_prev_arg_pos(const char *str, int pos)
@@ -1566,6 +1552,28 @@
 }
 
 
+static int wlantest_cli_cmd_help(int s, int argc, char *argv[])
+{
+	print_help(stdout, argc > 0 ? argv[0] : NULL);
+	return 0;
+}
+
+
+static char ** wlantest_cli_complete_help(int s, const char *str, int pos)
+{
+	int arg = get_cmd_arg_num(str, pos);
+	char **res = NULL;
+
+	switch (arg) {
+	case 1:
+		res = wlantest_cli_cmd_list();
+		break;
+	}
+
+	return res;
+}
+
+
 struct wlantest_cli_cmd {
 	const char *cmd;
 	int (*handler)(int s, int argc, char *argv[]);
@@ -1623,10 +1631,45 @@
 	{ "get_rx_tid", cmd_get_rx_tid,
 	  "<BSSID> <STA> <TID> = get STA RX TID counter value",
 	  complete_get_tid },
+	{ "help", wlantest_cli_cmd_help,
+	  "= show this usage help", wlantest_cli_complete_help },
 	{ NULL, NULL, NULL, NULL }
 };
 
 
+/*
+ * Prints command usage, lines are padded with the specified string.
+ */
+static void print_cmd_help(FILE *stream, const struct wlantest_cli_cmd *cmd,
+			   const char *pad)
+{
+	char c;
+	size_t n;
+
+	if (!cmd->usage)
+		return;
+	fprintf(stream, "%s%s ", pad, cmd->cmd);
+	for (n = 0; (c = cmd->usage[n]); n++) {
+		fprintf(stream, "%c", c);
+		if (c == '\n')
+			fprintf(stream, "%s", pad);
+	}
+	fprintf(stream, "\n");
+}
+
+
+static void print_help(FILE *stream, const char *cmd)
+{
+	int n;
+
+	fprintf(stream, "commands:\n");
+	for (n = 0; wlantest_cli_commands[n].cmd; n++) {
+		if (!cmd || str_starts(wlantest_cli_commands[n].cmd, cmd))
+			print_cmd_help(stream, &wlantest_cli_commands[n], "  ");
+	}
+}
+
+
 static int ctrl_command(int s, int argc, char *argv[])
 {
 	const struct wlantest_cli_cmd *cmd, *match = NULL;
@@ -1672,38 +1715,6 @@
 };
 
 
-#define max_args 10
-
-static int tokenize_cmd(char *cmd, char *argv[])
-{
-	char *pos;
-	int argc = 0;
-
-	pos = cmd;
-	for (;;) {
-		while (*pos == ' ')
-			pos++;
-		if (*pos == '\0')
-			break;
-		argv[argc] = pos;
-		argc++;
-		if (argc == max_args)
-			break;
-		if (*pos == '"') {
-			char *pos2 = os_strrchr(pos, '"');
-			if (pos2)
-				pos = pos2 + 1;
-		}
-		while (*pos != '\0' && *pos != ' ')
-			pos++;
-		if (*pos == ' ')
-			*pos++ = '\0';
-	}
-
-	return argc;
-}
-
-
 static void wlantest_cli_edit_cmd_cb(void *ctx, char *cmd)
 {
 	struct wlantest_cli *cli = ctx;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/.config b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/.config
index 5695d49..8f89787 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/.config
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/.config
@@ -248,6 +248,9 @@
 # Simultaneous Authentication of Equals (SAE), WPA3-Personal
 CONFIG_SAE=y
 
+# Set SAE Auth status early
+CONFIG_WPA3_SAE_AUTH_EARLY_SET=y
+
 # Host SAE via Vendor commands
 #CONFIG_WL_SAE=y
 
@@ -485,6 +488,12 @@
 # (depends on CONFIG_IEEE80211N)
 CONFIG_IEEE80211AC=y
 
+# IEEE 802.11ax HE support (mainly for AP mode)
+# Note: This is experimental and work in progress. The definitions are still
+# subject to change and this should not be expected to interoperate with the
+# final IEEE 802.11ax version.
+CONFIG_IEEE80211AX=y
+
 # Wireless Network Management (IEEE Std 802.11v-2011)
 # Note: This is experimental and not complete implementation.
 #CONFIG_WNM=y
@@ -608,11 +617,11 @@
 CONFIG_BGSCAN_SIMPLE=y
 # Learn channels used by the network and try to avoid bgscans on other
 # channels (experimental)
-#CONFIG_BGSCAN_LEARN=y
+CONFIG_BGSCAN_LEARN=y
 
 # Opportunistic Wireless Encryption (OWE)
 # Experimental implementation of draft-harkins-owe-07.txt
-#CONFIG_OWE=y
+CONFIG_OWE=y
 
 # Device Provisioning Protocol (DPP)
 # This requires CONFIG_IEEE80211W=y to be enabled, too. (see
@@ -623,6 +632,7 @@
 #on2.4G and 5G
 #CONFIG_RANDCHAN=y
 CONFIG_BRCM_AUTOMOTIVE=y
+CONFIG_WPA3_SAE_AUTH_EARLY_SET=y
 
 # Uncomment the below line for AP to receive disconnect management frame.
 #CONFIG_CY_AP_RX_MGMT_DISCONNECT=y
@@ -630,6 +640,15 @@
 # Enable patch for OKC
 #CONFIG_BRCM_OKC=y
 
+# Enabling WPA3-192 enterprise security
+CONFIG_SUITEB192=y
+CONFIG_SUITEB=y
+
 # Define any features here which are dependent upon some specific linux kernel versions
-#CONFIG_BRCM_VE=y
-CONFIG_BUILD_WPA_CLIENT_SO=y
+CONFIG_BRCM_VE=y
+
+# Enable all IFX/Cypress changes
+CONFIG_DRIVER_NL80211_IFX=y
+
+# Offload the TWT Session management to FW
+CONFIG_TWT_OFFLOAD_IFX=y
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/Android.mk b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/Android.mk
index 8157dc8..d4689d3 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/Android.mk
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/Android.mk
@@ -85,6 +85,10 @@
 L_CFLAGS += -DANDROID_LIB_STUB
 endif
 
+ifneq ($(BOARD_WPA_SUPPLICANT_PRIVATE_LIB_EVENT),)
+L_CFLAGS += -DANDROID_LIB_EVENT
+endif
+
 # Disable roaming in wpa_supplicant
 ifdef CONFIG_NO_ROAMING
 L_CFLAGS += -DCONFIG_NO_ROAMING
@@ -169,7 +173,7 @@
 endif
 
 #common flags needed by Android flavors
-ifneq ($(filter O P 8.0.0 8.1.0 9 10 11 12,$(PLATFORM_VERSION)),)
+ifneq ($(filter O P 8.0.0 8.1.0 9 10 11 12 13,$(PLATFORM_VERSION)),)
 L_CFLAGS += \
 	-DABOVE_8_1 \
 	-Wno-date-time \
@@ -185,7 +189,7 @@
 # for Android O
 L_CFLAGS += -DOREO
 L_CFLAGS += -Wno-tautological-compare
-L_CFLAGS += -Wno-tautological-constant-out-of-range-compare
+L_CFLAGS += -Wno-tautological-constant-out-of-range-compare -Wno-missing-field-initializers
 ABOVE_8_1=y
 HIDL_INTERFACE_VERSION = 1.0
 endif
@@ -243,6 +247,19 @@
 INCLUDES += $(LOCAL_PATH)/hidl/$(HIDL_INTERFACE_VERSION)
 endif
 
+ifneq ($(findstring 13,$(PLATFORM_VERSION)),)
+#for android 13
+L_CFLAGS += -DABOVE_9
+L_CFLAGS += -DABOVE_10
+L_CFLAGS += -DABOVE_13
+L_CFLAGS += -DCONFIG_ANDROID12
+ABOVE_8_1=y
+ABOVE_9=y
+ABOVE_10=y
+ABOVE_13=y
+HIDL_INTERFACE_VERSION = 1.4
+endif
+
 INCLUDES = $(LOCAL_PATH)
 INCLUDES += $(LOCAL_PATH)/src
 INCLUDES += $(LOCAL_PATH)/src/common
@@ -267,6 +284,10 @@
 INCLUDES += external/openssl/include
 endif
 
+ifdef ABOVE_13
+INCLUDES += external/boringssl/src/crypto/
+endif
+
 ifneq ($(findstring 4.0,$(PLATFORM_VERSION)),)
 INCLUDES += frameworks/base/cmds/keystore
 else
@@ -294,6 +315,7 @@
 OBJS += bss.c
 OBJS += eap_register.c
 OBJS += src/utils/common.c
+OBJS += src/utils/config.c
 OBJS += src/utils/wpa_debug.c
 OBJS += src/utils/wpabuf.c
 OBJS += src/utils/bitfield.c
@@ -302,6 +324,7 @@
 OBJS += wmm_ac.c
 OBJS += op_classes.c
 OBJS += rrm.c
+OBJS += twt.c
 OBJS += robust_av.c
 OBJS_p = wpa_passphrase.c
 OBJS_p += src/utils/common.c
@@ -316,6 +339,8 @@
 
 ifdef CONFIG_WAPI_AP
 L_CFLAGS += -DWAPI
+#Added new flag WAPI_ANDROID in android to differentiate from already existing WAPI flag.
+L_CFLAGS += -DWAPI_ANDROID
 L_CFLAGS += -DWAPI_AP
 L_CFLAGS += -DBCMDBG
 INCLUDES += $(LOCAL_PATH)/src/wapi
@@ -473,10 +498,6 @@
 L_CFLAGS += -DWL_SAE
 endif
 
-ifdef CONFIG_WPA3_SAE_AUTH_EARLY_SET
-L_CFLAGS += -DCONFIG_WPA3_SAE_AUTH_EARLY_SET
-endif
-
 ifdef CONFIG_SAE
 L_CFLAGS += -DCONFIG_SAE
 OBJS += src/common/sae.c
@@ -493,6 +514,10 @@
 endif
 endif
 
+ifdef CONFIG_WPA3_SAE_AUTH_EARLY_SET
+L_CFLAGS += -DCONFIG_WPA3_SAE_AUTH_EARLY_SET
+endif
+
 ifdef CONFIG_DPP
 L_CFLAGS += -DCONFIG_DPP
 L_CFLAGS += -DCONFIG_DPP_FIX
@@ -518,6 +543,9 @@
 ifdef CONFIG_DPP2
 L_CFLAGS += -DCONFIG_DPP2
 endif
+ifdef CONFIG_DPP3
+L_CFLAGS += -DCONFIG_DPP3
+endif
 endif
 
 ifdef CONFIG_OWE
@@ -605,15 +633,25 @@
 ifdef CONFIG_P2P_STRICT
 L_CFLAGS += -DCONFIG_P2P_STRICT
 endif
+ifdef CONFIG_WIFI_DISPLAY
+L_CFLAGS += -DCONFIG_WIFI_DISPLAY
+OBJS += wifi_display.c
+endif
 endif
 
 ifdef CONFIG_BRCM_VE
 L_CFLAGS += -DBRCM_VE
 endif
 
-ifdef CONFIG_WIFI_DISPLAY
-L_CFLAGS += -DCONFIG_WIFI_DISPLAY
-OBJS += wifi_display.c
+ifdef CONFIG_PASN
+L_CFLAGS += -DCONFIG_PASN
+L_CFLAGS += -DCONFIG_PTKSA_CACHE
+NEED_HMAC_SHA256_KDF=y
+NEED_HMAC_SHA384_KDF=y
+NEED_SHA256=y
+NEED_SHA384=y
+OBJS += src/common/ptksa_cache.c
+OBJS += pasn_supplicant.c
 endif
 
 ifdef CONFIG_HS20
@@ -1758,6 +1796,10 @@
 WPA_SUPPLICANT_USE_HIDL=y
 L_CFLAGS += -DCONFIG_HIDL -DCONFIG_CTRL_IFACE_HIDL
 endif
+ifdef CONFIG_CTRL_IFACE_AIDL
+WPA_SUPPLICANT_USE_AIDL=y
+L_CFLAGS += -DCONFIG_AIDL -DCONFIG_CTRL_IFACE_AIDL
+endif
 endif
 
 ifdef CONFIG_READLINE
@@ -1885,6 +1927,12 @@
 NEED_EXT_PASSWORD=y
 endif
 
+ifdef CONFIG_EXT_PASSWORD_FILE
+OBJS += src/utils/ext_password_file.c
+L_CFLAGS += -DCONFIG_EXT_PASSWORD_FILE
+NEED_EXT_PASSWORD=y
+endif
+
 ifdef NEED_EXT_PASSWORD
 OBJS += src/utils/ext_password.c
 L_CFLAGS += -DCONFIG_EXT_PASSWORD
@@ -1915,7 +1963,7 @@
 
 OBJS += src/drivers/driver_common.c
 
-OBJS += wpa_supplicant.c events.c blacklist.c wpas_glue.c scan.c
+OBJS += wpa_supplicant.c events.c bssid_ignore.c wpas_glue.c scan.c
 OBJS_t := $(OBJS) $(OBJS_l2) eapol_test.c
 OBJS_t += src/radius/radius_client.c
 OBJS_t += src/radius/radius.c
@@ -2079,8 +2127,17 @@
 
 LOCAL_SHARED_LIBRARIES += libhidlbase libhidltransport libhwbinder libutils libbase
 LOCAL_STATIC_LIBRARIES += libwpa_hidl
-endif
-endif
+endif #WPA_SUPPLICANT_USE_HIDL
+
+ifeq ($(WPA_SUPPLICANT_USE_AIDL), y)
+LOCAL_SHARED_LIBRARIES += android.hardware.wifi.supplicant-V1-ndk
+LOCAL_SHARED_LIBRARIES += libutils libbase
+LOCAL_SHARED_LIBRARIES += libbinder_ndk
+LOCAL_STATIC_LIBRARIES += libwpa_aidl
+LOCAL_VINTF_FRAGMENTS := aidl/android.hardware.wifi.supplicant.xml
+endif #WPA_SUPPLICANT_USE_AIDL
+endif #ifdef ABOVE_8_1
+
 include $(BUILD_EXECUTABLE)
 
 ########################
@@ -2198,3 +2255,38 @@
     $(LOCAL_PATH)/hidl/$(HIDL_INTERFACE_VERSION)
 include $(BUILD_STATIC_LIBRARY)
 endif # WPA_SUPPLICANT_USE_HIDL == y
+
+ifeq ($(WPA_SUPPLICANT_USE_AIDL), y)
+### Aidl service library ###
+########################
+include $(CLEAR_VARS)
+LOCAL_MODULE := libwpa_aidl
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-BSD SPDX-license-identifier-BSD-3-Clause SPDX-license-identifier-ISC legacy_unencumbered
+LOCAL_LICENSE_CONDITIONS := notice unencumbered
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../LICENSE
+LOCAL_VENDOR_MODULE := true
+LOCAL_CPPFLAGS := $(L_CPPFLAGS) \
+	-Wno-unused-variable    \
+        -Wno-unused-function
+LOCAL_CFLAGS := $(L_CFLAGS)
+LOCAL_C_INCLUDES := $(INCLUDES)
+LOCAL_SRC_FILES := \
+    aidl/aidl.cpp \
+    aidl/aidl_manager.cpp \
+    aidl/iface_config_utils.cpp \
+    aidl/p2p_iface.cpp \
+    aidl/p2p_network.cpp \
+    aidl/sta_iface.cpp \
+    aidl/sta_network.cpp \
+    aidl/supplicant.cpp
+LOCAL_SHARED_LIBRARIES := \
+    android.hardware.wifi.supplicant-V1-ndk \
+    libbinder_ndk \
+    libbase \
+    libutils \
+    liblog \
+    libssl
+LOCAL_EXPORT_C_INCLUDE_DIRS := \
+    $(LOCAL_PATH)/aidl
+include $(BUILD_STATIC_LIBRARY)
+endif # WPA_SUPPLICANT_USE_AIDL == y
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ChangeLog b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ChangeLog
index a06a93b..efcc6cd 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ChangeLog
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ChangeLog
@@ -1,5 +1,58 @@
 ChangeLog for wpa_supplicant
 
+2022-01-16 - v2.10
+	* SAE changes
+	  - improved protection against side channel attacks
+	    [https://w1.fi/security/2022-1/]
+	  - added support for the hash-to-element mechanism (sae_pwe=1 or
+	    sae_pwe=2); this is currently disabled by default, but will likely
+	    get enabled by default in the future
+	  - fixed PMKSA caching with OKC
+	  - added support for SAE-PK
+	* EAP-pwd changes
+	  - improved protection against side channel attacks
+	  [https://w1.fi/security/2022-1/]
+	* fixed P2P provision discovery processing of a specially constructed
+	  invalid frame
+	  [https://w1.fi/security/2021-1/]
+	* fixed P2P group information processing of a specially constructed
+	  invalid frame
+	  [https://w1.fi/security/2020-2/]
+	* fixed PMF disconnection protection bypass in AP mode
+	  [https://w1.fi/security/2019-7/]
+	* added support for using OpenSSL 3.0
+	* increased the maximum number of EAP message exchanges (mainly to
+	  support cases with very large certificates)
+	* fixed various issues in experimental support for EAP-TEAP peer
+	* added support for DPP release 2 (Wi-Fi Device Provisioning Protocol)
+	* a number of MKA/MACsec fixes and extensions
+	* added support for SAE (WPA3-Personal) AP mode configuration
+	* added P2P support for EDMG (IEEE 802.11ay) channels
+	* fixed EAP-FAST peer with TLS GCM/CCM ciphers
+	* improved throughput estimation and BSS selection
+	* dropped support for libnl 1.1
+	* added support for nl80211 control port for EAPOL frame TX/RX
+	* fixed OWE key derivation with groups 20 and 21; this breaks backwards
+	  compatibility for these groups while the default group 19 remains
+	  backwards compatible
+	* added support for Beacon protection
+	* added support for Extended Key ID for pairwise keys
+	* removed WEP support from the default build (CONFIG_WEP=y can be used
+	  to enable it, if really needed)
+	* added a build option to remove TKIP support (CONFIG_NO_TKIP=y)
+	* added support for Transition Disable mechanism to allow the AP to
+	  automatically disable transition mode to improve security
+	* extended D-Bus interface
+	* added support for PASN
+	* added a file-based backend for external password storage to allow
+	  secret information to be moved away from the main configuration file
+	  without requiring external tools
+	* added EAP-TLS peer support for TLS 1.3 (disabled by default for now)
+	* added support for SCS, MSCS, DSCP policy
+	* changed driver interface selection to default to automatic fallback
+	  to other compiled in options
+	* a large number of other fixes, cleanup, and extensions
+
 2019-08-07 - v2.9
 	* SAE changes
 	  - disable use of groups using Brainpool curves
@@ -1864,7 +1917,8 @@
 	  generate, e.g., man pages
 	* l2_packet_linux: use socket type SOCK_DGRAM instead of SOCK_RAW for
 	  PF_PACKET in order to prepare for network devices that do not use
-	  Ethernet headers (e.g., network stack with native IEEE 802.11 frames)
+	  Ethernet headers (e.g., network stack that includes IEEE 802.11
+	  header in the frames)
 	* use receipt of EAPOL-Key frame as a lower layer success indication
 	  for EAP state machine to allow recovery from dropped EAP-Success
 	  frame
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/Makefile b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/Makefile
index a176a9e..c888833 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/Makefile
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/Makefile
@@ -30,9 +30,9 @@
 endif
 endif
 
-export LIBDIR ?= /usr/local/lib/
-export INCDIR ?= /usr/local/include/
-export BINDIR ?= /usr/local/sbin/
+export LIBDIR ?= /usr/local/lib
+export INCDIR ?= /usr/local/include
+export BINDIR ?= /usr/local/sbin
 PKG_CONFIG ?= pkg-config
 
 CFLAGS += $(EXTRA_CFLAGS)
@@ -96,6 +96,10 @@
 	install -m 0644 -D libwpa_client.so $(DESTDIR)/$(LIBDIR)/libwpa_client.so
 	install -m 0644 -D ../src/common/wpa_ctrl.h $(DESTDIR)/$(INCDIR)/wpa_ctrl.h
 endif
+	if ls eap_*.so >/dev/null 2>&1; then \
+		install -d $(DESTDIR)$(LIBDIR)/wpa_supplicant && \
+		cp *.so $(DESTDIR)$(LIBDIR)/wpa_supplicant \
+	; fi
 
 ifdef CONFIG_FIPS
 CONFIG_NO_RANDOM_POOL=
@@ -107,6 +111,7 @@
 OBJS += bss.o
 OBJS += eap_register.o
 OBJS += ../src/utils/common.o
+OBJS += ../src/utils/config.o
 OBJS += ../src/utils/wpa_debug.o
 OBJS += ../src/utils/wpabuf.o
 OBJS += ../src/utils/bitfield.o
@@ -114,6 +119,7 @@
 OBJS += ../src/utils/crc32.o
 OBJS += op_classes.o
 OBJS += rrm.o
+OBJS += twt.o
 OBJS += robust_av.o
 OBJS_p = wpa_passphrase.o
 OBJS_p += ../src/utils/common.o
@@ -287,12 +293,12 @@
 CFLAGS += -DWL_SAE
 endif
 
+endif # CONFIG_DRIVER_NL80211_IFX == y
+
 ifdef CONFIG_WPA3_SAE_AUTH_EARLY_SET
 CFLAGS += -DCONFIG_WPA3_SAE_AUTH_EARLY_SET
 endif
 
-endif # CONFIG_DRIVER_NL80211_IFX == y
-
 ifdef CONFIG_SAE
 CFLAGS += -DCONFIG_SAE
 OBJS += ../src/common/sae.o
@@ -334,6 +340,9 @@
 ifdef CONFIG_DPP2
 CFLAGS += -DCONFIG_DPP2
 endif
+ifdef CONFIG_DPP3
+CFLAGS += -DCONFIG_DPP3
+endif
 endif
 
 ifdef CONFIG_OWE
@@ -429,6 +438,10 @@
 ifdef CONFIG_P2P_STRICT
 CFLAGS += -DCONFIG_P2P_STRICT
 endif
+ifdef CONFIG_WIFI_DISPLAY
+CFLAGS += -DCONFIG_WIFI_DISPLAY
+OBJS += wifi_display.o
+endif
 endif
 
 ifdef CONFIG_DRIVER_NL80211_IFX
@@ -437,9 +450,15 @@
 endif
 endif # CONFIG_DRIVER_NL80211_IFX == y
 
-ifdef CONFIG_WIFI_DISPLAY
-CFLAGS += -DCONFIG_WIFI_DISPLAY
-OBJS += wifi_display.o
+ifdef CONFIG_PASN
+CFLAGS += -DCONFIG_PASN
+CFLAGS += -DCONFIG_PTKSA_CACHE
+NEED_HMAC_SHA256_KDF=y
+NEED_HMAC_SHA384_KDF=y
+NEED_SHA256=y
+NEED_SHA384=y
+OBJS += ../src/common/ptksa_cache.o
+OBJS += pasn_supplicant.o
 endif
 
 ifdef CONFIG_HS20
@@ -532,7 +551,7 @@
 # EAP-TLS
 ifeq ($(CONFIG_EAP_TLS), dyn)
 CFLAGS += -DEAP_TLS_DYNAMIC
-EAPDYN += ../src/eap_peer/eap_tls.so
+EAPDYN += eap_tls.so
 else
 CFLAGS += -DEAP_TLS
 OBJS += ../src/eap_peer/eap_tls.o
@@ -553,13 +572,13 @@
 
 ifdef CONFIG_EAP_PEAP
 # EAP-PEAP
+SRC_EAP_PEAP = ../src/eap_peer/eap_peap.c ../src/eap_common/eap_peap_common.c
 ifeq ($(CONFIG_EAP_PEAP), dyn)
 CFLAGS += -DEAP_PEAP_DYNAMIC
-EAPDYN += ../src/eap_peer/eap_peap.so
+EAPDYN += eap_peap.so
 else
 CFLAGS += -DEAP_PEAP
-OBJS += ../src/eap_peer/eap_peap.o
-OBJS += ../src/eap_common/eap_peap_common.o
+OBJS += $(patsubst %.c, %.o, $(SRC_EAP_PEAP))
 endif
 TLS_FUNCS=y
 CONFIG_IEEE8021X_EAPOL=y
@@ -569,7 +588,7 @@
 # EAP-TTLS
 ifeq ($(CONFIG_EAP_TTLS), dyn)
 CFLAGS += -DEAP_TTLS_DYNAMIC
-EAPDYN += ../src/eap_peer/eap_ttls.so
+EAPDYN += eap_ttls.so
 else
 CFLAGS += -DEAP_TTLS
 OBJS += ../src/eap_peer/eap_ttls.o
@@ -586,7 +605,7 @@
 # EAP-MD5
 ifeq ($(CONFIG_EAP_MD5), dyn)
 CFLAGS += -DEAP_MD5_DYNAMIC
-EAPDYN += ../src/eap_peer/eap_md5.so
+EAPDYN += eap_md5.so
 else
 CFLAGS += -DEAP_MD5
 OBJS += ../src/eap_peer/eap_md5.o
@@ -604,14 +623,13 @@
 
 ifdef CONFIG_EAP_MSCHAPV2
 # EAP-MSCHAPv2
+SRC_EAP_MSCHAPV2 = ../src/eap_peer/eap_mschapv2.c ../src/eap_peer/mschapv2.c
 ifeq ($(CONFIG_EAP_MSCHAPV2), dyn)
 CFLAGS += -DEAP_MSCHAPv2_DYNAMIC
-EAPDYN += ../src/eap_peer/eap_mschapv2.so
-EAPDYN += ../src/eap_peer/mschapv2.so
+EAPDYN += eap_mschapv2.so
 else
 CFLAGS += -DEAP_MSCHAPv2
-OBJS += ../src/eap_peer/eap_mschapv2.o
-OBJS += ../src/eap_peer/mschapv2.o
+OBJS += $(patsubst %.c, %.o, $(SRC_EAP_MSCHAPV2))
 endif
 MS_FUNCS=y
 CONFIG_IEEE8021X_EAPOL=y
@@ -621,7 +639,7 @@
 # EAP-GTC
 ifeq ($(CONFIG_EAP_GTC), dyn)
 CFLAGS += -DEAP_GTC_DYNAMIC
-EAPDYN += ../src/eap_peer/eap_gtc.so
+EAPDYN += eap_gtc.so
 else
 CFLAGS += -DEAP_GTC
 OBJS += ../src/eap_peer/eap_gtc.o
@@ -633,7 +651,7 @@
 # EAP-OTP
 ifeq ($(CONFIG_EAP_OTP), dyn)
 CFLAGS += -DEAP_OTP_DYNAMIC
-EAPDYN += ../src/eap_peer/eap_otp.so
+EAPDYN += eap_otp.so
 else
 CFLAGS += -DEAP_OTP
 OBJS += ../src/eap_peer/eap_otp.o
@@ -645,7 +663,7 @@
 # EAP-SIM
 ifeq ($(CONFIG_EAP_SIM), dyn)
 CFLAGS += -DEAP_SIM_DYNAMIC
-EAPDYN += ../src/eap_peer/eap_sim.so
+EAPDYN += eap_sim.so
 else
 CFLAGS += -DEAP_SIM
 OBJS += ../src/eap_peer/eap_sim.o
@@ -659,7 +677,7 @@
 # EAP-LEAP
 ifeq ($(CONFIG_EAP_LEAP), dyn)
 CFLAGS += -DEAP_LEAP_DYNAMIC
-EAPDYN += ../src/eap_peer/eap_leap.so
+EAPDYN += eap_leap.so
 else
 CFLAGS += -DEAP_LEAP
 OBJS += ../src/eap_peer/eap_leap.o
@@ -670,12 +688,13 @@
 
 ifdef CONFIG_EAP_PSK
 # EAP-PSK
+SRC_EAP_PSK = ../src/eap_peer/eap_psk.c ../src/eap_common/eap_psk_common.c
 ifeq ($(CONFIG_EAP_PSK), dyn)
 CFLAGS += -DEAP_PSK_DYNAMIC
-EAPDYN += ../src/eap_peer/eap_psk.so
+EAPDYN += eap_psk.so
 else
 CFLAGS += -DEAP_PSK
-OBJS += ../src/eap_peer/eap_psk.o ../src/eap_common/eap_psk_common.o
+OBJS += $(patsubst %.c, %.o, $(SRC_EAP_PSK))
 endif
 CONFIG_IEEE8021X_EAPOL=y
 NEED_AES=y
@@ -687,7 +706,7 @@
 # EAP-AKA
 ifeq ($(CONFIG_EAP_AKA), dyn)
 CFLAGS += -DEAP_AKA_DYNAMIC
-EAPDYN += ../src/eap_peer/eap_aka.so
+EAPDYN += eap_aka.so
 else
 CFLAGS += -DEAP_AKA
 OBJS += ../src/eap_peer/eap_aka.o
@@ -721,14 +740,14 @@
 
 ifdef CONFIG_EAP_FAST
 # EAP-FAST
+SRC_EAP_FAST = ../src/eap_peer/eap_fast.c ../src/eap_peer/eap_fast_pac.c
+SRC_EAP_FAST += ../src/eap_common/eap_fast_common.c
 ifeq ($(CONFIG_EAP_FAST), dyn)
 CFLAGS += -DEAP_FAST_DYNAMIC
-EAPDYN += ../src/eap_peer/eap_fast.so
-EAPDYN += ../src/eap_common/eap_fast_common.o
+EAPDYN += eap_fast.so
 else
 CFLAGS += -DEAP_FAST
-OBJS += ../src/eap_peer/eap_fast.o ../src/eap_peer/eap_fast_pac.o
-OBJS += ../src/eap_common/eap_fast_common.o
+OBJS += $(patsubst %.c, %.o, $(SRC_EAP_FAST))
 endif
 TLS_FUNCS=y
 CONFIG_IEEE8021X_EAPOL=y
@@ -737,14 +756,14 @@
 
 ifdef CONFIG_EAP_TEAP
 # EAP-TEAP
+SRC_EAP_TEAP = ../src/eap_peer/eap_teap.c ../src/eap_peer/eap_teap_pac.c
+SRC_EAP_TEAP += ../src/eap_common/eap_teap_common.c
 ifeq ($(CONFIG_EAP_TEAP), dyn)
 CFLAGS += -DEAP_TEAP_DYNAMIC
-EAPDYN += ../src/eap_peer/eap_teap.so
-EAPDYN += ../src/eap_common/eap_teap_common.o
+EAPDYN += eap_teap.so
 else
 CFLAGS += -DEAP_TEAP
-OBJS += ../src/eap_peer/eap_teap.o ../src/eap_peer/eap_teap_pac.o
-OBJS += ../src/eap_common/eap_teap_common.o
+OBJS += $(patsubst %.c, %.o, $(SRC_EAP_TEAP))
 endif
 TLS_FUNCS=y
 CONFIG_IEEE8021X_EAPOL=y
@@ -756,36 +775,39 @@
 
 ifdef CONFIG_EAP_PAX
 # EAP-PAX
+SRC_EAP_PAX = ../src/eap_peer/eap_pax.c ../src/eap_common/eap_pax_common.c
 ifeq ($(CONFIG_EAP_PAX), dyn)
 CFLAGS += -DEAP_PAX_DYNAMIC
-EAPDYN += ../src/eap_peer/eap_pax.so
+EAPDYN += eap_pax.so
 else
 CFLAGS += -DEAP_PAX
-OBJS += ../src/eap_peer/eap_pax.o ../src/eap_common/eap_pax_common.o
+OBJS += $(patsubst %.c, %.o, $(SRC_EAP_PAX))
 endif
 CONFIG_IEEE8021X_EAPOL=y
 endif
 
 ifdef CONFIG_EAP_SAKE
 # EAP-SAKE
+SRC_EAP_SAKE = ../src/eap_peer/eap_sake.c ../src/eap_common/eap_sake_common.c
 ifeq ($(CONFIG_EAP_SAKE), dyn)
 CFLAGS += -DEAP_SAKE_DYNAMIC
-EAPDYN += ../src/eap_peer/eap_sake.so
+EAPDYN += eap_sake.so
 else
 CFLAGS += -DEAP_SAKE
-OBJS += ../src/eap_peer/eap_sake.o ../src/eap_common/eap_sake_common.o
+OBJS += $(patsubst %.c, %.o, $(SRC_EAP_SAKE))
 endif
 CONFIG_IEEE8021X_EAPOL=y
 endif
 
 ifdef CONFIG_EAP_GPSK
 # EAP-GPSK
+SRC_EAP_GPSK = ../src/eap_peer/eap_gpsk.c ../src/eap_common/eap_gpsk_common.c
 ifeq ($(CONFIG_EAP_GPSK), dyn)
 CFLAGS += -DEAP_GPSK_DYNAMIC
-EAPDYN += ../src/eap_peer/eap_gpsk.so
+EAPDYN += eap_gpsk.so
 else
 CFLAGS += -DEAP_GPSK
-OBJS += ../src/eap_peer/eap_gpsk.o ../src/eap_common/eap_gpsk_common.o
+OBJS += $(patsubst %.c, %.o, $(SRC_EAP_GPSK))
 endif
 CONFIG_IEEE8021X_EAPOL=y
 ifdef CONFIG_EAP_GPSK_SHA256
@@ -806,12 +828,13 @@
 
 ifdef CONFIG_EAP_EKE
 # EAP-EKE
+SRC_EAP_EKE = ../src/eap_peer/eap_eke.c ../src/eap_common/eap_eke_common.c
 ifeq ($(CONFIG_EAP_EKE), dyn)
 CFLAGS += -DEAP_EKE_DYNAMIC
-EAPDYN += ../src/eap_peer/eap_eke.so
+EAPDYN += eap_eke.so
 else
 CFLAGS += -DEAP_EKE
-OBJS += ../src/eap_peer/eap_eke.o ../src/eap_common/eap_eke_common.o
+OBJS += $(patsubst %.c, %.o, $(SRC_EAP_EKE))
 endif
 CONFIG_IEEE8021X_EAPOL=y
 NEED_DH_GROUPS=y
@@ -918,6 +941,10 @@
 endif
 endif # CONFIG_DRIVER_NL80211_IFX == y
 
+ifdef CONFIG_TWT_OFFLOAD_IFX
+CFLAGS += -DCONFIG_TWT_OFFLOAD_IFX
+endif # CONFIG_TWT_OFFLOAD_IFX == y
+
 ifdef CONFIG_WPS_TESTING
 CFLAGS += -DCONFIG_WPS_TESTING
 endif
@@ -930,14 +957,16 @@
 
 ifdef CONFIG_EAP_IKEV2
 # EAP-IKEv2
+SRC_EAP_IKEV2 = ../src/eap_peer/eap_ikev2.c
+SRC_EAP_IKEV2 += ../src/eap_peer/ikev2.c
+SRC_EAP_IKEV2 += ../src/eap_common/eap_ikev2_common.c
+SRC_EAP_IKEV2 += ../src/eap_common/ikev2_common.c
 ifeq ($(CONFIG_EAP_IKEV2), dyn)
 CFLAGS += -DEAP_IKEV2_DYNAMIC
-EAPDYN += ../src/eap_peer/eap_ikev2.so ../src/eap_peer/ikev2.o
-EAPDYN += ../src/eap_common/eap_ikev2_common.o ../src/eap_common/ikev2_common.o
+EAPDYN += eap_ikev2.so
 else
 CFLAGS += -DEAP_IKEV2
-OBJS += ../src/eap_peer/eap_ikev2.o ../src/eap_peer/ikev2.o
-OBJS += ../src/eap_common/eap_ikev2_common.o ../src/eap_common/ikev2_common.o
+OBJS += $(patsubst %.c, %.o, $(SRC_EAP_IKEV2))
 endif
 CONFIG_IEEE8021X_EAPOL=y
 NEED_DH_GROUPS=y
@@ -949,7 +978,7 @@
 ifdef CONFIG_EAP_VENDOR_TEST
 ifeq ($(CONFIG_EAP_VENDOR_TEST), dyn)
 CFLAGS += -DEAP_VENDOR_TEST_DYNAMIC
-EAPDYN += ../src/eap_peer/eap_vendor_test.so
+EAPDYN += eap_vendor_test.so
 else
 CFLAGS += -DEAP_VENDOR_TEST
 OBJS += ../src/eap_peer/eap_vendor_test.o
@@ -1115,7 +1144,6 @@
 # PC/SC interface for smartcards (USIM, GSM SIM)
 CFLAGS += -DPCSC_FUNCS -I/usr/include/PCSC
 OBJS += ../src/utils/pcsc_funcs.o
-# -lpthread may not be needed depending on how pcsc-lite was configured
 ifdef CONFIG_NATIVE_WINDOWS
 #Once MinGW gets support for WinScard, -lwinscard could be used instead of the
 #dynamic symbol loading that is now used in pcsc_funcs.c
@@ -1124,7 +1152,7 @@
 ifdef CONFIG_OSX
 LIBS += -framework PCSC
 else
-LIBS += -lpcsclite -lpthread
+LIBS += $(shell $(PKG_CONFIG) --libs libpcsclite)
 endif
 endif
 endif
@@ -1866,6 +1894,12 @@
 NEED_EXT_PASSWORD=y
 endif
 
+ifdef CONFIG_EXT_PASSWORD_FILE
+OBJS += ../src/utils/ext_password_file.o
+CFLAGS += -DCONFIG_EXT_PASSWORD_FILE
+NEED_EXT_PASSWORD=y
+endif
+
 ifdef NEED_EXT_PASSWORD
 OBJS += ../src/utils/ext_password.o
 CFLAGS += -DCONFIG_EXT_PASSWORD
@@ -1908,7 +1942,7 @@
 OBJS += ../src/drivers/driver_common.o
 OBJS_priv += ../src/drivers/driver_common.o
 
-OBJS += wpa_supplicant.o events.o blacklist.o wpas_glue.o scan.o
+OBJS += wpa_supplicant.o events.o bssid_ignore.o wpas_glue.o scan.o
 OBJS_t := $(OBJS) $(OBJS_l2) eapol_test.o
 OBJS_t += ../src/radius/radius_client.o
 OBJS_t += ../src/radius/radius.o
@@ -2056,33 +2090,60 @@
 	$(Q)$(LDO) $(LDFLAGS) -o $@ win_if_list.c $(CFLAGS) $(LIBS_w)
 	@$(E) "  LD " $@
 
-eap_psk.so: ../src/eap_peer/eap_psk.c ../src/eap_common/eap_psk_common.c
-	$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
+eap_psk.so: $(SRC_EAP_PSK)
+	$(Q)$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
 		-Deap_peer_psk_register=eap_peer_method_dynamic_init
+	@$(E) "  CC/LD " $@
 
-eap_pax.so: ../src/eap_peer/eap_pax.c ../src/eap_common/eap_pax_common.c
-	$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
-		-Deap_peer_pax_register=eap_peer_method_dynamic_init
+eap_pax.so: $(SRC_EAP_PAX)
+	$(Q)$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
+		-D$(@F:eap_%.so=eap_peer_%)_register=eap_peer_method_dynamic_init
+	@$(E) "  CC/LD " $@
 
-eap_sake.so: ../src/eap_peer/eap_sake.c ../src/eap_common/eap_sake_common.c
-	$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
-		-Deap_peer_sake_register=eap_peer_method_dynamic_init
+eap_peap.so: $(SRC_EAP_PEAP)
+	$(Q)$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
+		-D$(@F:eap_%.so=eap_peer_%)_register=eap_peer_method_dynamic_init
+	@$(E) "  CC/LD " $@
 
-eap_wsc.so: ../src/eap_peer/eap_wsc.c ../src/eap_common/eap_wsc_common.c ../src/wps/wps.c
-	$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
-		-Deap_peer_wsc_register=eap_peer_method_dynamic_init
+eap_sake.so: $(SRC_EAP_SAKE)
+	$(Q)$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
+		-D$(@F:eap_%.so=eap_peer_%)_register=eap_peer_method_dynamic_init
+	@$(E) "  CC/LD " $@
 
-eap_ikev2.so: ../src/eap_peer/eap_ikev2.c ../src/eap_peer/ikev2.c ../src/eap_common/eap_ikev2_common.o ../src/eap_common/ikev2_common.c
-	$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
-		-Deap_peer_ikev2_register=eap_peer_method_dynamic_init
+eap_ikev2.so: $(SRC_EAP_IKEV2)
+	$(Q)$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
+		-D$(@F:eap_%.so=eap_peer_%)_register=eap_peer_method_dynamic_init
+	@$(E) "  CC/LD " $@
 
-eap_eke.so: ../src/eap_peer/eap_eke.c ../src/eap_common/eap_eke_common.c
-	$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
-		-Deap_peer_eke_register=eap_peer_method_dynamic_init
+eap_eke.so: $(SRC_EAP_EKE)
+	$(Q)$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
+		-D$(@F:eap_%.so=eap_peer_%)_register=eap_peer_method_dynamic_init
+	@$(E) "  CC/LD " $@
 
-%.so: %.c
-	$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $< \
+eap_mschapv2.so: $(SRC_EAP_MSCHAPV2)
+	$(Q)$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
+		-D$(@F:eap_%.so=eap_peer_%)_register=eap_peer_method_dynamic_init
+	@$(E) "  CC/LD " $@
+
+eap_fast.so: $(SRC_EAP_FAST)
+	$(Q)$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
+		-D$(@F:eap_%.so=eap_peer_%)_register=eap_peer_method_dynamic_init
+	@$(E) "  CC/LD " $@
+
+eap_teap.so: $(SRC_EAP_TEAP)
+	$(Q)$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
+		-D$(@F:eap_%.so=eap_peer_%)_register=eap_peer_method_dynamic_init
+	@$(E) "  CC/LD " $@
+
+eap_gpsk.so: $(SRC_EAP_GPSK)
+	$(Q)$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
+		-D$(@F:eap_%.so=eap_peer_%)_register=eap_peer_method_dynamic_init
+	@$(E) "  CC/LD " $@
+
+%.so: ../src/eap_peer/%.c
+	$(Q)$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $< \
 		-D$(*F:eap_%=eap_peer_%)_register=eap_peer_method_dynamic_init
+	@$(E) "  CC/LD " $@
 
 %.service: %.service.in
 	$(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/README b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/README
index 391912e..c643b26 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/README
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/README
@@ -1,7 +1,7 @@
 wpa_supplicant
 ==============
 
-Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi> and contributors
+Copyright (c) 2003-2022, Jouni Malinen <j@w1.fi> and contributors
 All Rights Reserved.
 
 This program is licensed under the BSD license (the one with
@@ -1077,3 +1077,87 @@
 OK
 <3>EXT-RADIO-WORK-START 7
 <3>EXT-RADIO-WORK-TIMEOUT 7
+
+
+DSCP policy procedures
+----------------------
+
+DSCP policy procedures defined in WFA QoS Management-R2 program
+facilitates AP devices to configure DSCP settings for specific uplink
+data streams.
+
+An AP may transmit a DSCP Policy Request frame containing zero or more
+QoS Management IEs to an associated STA which supports DSCP policy
+procedures. Each QoS Management element in a DSCP Policy Request frame
+represents one DSCP policy, and shall include one DSCP Policy attribute
+including a DSCP Policy ID, Request type, and a DSCP value.
+
+wpa_supplicant sends control interface event messages consisting details
+of DSCP policies requested by the AP through a DSCP Policy Request frame
+to external programs. The format of the control interface event messages
+is as shown below:
+
+- Control interface event message format to indicate DSCP request start
+
+  <3>CTRL-EVENT-DSCP-POLICY request_start [clear_all] [more]
+
+  clear_all - AP requested to clear all DSCP policies configured earlier
+  more      - AP may request to configure more DSCP policies with new DSCP
+              request
+
+- Control interface event message format to add new policy
+
+  <3>CTRL-EVENT-DSCP-POLICY add <policy_id> <dscp_value> <ip_version=0|4|6>
+  [protocol] [source ip] [destination_ip]/[domain name] [source port]
+  [[<start_port> <end_port>]/destination port]
+
+  ip_version = 0: Both IPv4 and IPv6
+             = 4: IPv4
+             = 6: IPv6
+  protocol: Internet Protocol Numbers as per IETF RFCs
+	 = 6: TCP
+	 = 17: UDP
+	 = 50: ESP
+
+- Control interface event message format to remove a particular policy,
+  identified by the policy_id attribute.
+
+  <3>CTRL-EVENT-DSCP-POLICY remove <policy_id>
+
+- DSCP policy may get rejected due to invalid policy parameters. Ccontrol
+  interface event message format for rejected policy.
+
+  <3>CTRL-EVENT-DSCP-POLICY reject <policy_id>
+
+- Control interface event message format to indicate end of DSCP request.
+
+  <3>CTRL-EVENT-DSCP-POLICY request_end
+
+- External applications shall clear active DSCP policies upon receiving
+  "CTRL-EVENT-DISCONNECTED" or "CTRL-EVENT-DSCP-POLICY clear_all" events.
+
+- Control interface event message format to indicate wpa_supplicant started
+  a timer to wait until the unsolicited DSCP request from the AP.
+
+  <3>CTRL-EVENT-DSCP-POLICY request_wait start
+
+- Control interface event message format to indicate timeout to receive the
+  unsolicited DSCP request. This event is expected only when an unsolicited
+  DSCP request is not received from the AP before timeout.
+
+  <3>CTRL-EVENT-DSCP-POLICY request_wait end
+
+DSCP Response:
+A QoS Management STA that enables DSCP Policy capability shall respond
+with DSCP response on receipt of a successful DSCP request from its
+associated AP.  wpa_supplicant sends DSCP policy response based on the
+control interface command received from the user is as below:
+
+DSCP_RESP <[reset]>/<[solicited] [policy_id=1 status=0...]> [more]
+
+DSCP Query:
+DSCP Policy Query enables a STA to query its associated AP for DSCP
+policies applicable to the STA. Currently, this includes support to send
+a wildcard DSCP query or a DSCP query with a single domain name
+attribute. The command format for the DSCP query command is as follows:
+DSCP_QUERY <wildcard>/<domain_name=<string>>
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/README-HS20 b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/README-HS20
index 484e4cb..b076621 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/README-HS20
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/README-HS20
@@ -286,6 +286,12 @@
 #
 # sim_num: Identifier for which SIM to use in multi-SIM devices
 #
+# engine: Whether to use an engine for private key operations (0/1)
+# engine_id: String identifying the engine to use
+# ca_cert_id: The CA certificate identifier when using an engine
+# cert_id: The certificate identifier when using an engine
+# key_id: The private key identifier when using an engine
+#
 # for example:
 #
 #cred={
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/.clang-format b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/.clang-format
new file mode 100755
index 0000000..42fadb5
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/.clang-format
@@ -0,0 +1,9 @@
+BasedOnStyle: Google
+IndentWidth: 8
+UseTab: Always
+BreakBeforeBraces: Mozilla
+AllowShortIfStatementsOnASingleLine: false
+IndentCaseLabels: false
+AccessModifierOffset: -8
+AlignAfterOpenBracket: AlwaysBreak
+SortIncludes: false
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/aidl.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/aidl.cpp
new file mode 100755
index 0000000..8a5b9c3
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/aidl.cpp
@@ -0,0 +1,1035 @@
+/*
+ * WPA Supplicant - Aidl entry point to wpa_supplicant core
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include <android/binder_process.h>
+#include <android/binder_manager.h>
+
+#include "aidl_manager.h"
+
+extern "C"
+{
+#include "aidl.h"
+#include "aidl_i.h"
+#include "utils/common.h"
+#include "utils/eloop.h"
+#include "utils/includes.h"
+#include "dpp.h"
+}
+
+using aidl::android::hardware::wifi::supplicant::AidlManager;
+using aidl::android::hardware::wifi::supplicant::AuxiliarySupplicantEventCode;
+using aidl::android::hardware::wifi::supplicant::DppEventType;
+using aidl::android::hardware::wifi::supplicant::DppFailureCode;
+using aidl::android::hardware::wifi::supplicant::DppProgressCode;
+
+static void wpas_aidl_notify_dpp_failure(struct wpa_supplicant *wpa_s, DppFailureCode code);
+static void wpas_aidl_notify_dpp_progress(struct wpa_supplicant *wpa_s, DppProgressCode code);
+static void wpas_aidl_notify_dpp_success(struct wpa_supplicant *wpa_s, DppEventType code);
+
+void wpas_aidl_sock_handler(
+	int /* sock */, void * /* eloop_ctx */, void * /* sock_ctx */)
+{
+	ABinderProcess_handlePolledCommands();
+}
+
+struct wpas_aidl_priv *wpas_aidl_init(struct wpa_global *global)
+{
+	struct wpas_aidl_priv *priv;
+	AidlManager *aidl_manager;
+
+	priv = (wpas_aidl_priv *)os_zalloc(sizeof(*priv));
+	if (!priv)
+		return NULL;
+	priv->global = global;
+
+	wpa_printf(MSG_DEBUG, "Initing aidl control");
+
+	ABinderProcess_setupPolling(&priv->aidl_fd);
+	if (priv->aidl_fd < 0)
+		goto err;
+
+	wpa_printf(MSG_INFO, "Processing aidl events on FD %d", priv->aidl_fd);
+	// Look for read events from the aidl socket in the eloop.
+	if (eloop_register_read_sock(
+		priv->aidl_fd, wpas_aidl_sock_handler, global, priv) < 0)
+		goto err;
+
+	aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		goto err;
+	if (aidl_manager->registerAidlService(global)) {
+		goto err;
+	}
+	// We may not need to store this aidl manager reference in the
+	// global data strucure because we've made it a singleton class.
+	priv->aidl_manager = (void *)aidl_manager;
+
+	return priv;
+err:
+	wpas_aidl_deinit(priv);
+	return NULL;
+}
+
+void wpas_aidl_deinit(struct wpas_aidl_priv *priv)
+{
+	if (!priv)
+		return;
+
+	wpa_printf(MSG_DEBUG, "Deiniting aidl control");
+
+	AidlManager::destroyInstance();
+	eloop_unregister_read_sock(priv->aidl_fd);
+	os_free(priv);
+}
+
+int wpas_aidl_register_interface(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s || !wpa_s->global->aidl)
+		return 1;
+
+	wpa_printf(
+		MSG_DEBUG, "Registering interface to aidl control: %s",
+		wpa_s->ifname);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return 1;
+
+	return aidl_manager->registerInterface(wpa_s);
+}
+
+int wpas_aidl_unregister_interface(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s || !wpa_s->global->aidl)
+		return 1;
+
+	wpa_printf(
+		MSG_DEBUG, "Deregistering interface from aidl control: %s",
+		wpa_s->ifname);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return 1;
+
+	return aidl_manager->unregisterInterface(wpa_s);
+}
+
+int wpas_aidl_register_network(
+	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
+{
+	if (!wpa_s || !wpa_s->global->aidl || !ssid)
+		return 1;
+
+	wpa_printf(
+		MSG_DEBUG, "Registering network to aidl control: %d", ssid->id);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return 1;
+
+	return aidl_manager->registerNetwork(wpa_s, ssid);
+}
+
+int wpas_aidl_unregister_network(
+	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
+{
+	if (!wpa_s || !wpa_s->global->aidl || !ssid)
+		return 1;
+
+	wpa_printf(
+		MSG_DEBUG, "Deregistering network from aidl control: %d", ssid->id);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return 1;
+
+	return aidl_manager->unregisterNetwork(wpa_s, ssid);
+}
+
+int wpas_aidl_notify_state_changed(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s || !wpa_s->global->aidl)
+		return 1;
+
+	wpa_printf(
+		MSG_DEBUG, "Notifying state change event to aidl control: %d",
+		wpa_s->wpa_state);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return 1;
+
+	return aidl_manager->notifyStateChange(wpa_s);
+}
+
+int wpas_aidl_notify_network_request(
+	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
+	enum wpa_ctrl_req_type rtype, const char *default_txt)
+{
+	if (!wpa_s || !wpa_s->global->aidl || !ssid)
+		return 1;
+
+	wpa_printf(
+		MSG_DEBUG, "Notifying network request to aidl control: %d",
+		ssid->id);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return 1;
+
+	return aidl_manager->notifyNetworkRequest(
+		wpa_s, ssid, rtype, default_txt);
+}
+
+void wpas_aidl_notify_anqp_query_done(
+	struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
+	const struct wpa_bss_anqp *anqp)
+{
+	if (!wpa_s || !wpa_s->global->aidl || !bssid || !result || !anqp)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying ANQP query done to aidl control: " MACSTR "result: %s",
+		MAC2STR(bssid), result);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyAnqpQueryDone(wpa_s, bssid, result, anqp);
+}
+
+void wpas_aidl_notify_hs20_icon_query_done(
+	struct wpa_supplicant *wpa_s, const u8 *bssid, const char *file_name,
+	const u8 *image, u32 image_length)
+{
+	if (!wpa_s || !wpa_s->global->aidl || !bssid || !file_name || !image)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying HS20 icon query done to aidl control: " MACSTR
+		"file_name: %s",
+		MAC2STR(bssid), file_name);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyHs20IconQueryDone(
+		wpa_s, bssid, file_name, image, image_length);
+}
+
+void wpas_aidl_notify_hs20_rx_subscription_remediation(
+	struct wpa_supplicant *wpa_s, const char *url, u8 osu_method)
+{
+	if (!wpa_s || !wpa_s->global->aidl || !url)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying HS20 subscription remediation rx to aidl control: %s",
+		url);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyHs20RxSubscriptionRemediation(
+		wpa_s, url, osu_method);
+}
+
+void wpas_aidl_notify_hs20_rx_deauth_imminent_notice(
+	struct wpa_supplicant *wpa_s, u8 code, u16 reauth_delay, const char *url)
+{
+	if (!wpa_s || !wpa_s->global->aidl)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying HS20 deauth imminent notice rx to aidl control: %s",
+		url ? url : "<no URL>");
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyHs20RxDeauthImminentNotice(
+		wpa_s, code, reauth_delay, url);
+}
+
+void wpas_aidl_notify_hs20_rx_terms_and_conditions_acceptance(
+		struct wpa_supplicant *wpa_s, const char *url)
+{
+	if (!wpa_s || !wpa_s->global->aidl || !url)
+		return;
+
+	wpa_printf(MSG_DEBUG,
+			"Notifying HS20 terms and conditions acceptance rx to aidl control: %s",
+			url);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyHs20RxTermsAndConditionsAcceptance(wpa_s, url);
+}
+
+void wpas_aidl_notify_disconnect_reason(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG, "Notifying disconnect reason to aidl control: %d",
+		wpa_s->disconnect_reason);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyDisconnectReason(wpa_s);
+}
+
+void wpas_aidl_notify_assoc_reject(struct wpa_supplicant *wpa_s,
+	const u8 *bssid, u8 timed_out, const u8 *assoc_resp_ie, size_t assoc_resp_ie_len)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG, "Notifying assoc reject to aidl control: %d",
+		wpa_s->assoc_status_code);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyAssocReject(wpa_s, bssid, timed_out, assoc_resp_ie, assoc_resp_ie_len);
+}
+
+void wpas_aidl_notify_auth_timeout(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(MSG_DEBUG, "Notifying auth timeout to aidl control");
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyAuthTimeout(wpa_s);
+}
+
+void wpas_aidl_notify_bssid_changed(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(MSG_DEBUG, "Notifying bssid changed to aidl control");
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyBssidChanged(wpa_s);
+}
+
+void wpas_aidl_notify_wps_event_fail(
+	struct wpa_supplicant *wpa_s, uint8_t *peer_macaddr, uint16_t config_error,
+	uint16_t error_indication)
+{
+	if (!wpa_s || !peer_macaddr)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG, "Notifying Wps event fail to aidl control: %d, %d",
+		config_error, error_indication);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyWpsEventFail(
+		wpa_s, peer_macaddr, config_error, error_indication);
+}
+
+void wpas_aidl_notify_wps_event_success(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(MSG_DEBUG, "Notifying Wps event success to aidl control");
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyWpsEventSuccess(wpa_s);
+}
+
+void wpas_aidl_notify_wps_event_pbc_overlap(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG, "Notifying Wps event PBC overlap to aidl control");
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyWpsEventPbcOverlap(wpa_s);
+}
+
+void wpas_aidl_notify_p2p_device_found(
+	struct wpa_supplicant *wpa_s, const u8 *addr,
+	const struct p2p_peer_info *info, const u8 *peer_wfd_device_info,
+	u8 peer_wfd_device_info_len, const u8 *peer_wfd_r2_device_info,
+	u8 peer_wfd_r2_device_info_len)
+{
+	if (!wpa_s || !addr || !info)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG, "Notifying P2P device found to aidl control " MACSTR,
+		MAC2STR(info->p2p_device_addr));
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyP2pDeviceFound(
+		wpa_s, addr, info, peer_wfd_device_info,
+		peer_wfd_device_info_len, peer_wfd_r2_device_info,
+		peer_wfd_r2_device_info_len);
+}
+
+void wpas_aidl_notify_p2p_device_lost(
+	struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr)
+{
+	if (!wpa_s || !p2p_device_addr)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG, "Notifying P2P device lost to aidl control " MACSTR,
+		MAC2STR(p2p_device_addr));
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyP2pDeviceLost(wpa_s, p2p_device_addr);
+}
+
+void wpas_aidl_notify_p2p_find_stopped(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(MSG_DEBUG, "Notifying P2P find stop to aidl control");
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyP2pFindStopped(wpa_s);
+}
+
+void wpas_aidl_notify_p2p_go_neg_req(
+	struct wpa_supplicant *wpa_s, const u8 *src_addr, u16 dev_passwd_id,
+	u8 go_intent)
+{
+	if (!wpa_s || !src_addr)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying P2P GO negotiation request to aidl control " MACSTR,
+		MAC2STR(src_addr));
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyP2pGoNegReq(
+		wpa_s, src_addr, dev_passwd_id, go_intent);
+}
+
+void wpas_aidl_notify_p2p_go_neg_completed(
+	struct wpa_supplicant *wpa_s, const struct p2p_go_neg_results *res)
+{
+	if (!wpa_s || !res)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying P2P GO negotiation completed to aidl control: %d",
+		res->status);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyP2pGoNegCompleted(wpa_s, res);
+}
+
+void wpas_aidl_notify_p2p_group_formation_failure(
+	struct wpa_supplicant *wpa_s, const char *reason)
+{
+	if (!wpa_s || !reason)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying P2P Group formation failure to aidl control: %s",
+		reason);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyP2pGroupFormationFailure(wpa_s, reason);
+}
+
+void wpas_aidl_notify_p2p_group_started(
+	struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid, int persistent,
+	int client)
+{
+	if (!wpa_s || !ssid)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG, "Notifying P2P Group start to aidl control: %d",
+		ssid->id);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyP2pGroupStarted(wpa_s, ssid, persistent, client);
+}
+
+void wpas_aidl_notify_p2p_group_removed(
+	struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid, const char *role)
+{
+	if (!wpa_s || !ssid || !role)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG, "Notifying P2P Group removed to aidl control: %d",
+		ssid->id);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyP2pGroupRemoved(wpa_s, ssid, role);
+}
+
+void wpas_aidl_notify_p2p_invitation_received(
+	struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *go_dev_addr,
+	const u8 *bssid, int id, int op_freq)
+{
+	if (!wpa_s || !sa || !go_dev_addr || !bssid)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying P2P invitation received to aidl control: %d " MACSTR, id,
+		MAC2STR(bssid));
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyP2pInvitationReceived(
+		wpa_s, sa, go_dev_addr, bssid, id, op_freq);
+}
+
+void wpas_aidl_notify_p2p_invitation_result(
+	struct wpa_supplicant *wpa_s, int status, const u8 *bssid)
+{
+	if (!wpa_s)
+		return;
+	if (bssid) {
+		wpa_printf(
+			MSG_DEBUG,
+			"Notifying P2P invitation result to aidl control: " MACSTR,
+			MAC2STR(bssid));
+	} else {
+		wpa_printf(
+			MSG_DEBUG,
+			"Notifying P2P invitation result to aidl control: NULL "
+			"bssid");
+	}
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyP2pInvitationResult(wpa_s, status, bssid);
+}
+
+void wpas_aidl_notify_p2p_provision_discovery(
+	struct wpa_supplicant *wpa_s, const u8 *dev_addr, int request,
+	enum p2p_prov_disc_status status, u16 config_methods,
+	unsigned int generated_pin)
+{
+	if (!wpa_s || !dev_addr)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying P2P provision discovery to aidl control " MACSTR,
+		MAC2STR(dev_addr));
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyP2pProvisionDiscovery(
+		wpa_s, dev_addr, request, status, config_methods, generated_pin);
+}
+
+void wpas_aidl_notify_p2p_sd_response(
+	struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic,
+	const u8 *tlvs, size_t tlvs_len)
+{
+	if (!wpa_s || !sa || !tlvs)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying P2P service discovery response to aidl control " MACSTR,
+		MAC2STR(sa));
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyP2pSdResponse(
+		wpa_s, sa, update_indic, tlvs, tlvs_len);
+}
+
+void wpas_aidl_notify_ap_sta_authorized(
+	struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr)
+{
+	if (!wpa_s || !sta)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying P2P AP STA authorized to aidl control " MACSTR,
+		MAC2STR(sta));
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyApStaAuthorized(wpa_s, sta, p2p_dev_addr);
+}
+
+void wpas_aidl_notify_ap_sta_deauthorized(
+	struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr)
+{
+	if (!wpa_s || !sta)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying P2P AP STA deauthorized to aidl control " MACSTR,
+		MAC2STR(sta));
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyApStaDeauthorized(wpa_s, sta, p2p_dev_addr);
+}
+
+void wpas_aidl_notify_eap_error(struct wpa_supplicant *wpa_s, int error_code)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(MSG_DEBUG, "Notifying EAP Error: %d ", error_code);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyEapError(wpa_s, error_code);
+}
+
+void wpas_aidl_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
+		struct wpa_ssid *ssid)
+{
+	if (!wpa_s || !ssid)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying DPP configuration received for SSID %d", ssid->id);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyDppConfigReceived(wpa_s, ssid);
+}
+
+void wpas_aidl_notify_dpp_config_sent(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_success(wpa_s, DppEventType::CONFIGURATION_SENT);
+}
+
+/* DPP Progress notifications */
+void wpas_aidl_notify_dpp_auth_success(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_progress(wpa_s, DppProgressCode::AUTHENTICATION_SUCCESS);
+}
+
+void wpas_aidl_notify_dpp_resp_pending(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_progress(wpa_s, DppProgressCode::RESPONSE_PENDING);
+}
+
+/* DPP Failure notifications */
+void wpas_aidl_notify_dpp_not_compatible(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_failure(wpa_s, DppFailureCode::NOT_COMPATIBLE);
+}
+
+void wpas_aidl_notify_dpp_missing_auth(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_failure(wpa_s, DppFailureCode::AUTHENTICATION);
+}
+
+void wpas_aidl_notify_dpp_configuration_failure(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_failure(wpa_s, DppFailureCode::CONFIGURATION);
+}
+
+void wpas_aidl_notify_dpp_timeout(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_failure(wpa_s, DppFailureCode::TIMEOUT);
+}
+
+void wpas_aidl_notify_dpp_auth_failure(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_failure(wpa_s, DppFailureCode::AUTHENTICATION);
+}
+
+void wpas_aidl_notify_dpp_fail(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_failure(wpa_s, DppFailureCode::FAILURE);
+}
+
+void wpas_aidl_notify_dpp_config_sent_wait_response(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_progress(wpa_s, DppProgressCode::CONFIGURATION_SENT_WAITING_RESPONSE);
+}
+
+/* DPP notification helper functions */
+static void wpas_aidl_notify_dpp_failure(struct wpa_supplicant *wpa_s, DppFailureCode code)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying DPP failure event %d", code);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyDppFailure(wpa_s, code);
+}
+
+static void wpas_aidl_notify_dpp_progress(struct wpa_supplicant *wpa_s, DppProgressCode code)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying DPP progress event %d", code);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyDppProgress(wpa_s, code);
+}
+
+void wpas_aidl_notify_dpp_config_accepted(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_progress(wpa_s, DppProgressCode::CONFIGURATION_ACCEPTED);
+}
+
+static void wpas_aidl_notify_dpp_config_applied(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_success(wpa_s, DppEventType::CONFIGURATION_APPLIED);
+}
+
+static void wpas_aidl_notify_dpp_success(struct wpa_supplicant *wpa_s, DppEventType code)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying DPP progress event %d", code);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyDppSuccess(wpa_s, code);
+}
+
+void wpas_aidl_notify_dpp_config_rejected(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_failure(wpa_s, DppFailureCode::CONFIGURATION_REJECTED);
+}
+
+static void wpas_aidl_notify_dpp_no_ap_failure(struct wpa_supplicant *wpa_s,
+		const char *ssid, const char *channel_list, unsigned short band_list[],
+		int size)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(MSG_DEBUG,
+			"Notifying DPP NO AP event for SSID %s\nTried channels: %s",
+			ssid ? ssid : "N/A", channel_list ? channel_list : "N/A");
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyDppFailure(wpa_s, DppFailureCode::CANNOT_FIND_NETWORK,
+			ssid, channel_list, band_list, size);
+}
+
+void wpas_aidl_notify_dpp_enrollee_auth_failure(struct wpa_supplicant *wpa_s,
+		const char *ssid, unsigned short band_list[], int size)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(MSG_DEBUG,
+			"Notifying DPP Enrollee authentication failure, SSID %s",
+			ssid ? ssid : "N/A");
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyDppFailure(wpa_s, DppFailureCode::ENROLLEE_AUTHENTICATION,
+			ssid, NULL, band_list, size);
+}
+
+#ifdef CONFIG_DPP
+void wpas_aidl_notify_dpp_conn_status(struct wpa_supplicant *wpa_s, enum dpp_status_error status,
+		const char *ssid, const char *channel_list, unsigned short band_list[], int size)
+{
+	switch (status)
+	{
+	case DPP_STATUS_OK:
+		wpas_aidl_notify_dpp_config_applied(wpa_s);
+		break;
+
+	case DPP_STATUS_NO_AP:
+		wpas_aidl_notify_dpp_no_ap_failure(wpa_s, ssid, channel_list, band_list, size);
+		break;
+
+	case DPP_STATUS_AUTH_FAILURE:
+		wpas_aidl_notify_dpp_enrollee_auth_failure(wpa_s, ssid, band_list, size);
+		break;
+
+	default:
+		break;
+	}
+}
+#endif
+
+void wpas_aidl_notify_pmk_cache_added(
+	struct wpa_supplicant *wpa_s,
+	struct rsn_pmksa_cache_entry *pmksa_entry)
+{
+	if (!wpa_s || !pmksa_entry)
+		return;
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying PMK cache added event");
+
+	aidl_manager->notifyPmkCacheAdded(wpa_s, pmksa_entry);
+}
+
+void wpas_aidl_notify_bss_tm_status(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	wpa_printf(MSG_DEBUG, "Notifying BSS transition status");
+
+	aidl_manager->notifyBssTmStatus(wpa_s);
+}
+
+void wpas_aidl_notify_transition_disable(struct wpa_supplicant *wpa_s,
+						struct wpa_ssid *ssid,
+						u8 bitmap)
+{
+	if (!wpa_s || !ssid)
+		return;
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyTransitionDisable(wpa_s, ssid, bitmap);
+}
+
+void wpas_aidl_notify_network_not_found(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	wpa_printf(MSG_DEBUG, "Notify network not found");
+
+	aidl_manager->notifyNetworkNotFound(wpa_s);
+}
+
+void wpas_aidl_notify_frequency_changed(struct wpa_supplicant *wpa_s, int frequency)
+{
+	if (!wpa_s)
+		return;
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	wpa_printf(MSG_INFO, "Notify %s frequency changed to %d",
+	    wpa_s->ifname, frequency);
+
+	aidl_manager->notifyFrequencyChanged(wpa_s, frequency);
+}
+
+void wpas_aidl_notify_ceritification(struct wpa_supplicant *wpa_s,
+		int depth, const char *subject,
+		const char *altsubject[],
+		int num_altsubject,
+		const char *cert_hash,
+		const struct wpabuf *cert)
+{
+	if (!wpa_s)
+		return;
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	wpa_printf(MSG_DEBUG, "Notify certification");
+
+	aidl_manager->notifyCertification(wpa_s,
+			depth,
+			subject,
+			altsubject,
+			num_altsubject,
+			cert_hash,
+			cert);
+}
+
+void wpas_aidl_notify_auxiliary_event(struct wpa_supplicant *wpa_s,
+	AuxiliarySupplicantEventCode event_code, const char *reason_string)
+{
+	if (!wpa_s)
+		return;
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	wpa_printf(MSG_DEBUG, "Notify auxiliary event, code=%d",
+		static_cast<int>(event_code));
+	aidl_manager->notifyAuxiliaryEvent(wpa_s, event_code, reason_string);
+}
+
+void wpas_aidl_notify_eap_method_selected(struct wpa_supplicant *wpa_s,
+	const char *reason_string)
+{
+	wpas_aidl_notify_auxiliary_event(wpa_s,
+		AuxiliarySupplicantEventCode::EAP_METHOD_SELECTED,
+		reason_string);
+}
+
+void wpas_aidl_notify_ssid_temp_disabled(struct wpa_supplicant *wpa_s,
+	const char *reason_string)
+{
+	wpas_aidl_notify_auxiliary_event(wpa_s,
+		AuxiliarySupplicantEventCode::SSID_TEMP_DISABLED,
+		reason_string);
+}
+
+void wpas_aidl_notify_open_ssl_failure(struct wpa_supplicant *wpa_s,
+	const char *reason_string)
+{
+	wpas_aidl_notify_auxiliary_event(wpa_s,
+		AuxiliarySupplicantEventCode::OPEN_SSL_FAILURE,
+		reason_string);
+}
+
+void wpas_aidl_notify_qos_policy_reset(
+	struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+	wpa_printf(
+		MSG_DEBUG, "Notifying Qos Policy Reset");
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyQosPolicyReset(wpa_s);
+}
+
+void wpas_aidl_notify_qos_policy_request(struct wpa_supplicant *wpa_s,
+	struct dscp_policy_data *policies, int num_policies)
+{
+	if (!wpa_s || !policies)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG, "Notifying Qos Policy Request");
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyQosPolicyRequest(wpa_s, policies, num_policies);
+}
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/aidl.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/aidl.h
new file mode 100755
index 0000000..a197e6e
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/aidl.h
@@ -0,0 +1,327 @@
+/*
+ * WPA Supplicant - Aidl entry point to wpa_supplicant core
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef WPA_SUPPLICANT_AIDL_AIDL_H
+#define WPA_SUPPLICANT_AIDL_AIDL_H
+
+#ifdef _cplusplus
+extern "C"
+{
+#endif  // _cplusplus
+
+	/**
+	 * This is the aidl RPC interface entry point to the wpa_supplicant
+	 * core. This initializes the aidl driver & AidlManager instance and
+	 * then forwards all the notifcations from the supplicant core to the
+	 * AidlManager.
+	 */
+	struct wpas_aidl_priv;
+	struct wpa_global;
+
+	struct wpas_aidl_priv *wpas_aidl_init(struct wpa_global *global);
+	void wpas_aidl_deinit(struct wpas_aidl_priv *priv);
+
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	int wpas_aidl_register_interface(struct wpa_supplicant *wpa_s);
+	int wpas_aidl_unregister_interface(struct wpa_supplicant *wpa_s);
+	int wpas_aidl_register_network(
+		struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
+	int wpas_aidl_unregister_network(
+		struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
+	int wpas_aidl_notify_state_changed(struct wpa_supplicant *wpa_s);
+	int wpas_aidl_notify_network_request(
+		struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
+		enum wpa_ctrl_req_type rtype, const char *default_txt);
+	void wpas_aidl_notify_anqp_query_done(
+		struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
+		const struct wpa_bss_anqp *anqp);
+	void wpas_aidl_notify_hs20_icon_query_done(
+		struct wpa_supplicant *wpa_s, const u8 *bssid,
+		const char *file_name, const u8 *image, u32 image_length);
+	void wpas_aidl_notify_hs20_rx_subscription_remediation(
+		struct wpa_supplicant *wpa_s, const char *url, u8 osu_method);
+	void wpas_aidl_notify_hs20_rx_deauth_imminent_notice(
+		struct wpa_supplicant *wpa_s, u8 code, u16 reauth_delay,
+		const char *url);
+	void wpas_aidl_notify_hs20_rx_terms_and_conditions_acceptance(
+			struct wpa_supplicant *wpa_s, const char *url);
+	void wpas_aidl_notify_disconnect_reason(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_assoc_reject(struct wpa_supplicant *wpa_s, const u8 *bssid,
+		u8 timed_out, const u8 *assoc_resp_ie, size_t assoc_resp_ie_len);
+	void wpas_aidl_notify_auth_timeout(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_bssid_changed(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_wps_event_fail(
+		struct wpa_supplicant *wpa_s, uint8_t *peer_macaddr,
+		uint16_t config_error, uint16_t error_indication);
+	void wpas_aidl_notify_wps_event_success(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_wps_event_pbc_overlap(
+		struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_p2p_device_found(
+		struct wpa_supplicant *wpa_s, const u8 *addr,
+		const struct p2p_peer_info *info, const u8 *peer_wfd_device_info,
+		u8 peer_wfd_device_info_len, const u8 *peer_wfd_r2_device_info,
+		u8 peer_wfd_r2_device_info_len);
+	void wpas_aidl_notify_p2p_device_lost(
+		struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr);
+	void wpas_aidl_notify_p2p_find_stopped(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_p2p_go_neg_req(
+		struct wpa_supplicant *wpa_s, const u8 *src_addr, u16 dev_passwd_id,
+		u8 go_intent);
+	void wpas_aidl_notify_p2p_go_neg_completed(
+		struct wpa_supplicant *wpa_s, const struct p2p_go_neg_results *res);
+	void wpas_aidl_notify_p2p_group_formation_failure(
+		struct wpa_supplicant *wpa_s, const char *reason);
+	void wpas_aidl_notify_p2p_group_started(
+		struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid,
+		int persistent, int client);
+	void wpas_aidl_notify_p2p_group_removed(
+		struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid,
+		const char *role);
+	void wpas_aidl_notify_p2p_invitation_received(
+		struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *go_dev_addr,
+		const u8 *bssid, int id, int op_freq);
+	void wpas_aidl_notify_p2p_invitation_result(
+		struct wpa_supplicant *wpa_s, int status, const u8 *bssid);
+	void wpas_aidl_notify_p2p_provision_discovery(
+		struct wpa_supplicant *wpa_s, const u8 *dev_addr, int request,
+		enum p2p_prov_disc_status status, u16 config_methods,
+		unsigned int generated_pin);
+	void wpas_aidl_notify_p2p_sd_response(
+		struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic,
+		const u8 *tlvs, size_t tlvs_len);
+	void wpas_aidl_notify_ap_sta_authorized(
+		struct wpa_supplicant *wpa_s, const u8 *sta,
+		const u8 *p2p_dev_addr);
+	void wpas_aidl_notify_ap_sta_deauthorized(
+		struct wpa_supplicant *wpa_s, const u8 *sta,
+		const u8 *p2p_dev_addr);
+	void wpas_aidl_notify_eap_error(
+		struct wpa_supplicant *wpa_s, int error_code);
+#ifdef CONFIG_DPP
+	void wpas_aidl_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
+			struct wpa_ssid *ssid);
+	void wpas_aidl_notify_dpp_config_sent(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_auth_success(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_resp_pending(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_not_compatible(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_missing_auth(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_configuration_failure(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_invalid_uri(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_timeout(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_auth_failure(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_fail(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_config_sent_wait_response(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_config_accepted(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_config_rejected(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_conn_status(struct wpa_supplicant *wpa_s,
+		enum dpp_status_error status, const char *ssid,
+		const char *channel_list, unsigned short band_list[], int size);
+#endif
+	void wpas_aidl_notify_pmk_cache_added(
+		struct wpa_supplicant *wpas, struct rsn_pmksa_cache_entry *pmksa_entry);
+	void wpas_aidl_notify_bss_tm_status(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_transition_disable(
+		struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, u8 bitmap);
+	void wpas_aidl_notify_network_not_found(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_frequency_changed(struct wpa_supplicant *wpa_s, int frequency);
+	void wpas_aidl_notify_ceritification(struct wpa_supplicant *wpa_s,
+		int depth, const char *subject,
+		const char *altsubject[],
+		int num_altsubject,
+		const char *cert_hash,
+		const struct wpabuf *cert);
+	void wpas_aidl_notify_eap_method_selected(struct wpa_supplicant *wpa_s,
+		const char *reason_string);
+	void wpas_aidl_notify_ssid_temp_disabled(struct wpa_supplicant *wpa_s,
+		const char *reason_string);
+	void wpas_aidl_notify_open_ssl_failure(struct wpa_supplicant *wpa_s,
+		const char *reason_string);
+	void wpas_aidl_notify_qos_policy_reset(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_qos_policy_request(struct wpa_supplicant *wpa_s,
+		struct dscp_policy_data *policies, int num_policies);
+#else   // CONFIG_CTRL_IFACE_AIDL
+static inline int wpas_aidl_register_interface(struct wpa_supplicant *wpa_s)
+{
+	return 0;
+}
+static inline int wpas_aidl_unregister_interface(struct wpa_supplicant *wpa_s)
+{
+	return 0;
+}
+static inline int wpas_aidl_register_network(
+	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
+{
+	return 0;
+}
+static inline int wpas_aidl_unregister_network(
+	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
+{
+	return 0;
+}
+static inline int wpas_aidl_notify_state_changed(struct wpa_supplicant *wpa_s)
+{
+	return 0;
+}
+static inline int wpas_aidl_notify_network_request(
+	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
+	enum wpa_ctrl_req_type rtype, const char *default_txt)
+{
+	return 0;
+}
+static void wpas_aidl_notify_anqp_query_done(
+	struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
+	const struct wpa_bss_anqp *anqp)
+{}
+static void wpas_aidl_notify_hs20_icon_query_done(
+	struct wpa_supplicant *wpa_s, const u8 *bssid, const char *file_name,
+	const u8 *image, u32 image_length)
+{}
+static void wpas_aidl_notify_hs20_rx_subscription_remediation(
+	struct wpa_supplicant *wpa_s, const char *url, u8 osu_method)
+{}
+static void wpas_aidl_notify_hs20_rx_deauth_imminent_notice(
+	struct wpa_supplicant *wpa_s, u8 code, u16 reauth_delay, const char *url)
+{}
+void wpas_aidl_notify_hs20_rx_terms_and_conditions_acceptance(
+		struct wpa_supplicant *wpa_s, const char *url)
+{}
+static void wpas_aidl_notify_disconnect_reason(struct wpa_supplicant *wpa_s) {}
+static void wpas_aidl_notify_assoc_reject(struct wpa_supplicant *wpa_s, const u8 *bssid,
+	u8 timed_out, const u8 *assoc_resp_ie, size_t assoc_resp_ie_len) {}
+static void wpas_aidl_notify_auth_timeout(struct wpa_supplicant *wpa_s) {}
+static void wpas_aidl_notify_wps_event_fail(
+	struct wpa_supplicant *wpa_s, uint8_t *peer_macaddr, uint16_t config_error,
+	uint16_t error_indication)
+{}
+static void wpas_aidl_notify_bssid_changed(struct wpa_supplicant *wpa_s) {}
+static void wpas_aidl_notify_wps_event_success(struct wpa_supplicant *wpa_s) {}
+static void wpas_aidl_notify_wps_event_pbc_overlap(struct wpa_supplicant *wpa_s)
+{}
+static void wpas_aidl_notify_p2p_device_found(
+	struct wpa_supplicant *wpa_s, const u8 *addr,
+	const struct p2p_peer_info *info, const u8 *peer_wfd_device_info,
+	u8 peer_wfd_device_info_len)
+{}
+static void wpas_aidl_notify_p2p_device_lost(
+	struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr)
+{}
+static void wpas_aidl_notify_p2p_find_stopped(struct wpa_supplicant *wpa_s) {}
+static void wpas_aidl_notify_p2p_go_neg_req(
+	struct wpa_supplicant *wpa_s, const u8 *src_addr, u16 dev_passwd_id,
+	u8 go_intent)
+{}
+static void wpas_aidl_notify_p2p_go_neg_completed(
+	struct wpa_supplicant *wpa_s, const struct p2p_go_neg_results *res)
+{}
+static void wpas_aidl_notify_p2p_group_formation_failure(
+	struct wpa_supplicant *wpa_s, const char *reason)
+{}
+static void wpas_aidl_notify_p2p_group_started(
+	struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid, int persistent,
+	int client)
+{}
+static void wpas_aidl_notify_p2p_group_removed(
+	struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid, const char *role)
+{}
+static void wpas_aidl_notify_p2p_invitation_received(
+	struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *go_dev_addr,
+	const u8 *bssid, int id, int op_freq)
+{}
+static void wpas_aidl_notify_p2p_invitation_result(
+	struct wpa_supplicant *wpa_s, int status, const u8 *bssid)
+{}
+static void wpas_aidl_notify_p2p_provision_discovery(
+	struct wpa_supplicant *wpa_s, const u8 *dev_addr, int request,
+	enum p2p_prov_disc_status status, u16 config_methods,
+	unsigned int generated_pin)
+{}
+static void wpas_aidl_notify_p2p_sd_response(
+	struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic,
+	const u8 *tlvs, size_t tlvs_len)
+{}
+static void wpas_aidl_notify_ap_sta_authorized(
+	struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr)
+{}
+static void wpas_aidl_notify_ap_sta_deauthorized(
+	struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr)
+{}
+static void wpas_aidl_notify_eap_error(
+	struct wpa_supplicant *wpa_s, int error_code)
+{}
+static void wpas_aidl_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
+		struct wpa_ssid *ssid)
+{}
+static void wpas_aidl_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
+		struct wpa_ssid *ssid);
+static void wpas_aidl_notify_dpp_config_sent(struct wpa_supplicant *wpa_s)
+{}
+static void wpas_aidl_notify_dpp_auth_success(struct wpa_supplicant *wpa_s)
+{}
+static void wpas_aidl_notify_dpp_resp_pending(struct wpa_supplicant *wpa_s)
+{}
+static void wpas_aidl_notify_dpp_not_compatible(struct wpa_supplicant *wpa_s)
+{}
+static void wpas_aidl_notify_dpp_missing_auth(struct wpa_supplicant *wpa_s)
+{}
+static void wpas_aidl_notify_dpp_configuration_failure(struct wpa_supplicant *wpa_s)
+{}
+static void wpas_aidl_notify_dpp_invalid_uri(struct wpa_supplicant *wpa_s)
+{}
+static void wpas_aidl_notify_dpp_timeout(struct wpa_supplicant *wpa_s)
+{}
+static void wpas_aidl_notify_dpp_failure(struct wpa_supplicant *wpa_s)
+{}
+void wpas_aidl_notify_dpp_config_sent_wait_response(struct wpa_supplicant *wpa_s)
+{}
+void wpas_aidl_notify_dpp_config_accepted(struct wpa_supplicant *wpa_s)
+{}
+void wpas_aidl_notify_dpp_config_applied(struct wpa_supplicant *wpa_s)
+{}
+void wpas_aidl_notify_dpp_config_rejected(struct wpa_supplicant *wpa_s)
+{}
+static void wpas_aidl_notify_pmk_cache_added(struct wpa_supplicant *wpas,
+						 struct rsn_pmksa_cache_entry *pmksa_entry)
+{}
+void wpas_aidl_notify_bss_tm_status(struct wpa_supplicant *wpa_s)
+{}
+static void wpas_aidl_notify_transition_disable(struct wpa_supplicant *wpa_s,
+						struct wpa_ssid *ssid,
+						u8 bitmap)
+{}
+static void wpas_aidl_notify_network_not_found(struct wpa_supplicant *wpa_s)
+{}
+void wpas_aidl_notify_frequency_changed(struct wpa_supplicant *wpa_s, int frequency)
+{}
+void wpas_aidl_notify_ceritification(struct wpa_supplicant *wpa_s,
+	int depth, const char *subject,
+	const char *altsubject[],
+	int num_altsubject,
+	const char *cert_hash,
+	const struct wpabuf *cert)
+{}
+void wpas_aidl_notify_eap_method_selected(struct wpa_supplicant *wpa_s,
+	const char *reason_string)
+{}
+void wpas_aidl_notify_ssid_temp_disabled(struct wpa_supplicant *wpa_s,
+	const char *reason_string)
+{}
+void wpas_aidl_notify_open_ssl_failure(struct wpa_supplicant *wpa_s,
+	const char *reason_string)
+{}
+static void wpas_aidl_notify_qos_policy_reset(struct wpa_supplicant *wpa_s) {}
+static void wpas_aidl_notify_qos_policy_request(struct wpa_supplicant *wpa_s,
+						struct dscp_policy_data *policies,
+						int num_policies)
+{}
+#endif  // CONFIG_CTRL_IFACE_AIDL
+
+#ifdef _cplusplus
+}
+#endif  // _cplusplus
+
+#endif  // WPA_SUPPLICANT_AIDL_AIDL_H
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/aidl_i.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/aidl_i.h
new file mode 100755
index 0000000..7f377cd
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/aidl_i.h
@@ -0,0 +1,28 @@
+/*
+ * WPA Supplicant - Global Aidl struct
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef AIDL_I_H
+#define AIDL_I_H
+
+#ifdef _cplusplus
+extern "C"
+{
+#endif  // _cplusplus
+
+	struct wpas_aidl_priv
+	{
+		int aidl_fd;
+		struct wpa_global *global;
+		void *aidl_manager;
+	};
+
+#ifdef _cplusplus
+}
+#endif  // _cplusplus
+
+#endif  // AIDL_I_H
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/aidl_manager.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/aidl_manager.cpp
new file mode 100755
index 0000000..da90c38
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/aidl_manager.cpp
@@ -0,0 +1,2466 @@
+/*
+ * WPA Supplicant - Manager for Aidl interface objects
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include <algorithm>
+#include <functional>
+#include <iostream>
+#include <regex>
+
+#include "aidl_manager.h"
+#include "misc_utils.h"
+#include <android/binder_process.h>
+#include <android/binder_manager.h>
+#include <aidl/android/hardware/wifi/supplicant/IpVersion.h>
+
+extern "C" {
+#include "scan.h"
+#include "src/eap_common/eap_sim_common.h"
+#include "list.h"
+}
+
+namespace {
+
+constexpr uint8_t kWfdDeviceInfoLen = 6;
+constexpr uint8_t kWfdR2DeviceInfoLen = 2;
+// GSM-AUTH:<RAND1>:<RAND2>[:<RAND3>]
+constexpr char kGsmAuthRegex2[] = "GSM-AUTH:([0-9a-f]+):([0-9a-f]+)";
+constexpr char kGsmAuthRegex3[] =
+	"GSM-AUTH:([0-9a-f]+):([0-9a-f]+):([0-9a-f]+)";
+// UMTS-AUTH:<RAND>:<AUTN>
+constexpr char kUmtsAuthRegex[] = "UMTS-AUTH:([0-9a-f]+):([0-9a-f]+)";
+constexpr size_t kGsmRandLenBytes = GSM_RAND_LEN;
+constexpr size_t kUmtsRandLenBytes = EAP_AKA_RAND_LEN;
+constexpr size_t kUmtsAutnLenBytes = EAP_AKA_AUTN_LEN;
+const std::vector<uint8_t> kZeroBssid = {0, 0, 0, 0, 0, 0};
+
+using aidl::android::hardware::wifi::supplicant::GsmRand;
+
+/**
+ * Check if the provided |wpa_supplicant| structure represents a P2P iface or
+ * not.
+ */
+constexpr bool isP2pIface(const struct wpa_supplicant *wpa_s)
+{
+	return wpa_s->global->p2p_init_wpa_s == wpa_s;
+}
+
+/**
+ * Creates a unique key for the network using the provided |ifname| and
+ * |network_id| to be used in the internal map of |ISupplicantNetwork| objects.
+ * This is of the form |ifname|_|network_id|. For ex: "wlan0_1".
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param network_id ID of the corresponding network.
+ */
+const std::string getNetworkObjectMapKey(
+	const std::string &ifname, int network_id)
+{
+	return ifname + "_" + std::to_string(network_id);
+}
+
+/**
+ * Add callback to the corresponding list after linking to death on the
+ * corresponding aidl object reference.
+ */
+template <class CallbackType>
+int registerForDeathAndAddCallbackAidlObjectToList(
+	AIBinder_DeathRecipient* death_notifier,
+	const std::shared_ptr<CallbackType> &callback,
+	std::vector<std::shared_ptr<CallbackType>> &callback_list)
+{
+	binder_status_t status = AIBinder_linkToDeath(callback->asBinder().get(),
+			death_notifier, nullptr /* cookie */);
+	if (status != STATUS_OK) {
+		wpa_printf(
+			MSG_ERROR,
+			"Error registering for death notification for "
+			"supplicant callback object");
+		return 1;
+	}
+	callback_list.push_back(callback);
+	return 0;
+}
+
+template <class ObjectType>
+int addAidlObjectToMap(
+	const std::string &key, const std::shared_ptr<ObjectType> &object,
+	std::map<const std::string, std::shared_ptr<ObjectType>> &object_map)
+{
+	// Return failure if we already have an object for that |key|.
+	if (object_map.find(key) != object_map.end())
+		return 1;
+	object_map[key] = object;
+	if (!object_map[key].get())
+		return 1;
+	return 0;
+}
+
+template <class ObjectType>
+int removeAidlObjectFromMap(
+	const std::string &key,
+	std::map<const std::string, std::shared_ptr<ObjectType>> &object_map)
+{
+	// Return failure if we dont have an object for that |key|.
+	const auto &object_iter = object_map.find(key);
+	if (object_iter == object_map.end())
+		return 1;
+	object_iter->second->invalidate();
+	object_map.erase(object_iter);
+	return 0;
+}
+
+template <class CallbackType>
+int addIfaceCallbackAidlObjectToMap(
+	AIBinder_DeathRecipient* death_notifier,
+	const std::string &ifname, const std::shared_ptr<CallbackType> &callback,
+	std::map<const std::string, std::vector<std::shared_ptr<CallbackType>>>
+	&callbacks_map)
+{
+	if (ifname.empty())
+		return 1;
+
+	auto iface_callback_map_iter = callbacks_map.find(ifname);
+	if (iface_callback_map_iter == callbacks_map.end())
+		return 1;
+	auto &iface_callback_list = iface_callback_map_iter->second;
+
+	// Register for death notification before we add it to our list.
+	return registerForDeathAndAddCallbackAidlObjectToList<CallbackType>(
+		death_notifier, callback, iface_callback_list);
+}
+
+template <class CallbackType>
+int addNetworkCallbackAidlObjectToMap(
+	AIBinder_DeathRecipient* death_notifier,
+	const std::string &ifname, int network_id,
+	const std::shared_ptr<CallbackType> &callback,
+	std::map<const std::string, std::vector<std::shared_ptr<CallbackType>>>
+	&callbacks_map)
+{
+	if (ifname.empty() || network_id < 0)
+		return 1;
+
+	// Generate the key to be used to lookup the network.
+	const std::string network_key =
+		getNetworkObjectMapKey(ifname, network_id);
+	auto network_callback_map_iter = callbacks_map.find(network_key);
+	if (network_callback_map_iter == callbacks_map.end())
+		return 1;
+	auto &network_callback_list = network_callback_map_iter->second;
+
+	// Register for death notification before we add it to our list.
+	return registerForDeathAndAddCallbackAidlObjectToList<CallbackType>(
+		death_notifier, callback, network_callback_list);
+}
+
+template <class CallbackType>
+int removeAllIfaceCallbackAidlObjectsFromMap(
+	AIBinder_DeathRecipient* death_notifier,
+	const std::string &ifname,
+	std::map<const std::string, std::vector<std::shared_ptr<CallbackType>>>
+	&callbacks_map)
+{
+	auto iface_callback_map_iter = callbacks_map.find(ifname);
+	if (iface_callback_map_iter == callbacks_map.end())
+		return 1;
+	const auto &iface_callback_list = iface_callback_map_iter->second;
+	for (const auto &callback : iface_callback_list) {
+		binder_status_t status = AIBinder_linkToDeath(callback->asBinder().get(),
+				death_notifier, nullptr /* cookie */);
+		if (status != STATUS_OK) {
+			wpa_printf(
+				MSG_ERROR,
+				"Error deregistering for death notification for "
+				"iface callback object");
+		}
+	}
+	callbacks_map.erase(iface_callback_map_iter);
+	return 0;
+}
+
+template <class CallbackType>
+int removeAllNetworkCallbackAidlObjectsFromMap(
+	AIBinder_DeathRecipient* death_notifier,
+	const std::string &network_key,
+	std::map<const std::string, std::vector<std::shared_ptr<CallbackType>>>
+	&callbacks_map)
+{
+	auto network_callback_map_iter = callbacks_map.find(network_key);
+	if (network_callback_map_iter == callbacks_map.end())
+		return 1;
+	const auto &network_callback_list = network_callback_map_iter->second;
+	for (const auto &callback : network_callback_list) {
+		binder_status_t status = AIBinder_linkToDeath(callback->asBinder().get(),
+				death_notifier, nullptr /* cookie */);
+		if (status != STATUS_OK) {
+			wpa_printf(
+				MSG_ERROR,
+				"Error deregistering for death "
+				"notification for "
+				"network callback object");
+		}
+	}
+	callbacks_map.erase(network_callback_map_iter);
+	return 0;
+}
+
+template <class CallbackType>
+void removeIfaceCallbackAidlObjectFromMap(
+	const std::string &ifname, const std::shared_ptr<CallbackType> &callback,
+	std::map<const std::string, std::vector<std::shared_ptr<CallbackType>>>
+	&callbacks_map)
+{
+	if (ifname.empty())
+		return;
+
+	auto iface_callback_map_iter = callbacks_map.find(ifname);
+	if (iface_callback_map_iter == callbacks_map.end())
+		return;
+
+	auto &iface_callback_list = iface_callback_map_iter->second;
+	iface_callback_list.erase(
+		std::remove(
+		iface_callback_list.begin(), iface_callback_list.end(),
+		callback),
+		iface_callback_list.end());
+}
+
+template <class CallbackType>
+void removeNetworkCallbackAidlObjectFromMap(
+	const std::string &ifname, int network_id,
+	const std::shared_ptr<CallbackType> &callback,
+	std::map<const std::string, std::vector<std::shared_ptr<CallbackType>>>
+	&callbacks_map)
+{
+	if (ifname.empty() || network_id < 0)
+		return;
+
+	// Generate the key to be used to lookup the network.
+	const std::string network_key =
+		getNetworkObjectMapKey(ifname, network_id);
+
+	auto network_callback_map_iter = callbacks_map.find(network_key);
+	if (network_callback_map_iter == callbacks_map.end())
+		return;
+
+	auto &network_callback_list = network_callback_map_iter->second;
+	network_callback_list.erase(
+		std::remove(
+		network_callback_list.begin(), network_callback_list.end(),
+		callback),
+		network_callback_list.end());
+}
+
+template <class CallbackType>
+void callWithEachIfaceCallback(
+	const std::string &ifname,
+	const std::function<ndk::ScopedAStatus(std::shared_ptr<CallbackType>)> &method,
+	const std::map<const std::string, std::vector<std::shared_ptr<CallbackType>>>
+	&callbacks_map)
+{
+	if (ifname.empty())
+		return;
+
+	auto iface_callback_map_iter = callbacks_map.find(ifname);
+	if (iface_callback_map_iter == callbacks_map.end())
+		return;
+	const auto &iface_callback_list = iface_callback_map_iter->second;
+	for (const auto &callback : iface_callback_list) {
+		if (!method(callback).isOk()) {
+			wpa_printf(
+				MSG_ERROR, "Failed to invoke AIDL iface callback");
+		}
+	}
+}
+
+template <class CallbackType>
+void callWithEachNetworkCallback(
+	const std::string &ifname, int network_id,
+	const std::function<
+	ndk::ScopedAStatus(std::shared_ptr<CallbackType>)> &method,
+	const std::map<const std::string, std::vector<std::shared_ptr<CallbackType>>>
+	&callbacks_map)
+{
+	if (ifname.empty() || network_id < 0)
+		return;
+
+	// Generate the key to be used to lookup the network.
+	const std::string network_key =
+		getNetworkObjectMapKey(ifname, network_id);
+	auto network_callback_map_iter = callbacks_map.find(network_key);
+	if (network_callback_map_iter == callbacks_map.end())
+		return;
+	const auto &network_callback_list = network_callback_map_iter->second;
+	for (const auto &callback : network_callback_list) {
+		if (!method(callback).isOk()) {
+			wpa_printf(
+				MSG_ERROR,
+				"Failed to invoke AIDL network callback");
+		}
+	}
+}
+
+int parseGsmAuthNetworkRequest(
+	const std::string &params_str,
+	std::vector<GsmRand> *out_rands)
+{
+	std::smatch matches;
+	std::regex params_gsm_regex2(kGsmAuthRegex2);
+	std::regex params_gsm_regex3(kGsmAuthRegex3);
+	if (!std::regex_match(params_str, matches, params_gsm_regex3) &&
+		!std::regex_match(params_str, matches, params_gsm_regex2)) {
+		return 1;
+	}
+	for (uint32_t i = 1; i < matches.size(); i++) {
+		GsmRand rand;
+		rand.data = std::vector<uint8_t>(kGsmRandLenBytes);
+		const auto &match = matches[i];
+		WPA_ASSERT(match.size() >= 2 * rand.data.size());
+		if (hexstr2bin(match.str().c_str(), rand.data.data(), rand.data.size())) {
+			wpa_printf(MSG_ERROR, "Failed to parse GSM auth params");
+			return 1;
+		}
+		out_rands->push_back(rand);
+	}
+	return 0;
+}
+
+int parseUmtsAuthNetworkRequest(
+	const std::string &params_str,
+	std::vector<uint8_t> *out_rand,
+	std::vector<uint8_t> *out_autn)
+{
+	std::smatch matches;
+	std::regex params_umts_regex(kUmtsAuthRegex);
+	if (!std::regex_match(params_str, matches, params_umts_regex)) {
+		return 1;
+	}
+	WPA_ASSERT(matches[1].size() >= 2 * out_rand->size());
+	if (hexstr2bin(
+		matches[1].str().c_str(), out_rand->data(), out_rand->size())) {
+		wpa_printf(MSG_ERROR, "Failed to parse UMTS auth params");
+		return 1;
+	}
+	WPA_ASSERT(matches[2].size() >= 2 * out_autn->size());
+	if (hexstr2bin(
+		matches[2].str().c_str(), out_autn->data(), out_autn->size())) {
+		wpa_printf(MSG_ERROR, "Failed to parse UMTS auth params");
+		return 1;
+	}
+	return 0;
+}
+
+inline std::vector<uint8_t> byteArrToVec(const uint8_t* arr, int len) {
+	return std::vector<uint8_t>{arr, arr + len};
+}
+
+inline std::vector<uint8_t> macAddrToVec(const uint8_t* mac_addr) {
+	return byteArrToVec(mac_addr, ETH_ALEN);
+}
+
+// Raw pointer to the global structure maintained by the core.
+// Declared here to be accessible to onDeath()
+struct wpa_global *wpa_global_;
+
+void onDeath(void* cookie) {
+	wpa_printf(MSG_ERROR, "Client died. Terminating...");
+	wpa_supplicant_terminate_proc(wpa_global_);
+}
+
+}  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+
+AidlManager *AidlManager::instance_ = NULL;
+
+AidlManager *AidlManager::getInstance()
+{
+	if (!instance_)
+		instance_ = new AidlManager();
+	return instance_;
+}
+
+void AidlManager::destroyInstance()
+{
+	if (instance_)
+		delete instance_;
+	instance_ = NULL;
+}
+
+int AidlManager::registerAidlService(struct wpa_global *global)
+{
+	// Create the main aidl service object and register it.
+	wpa_printf(MSG_INFO, "Starting AIDL supplicant");
+	supplicant_object_ = ndk::SharedRefBase::make<Supplicant>(global);
+	wpa_global_ = global;
+	std::string instance = std::string() + Supplicant::descriptor + "/default";
+	if (AServiceManager_addService(supplicant_object_->asBinder().get(),
+			instance.c_str()) != STATUS_OK)
+	{
+		return 1;
+	}
+
+	// Initialize the death notifier.
+	death_notifier_ = AIBinder_DeathRecipient_new(onDeath);
+	return 0;
+}
+
+/**
+ * Register an interface to aidl manager.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int AidlManager::registerInterface(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return 1;
+
+	if (isP2pIface(wpa_s)) {
+		if (addAidlObjectToMap<P2pIface>(
+			wpa_s->ifname,
+			ndk::SharedRefBase::make<P2pIface>(wpa_s->global, wpa_s->ifname),
+			p2p_iface_object_map_)) {
+			wpa_printf(
+				MSG_ERROR,
+				"Failed to register P2P interface with AIDL "
+				"control: %s",
+				wpa_s->ifname);
+			return 1;
+		}
+		p2p_iface_callbacks_map_[wpa_s->ifname] =
+			std::vector<std::shared_ptr<ISupplicantP2pIfaceCallback>>();
+	} else {
+		if (addAidlObjectToMap<StaIface>(
+			wpa_s->ifname,
+			ndk::SharedRefBase::make<StaIface>(wpa_s->global, wpa_s->ifname),
+			sta_iface_object_map_)) {
+			wpa_printf(
+				MSG_ERROR,
+				"Failed to register STA interface with AIDL "
+				"control: %s",
+				wpa_s->ifname);
+			return 1;
+		}
+		sta_iface_callbacks_map_[wpa_s->ifname] =
+			std::vector<std::shared_ptr<ISupplicantStaIfaceCallback>>();
+		// Turn on Android specific customizations for STA interfaces
+		// here!
+		//
+		// Turn on scan mac randomization only if driver supports.
+		if (wpa_s->mac_addr_rand_supported & MAC_ADDR_RAND_SCAN) {
+			if (wpas_mac_addr_rand_scan_set(
+				wpa_s, MAC_ADDR_RAND_SCAN, nullptr, nullptr)) {
+				wpa_printf(
+					MSG_ERROR,
+					"Failed to enable scan mac randomization");
+			}
+		}
+
+		// Enable randomized source MAC address for GAS/ANQP
+		// Set the lifetime to 0, guarantees a unique address for each GAS
+		// session
+		wpa_s->conf->gas_rand_mac_addr = 1;
+		wpa_s->conf->gas_rand_addr_lifetime = 0;
+	}
+
+	// Invoke the |onInterfaceCreated| method on all registered callbacks.
+	callWithEachSupplicantCallback(std::bind(
+		&ISupplicantCallback::onInterfaceCreated, std::placeholders::_1,
+		misc_utils::charBufToString(wpa_s->ifname)));
+	return 0;
+}
+
+/**
+ * Unregister an interface from aidl manager.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int AidlManager::unregisterInterface(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return 1;
+
+	// Check if this interface is present in P2P map first, else check in
+	// STA map.
+	// Note: We can't use isP2pIface() here because interface
+	// pointers (wpa_s->global->p2p_init_wpa_s == wpa_s) used by the helper
+	// function is cleared by the core before notifying the AIDL interface.
+	bool success =
+		!removeAidlObjectFromMap(wpa_s->ifname, p2p_iface_object_map_);
+	if (success) {  // assumed to be P2P
+		success = !removeAllIfaceCallbackAidlObjectsFromMap(
+			death_notifier_, wpa_s->ifname, p2p_iface_callbacks_map_);
+	} else {  // assumed to be STA
+		success = !removeAidlObjectFromMap(
+			wpa_s->ifname, sta_iface_object_map_);
+		if (success) {
+			success = !removeAllIfaceCallbackAidlObjectsFromMap(
+				death_notifier_, wpa_s->ifname, sta_iface_callbacks_map_);
+		}
+	}
+	if (!success) {
+		wpa_printf(
+			MSG_ERROR,
+			"Failed to unregister interface with AIDL "
+			"control: %s",
+			wpa_s->ifname);
+		return 1;
+	}
+
+	// Invoke the |onInterfaceRemoved| method on all registered callbacks.
+	callWithEachSupplicantCallback(std::bind(
+		&ISupplicantCallback::onInterfaceRemoved, std::placeholders::_1,
+		misc_utils::charBufToString(wpa_s->ifname)));
+	return 0;
+}
+
+/**
+ * Register a network to aidl manager.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
+ * the network is added.
+ * @param ssid |wpa_ssid| struct corresponding to the network being added.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int AidlManager::registerNetwork(
+	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
+{
+	if (!wpa_s || !ssid)
+		return 1;
+
+	// Generate the key to be used to lookup the network.
+	const std::string network_key =
+		getNetworkObjectMapKey(wpa_s->ifname, ssid->id);
+
+	if (isP2pIface(wpa_s)) {
+		if (addAidlObjectToMap<P2pNetwork>(
+			network_key,
+			ndk::SharedRefBase::make<P2pNetwork>(wpa_s->global, wpa_s->ifname, ssid->id),
+			p2p_network_object_map_)) {
+			wpa_printf(
+				MSG_ERROR,
+				"Failed to register P2P network with AIDL "
+				"control: %d",
+				ssid->id);
+			return 1;
+		}
+	} else {
+		if (addAidlObjectToMap<StaNetwork>(
+			network_key,
+			ndk::SharedRefBase::make<StaNetwork>(wpa_s->global, wpa_s->ifname, ssid->id),
+			sta_network_object_map_)) {
+			wpa_printf(
+				MSG_ERROR,
+				"Failed to register STA network with AIDL "
+				"control: %d",
+				ssid->id);
+			return 1;
+		}
+		sta_network_callbacks_map_[network_key] =
+			std::vector<std::shared_ptr<ISupplicantStaNetworkCallback>>();
+		// Invoke the |onNetworkAdded| method on all registered
+		// callbacks.
+		callWithEachStaIfaceCallback(
+			misc_utils::charBufToString(wpa_s->ifname),
+			std::bind(
+			&ISupplicantStaIfaceCallback::onNetworkAdded,
+			std::placeholders::_1, ssid->id));
+	}
+	return 0;
+}
+
+/**
+ * Unregister a network from aidl manager.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
+ * the network is added.
+ * @param ssid |wpa_ssid| struct corresponding to the network being added.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int AidlManager::unregisterNetwork(
+	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
+{
+	if (!wpa_s || !ssid)
+		return 1;
+
+	// Generate the key to be used to lookup the network.
+	const std::string network_key =
+		getNetworkObjectMapKey(wpa_s->ifname, ssid->id);
+
+	if (isP2pIface(wpa_s)) {
+		if (removeAidlObjectFromMap(
+			network_key, p2p_network_object_map_)) {
+			wpa_printf(
+				MSG_ERROR,
+				"Failed to unregister P2P network with AIDL "
+				"control: %d",
+				ssid->id);
+			return 1;
+		}
+	} else {
+		if (removeAidlObjectFromMap(
+			network_key, sta_network_object_map_)) {
+			wpa_printf(
+				MSG_ERROR,
+				"Failed to unregister STA network with AIDL "
+				"control: %d",
+				ssid->id);
+			return 1;
+		}
+		if (removeAllNetworkCallbackAidlObjectsFromMap(
+			death_notifier_, network_key, sta_network_callbacks_map_)) {
+			return 1;
+		}
+
+		// Invoke the |onNetworkRemoved| method on all registered
+		// callbacks.
+		callWithEachStaIfaceCallback(
+			misc_utils::charBufToString(wpa_s->ifname),
+			std::bind(
+			&ISupplicantStaIfaceCallback::onNetworkRemoved,
+			std::placeholders::_1, ssid->id));
+	}
+	return 0;
+}
+
+/**
+ * Notify all listeners about any state changes on a particular interface.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
+ * the state change event occured.
+ */
+int AidlManager::notifyStateChange(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return 1;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return 1;
+
+	// Invoke the |onStateChanged| method on all registered callbacks.
+	uint32_t aidl_network_id = UINT32_MAX;
+	std::vector<uint8_t> aidl_ssid;
+	if (wpa_s->current_ssid) {
+		aidl_network_id = wpa_s->current_ssid->id;
+		aidl_ssid.assign(
+			wpa_s->current_ssid->ssid,
+			wpa_s->current_ssid->ssid + wpa_s->current_ssid->ssid_len);
+	}
+	std::vector<uint8_t> bssid;
+	// wpa_supplicant sets the |pending_bssid| field when it starts a
+	// connection. Only after association state does it update the |bssid|
+	// field. So, in the AIDL callback send the appropriate bssid.
+	if (wpa_s->wpa_state <= WPA_ASSOCIATED) {
+		bssid = macAddrToVec(wpa_s->pending_bssid);
+	} else {
+		bssid = macAddrToVec(wpa_s->bssid);
+	}
+	bool fils_hlp_sent =
+		(wpa_auth_alg_fils(wpa_s->auth_alg) &&
+		 !dl_list_empty(&wpa_s->fils_hlp_req) &&
+		 (wpa_s->wpa_state == WPA_COMPLETED)) ? true : false;
+
+	// Invoke the |onStateChanged| method on all registered callbacks.
+	std::function<
+		ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaIfaceCallback>)>
+		func = std::bind(
+			&ISupplicantStaIfaceCallback::onStateChanged,
+			std::placeholders::_1,
+			static_cast<StaIfaceCallbackState>(
+				wpa_s->wpa_state),
+				bssid, aidl_network_id, aidl_ssid,
+				fils_hlp_sent);
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname), func);
+	return 0;
+}
+
+/**
+ * Notify all listeners about a request on a particular network.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
+ * the network is present.
+ * @param ssid |wpa_ssid| struct corresponding to the network.
+ * @param type type of request.
+ * @param param addition params associated with the request.
+ */
+int AidlManager::notifyNetworkRequest(
+	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, int type,
+	const char *param)
+{
+	if (!wpa_s || !ssid)
+		return 1;
+
+	const std::string network_key =
+		getNetworkObjectMapKey(wpa_s->ifname, ssid->id);
+	if (sta_network_object_map_.find(network_key) ==
+		sta_network_object_map_.end())
+		return 1;
+
+	if (type == WPA_CTRL_REQ_EAP_IDENTITY) {
+		callWithEachStaNetworkCallback(
+			misc_utils::charBufToString(wpa_s->ifname),
+			ssid->id,
+			std::bind(
+			&ISupplicantStaNetworkCallback::
+				onNetworkEapIdentityRequest,
+			std::placeholders::_1));
+		return 0;
+	}
+	if (type == WPA_CTRL_REQ_SIM) {
+		std::vector<GsmRand> gsm_rands;
+		std::vector<uint8_t> umts_rand = std::vector<uint8_t>(16);
+		std::vector<uint8_t> umts_autn = std::vector<uint8_t>(16);
+		if (!parseGsmAuthNetworkRequest(param, &gsm_rands)) {
+			NetworkRequestEapSimGsmAuthParams aidl_params;
+			aidl_params.rands = gsm_rands;
+			callWithEachStaNetworkCallback(
+				misc_utils::charBufToString(wpa_s->ifname),
+				ssid->id,
+				std::bind(
+				&ISupplicantStaNetworkCallback::
+					onNetworkEapSimGsmAuthRequest,
+				std::placeholders::_1, aidl_params));
+			return 0;
+		}
+		if (!parseUmtsAuthNetworkRequest(
+			param, &umts_rand, &umts_autn)) {
+			NetworkRequestEapSimUmtsAuthParams aidl_params;
+			aidl_params.rand = umts_rand;
+			aidl_params.autn = umts_autn;
+			callWithEachStaNetworkCallback(
+				misc_utils::charBufToString(wpa_s->ifname),
+				ssid->id,
+				std::bind(
+				&ISupplicantStaNetworkCallback::
+					onNetworkEapSimUmtsAuthRequest,
+				std::placeholders::_1, aidl_params));
+			return 0;
+		}
+	}
+	return 1;
+}
+
+/**
+ * Notify all listeners about the end of an ANQP query.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
+ * @param bssid BSSID of the access point.
+ * @param result Result of the operation ("SUCCESS" or "FAILURE").
+ * @param anqp |wpa_bss_anqp| ANQP data fetched.
+ */
+void AidlManager::notifyAnqpQueryDone(
+	struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
+	const struct wpa_bss_anqp *anqp)
+{
+	if (!wpa_s || !bssid || !result || !anqp)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return;
+
+	AnqpData aidl_anqp_data;
+	Hs20AnqpData aidl_hs20_anqp_data;
+	if (std::string(result) == "SUCCESS") {
+		aidl_anqp_data.venueName =
+			misc_utils::convertWpaBufToVector(anqp->venue_name);
+		aidl_anqp_data.roamingConsortium =
+			misc_utils::convertWpaBufToVector(anqp->roaming_consortium);
+		aidl_anqp_data.ipAddrTypeAvailability =
+			misc_utils::convertWpaBufToVector(
+			anqp->ip_addr_type_availability);
+		aidl_anqp_data.naiRealm =
+			misc_utils::convertWpaBufToVector(anqp->nai_realm);
+		aidl_anqp_data.anqp3gppCellularNetwork =
+			misc_utils::convertWpaBufToVector(anqp->anqp_3gpp);
+		aidl_anqp_data.domainName =
+			misc_utils::convertWpaBufToVector(anqp->domain_name);
+
+		struct wpa_bss_anqp_elem *elem;
+		dl_list_for_each(elem, &anqp->anqp_elems, struct wpa_bss_anqp_elem,
+				 list) {
+			if (elem->infoid == ANQP_VENUE_URL && elem->protected_response) {
+				aidl_anqp_data.venueUrl =
+							misc_utils::convertWpaBufToVector(elem->payload);
+				break;
+			}
+		}
+
+		aidl_hs20_anqp_data.operatorFriendlyName =
+			misc_utils::convertWpaBufToVector(
+			anqp->hs20_operator_friendly_name);
+		aidl_hs20_anqp_data.wanMetrics =
+			misc_utils::convertWpaBufToVector(anqp->hs20_wan_metrics);
+		aidl_hs20_anqp_data.connectionCapability =
+			misc_utils::convertWpaBufToVector(
+			anqp->hs20_connection_capability);
+		aidl_hs20_anqp_data.osuProvidersList =
+			misc_utils::convertWpaBufToVector(
+			anqp->hs20_osu_providers_list);
+	}
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname), std::bind(
+				   &ISupplicantStaIfaceCallback::onAnqpQueryDone,
+				   std::placeholders::_1, macAddrToVec(bssid), aidl_anqp_data,
+				   aidl_hs20_anqp_data));
+}
+
+/**
+ * Notify all listeners about the end of an HS20 icon query.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
+ * @param bssid BSSID of the access point.
+ * @param file_name Name of the icon file.
+ * @param image Raw bytes of the icon file.
+ * @param image_length Size of the the icon file.
+ */
+void AidlManager::notifyHs20IconQueryDone(
+	struct wpa_supplicant *wpa_s, const u8 *bssid, const char *file_name,
+	const u8 *image, u32 image_length)
+{
+	if (!wpa_s || !bssid || !file_name || !image)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return;
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantStaIfaceCallback::onHs20IconQueryDone,
+		std::placeholders::_1, macAddrToVec(bssid), file_name,
+		std::vector<uint8_t>(image, image + image_length)));
+}
+
+/**
+ * Notify all listeners about the reception of HS20 subscription
+ * remediation notification from the server.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
+ * @param url URL of the server.
+ * @param osu_method OSU method (OMA_DM or SOAP_XML_SPP).
+ */
+void AidlManager::notifyHs20RxSubscriptionRemediation(
+	struct wpa_supplicant *wpa_s, const char *url, u8 osu_method)
+{
+	if (!wpa_s || !url)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return;
+
+	OsuMethod aidl_osu_method;
+	if (osu_method & 0x1) {
+		aidl_osu_method = OsuMethod::OMA_DM;
+	} else if (osu_method & 0x2) {
+		aidl_osu_method = OsuMethod::SOAP_XML_SPP;
+	}
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantStaIfaceCallback::onHs20SubscriptionRemediation,
+		std::placeholders::_1, macAddrToVec(wpa_s->bssid), aidl_osu_method, url));
+}
+
+/**
+ * Notify all listeners about the reception of HS20 imminent death
+ * notification from the server.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
+ * @param code Death reason code sent from server.
+ * @param reauth_delay Reauthentication delay in seconds sent from server.
+ * @param url URL of the server containing the reason text.
+ */
+void AidlManager::notifyHs20RxDeauthImminentNotice(
+	struct wpa_supplicant *wpa_s, u8 code, u16 reauth_delay, const char *url)
+{
+	if (!wpa_s)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return;
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantStaIfaceCallback::onHs20DeauthImminentNotice,
+		std::placeholders::_1, macAddrToVec(wpa_s->bssid), code,
+		reauth_delay, misc_utils::charBufToString(url)));
+}
+
+/**
+ * Notify all listeners about the reception of HS20 terms and conditions
+ * acceptance notification from the server.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
+ * @param url URL of the T&C server.
+ */
+void AidlManager::notifyHs20RxTermsAndConditionsAcceptance(
+	struct wpa_supplicant *wpa_s, const char *url)
+{
+	if (!wpa_s || !url)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname)
+			== sta_iface_object_map_.end())
+		return;
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+			&ISupplicantStaIfaceCallback
+			::onHs20TermsAndConditionsAcceptanceRequestedNotification,
+			std::placeholders::_1, macAddrToVec(wpa_s->bssid), url));
+}
+
+/**
+ * Notify all listeners about the reason code for disconnection from the
+ * currently connected network.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
+ * the network is present.
+ */
+void AidlManager::notifyDisconnectReason(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return;
+
+	const u8 *bssid = wpa_s->bssid;
+	if (is_zero_ether_addr(bssid)) {
+		bssid = wpa_s->pending_bssid;
+	}
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantStaIfaceCallback::onDisconnected,
+		std::placeholders::_1, macAddrToVec(bssid), wpa_s->disconnect_reason < 0,
+		static_cast<StaIfaceReasonCode>(
+			abs(wpa_s->disconnect_reason))));
+}
+
+/**
+ * Notify all listeners about association reject from the access point to which
+ * we are attempting to connect.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
+ * the network is present.
+ * @param bssid bssid of AP that rejected the association.
+ * @param timed_out flag to indicate failure is due to timeout
+ * (auth, assoc, ...) rather than explicit rejection response from the AP.
+ * @param assoc_resp_ie Association response IE.
+ * @param assoc_resp_ie_len Association response IE length.
+ */
+void AidlManager::notifyAssocReject(struct wpa_supplicant *wpa_s,
+	const u8 *bssid, u8 timed_out, const u8 *assoc_resp_ie, size_t assoc_resp_ie_len)
+{
+	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
+#ifdef CONFIG_MBO
+	struct wpa_bss *reject_bss;
+#endif /* CONFIG_MBO */
+	AssociationRejectionData aidl_assoc_reject_data{};
+
+	if (!wpa_s)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return;
+	if (wpa_s->current_ssid) {
+		aidl_assoc_reject_data.ssid = std::vector<uint8_t>(
+			wpa_s->current_ssid->ssid,
+			wpa_s->current_ssid->ssid + wpa_s->current_ssid->ssid_len);
+	}
+	aidl_assoc_reject_data.bssid = macAddrToVec(bssid);
+	aidl_assoc_reject_data.statusCode = static_cast<StaIfaceStatusCode>(
+						wpa_s->assoc_status_code);
+	if (timed_out) {
+		aidl_assoc_reject_data.timedOut = true;
+	}
+#ifdef CONFIG_MBO
+	if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) {
+		reject_bss = wpa_s->current_bss;
+	} else {
+		reject_bss = wpa_bss_get_bssid(wpa_s, bssid);
+	}
+	if (reject_bss && assoc_resp_ie && assoc_resp_ie_len > 0) {
+		if (wpa_s->assoc_status_code ==
+			WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS) {
+			const u8 *rssi_rej;
+			rssi_rej = mbo_get_attr_from_ies(
+					assoc_resp_ie,
+					assoc_resp_ie_len,
+					OCE_ATTR_ID_RSSI_BASED_ASSOC_REJECT);
+			if (rssi_rej && rssi_rej[1] == 2) {
+				wpa_printf(MSG_INFO,
+					   "OCE: RSSI-based association rejection from "
+					   MACSTR " Delta RSSI: %u, Retry Delay: %u bss rssi: %d",
+					   MAC2STR(reject_bss->bssid),
+					   rssi_rej[2], rssi_rej[3], reject_bss->level);
+				aidl_assoc_reject_data.isOceRssiBasedAssocRejectAttrPresent = true;
+				aidl_assoc_reject_data.oceRssiBasedAssocRejectData.deltaRssi
+						= rssi_rej[2];
+				aidl_assoc_reject_data.oceRssiBasedAssocRejectData.retryDelayS
+						= rssi_rej[3];
+			}
+		} else if (wpa_s->assoc_status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
+			  || wpa_s->assoc_status_code == WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA) {
+			const u8 *assoc_disallowed;
+			assoc_disallowed = mbo_get_attr_from_ies(
+							assoc_resp_ie,
+							assoc_resp_ie_len,
+							MBO_ATTR_ID_ASSOC_DISALLOW);
+			if (assoc_disallowed && assoc_disallowed[1] == 1) {
+				wpa_printf(MSG_INFO,
+					"MBO: association disallowed indication from "
+					MACSTR " Reason: %d",
+					MAC2STR(reject_bss->bssid),
+					assoc_disallowed[2]);
+				aidl_assoc_reject_data.isMboAssocDisallowedReasonCodePresent = true;
+				aidl_assoc_reject_data.mboAssocDisallowedReason
+					= static_cast<MboAssocDisallowedReasonCode>(assoc_disallowed[2]);
+			}
+		}
+	}
+#endif /* CONFIG_MBO */
+
+	const std::function<
+			ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaIfaceCallback>)>
+			func = std::bind(
+			&ISupplicantStaIfaceCallback::onAssociationRejected,
+			std::placeholders::_1, aidl_assoc_reject_data);
+	callWithEachStaIfaceCallback(aidl_ifname, func);
+}
+
+void AidlManager::notifyAuthTimeout(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	const std::string ifname(wpa_s->ifname);
+	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
+		return;
+
+	const u8 *bssid = wpa_s->bssid;
+	if (is_zero_ether_addr(bssid)) {
+		bssid = wpa_s->pending_bssid;
+	}
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantStaIfaceCallback::onAuthenticationTimeout,
+		std::placeholders::_1, macAddrToVec(bssid)));
+}
+
+void AidlManager::notifyBssidChanged(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	const std::string ifname(wpa_s->ifname);
+	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
+		return;
+
+	// wpa_supplicant does not explicitly give us the reason for bssid
+	// change, but we figure that out from what is set out of |wpa_s->bssid|
+	// & |wpa_s->pending_bssid|.
+	const u8 *bssid;
+	BssidChangeReason reason;
+	if (is_zero_ether_addr(wpa_s->bssid) &&
+		!is_zero_ether_addr(wpa_s->pending_bssid)) {
+		bssid = wpa_s->pending_bssid;
+		reason = BssidChangeReason::ASSOC_START;
+	} else if (
+		!is_zero_ether_addr(wpa_s->bssid) &&
+		is_zero_ether_addr(wpa_s->pending_bssid)) {
+		bssid = wpa_s->bssid;
+		reason = BssidChangeReason::ASSOC_COMPLETE;
+	} else if (
+		is_zero_ether_addr(wpa_s->bssid) &&
+		is_zero_ether_addr(wpa_s->pending_bssid)) {
+		bssid = wpa_s->pending_bssid;
+		reason = BssidChangeReason::DISASSOC;
+	} else {
+		wpa_printf(MSG_ERROR, "Unknown bssid change reason");
+		return;
+	}
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname), std::bind(
+				   &ISupplicantStaIfaceCallback::onBssidChanged,
+				   std::placeholders::_1, reason, macAddrToVec(bssid)));
+}
+
+void AidlManager::notifyWpsEventFail(
+	struct wpa_supplicant *wpa_s, uint8_t *peer_macaddr, uint16_t config_error,
+	uint16_t error_indication)
+{
+	if (!wpa_s || !peer_macaddr)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return;
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantStaIfaceCallback::onWpsEventFail,
+		std::placeholders::_1, macAddrToVec(peer_macaddr),
+		static_cast<WpsConfigError>(
+			config_error),
+		static_cast<WpsErrorIndication>(
+			error_indication)));
+}
+
+void AidlManager::notifyWpsEventSuccess(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return;
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname), std::bind(
+				   &ISupplicantStaIfaceCallback::onWpsEventSuccess,
+				   std::placeholders::_1));
+}
+
+void AidlManager::notifyWpsEventPbcOverlap(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return;
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantStaIfaceCallback::onWpsEventPbcOverlap,
+		std::placeholders::_1));
+}
+
+void AidlManager::notifyP2pDeviceFound(
+	struct wpa_supplicant *wpa_s, const u8 *addr,
+	const struct p2p_peer_info *info, const u8 *peer_wfd_device_info,
+	u8 peer_wfd_device_info_len, const u8 *peer_wfd_r2_device_info,
+	u8 peer_wfd_r2_device_info_len)
+{
+	if (!wpa_s || !addr || !info)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	std::vector<uint8_t> aidl_peer_wfd_device_info(kWfdDeviceInfoLen);
+	if (peer_wfd_device_info) {
+		if (peer_wfd_device_info_len != kWfdDeviceInfoLen) {
+			wpa_printf(
+				MSG_ERROR, "Unexpected WFD device info len: %d",
+				peer_wfd_device_info_len);
+		} else {
+			os_memcpy(
+				aidl_peer_wfd_device_info.data(),
+				peer_wfd_device_info, kWfdDeviceInfoLen);
+		}
+	}
+
+	std::vector<uint8_t> aidl_peer_wfd_r2_device_info;
+	if (peer_wfd_r2_device_info) {
+		if (peer_wfd_r2_device_info_len != kWfdR2DeviceInfoLen) {
+			wpa_printf(
+				MSG_ERROR, "Unexpected WFD R2 device info len: %d",
+				peer_wfd_r2_device_info_len);
+			return;
+		} else {
+			std::copy(peer_wfd_r2_device_info,
+			    peer_wfd_r2_device_info + peer_wfd_r2_device_info_len,
+			    std::back_inserter(aidl_peer_wfd_r2_device_info));
+		}
+	}
+
+	std::vector<uint8_t> aidl_vendor_elems;
+	if (NULL != info->vendor_elems && wpabuf_len(info->vendor_elems) > 0) {
+		aidl_vendor_elems.reserve(wpabuf_len(info->vendor_elems));
+		std::copy(wpabuf_head_u8(info->vendor_elems),
+			wpabuf_head_u8(info->vendor_elems)
+				+ wpabuf_len(info->vendor_elems),
+			std::back_inserter(aidl_vendor_elems));
+	}
+
+	const std::function<
+		ndk::ScopedAStatus(std::shared_ptr<ISupplicantP2pIfaceCallback>)>
+		func = std::bind(
+		&ISupplicantP2pIfaceCallback::onDeviceFoundWithVendorElements,
+		std::placeholders::_1, macAddrToVec(addr), macAddrToVec(info->p2p_device_addr),
+		byteArrToVec(info->pri_dev_type, 8), misc_utils::charBufToString(info->device_name),
+		static_cast<WpsConfigMethods>(info->config_methods),
+		info->dev_capab, static_cast<P2pGroupCapabilityMask>(info->group_capab), aidl_peer_wfd_device_info,
+		aidl_peer_wfd_r2_device_info, aidl_vendor_elems);
+	callWithEachP2pIfaceCallback(wpa_s->ifname, func);
+}
+
+void AidlManager::notifyP2pDeviceLost(
+	struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr)
+{
+	if (!wpa_s || !p2p_device_addr)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname), std::bind(
+				   &ISupplicantP2pIfaceCallback::onDeviceLost,
+				   std::placeholders::_1, macAddrToVec(p2p_device_addr)));
+}
+
+void AidlManager::notifyP2pFindStopped(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname), std::bind(
+				   &ISupplicantP2pIfaceCallback::onFindStopped,
+				   std::placeholders::_1));
+}
+
+void AidlManager::notifyP2pGoNegReq(
+	struct wpa_supplicant *wpa_s, const u8 *src_addr, u16 dev_passwd_id,
+	u8 /* go_intent */)
+{
+	if (!wpa_s || !src_addr)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onGoNegotiationRequest,
+		std::placeholders::_1, macAddrToVec(src_addr),
+		static_cast<WpsDevPasswordId>(
+			dev_passwd_id)));
+}
+
+void AidlManager::notifyP2pGoNegCompleted(
+	struct wpa_supplicant *wpa_s, const struct p2p_go_neg_results *res)
+{
+	if (!wpa_s || !res)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onGoNegotiationCompleted,
+		std::placeholders::_1,
+		static_cast<P2pStatusCode>(
+			res->status)));
+}
+
+void AidlManager::notifyP2pGroupFormationFailure(
+	struct wpa_supplicant *wpa_s, const char *reason)
+{
+	if (!wpa_s || !reason)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onGroupFormationFailure,
+		std::placeholders::_1, reason));
+}
+
+void AidlManager::notifyP2pGroupStarted(
+	struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid,
+	int persistent, int client)
+{
+	if (!wpa_group_s || !wpa_group_s->parent || !ssid)
+		return;
+
+	// For group notifications, need to use the parent iface for callbacks.
+	struct wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
+	if (!wpa_s)
+		return;
+
+	uint32_t aidl_freq = wpa_group_s->current_bss
+				 ? wpa_group_s->current_bss->freq
+				 : wpa_group_s->assoc_freq;
+	std::vector<uint8_t> aidl_psk(32);
+	if (ssid->psk_set) {
+		aidl_psk.assign(ssid->psk, ssid->psk + 32);
+	}
+	bool aidl_is_go = (client == 0 ? true : false);
+	bool aidl_is_persistent = (persistent == 1 ? true : false);
+
+	// notify the group device again to ensure the framework knowing this device.
+	struct p2p_data *p2p = wpa_s->global->p2p;
+	struct p2p_device *dev = p2p_get_device(p2p, wpa_group_s->go_dev_addr);
+	if (NULL != dev) {
+		wpa_printf(MSG_DEBUG, "P2P: Update GO device on group started.");
+		p2p->cfg->dev_found(p2p->cfg->cb_ctx, wpa_group_s->go_dev_addr,
+				&dev->info, !(dev->flags & P2P_DEV_REPORTED_ONCE));
+		dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE;
+	}
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onGroupStarted,
+		std::placeholders::_1, misc_utils::charBufToString(wpa_group_s->ifname),
+		aidl_is_go, byteArrToVec(ssid->ssid, ssid->ssid_len),
+		aidl_freq, aidl_psk, misc_utils::charBufToString(ssid->passphrase),
+		macAddrToVec(wpa_group_s->go_dev_addr), aidl_is_persistent));
+}
+
+void AidlManager::notifyP2pGroupRemoved(
+	struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid,
+	const char *role)
+{
+	if (!wpa_group_s || !wpa_group_s->parent || !ssid || !role)
+		return;
+
+	// For group notifications, need to use the parent iface for callbacks.
+	struct wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
+	if (!wpa_s)
+		return;
+
+	bool aidl_is_go = (std::string(role) == "GO");
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onGroupRemoved,
+		std::placeholders::_1, misc_utils::charBufToString(wpa_group_s->ifname), aidl_is_go));
+}
+
+void AidlManager::notifyP2pInvitationReceived(
+	struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *go_dev_addr,
+	const u8 *bssid, int id, int op_freq)
+{
+	if (!wpa_s || !sa || !go_dev_addr || !bssid)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	int aidl_network_id;
+	if (id < 0) {
+		aidl_network_id = UINT32_MAX;
+	}
+	aidl_network_id = id;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onInvitationReceived,
+		std::placeholders::_1, macAddrToVec(sa), macAddrToVec(go_dev_addr),
+		macAddrToVec(bssid), aidl_network_id, op_freq));
+}
+
+void AidlManager::notifyP2pInvitationResult(
+	struct wpa_supplicant *wpa_s, int status, const u8 *bssid)
+{
+	if (!wpa_s)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onInvitationResult,
+		std::placeholders::_1, bssid ? macAddrToVec(bssid) : kZeroBssid,
+		static_cast<P2pStatusCode>(
+			status)));
+}
+
+void AidlManager::notifyP2pProvisionDiscovery(
+	struct wpa_supplicant *wpa_s, const u8 *dev_addr, int request,
+	enum p2p_prov_disc_status status, u16 config_methods,
+	unsigned int generated_pin)
+{
+	if (!wpa_s || !dev_addr)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	std::string aidl_generated_pin;
+	if (generated_pin > 0) {
+		aidl_generated_pin =
+			misc_utils::convertWpsPinToString(generated_pin);
+	}
+	bool aidl_is_request = (request == 1 ? true : false);
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onProvisionDiscoveryCompleted,
+		std::placeholders::_1, macAddrToVec(dev_addr), aidl_is_request,
+		static_cast<P2pProvDiscStatusCode>(status),
+		static_cast<WpsConfigMethods>(config_methods), aidl_generated_pin));
+}
+
+void AidlManager::notifyP2pSdResponse(
+	struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic,
+	const u8 *tlvs, size_t tlvs_len)
+{
+	if (!wpa_s || !sa || !tlvs)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onServiceDiscoveryResponse,
+		std::placeholders::_1, macAddrToVec(sa), update_indic,
+		byteArrToVec(tlvs, tlvs_len)));
+}
+
+void AidlManager::notifyApStaAuthorized(
+	struct wpa_supplicant *wpa_group_s, const u8 *sta, const u8 *p2p_dev_addr)
+{
+	if (!wpa_group_s || !wpa_group_s->parent || !sta)
+		return;
+	wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
+	if (!wpa_s)
+		return;
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onStaAuthorized,
+		std::placeholders::_1, macAddrToVec(sta),
+		p2p_dev_addr ? macAddrToVec(p2p_dev_addr) : kZeroBssid));
+}
+
+void AidlManager::notifyApStaDeauthorized(
+	struct wpa_supplicant *wpa_group_s, const u8 *sta, const u8 *p2p_dev_addr)
+{
+	if (!wpa_group_s || !wpa_group_s->parent || !sta)
+		return;
+	wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
+	if (!wpa_s)
+		return;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onStaDeauthorized,
+		std::placeholders::_1, macAddrToVec(sta),
+		p2p_dev_addr ? macAddrToVec(p2p_dev_addr) : kZeroBssid));
+}
+
+void AidlManager::notifyExtRadioWorkStart(
+	struct wpa_supplicant *wpa_s, uint32_t id)
+{
+	if (!wpa_s)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return;
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantStaIfaceCallback::onExtRadioWorkStart,
+		std::placeholders::_1, id));
+}
+
+void AidlManager::notifyExtRadioWorkTimeout(
+	struct wpa_supplicant *wpa_s, uint32_t id)
+{
+	if (!wpa_s)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return;
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantStaIfaceCallback::onExtRadioWorkTimeout,
+		std::placeholders::_1, id));
+}
+
+void AidlManager::notifyEapError(struct wpa_supplicant *wpa_s, int error_code)
+{
+	if (!wpa_s)
+		return;
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantStaIfaceCallback::onEapFailure,
+		std::placeholders::_1,
+		macAddrToVec(wpa_s->bssid), error_code));
+}
+
+/**
+ * Notify listener about a new DPP configuration received success event
+ *
+ * @param ifname Interface name
+ * @param config Configuration object
+ */
+void AidlManager::notifyDppConfigReceived(struct wpa_supplicant *wpa_s,
+		struct wpa_ssid *config)
+{
+	DppAkm securityAkm;
+	DppConnectionKeys aidl_keys{};
+	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
+
+	if ((config->key_mgmt & WPA_KEY_MGMT_SAE) &&
+			(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE)) {
+		securityAkm = DppAkm::SAE;
+	} else if (config->key_mgmt & WPA_KEY_MGMT_PSK) {
+			securityAkm = DppAkm::PSK;
+	} else if (config->key_mgmt & WPA_KEY_MGMT_DPP) {
+			securityAkm = DppAkm::DPP;
+	} else {
+		/* Unsupported AKM */
+		wpa_printf(MSG_ERROR, "DPP: Error: Unsupported AKM 0x%X",
+				config->key_mgmt);
+		notifyDppFailure(wpa_s, DppFailureCode::NOT_SUPPORTED);
+		return;
+	}
+
+	std::string passphrase = misc_utils::charBufToString(config->passphrase);
+	std::vector<uint8_t> aidl_ssid(
+		config->ssid,
+		config->ssid + config->ssid_len);
+
+	if (securityAkm == DppAkm::DPP) {
+		std::string connector_str = misc_utils::charBufToString(config->dpp_connector);
+		aidl_keys.connector = std::vector<uint8_t>(connector_str.begin(),
+			connector_str.end());
+		aidl_keys.cSign = byteArrToVec(config->dpp_csign, config->dpp_csign_len);
+		aidl_keys.netAccessKey = byteArrToVec(config->dpp_netaccesskey,
+			config->dpp_netaccesskey_len);
+	}
+
+	/* At this point, the network is already registered, notify about new
+	 * received configuration
+	 */
+	callWithEachStaIfaceCallback(aidl_ifname,
+			std::bind(
+					&ISupplicantStaIfaceCallback::onDppSuccessConfigReceived,
+					std::placeholders::_1, aidl_ssid, passphrase,
+					byteArrToVec(config->psk, 32), securityAkm,
+					aidl_keys));
+}
+
+/**
+ * Notify listener about a DPP configuration sent success event
+ *
+ * @param ifname Interface name
+ */
+void AidlManager::notifyDppConfigSent(struct wpa_supplicant *wpa_s)
+{
+	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
+
+	callWithEachStaIfaceCallback(aidl_ifname,
+			std::bind(&ISupplicantStaIfaceCallback::onDppSuccessConfigSent,
+					std::placeholders::_1));
+}
+
+/**
+ * Notify listener about a DPP failure event
+ *
+ * @param ifname Interface name
+ * @param code Status code
+ */
+void AidlManager::notifyDppFailure(struct wpa_supplicant *wpa_s,
+		android::hardware::wifi::supplicant::DppFailureCode code) {
+	notifyDppFailure(wpa_s, code, NULL, NULL, NULL, 0);
+}
+
+/**
+ * Notify listener about a DPP failure event
+ *
+ * @param ifname Interface name
+ * @param code Status code
+ */
+void AidlManager::notifyDppFailure(struct wpa_supplicant *wpa_s,
+		DppFailureCode code, const char *ssid, const char *channel_list,
+		unsigned short band_list[], int size) {
+	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
+	std::vector<char16_t> band_list_vec(band_list, band_list + size);
+
+	callWithEachStaIfaceCallback(aidl_ifname,
+			std::bind(&ISupplicantStaIfaceCallback::onDppFailure,
+					std::placeholders::_1, code, misc_utils::charBufToString(ssid),
+					misc_utils::charBufToString(channel_list), band_list_vec));
+}
+
+/**
+ * Notify listener about a DPP progress event
+ *
+ * @param ifname Interface name
+ * @param code Status code
+ */
+void AidlManager::notifyDppProgress(
+		struct wpa_supplicant *wpa_s, DppProgressCode code) {
+	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
+
+	callWithEachStaIfaceCallback(aidl_ifname,
+			std::bind(&ISupplicantStaIfaceCallback::onDppProgress,
+					std::placeholders::_1, code));
+}
+
+/**
+ * Notify listener about a DPP success event
+ *
+ * @param ifname Interface name
+ * @param code Status code
+ */
+void AidlManager::notifyDppSuccess(struct wpa_supplicant *wpa_s, DppEventType code)
+{
+	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
+
+	callWithEachStaIfaceCallback(aidl_ifname,
+			std::bind(&ISupplicantStaIfaceCallback::onDppSuccess,
+					std::placeholders::_1, code));
+}
+
+/**
+ * Notify listener about a PMK cache added event
+ *
+ * @param ifname Interface name
+ * @param entry PMK cache entry
+ */
+void AidlManager::notifyPmkCacheAdded(
+	struct wpa_supplicant *wpa_s, struct rsn_pmksa_cache_entry *pmksa_entry)
+{
+	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
+
+	// Serialize PmkCacheEntry into blob.
+	std::stringstream ss(
+		std::stringstream::in | std::stringstream::out | std::stringstream::binary);
+	misc_utils::serializePmkCacheEntry(ss, pmksa_entry);
+	std::vector<uint8_t> serializedEntry(
+		std::istreambuf_iterator<char>(ss), {});
+
+	const std::function<
+		ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaIfaceCallback>)>
+		func = std::bind(
+		&ISupplicantStaIfaceCallback::onPmkCacheAdded,
+		std::placeholders::_1, pmksa_entry->expiration, serializedEntry);
+	callWithEachStaIfaceCallback(aidl_ifname, func);
+}
+
+#ifdef CONFIG_WNM
+BssTmStatusCode convertSupplicantBssTmStatusToAidl(
+	enum bss_trans_mgmt_status_code bss_tm_status)
+{
+	switch (bss_tm_status) {
+		case WNM_BSS_TM_ACCEPT:
+			return BssTmStatusCode::ACCEPT;
+		case WNM_BSS_TM_REJECT_UNSPECIFIED:
+			return BssTmStatusCode::REJECT_UNSPECIFIED;
+		case WNM_BSS_TM_REJECT_INSUFFICIENT_BEACON:
+			return BssTmStatusCode::REJECT_INSUFFICIENT_BEACON;
+		case WNM_BSS_TM_REJECT_INSUFFICIENT_CAPABITY:
+			return BssTmStatusCode::REJECT_INSUFFICIENT_CAPABITY;
+		case WNM_BSS_TM_REJECT_UNDESIRED:
+			return BssTmStatusCode::REJECT_BSS_TERMINATION_UNDESIRED;
+		case WNM_BSS_TM_REJECT_DELAY_REQUEST:
+			return BssTmStatusCode::REJECT_BSS_TERMINATION_DELAY_REQUEST;
+		case WNM_BSS_TM_REJECT_STA_CANDIDATE_LIST_PROVIDED:
+			return BssTmStatusCode::REJECT_STA_CANDIDATE_LIST_PROVIDED;
+		case WNM_BSS_TM_REJECT_NO_SUITABLE_CANDIDATES:
+			return BssTmStatusCode::REJECT_NO_SUITABLE_CANDIDATES;
+		case WNM_BSS_TM_REJECT_LEAVING_ESS:
+			return BssTmStatusCode::REJECT_LEAVING_ESS;
+		default:
+			return BssTmStatusCode::REJECT_UNSPECIFIED;
+	}
+}
+
+BssTmDataFlagsMask setBssTmDataFlagsMask(struct wpa_supplicant *wpa_s)
+{
+	uint32_t flags = 0;
+
+	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_BSS_TERMINATION_INCLUDED) {
+		flags |= static_cast<uint32_t>(BssTmDataFlagsMask::WNM_MODE_BSS_TERMINATION_INCLUDED);
+	}
+	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_ESS_DISASSOC_IMMINENT) {
+		flags |= static_cast<uint32_t>(BssTmDataFlagsMask::WNM_MODE_ESS_DISASSOCIATION_IMMINENT);
+	}
+	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_DISASSOC_IMMINENT) {
+		flags |= static_cast<uint32_t>(BssTmDataFlagsMask::WNM_MODE_DISASSOCIATION_IMMINENT);
+	}
+	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_ABRIDGED) {
+		flags |= static_cast<uint32_t>(BssTmDataFlagsMask::WNM_MODE_ABRIDGED);
+	}
+	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_PREF_CAND_LIST_INCLUDED) {
+		flags |= static_cast<uint32_t>(BssTmDataFlagsMask::WNM_MODE_PREFERRED_CANDIDATE_LIST_INCLUDED);
+	}
+#ifdef CONFIG_MBO
+	if (wpa_s->wnm_mbo_assoc_retry_delay_present) {
+		flags |= static_cast<uint32_t>(BssTmDataFlagsMask::MBO_ASSOC_RETRY_DELAY_INCLUDED);
+	}
+	if (wpa_s->wnm_mbo_trans_reason_present) {
+		flags |= static_cast<uint32_t>(BssTmDataFlagsMask::MBO_TRANSITION_REASON_CODE_INCLUDED);
+	}
+	if (wpa_s->wnm_mbo_cell_pref_present) {
+		flags |= static_cast<uint32_t>(BssTmDataFlagsMask::MBO_CELLULAR_DATA_CONNECTION_PREFERENCE_INCLUDED);
+	}
+#endif
+	return static_cast<BssTmDataFlagsMask>(flags);
+}
+
+uint32_t getBssTmDataAssocRetryDelayMs(struct wpa_supplicant *wpa_s)
+{
+	uint32_t beacon_int;
+	uint32_t duration_ms = 0;
+
+	if (wpa_s->current_bss)
+		beacon_int = wpa_s->current_bss->beacon_int;
+	else
+		beacon_int = 100; /* best guess */
+
+	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_DISASSOC_IMMINENT) {
+		// number of tbtts to milliseconds
+		duration_ms = wpa_s->wnm_dissoc_timer * beacon_int * 128 / 125;
+	}
+	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_BSS_TERMINATION_INCLUDED) {
+		//wnm_bss_termination_duration contains 12 bytes of BSS
+		//termination duration subelement. Format of IE is
+		// Sub eid | Length | BSS termination TSF | Duration
+		//	1	 1		 8		2
+		// Duration indicates number of minutes for which BSS is not
+		// present.
+		duration_ms = WPA_GET_LE16(wpa_s->wnm_bss_termination_duration + 10);
+		// minutes to milliseconds
+		duration_ms = duration_ms * 60 * 1000;
+	}
+#ifdef CONFIG_MBO
+	if (wpa_s->wnm_mbo_assoc_retry_delay_present) {
+		// number of seconds to milliseconds
+		duration_ms = wpa_s->wnm_mbo_assoc_retry_delay_sec * 1000;
+	}
+#endif
+
+	return duration_ms;
+}
+#endif
+
+/**
+ * Notify listener about the status of BSS transition management
+ * request frame handling.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
+ * the network is present.
+ */
+void AidlManager::notifyBssTmStatus(struct wpa_supplicant *wpa_s)
+{
+#ifdef CONFIG_WNM
+	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
+	BssTmData aidl_bsstm_data{};
+
+	aidl_bsstm_data.status = convertSupplicantBssTmStatusToAidl(wpa_s->bss_tm_status);
+	aidl_bsstm_data.flags = setBssTmDataFlagsMask(wpa_s);
+	aidl_bsstm_data.assocRetryDelayMs = getBssTmDataAssocRetryDelayMs(wpa_s);
+#ifdef CONFIG_MBO
+	if (wpa_s->wnm_mbo_cell_pref_present) {
+		aidl_bsstm_data.mboCellPreference = static_cast
+			<MboCellularDataConnectionPrefValue>
+			(wpa_s->wnm_mbo_cell_preference);
+	}
+	if (wpa_s->wnm_mbo_trans_reason_present) {
+		aidl_bsstm_data.mboTransitionReason =
+			static_cast<MboTransitionReasonCode>
+			(wpa_s->wnm_mbo_transition_reason);
+	}
+#endif
+
+	const std::function<
+		ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaIfaceCallback>)>
+		func = std::bind(
+		&ISupplicantStaIfaceCallback::onBssTmHandlingDone,
+		std::placeholders::_1, aidl_bsstm_data);
+	callWithEachStaIfaceCallback(aidl_ifname, func);
+#endif
+}
+
+TransitionDisableIndication setTransitionDisableFlagsMask(u8 bitmap)
+{
+	uint32_t flags = 0;
+
+	if (bitmap & TRANSITION_DISABLE_WPA3_PERSONAL) {
+		flags |= static_cast<uint32_t>(TransitionDisableIndication::
+			USE_WPA3_PERSONAL);
+		bitmap &= ~TRANSITION_DISABLE_WPA3_PERSONAL;
+	}
+	if (bitmap & TRANSITION_DISABLE_SAE_PK) {
+		flags |= static_cast<uint32_t>(TransitionDisableIndication::
+			USE_SAE_PK);
+		bitmap &= ~TRANSITION_DISABLE_SAE_PK;
+	}
+	if (bitmap & TRANSITION_DISABLE_WPA3_ENTERPRISE) {
+		flags |= static_cast<uint32_t>(TransitionDisableIndication::
+			USE_WPA3_ENTERPRISE);
+		bitmap &= ~TRANSITION_DISABLE_WPA3_ENTERPRISE;
+	}
+	if (bitmap & TRANSITION_DISABLE_ENHANCED_OPEN) {
+		flags |= static_cast<uint32_t>(TransitionDisableIndication::
+			USE_ENHANCED_OPEN);
+		bitmap &= ~TRANSITION_DISABLE_ENHANCED_OPEN;
+	}
+
+	if (bitmap != 0) {
+		wpa_printf(MSG_WARNING, "Unhandled transition disable bit: 0x%x", bitmap);
+	}
+
+	return static_cast<TransitionDisableIndication>(flags);
+}
+
+void AidlManager::notifyTransitionDisable(struct wpa_supplicant *wpa_s,
+	struct wpa_ssid *ssid, u8 bitmap)
+{
+	TransitionDisableIndication flag = setTransitionDisableFlagsMask(bitmap);
+	const std::function<
+		ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaNetworkCallback>)>
+		func = std::bind(
+		&ISupplicantStaNetworkCallback::onTransitionDisable,
+		std::placeholders::_1, flag);
+
+	callWithEachStaNetworkCallback(
+		misc_utils::charBufToString(wpa_s->ifname), ssid->id, func);
+}
+
+void AidlManager::notifyNetworkNotFound(struct wpa_supplicant *wpa_s)
+{
+	std::vector<uint8_t> aidl_ssid;
+
+	if (!wpa_s->current_ssid) {
+		wpa_printf(MSG_ERROR, "Current network NULL. Drop WPA_EVENT_NETWORK_NOT_FOUND!");
+		return;
+	}
+
+	aidl_ssid.assign(
+			wpa_s->current_ssid->ssid,
+			wpa_s->current_ssid->ssid + wpa_s->current_ssid->ssid_len);
+
+	const std::function<
+		ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaIfaceCallback>)>
+		func = std::bind(
+		&ISupplicantStaIfaceCallback::onNetworkNotFound,
+		std::placeholders::_1, aidl_ssid);
+	callWithEachStaIfaceCallback(misc_utils::charBufToString(wpa_s->ifname), func);
+}
+
+void AidlManager::notifyFrequencyChanged(struct wpa_supplicant *wpa_group_s, int frequency)
+{
+	if (!wpa_group_s || !wpa_group_s->parent)
+		return;
+
+	// For group notifications, need to use the parent iface for callbacks.
+	struct wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
+	if (!wpa_s) {
+		wpa_printf(MSG_INFO, "Drop frequency changed event");
+		return;
+	}
+
+	const std::function<
+		ndk::ScopedAStatus(std::shared_ptr<ISupplicantP2pIfaceCallback>)>
+		func = std::bind(&ISupplicantP2pIfaceCallback::onGroupFrequencyChanged,
+		std::placeholders::_1, misc_utils::charBufToString(wpa_group_s->ifname),
+		frequency);
+	callWithEachP2pIfaceCallback(misc_utils::charBufToString(wpa_s->ifname), func);
+}
+
+void AidlManager::notifyCertification(struct wpa_supplicant *wpa_s,
+		int depth, const char *subject,
+		const char *altsubject[],
+		int num_altsubject,
+		const char *cert_hash,
+		const struct wpabuf *cert)
+{
+	if (!wpa_s->current_ssid) {
+		wpa_printf(MSG_ERROR, "Current network NULL. Drop Certification event!");
+		return;
+	}
+	struct wpa_ssid *current_ssid = wpa_s->current_ssid;
+	if (NULL == subject || NULL == cert_hash || NULL == cert) {
+		wpa_printf(MSG_ERROR,
+				"Incomplete certificate information. Drop Certification event!");
+		return;
+	}
+	if (!wpa_key_mgmt_wpa_ieee8021x(current_ssid->key_mgmt)) {
+		wpa_printf(MSG_ERROR, "Not 802.1x configuration, Drop Certification event!");
+		return;
+	}
+	if (current_ssid->eap.cert.ca_path || current_ssid->eap.cert.ca_cert) {
+		wpa_printf(MSG_DEBUG, "Already has CA certificate. Drop Certification event!");
+		return;
+	}
+
+	wpa_printf(MSG_DEBUG, "notifyCertification: depth=%d subject=%s hash=%s cert-size=%zu",
+			depth, subject, cert_hash, cert->used);
+	std::vector<uint8_t> subjectBlob(subject, subject + strlen(subject));
+	std::vector<uint8_t> certHashBlob(cert_hash, cert_hash + strlen(cert_hash));
+	std::vector<uint8_t> certBlob(cert->buf, cert->buf + cert->used);
+
+	const std::function<
+		ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaNetworkCallback>)>
+		func = std::bind(
+		&ISupplicantStaNetworkCallback::onServerCertificateAvailable,
+		std::placeholders::_1,
+		depth,
+		subjectBlob,
+		certHashBlob,
+		certBlob);
+
+	callWithEachStaNetworkCallback(
+		misc_utils::charBufToString(wpa_s->ifname), current_ssid->id, func);
+}
+
+void AidlManager::notifyAuxiliaryEvent(struct wpa_supplicant *wpa_s,
+	AuxiliarySupplicantEventCode event_code, const char *reason_string)
+{
+	if (!wpa_s)
+		return;
+
+	const std::function<
+		ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaIfaceCallback>)>
+		func = std::bind(
+		&ISupplicantStaIfaceCallback::onAuxiliarySupplicantEvent,
+		std::placeholders::_1, event_code, macAddrToVec(wpa_s->bssid),
+		misc_utils::charBufToString(reason_string));
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname), func);
+}
+
+/**
+ * Retrieve the |ISupplicantP2pIface| aidl object reference using the provided
+ * ifname.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param iface_object Aidl reference corresponding to the iface.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int AidlManager::getP2pIfaceAidlObjectByIfname(
+	const std::string &ifname, std::shared_ptr<ISupplicantP2pIface> *iface_object)
+{
+	if (ifname.empty() || !iface_object)
+		return 1;
+
+	auto iface_object_iter = p2p_iface_object_map_.find(ifname);
+	if (iface_object_iter == p2p_iface_object_map_.end())
+		return 1;
+
+	*iface_object = iface_object_iter->second;
+	return 0;
+}
+
+/**
+ * Retrieve the |ISupplicantStaIface| aidl object reference using the provided
+ * ifname.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param iface_object Aidl reference corresponding to the iface.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int AidlManager::getStaIfaceAidlObjectByIfname(
+	const std::string &ifname, std::shared_ptr<ISupplicantStaIface> *iface_object)
+{
+	if (ifname.empty() || !iface_object)
+		return 1;
+
+	auto iface_object_iter = sta_iface_object_map_.find(ifname);
+	if (iface_object_iter == sta_iface_object_map_.end())
+		return 1;
+
+	*iface_object = iface_object_iter->second;
+	return 0;
+}
+
+/**
+ * Retrieve the |ISupplicantP2pNetwork| aidl object reference using the provided
+ * ifname and network_id.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param network_id ID of the corresponding network.
+ * @param network_object Aidl reference corresponding to the network.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int AidlManager::getP2pNetworkAidlObjectByIfnameAndNetworkId(
+	const std::string &ifname, int network_id,
+	std::shared_ptr<ISupplicantP2pNetwork> *network_object)
+{
+	if (ifname.empty() || network_id < 0 || !network_object)
+		return 1;
+
+	// Generate the key to be used to lookup the network.
+	const std::string network_key =
+		getNetworkObjectMapKey(ifname, network_id);
+
+	auto network_object_iter = p2p_network_object_map_.find(network_key);
+	if (network_object_iter == p2p_network_object_map_.end())
+		return 1;
+
+	*network_object = network_object_iter->second;
+	return 0;
+}
+
+/**
+ * Retrieve the |ISupplicantStaNetwork| aidl object reference using the provided
+ * ifname and network_id.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param network_id ID of the corresponding network.
+ * @param network_object Aidl reference corresponding to the network.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int AidlManager::getStaNetworkAidlObjectByIfnameAndNetworkId(
+	const std::string &ifname, int network_id,
+	std::shared_ptr<ISupplicantStaNetwork> *network_object)
+{
+	if (ifname.empty() || network_id < 0 || !network_object)
+		return 1;
+
+	// Generate the key to be used to lookup the network.
+	const std::string network_key =
+		getNetworkObjectMapKey(ifname, network_id);
+
+	auto network_object_iter = sta_network_object_map_.find(network_key);
+	if (network_object_iter == sta_network_object_map_.end())
+		return 1;
+
+	*network_object = network_object_iter->second;
+	return 0;
+}
+
+/**
+ * Add a new |ISupplicantCallback| aidl object reference to our
+ * global callback list.
+ *
+ * @param callback Aidl reference of the |ISupplicantCallback| object.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int AidlManager::addSupplicantCallbackAidlObject(
+	const std::shared_ptr<ISupplicantCallback> &callback)
+{
+	return registerForDeathAndAddCallbackAidlObjectToList<
+		ISupplicantCallback>(
+		death_notifier_, callback, supplicant_callbacks_);
+}
+
+/**
+ * Add a new iface callback aidl object reference to our
+ * interface callback list.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param callback Aidl reference of the callback object.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int AidlManager::addP2pIfaceCallbackAidlObject(
+	const std::string &ifname,
+	const std::shared_ptr<ISupplicantP2pIfaceCallback> &callback)
+{
+	return addIfaceCallbackAidlObjectToMap(
+		death_notifier_, ifname, callback, p2p_iface_callbacks_map_);
+}
+
+/**
+ * Add a new iface callback aidl object reference to our
+ * interface callback list.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param callback Aidl reference of the callback object.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int AidlManager::addStaIfaceCallbackAidlObject(
+	const std::string &ifname,
+	const std::shared_ptr<ISupplicantStaIfaceCallback> &callback)
+{
+	return addIfaceCallbackAidlObjectToMap(
+		death_notifier_, ifname, callback, sta_iface_callbacks_map_);
+}
+
+/**
+ * Add a new network callback aidl object reference to our network callback
+ * list.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param network_id ID of the corresponding network.
+ * @param callback Aidl reference of the callback object.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int AidlManager::addStaNetworkCallbackAidlObject(
+	const std::string &ifname, int network_id,
+	const std::shared_ptr<ISupplicantStaNetworkCallback> &callback)
+{
+	return addNetworkCallbackAidlObjectToMap(
+		death_notifier_, ifname, network_id, callback,
+		sta_network_callbacks_map_);
+}
+
+/**
+ * Finds the correct |wpa_supplicant| object for P2P notifications
+ *
+ * @param wpa_s the |wpa_supplicant| that triggered the P2P event.
+ * @return appropriate |wpa_supplicant| object or NULL if not found.
+ */
+struct wpa_supplicant *AidlManager::getTargetP2pIfaceForGroup(
+		struct wpa_supplicant *wpa_group_s)
+{
+	if (!wpa_group_s || !wpa_group_s->parent)
+		return NULL;
+
+	struct wpa_supplicant *target_wpa_s = wpa_group_s->parent;
+
+	// check wpa_supplicant object is a p2p device interface
+	if ((wpa_group_s == wpa_group_s->p2pdev) && wpa_group_s->p2p_mgmt) {
+		if (p2p_iface_object_map_.find(wpa_group_s->ifname) !=
+			p2p_iface_object_map_.end())
+			return wpa_group_s;
+	}
+
+	if (p2p_iface_object_map_.find(target_wpa_s->ifname) !=
+		p2p_iface_object_map_.end())
+		return target_wpa_s;
+
+	// try P2P device if available
+	if (!target_wpa_s->p2pdev || !target_wpa_s->p2pdev->p2p_mgmt)
+		return NULL;
+
+	target_wpa_s = target_wpa_s->p2pdev;
+	if (p2p_iface_object_map_.find(target_wpa_s->ifname) !=
+		p2p_iface_object_map_.end())
+		return target_wpa_s;
+
+	return NULL;
+}
+
+/**
+ * Removes the provided |ISupplicantCallback| aidl object reference
+ * from our global callback list.
+ *
+ * @param callback Aidl reference of the |ISupplicantCallback| object.
+ */
+void AidlManager::removeSupplicantCallbackAidlObject(
+	const std::shared_ptr<ISupplicantCallback> &callback)
+{
+	supplicant_callbacks_.erase(
+		std::remove(
+		supplicant_callbacks_.begin(), supplicant_callbacks_.end(),
+		callback),
+		supplicant_callbacks_.end());
+}
+
+/**
+ * Removes the provided iface callback aidl object reference from
+ * our interface callback list.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param callback Aidl reference of the callback object.
+ */
+void AidlManager::removeP2pIfaceCallbackAidlObject(
+	const std::string &ifname,
+	const std::shared_ptr<ISupplicantP2pIfaceCallback> &callback)
+{
+	return removeIfaceCallbackAidlObjectFromMap(
+		ifname, callback, p2p_iface_callbacks_map_);
+}
+
+/**
+ * Removes the provided iface callback aidl object reference from
+ * our interface callback list.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param callback Aidl reference of the callback object.
+ */
+void AidlManager::removeStaIfaceCallbackAidlObject(
+	const std::string &ifname,
+	const std::shared_ptr<ISupplicantStaIfaceCallback> &callback)
+{
+	return removeIfaceCallbackAidlObjectFromMap(
+		ifname, callback, sta_iface_callbacks_map_);
+}
+
+/**
+ * Removes the provided network callback aidl object reference from
+ * our network callback list.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param network_id ID of the corresponding network.
+ * @param callback Aidl reference of the callback object.
+ */
+void AidlManager::removeStaNetworkCallbackAidlObject(
+	const std::string &ifname, int network_id,
+	const std::shared_ptr<ISupplicantStaNetworkCallback> &callback)
+{
+	return removeNetworkCallbackAidlObjectFromMap(
+		ifname, network_id, callback, sta_network_callbacks_map_);
+}
+
+/**
+ * Helper function to invoke the provided callback method on all the
+ * registered |ISupplicantCallback| callback aidl objects.
+ *
+ * @param method Pointer to the required aidl method from
+ * |ISupplicantCallback|.
+ */
+void AidlManager::callWithEachSupplicantCallback(
+	const std::function<ndk::ScopedAStatus(std::shared_ptr<ISupplicantCallback>)> &method)
+{
+	for (const auto &callback : supplicant_callbacks_) {
+		if (!method(callback).isOk()) {
+			wpa_printf(MSG_ERROR, "Failed to invoke AIDL callback");
+		}
+	}
+}
+
+/**
+ * Helper function to invoke the provided callback method on all the
+ * registered iface callback aidl objects for the specified
+ * |ifname|.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param method Pointer to the required aidl method from
+ * |ISupplicantIfaceCallback|.
+ */
+void AidlManager::callWithEachP2pIfaceCallback(
+	const std::string &ifname,
+	const std::function<ndk::ScopedAStatus(std::shared_ptr<ISupplicantP2pIfaceCallback>)>
+	&method)
+{
+	callWithEachIfaceCallback(ifname, method, p2p_iface_callbacks_map_);
+}
+
+/**
+ * Helper function to invoke the provided callback method on all the
+ * registered interface callback aidl objects for the specified
+ * |ifname|.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param method Pointer to the required aidl method from
+ * |ISupplicantIfaceCallback|.
+ */
+void AidlManager::callWithEachStaIfaceCallback(
+	const std::string &ifname,
+	const std::function<ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaIfaceCallback>)>
+	&method)
+{
+	callWithEachIfaceCallback(ifname, method, sta_iface_callbacks_map_);
+}
+
+/**
+ * Helper function to invoke the provided callback method on all the
+ * registered network callback aidl objects for the specified
+ * |ifname| & |network_id|.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param network_id ID of the corresponding network.
+ * @param method Pointer to the required aidl method from 
+ * |ISupplicantStaNetworkCallback|.
+ */
+void AidlManager::callWithEachStaNetworkCallback(
+	const std::string &ifname, int network_id,
+	const std::function<
+	ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaNetworkCallback>)> &method)
+{
+	callWithEachNetworkCallback(
+		ifname, network_id, method, sta_network_callbacks_map_);
+}
+
+void AidlManager::notifyQosPolicyReset(
+	struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname), std::bind(
+			&ISupplicantStaIfaceCallback::onQosPolicyReset,
+			std::placeholders::_1));
+}
+
+void AidlManager::notifyQosPolicyRequest(struct wpa_supplicant *wpa_s,
+	struct dscp_policy_data *policies, int num_policies)
+{
+	if (!wpa_s || !policies)
+		return;
+
+	std::vector<QosPolicyData> qosPolicyData;
+	uint32_t mask = 0;
+
+	for (int num = 0; num < num_policies; num++) {
+		QosPolicyData policy;
+		QosPolicyClassifierParams classifier_params;
+		QosPolicyClassifierParamsMask classifier_param_mask;
+		bool ip_ver4 = false;
+
+		if (policies[num].type4_param.ip_version == 4) {
+			classifier_params.ipVersion = IpVersion::VERSION_4;
+			ip_ver4 = true;
+		} else {
+			classifier_params.ipVersion = IpVersion::VERSION_6;
+			ip_ver4 = false;
+		}
+
+		// classifier_mask parameters are defined in IEEE Std 802.11-2020, Table 9-170
+		if (policies[num].type4_param.classifier_mask & BIT(1)) {
+			mask |= static_cast<uint32_t>(QosPolicyClassifierParamsMask::SRC_IP);
+			if (ip_ver4) {
+				classifier_params.srcIp =
+					byteArrToVec((const uint8_t *)
+						&policies[num].type4_param.ip_params.v4.src_ip, 4);
+			} else {
+				classifier_params.srcIp =
+					byteArrToVec((const uint8_t *)
+						&policies[num].type4_param.ip_params.v6.src_ip, 16);
+			}
+		}
+		if (policies[num].type4_param.classifier_mask & BIT(2)) {
+			mask |= static_cast<uint32_t>(QosPolicyClassifierParamsMask::DST_IP);
+			if (ip_ver4){
+				classifier_params.dstIp =
+					byteArrToVec((const uint8_t *)
+						&policies[num].type4_param.ip_params.v4.dst_ip, 4);
+			} else {
+				classifier_params.dstIp =
+					byteArrToVec((const uint8_t *)
+						&policies[num].type4_param.ip_params.v6.dst_ip, 16);
+			}
+		}
+		if (policies[num].type4_param.classifier_mask & BIT(3)) {
+			mask |= static_cast<uint32_t>(QosPolicyClassifierParamsMask::SRC_PORT);
+			if (ip_ver4){
+				classifier_params.srcPort =
+					policies[num].type4_param.ip_params.v4.src_port;
+			} else {
+				classifier_params.srcPort =
+					policies[num].type4_param.ip_params.v6.src_port;
+			}
+		}
+
+		if (policies[num].type4_param.classifier_mask & BIT(4)) {
+			mask |= static_cast<uint32_t>(
+				QosPolicyClassifierParamsMask::DST_PORT_RANGE);
+			if (ip_ver4) {
+				classifier_params.dstPortRange.startPort =
+					policies[num].type4_param.ip_params.v4.dst_port;
+				classifier_params.dstPortRange.endPort =
+					policies[num].type4_param.ip_params.v4.dst_port;
+			} else {
+				classifier_params.dstPortRange.startPort =
+					policies[num].type4_param.ip_params.v6.dst_port;
+				classifier_params.dstPortRange.endPort =
+					policies[num].type4_param.ip_params.v6.dst_port;
+			}
+		} else if (policies[num].port_range_info) {
+			mask |= static_cast<uint32_t>(
+				QosPolicyClassifierParamsMask::DST_PORT_RANGE);
+			classifier_params.dstPortRange.startPort = policies[num].start_port;
+			classifier_params.dstPortRange.endPort = policies[num].end_port;
+		}
+		if (policies[num].type4_param.classifier_mask & BIT(6)) {
+			mask |= static_cast<uint32_t>(
+				QosPolicyClassifierParamsMask::PROTOCOL_NEXT_HEADER);
+			if (ip_ver4) {
+				classifier_params.protocolNextHdr = static_cast<ProtocolNextHeader>(
+					policies[num].type4_param.ip_params.v4.protocol);
+			} else {
+				classifier_params.protocolNextHdr = static_cast<ProtocolNextHeader>(
+					policies[num].type4_param.ip_params.v6.next_header);
+			}
+		}
+		if (policies[num].type4_param.classifier_mask & BIT(7)) {
+			mask |= static_cast<uint32_t>(QosPolicyClassifierParamsMask::FLOW_LABEL);
+			classifier_params.flowLabelIpv6 =
+				byteArrToVec(policies[num].type4_param.ip_params.v6.flow_label, 3);
+		}
+		if (policies[num].domain_name_len != 0) {
+			mask |= static_cast<uint32_t>(QosPolicyClassifierParamsMask::DOMAIN_NAME);
+			classifier_params.domainName =
+				misc_utils::charBufToString(
+					reinterpret_cast<const char *>(policies[num].domain_name));
+		}
+
+		classifier_params.classifierParamMask =
+			static_cast<QosPolicyClassifierParamsMask>(mask);
+		policy.policyId = policies[num].policy_id;
+		policy.requestType = static_cast<QosPolicyRequestType>(policies[num].req_type);
+		policy.dscp = policies[num].dscp;
+		policy.classifierParams = classifier_params;
+
+		qosPolicyData.push_back(policy);
+	}
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname), std::bind(
+			&ISupplicantStaIfaceCallback::onQosPolicyRequest,
+			std::placeholders::_1, wpa_s->dscp_req_dialog_token, qosPolicyData));
+}
+
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/aidl_manager.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/aidl_manager.h
new file mode 100755
index 0000000..1ed6899
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/aidl_manager.h
@@ -0,0 +1,715 @@
+/*
+ * WPA Supplicant - Manager for Aidl interface objects
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef WPA_SUPPLICANT_AIDL_AIDL_MANAGER_H
+#define WPA_SUPPLICANT_AIDL_AIDL_MANAGER_H
+
+#include <map>
+#include <string>
+
+#include <aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.h>
+#include <aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.h>
+#include <aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.h>
+
+#include "p2p_iface.h"
+#include "p2p_network.h"
+#include "rsn_supp/pmksa_cache.h"
+#include "sta_iface.h"
+#include "sta_network.h"
+#include "supplicant.h"
+
+extern "C"
+{
+#include "utils/common.h"
+#include "utils/includes.h"
+#include "wpa_supplicant_i.h"
+#include "driver_i.h"
+}
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+
+/**
+ * AidlManager is responsible for managing the lifetime of all
+ * aidl objects created by wpa_supplicant. This is a singleton
+ * class which is created by the supplicant core and can be used
+ * to get references to the aidl objects.
+ */
+class AidlManager
+{
+public:
+	static AidlManager *getInstance();
+	static void destroyInstance();
+
+	// Methods called from wpa_supplicant core.
+	int registerAidlService(struct wpa_global *global);
+	int registerInterface(struct wpa_supplicant *wpa_s);
+	int unregisterInterface(struct wpa_supplicant *wpa_s);
+	int registerNetwork(
+		struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
+	int unregisterNetwork(
+		struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
+	int notifyStateChange(struct wpa_supplicant *wpa_s);
+	int notifyNetworkRequest(
+		struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, int type,
+		const char *param);
+	void notifyAnqpQueryDone(
+		struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
+		const struct wpa_bss_anqp *anqp);
+	void notifyHs20IconQueryDone(
+		struct wpa_supplicant *wpa_s, const u8 *bssid,
+		const char *file_name, const u8 *image, u32 image_length);
+	void notifyHs20RxSubscriptionRemediation(
+		struct wpa_supplicant *wpa_s, const char *url, u8 osu_method);
+	void notifyHs20RxDeauthImminentNotice(
+		struct wpa_supplicant *wpa_s, u8 code, u16 reauth_delay,
+		const char *url);
+	void notifyHs20RxTermsAndConditionsAcceptance(
+			struct wpa_supplicant *wpa_s, const char *url);
+	void notifyDisconnectReason(struct wpa_supplicant *wpa_s);
+	void notifyAssocReject(struct wpa_supplicant *wpa_s, const u8 *bssid,
+		u8 timed_out, const u8 *assoc_resp_ie, size_t assoc_resp_ie_len);
+	void notifyAuthTimeout(struct wpa_supplicant *wpa_s);
+	void notifyBssidChanged(struct wpa_supplicant *wpa_s);
+	void notifyWpsEventFail(
+		struct wpa_supplicant *wpa_s, uint8_t *peer_macaddr,
+		uint16_t config_error, uint16_t error_indication);
+	void notifyWpsEventSuccess(struct wpa_supplicant *wpa_s);
+	void notifyWpsEventPbcOverlap(struct wpa_supplicant *wpa_s);
+	void notifyP2pDeviceFound(
+		struct wpa_supplicant *wpa_s, const u8 *addr,
+		const struct p2p_peer_info *info, const u8 *peer_wfd_device_info,
+		u8 peer_wfd_device_info_len, const u8 *peer_wfd_r2_device_info,
+		u8 peer_wfd_r2_device_info_len);
+	void notifyP2pDeviceLost(
+		struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr);
+	void notifyP2pFindStopped(struct wpa_supplicant *wpa_s);
+	void notifyP2pGoNegReq(
+		struct wpa_supplicant *wpa_s, const u8 *src_addr, u16 dev_passwd_id,
+		u8 go_intent);
+	void notifyP2pGoNegCompleted(
+		struct wpa_supplicant *wpa_s, const struct p2p_go_neg_results *res);
+	void notifyP2pGroupFormationFailure(
+		struct wpa_supplicant *wpa_s, const char *reason);
+	void notifyP2pGroupStarted(
+		struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid,
+		int persistent, int client);
+	void notifyP2pGroupRemoved(
+		struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid,
+		const char *role);
+	void notifyP2pInvitationReceived(
+		struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *go_dev_addr,
+		const u8 *bssid, int id, int op_freq);
+	void notifyP2pInvitationResult(
+		struct wpa_supplicant *wpa_s, int status, const u8 *bssid);
+	void notifyP2pProvisionDiscovery(
+		struct wpa_supplicant *wpa_s, const u8 *dev_addr, int request,
+		enum p2p_prov_disc_status status, u16 config_methods,
+		unsigned int generated_pin);
+	void notifyP2pSdResponse(
+		struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic,
+		const u8 *tlvs, size_t tlvs_len);
+	void notifyApStaAuthorized(
+		struct wpa_supplicant *wpa_s, const u8 *sta,
+		const u8 *p2p_dev_addr);
+	void notifyApStaDeauthorized(
+		struct wpa_supplicant *wpa_s, const u8 *sta,
+		const u8 *p2p_dev_addr);
+	void notifyEapError(struct wpa_supplicant *wpa_s, int error_code);
+	void notifyDppConfigReceived(struct wpa_supplicant *wpa_s,
+			struct wpa_ssid *config);
+	void notifyDppConfigSent(struct wpa_supplicant *wpa_s);
+	void notifyDppSuccess(struct wpa_supplicant *wpa_s, DppEventType code);
+	void notifyDppFailure(struct wpa_supplicant *wpa_s,
+			DppFailureCode code);
+	void notifyDppFailure(struct wpa_supplicant *wpa_s,
+			DppFailureCode code,
+			const char *ssid, const char *channel_list, unsigned short band_list[],
+			int size);
+	void notifyDppProgress(struct wpa_supplicant *wpa_s,
+			DppProgressCode code);
+	void notifyPmkCacheAdded(struct wpa_supplicant *wpa_s,
+			struct rsn_pmksa_cache_entry *pmksa_entry);
+	void notifyBssTmStatus(struct wpa_supplicant *wpa_s);
+	void notifyTransitionDisable(struct wpa_supplicant *wpa_s,
+			struct wpa_ssid *ssid,
+			u8 bitmap);
+	void notifyNetworkNotFound(struct wpa_supplicant *wpa_s);
+	void notifyFrequencyChanged(struct wpa_supplicant *wpa_s, int frequency);
+	void notifyCertification(struct wpa_supplicant *wpa_s,
+			int depth, const char *subject,
+			const char *altsubject[],
+			int num_altsubject,
+			const char *cert_hash,
+			const struct wpabuf *cert);
+	void notifyAuxiliaryEvent(struct wpa_supplicant *wpa_s,
+			AuxiliarySupplicantEventCode event_code,
+			const char *reason_string);
+	void notifyQosPolicyReset(struct wpa_supplicant *wpa_s);
+	void notifyQosPolicyRequest(struct wpa_supplicant *wpa_s,
+			struct dscp_policy_data *policies,
+			int num_policies);
+
+	// Methods called from aidl objects.
+	void notifyExtRadioWorkStart(struct wpa_supplicant *wpa_s, uint32_t id);
+	void notifyExtRadioWorkTimeout(
+		struct wpa_supplicant *wpa_s, uint32_t id);
+
+	int getP2pIfaceAidlObjectByIfname(
+		const std::string &ifname,
+		std::shared_ptr<ISupplicantP2pIface> *iface_object);
+	int getStaIfaceAidlObjectByIfname(
+		const std::string &ifname,
+		std::shared_ptr<ISupplicantStaIface> *iface_object);
+	int getP2pNetworkAidlObjectByIfnameAndNetworkId(
+		const std::string &ifname, int network_id,
+		std::shared_ptr<ISupplicantP2pNetwork> *network_object);
+	int getStaNetworkAidlObjectByIfnameAndNetworkId(
+		const std::string &ifname, int network_id,
+		std::shared_ptr<ISupplicantStaNetwork> *network_object);
+	int addSupplicantCallbackAidlObject(
+		const std::shared_ptr<ISupplicantCallback> &callback);
+	int addP2pIfaceCallbackAidlObject(
+		const std::string &ifname,
+		const std::shared_ptr<ISupplicantP2pIfaceCallback> &callback);
+	int addStaIfaceCallbackAidlObject(
+		const std::string &ifname,
+		const std::shared_ptr<ISupplicantStaIfaceCallback> &callback);
+	int addStaNetworkCallbackAidlObject(
+		const std::string &ifname, int network_id,
+		const std::shared_ptr<ISupplicantStaNetworkCallback> &callback);
+
+private:
+	AidlManager() = default;
+	~AidlManager() = default;
+	AidlManager(const AidlManager &) = default;
+	AidlManager &operator=(const AidlManager &) = default;
+
+	struct wpa_supplicant *getTargetP2pIfaceForGroup(
+		struct wpa_supplicant *wpa_s);
+	void removeSupplicantCallbackAidlObject(
+		const std::shared_ptr<ISupplicantCallback> &callback);
+	void removeP2pIfaceCallbackAidlObject(
+		const std::string &ifname,
+		const std::shared_ptr<ISupplicantP2pIfaceCallback> &callback);
+	void removeStaIfaceCallbackAidlObject(
+		const std::string &ifname,
+		const std::shared_ptr<ISupplicantStaIfaceCallback> &callback);
+	void removeStaNetworkCallbackAidlObject(
+		const std::string &ifname, int network_id,
+		const std::shared_ptr<ISupplicantStaNetworkCallback> &callback);
+
+	void callWithEachSupplicantCallback(
+		const std::function<ndk::ScopedAStatus(
+		std::shared_ptr<ISupplicantCallback>)> &method);
+	void callWithEachP2pIfaceCallback(
+		const std::string &ifname,
+		const std::function<ndk::ScopedAStatus(
+		std::shared_ptr<ISupplicantP2pIfaceCallback>)> &method);
+	void callWithEachStaIfaceCallback(
+		const std::string &ifname,
+		const std::function<ndk::ScopedAStatus(
+		std::shared_ptr<ISupplicantStaIfaceCallback>)> &method);
+	void callWithEachStaNetworkCallback(
+		const std::string &ifname, int network_id,
+		const std::function<::ndk::ScopedAStatus(
+		std::shared_ptr<ISupplicantStaNetworkCallback>)> &method);
+
+	// Singleton instance of this class.
+	static AidlManager *instance_;
+	// Death notifier.
+	AIBinder_DeathRecipient* death_notifier_;
+	// The main aidl service object.
+	std::shared_ptr<Supplicant> supplicant_object_;
+	// Map of all the P2P interface specific aidl objects controlled by
+	// wpa_supplicant. This map is keyed in by the corresponding
+	// |ifname|.
+	std::map<const std::string, std::shared_ptr<P2pIface>>
+		p2p_iface_object_map_;
+	// Map of all the STA interface specific aidl objects controlled by
+	// wpa_supplicant. This map is keyed in by the corresponding
+	// |ifname|.
+	std::map<const std::string, std::shared_ptr<StaIface>>
+		sta_iface_object_map_;
+	// Map of all the P2P network specific aidl objects controlled by
+	// wpa_supplicant. This map is keyed in by the corresponding
+	// |ifname| & |network_id|.
+	std::map<const std::string, std::shared_ptr<P2pNetwork>>
+		p2p_network_object_map_;
+	// Map of all the STA network specific aidl objects controlled by
+	// wpa_supplicant. This map is keyed in by the corresponding
+	// |ifname| & |network_id|.
+	std::map<const std::string, std::shared_ptr<StaNetwork>>
+		sta_network_object_map_;
+
+	// Callbacks registered for the main aidl service object.
+	std::vector<std::shared_ptr<ISupplicantCallback>> supplicant_callbacks_;
+	// Map of all the callbacks registered for P2P interface specific
+	// aidl objects controlled by wpa_supplicant.  This map is keyed in by
+	// the corresponding |ifname|.
+	std::map<
+		const std::string,
+		std::vector<std::shared_ptr<ISupplicantP2pIfaceCallback>>>
+		p2p_iface_callbacks_map_;
+	// Map of all the callbacks registered for STA interface specific
+	// aidl objects controlled by wpa_supplicant.  This map is keyed in by
+	// the corresponding |ifname|.
+	std::map<
+		const std::string,
+		std::vector<std::shared_ptr<ISupplicantStaIfaceCallback>>>
+		sta_iface_callbacks_map_;
+	// Map of all the callbacks registered for STA network specific
+	// aidl objects controlled by wpa_supplicant.  This map is keyed in by
+	// the corresponding |ifname| & |network_id|.
+	std::map<
+		const std::string,
+		std::vector<std::shared_ptr<ISupplicantStaNetworkCallback>>>
+		sta_network_callbacks_map_;
+};
+
+// The aidl interface uses some values which are the same as internal ones to
+// avoid nasty runtime conversion functions. So, adding compile time asserts
+// to guard against any internal changes breaking the aidl interface.
+static_assert(
+	static_cast<uint32_t>(DebugLevel::EXCESSIVE) == MSG_EXCESSIVE,
+	"Debug level value mismatch");
+static_assert(
+	static_cast<uint32_t>(DebugLevel::ERROR) == MSG_ERROR,
+	"Debug level value mismatch");
+
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::NONE) ==
+	WPA_KEY_MGMT_NONE,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::WPA_PSK) ==
+	WPA_KEY_MGMT_PSK,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::WPA_EAP) ==
+	WPA_KEY_MGMT_IEEE8021X,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::IEEE8021X) ==
+	WPA_KEY_MGMT_IEEE8021X_NO_WPA,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::FT_EAP) ==
+	WPA_KEY_MGMT_FT_IEEE8021X,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::FT_PSK) ==
+	WPA_KEY_MGMT_FT_PSK,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::OSEN) ==
+	WPA_KEY_MGMT_OSEN,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::SAE) ==
+	WPA_KEY_MGMT_SAE,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::SUITE_B_192) ==
+	WPA_KEY_MGMT_IEEE8021X_SUITE_B_192,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::OWE) ==
+	WPA_KEY_MGMT_OWE,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::WPA_PSK_SHA256) ==
+	WPA_KEY_MGMT_PSK_SHA256,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::WPA_EAP_SHA256) ==
+	WPA_KEY_MGMT_IEEE8021X_SHA256,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::WAPI_PSK) ==
+	WPA_KEY_MGMT_WAPI_PSK,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::WAPI_CERT) ==
+	WPA_KEY_MGMT_WAPI_CERT,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(ProtoMask::WPA) ==
+	WPA_PROTO_WPA,
+	"Proto value mismatch");
+static_assert(
+	static_cast<uint32_t>(ProtoMask::RSN) ==
+	WPA_PROTO_RSN,
+	"Proto value mismatch");
+static_assert(
+	static_cast<uint32_t>(ProtoMask::OSEN) ==
+	WPA_PROTO_OSEN,
+	"Proto value mismatch");
+static_assert(
+	static_cast<uint32_t>(ProtoMask::WAPI) ==
+	WPA_PROTO_WAPI,
+	"Proto value mismatch");
+static_assert(
+	static_cast<uint32_t>(AuthAlgMask::OPEN) ==
+	WPA_AUTH_ALG_OPEN,
+	"AuthAlg value mismatch");
+static_assert(
+	static_cast<uint32_t>(AuthAlgMask::SHARED) ==
+	WPA_AUTH_ALG_SHARED,
+	"AuthAlg value mismatch");
+static_assert(
+	static_cast<uint32_t>(AuthAlgMask::LEAP) ==
+	WPA_AUTH_ALG_LEAP,
+	"AuthAlg value mismatch");
+static_assert(
+	static_cast<uint32_t>(GroupCipherMask::WEP40) ==
+	WPA_CIPHER_WEP40,
+	"GroupCipher value mismatch");
+static_assert(
+	static_cast<uint32_t>(GroupCipherMask::WEP104) ==
+	WPA_CIPHER_WEP104,
+	"GroupCipher value mismatch");
+static_assert(
+	static_cast<uint32_t>(GroupCipherMask::TKIP) ==
+	WPA_CIPHER_TKIP,
+	"GroupCipher value mismatch");
+static_assert(
+	static_cast<uint32_t>(GroupCipherMask::CCMP) ==
+	WPA_CIPHER_CCMP,
+	"GroupCipher value mismatch");
+static_assert(
+	static_cast<uint32_t>(GroupCipherMask::GCMP_256) ==
+	WPA_CIPHER_GCMP_256,
+	"GroupCipher value mismatch");
+static_assert(
+	static_cast<uint32_t>(GroupCipherMask::SMS4) ==
+	WPA_CIPHER_SMS4,
+	"GroupCipher value mismatch");
+static_assert(
+	static_cast<uint32_t>(
+	GroupCipherMask::GTK_NOT_USED) ==
+	WPA_CIPHER_GTK_NOT_USED,
+	"GroupCipher value mismatch");
+static_assert(
+	static_cast<uint32_t>(PairwiseCipherMask::NONE) ==
+	WPA_CIPHER_NONE,
+	"PairwiseCipher value mismatch");
+static_assert(
+	static_cast<uint32_t>(PairwiseCipherMask::TKIP) ==
+	WPA_CIPHER_TKIP,
+	"PairwiseCipher value mismatch");
+static_assert(
+	static_cast<uint32_t>(PairwiseCipherMask::CCMP) ==
+	WPA_CIPHER_CCMP,
+	"PairwiseCipher value mismatch");
+static_assert(
+	static_cast<uint32_t>(
+	PairwiseCipherMask::GCMP_256) ==
+	WPA_CIPHER_GCMP_256,
+	"PairwiseCipher value mismatch");
+static_assert(
+	static_cast<uint32_t>(
+	PairwiseCipherMask::SMS4) ==
+	WPA_CIPHER_SMS4,
+	"PairwiseCipher value mismatch");
+static_assert(
+	static_cast<uint32_t>(StaIfaceCallbackState::DISCONNECTED) ==
+	WPA_DISCONNECTED,
+	"State value mismatch");
+static_assert(
+	static_cast<uint32_t>(StaIfaceCallbackState::COMPLETED) ==
+	WPA_COMPLETED,
+	"State value mismatch");
+
+static_assert(
+	static_cast<uint32_t>(AnqpInfoId::VENUE_NAME) ==
+	ANQP_VENUE_NAME,
+	"ANQP ID value mismatch");
+static_assert(
+	static_cast<uint32_t>(
+	AnqpInfoId::ROAMING_CONSORTIUM) ==
+	ANQP_ROAMING_CONSORTIUM,
+	"ANQP ID value mismatch");
+static_assert(
+	static_cast<uint32_t>(AnqpInfoId::NAI_REALM) ==
+	ANQP_NAI_REALM,
+	"ANQP ID value mismatch");
+static_assert(
+	static_cast<uint32_t>(
+	AnqpInfoId::IP_ADDR_TYPE_AVAILABILITY) ==
+	ANQP_IP_ADDR_TYPE_AVAILABILITY,
+	"ANQP ID value mismatch");
+static_assert(
+	static_cast<uint32_t>(
+	AnqpInfoId::ANQP_3GPP_CELLULAR_NETWORK) ==
+	ANQP_3GPP_CELLULAR_NETWORK,
+	"ANQP ID value mismatch");
+static_assert(
+	static_cast<uint32_t>(AnqpInfoId::DOMAIN_NAME) ==
+	ANQP_DOMAIN_NAME,
+	"ANQP ID value mismatch");
+static_assert(
+	static_cast<uint32_t>(
+	Hs20AnqpSubtypes::OPERATOR_FRIENDLY_NAME) ==
+	HS20_STYPE_OPERATOR_FRIENDLY_NAME,
+	"HS Subtype value mismatch");
+static_assert(
+	static_cast<uint32_t>(Hs20AnqpSubtypes::WAN_METRICS) ==
+	HS20_STYPE_WAN_METRICS,
+	"HS Subtype value mismatch");
+static_assert(
+	static_cast<uint32_t>(
+	Hs20AnqpSubtypes::CONNECTION_CAPABILITY) ==
+	HS20_STYPE_CONNECTION_CAPABILITY,
+	"HS Subtype value mismatch");
+static_assert(
+	static_cast<uint32_t>(
+	Hs20AnqpSubtypes::OSU_PROVIDERS_LIST) ==
+	HS20_STYPE_OSU_PROVIDERS_LIST,
+	"HS Subtype value mismatch");
+
+static_assert(
+	static_cast<uint16_t>(
+	WpsConfigError::NO_ERROR) ==
+	WPS_CFG_NO_ERROR,
+	"Wps config error value mismatch");
+static_assert(
+	static_cast<uint16_t>(WpsConfigError::
+				  PUBLIC_KEY_HASH_MISMATCH) ==
+	WPS_CFG_PUBLIC_KEY_HASH_MISMATCH,
+	"Wps config error value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	WpsErrorIndication::NO_ERROR) ==
+	WPS_EI_NO_ERROR,
+	"Wps error indication value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	WpsErrorIndication::AUTH_FAILURE) ==
+	WPS_EI_AUTH_FAILURE,
+	"Wps error indication value mismatch");
+
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::USBA) == WPS_CONFIG_USBA,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::ETHERNET) == WPS_CONFIG_ETHERNET,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::LABEL) == WPS_CONFIG_LABEL,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::DISPLAY) == WPS_CONFIG_DISPLAY,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::INT_NFC_TOKEN) ==
+	WPS_CONFIG_INT_NFC_TOKEN,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::EXT_NFC_TOKEN) ==
+	WPS_CONFIG_EXT_NFC_TOKEN,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::NFC_INTERFACE) ==
+	WPS_CONFIG_NFC_INTERFACE,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::PUSHBUTTON) ==
+	WPS_CONFIG_PUSHBUTTON,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::KEYPAD) == WPS_CONFIG_KEYPAD,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::VIRT_PUSHBUTTON) ==
+	WPS_CONFIG_VIRT_PUSHBUTTON,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::PHY_PUSHBUTTON) ==
+	WPS_CONFIG_PHY_PUSHBUTTON,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::P2PS) == WPS_CONFIG_P2PS,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::VIRT_DISPLAY) ==
+	WPS_CONFIG_VIRT_DISPLAY,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::PHY_DISPLAY) ==
+	WPS_CONFIG_PHY_DISPLAY,
+	"Wps config value mismatch");
+
+static_assert(
+	static_cast<uint32_t>(P2pGroupCapabilityMask::GROUP_OWNER) ==
+	P2P_GROUP_CAPAB_GROUP_OWNER,
+	"P2P capability value mismatch");
+static_assert(
+	static_cast<uint32_t>(P2pGroupCapabilityMask::PERSISTENT_GROUP) ==
+	P2P_GROUP_CAPAB_PERSISTENT_GROUP,
+	"P2P capability value mismatch");
+static_assert(
+	static_cast<uint32_t>(P2pGroupCapabilityMask::GROUP_LIMIT) ==
+	P2P_GROUP_CAPAB_GROUP_LIMIT,
+	"P2P capability value mismatch");
+static_assert(
+	static_cast<uint32_t>(P2pGroupCapabilityMask::INTRA_BSS_DIST) ==
+	P2P_GROUP_CAPAB_INTRA_BSS_DIST,
+	"P2P capability value mismatch");
+static_assert(
+	static_cast<uint32_t>(P2pGroupCapabilityMask::CROSS_CONN) ==
+	P2P_GROUP_CAPAB_CROSS_CONN,
+	"P2P capability value mismatch");
+static_assert(
+	static_cast<uint32_t>(P2pGroupCapabilityMask::PERSISTENT_RECONN) ==
+	P2P_GROUP_CAPAB_PERSISTENT_RECONN,
+	"P2P capability value mismatch");
+static_assert(
+	static_cast<uint32_t>(P2pGroupCapabilityMask::GROUP_FORMATION) ==
+	P2P_GROUP_CAPAB_GROUP_FORMATION,
+	"P2P capability value mismatch");
+
+static_assert(
+	static_cast<uint16_t>(
+	WpsDevPasswordId::DEFAULT) ==
+	DEV_PW_DEFAULT,
+	"Wps dev password id value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	WpsDevPasswordId::USER_SPECIFIED) ==
+	DEV_PW_USER_SPECIFIED,
+	"Wps dev password id value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	WpsDevPasswordId::MACHINE_SPECIFIED) ==
+	DEV_PW_MACHINE_SPECIFIED,
+	"Wps dev password id value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	WpsDevPasswordId::REKEY) == DEV_PW_REKEY,
+	"Wps dev password id value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	WpsDevPasswordId::PUSHBUTTON) ==
+	DEV_PW_PUSHBUTTON,
+	"Wps dev password id value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	WpsDevPasswordId::REGISTRAR_SPECIFIED) ==
+	DEV_PW_REGISTRAR_SPECIFIED,
+	"Wps dev password id value mismatch");
+static_assert(
+	static_cast<uint16_t>(WpsDevPasswordId::
+				  NFC_CONNECTION_HANDOVER) ==
+	DEV_PW_NFC_CONNECTION_HANDOVER,
+	"Wps dev password id value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	WpsDevPasswordId::P2PS_DEFAULT) ==
+	DEV_PW_P2PS_DEFAULT,
+	"Wps dev password id value mismatch");
+
+static_assert(
+	static_cast<uint16_t>(
+	P2pStatusCode::SUCCESS) == P2P_SC_SUCCESS,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(P2pStatusCode::
+				  FAIL_INFO_CURRENTLY_UNAVAILABLE) ==
+	P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pStatusCode::FAIL_INCOMPATIBLE_PARAMS) ==
+	P2P_SC_FAIL_INCOMPATIBLE_PARAMS,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pStatusCode::FAIL_LIMIT_REACHED) ==
+	P2P_SC_FAIL_LIMIT_REACHED,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pStatusCode::FAIL_INVALID_PARAMS) ==
+	P2P_SC_FAIL_INVALID_PARAMS,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(P2pStatusCode::
+				  FAIL_UNABLE_TO_ACCOMMODATE) ==
+	P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pStatusCode::FAIL_PREV_PROTOCOL_ERROR) ==
+	P2P_SC_FAIL_PREV_PROTOCOL_ERROR,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pStatusCode::FAIL_NO_COMMON_CHANNELS) ==
+	P2P_SC_FAIL_NO_COMMON_CHANNELS,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pStatusCode::FAIL_UNKNOWN_GROUP) ==
+	P2P_SC_FAIL_UNKNOWN_GROUP,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pStatusCode::FAIL_BOTH_GO_INTENT_15) ==
+	P2P_SC_FAIL_BOTH_GO_INTENT_15,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(P2pStatusCode::
+				  FAIL_INCOMPATIBLE_PROV_METHOD) ==
+	P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pStatusCode::FAIL_REJECTED_BY_USER) ==
+	P2P_SC_FAIL_REJECTED_BY_USER,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pStatusCode::SUCCESS_DEFERRED) ==
+	P2P_SC_SUCCESS_DEFERRED,
+	"P2P status code value mismatch");
+
+static_assert(
+	static_cast<uint16_t>(
+	P2pProvDiscStatusCode::SUCCESS) ==
+	P2P_PROV_DISC_SUCCESS,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pProvDiscStatusCode::TIMEOUT) ==
+	P2P_PROV_DISC_TIMEOUT,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pProvDiscStatusCode::REJECTED) ==
+	P2P_PROV_DISC_REJECTED,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pProvDiscStatusCode::TIMEOUT_JOIN) ==
+	P2P_PROV_DISC_TIMEOUT_JOIN,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pProvDiscStatusCode::INFO_UNAVAILABLE) ==
+	P2P_PROV_DISC_INFO_UNAVAILABLE,
+	"P2P status code value mismatch");
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+#endif  // WPA_SUPPLICANT_AIDL_AIDL_MANAGER_H
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/aidl_return_util.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/aidl_return_util.h
new file mode 100755
index 0000000..109723a
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/aidl_return_util.h
@@ -0,0 +1,66 @@
+/*
+ * WPA Supplicant - Validate interfaces before calling methods
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef AIDL_RETURN_UTIL_H_
+#define AIDL_RETURN_UTIL_H_
+
+#include <aidl/android/hardware/wifi/supplicant/SupplicantStatusCode.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+namespace aidl_return_util {
+
+/**
+ * These utility functions are used to invoke a method on the provided
+ * AIDL interface object.
+ * These functions check if the provided AIDL interface object is valid.
+ * a) If valid, invokes the corresponding internal implementation function of
+ * the AIDL method.
+ * b) If invalid, return without calling the internal implementation function.
+ */
+
+// Use for AIDL methods which only return an AIDL status
+template <typename ObjT, typename WorkFuncT, typename... Args>
+::ndk::ScopedAStatus validateAndCall(
+	ObjT* obj, SupplicantStatusCode status_code_if_invalid, WorkFuncT&& work,
+	Args&&... args)
+{
+	if (obj->isValid()) {
+		return (obj->*work)(std::forward<Args>(args)...);
+	} else {
+		return ndk::ScopedAStatus::fromServiceSpecificError(
+			static_cast<int32_t>(status_code_if_invalid));
+	}
+}
+
+// Use for AIDL methods which have a return value along with the AIDL status
+template <typename ObjT, typename WorkFuncT, typename ReturnT, typename... Args>
+::ndk::ScopedAStatus validateAndCall(
+	ObjT* obj, SupplicantStatusCode status_code_if_invalid, WorkFuncT&& work,
+	ReturnT* ret_val, Args&&... args)
+{
+	if (obj->isValid()) {
+		auto call_pair = (obj->*work)(std::forward<Args>(args)...);
+		*ret_val = call_pair.first;
+		return std::forward<::ndk::ScopedAStatus>(call_pair.second);
+	} else {
+		return ndk::ScopedAStatus::fromServiceSpecificError(
+			static_cast<int32_t>(status_code_if_invalid));
+	}
+}
+
+}  // namespace aidl_return_util
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+#endif  // AIDL_RETURN_UTIL_H_
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/android.hardware.wifi.supplicant-service.rc b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/android.hardware.wifi.supplicant-service.rc
new file mode 100755
index 0000000..3275e36
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/android.hardware.wifi.supplicant-service.rc
@@ -0,0 +1,12 @@
+service wpa_supplicant /vendor/bin/hw/wpa_supplicant \
+	-O/data/vendor/wifi/wpa/sockets -dd \
+	-g@android:wpa_wlan0
+	#   we will start as root and wpa_supplicant will switch to user wifi
+	#   after setting up the capabilities required for WEXT
+	#   user wifi
+	#   group wifi inet keystore
+	interface aidl android.hardware.wifi.supplicant.ISupplicant/default
+	class main
+	socket wpa_wlan0 dgram 660 wifi wifi
+	disabled
+	oneshot
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/android.hardware.wifi.supplicant.xml b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/android.hardware.wifi.supplicant.xml
new file mode 100755
index 0000000..3dc9b02
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/android.hardware.wifi.supplicant.xml
@@ -0,0 +1,6 @@
+<manifest version="1.0" type="device">
+	<hal format="aidl">
+		<name>android.hardware.wifi.supplicant</name>
+		<fqname>ISupplicant/default</fqname>
+	</hal>
+</manifest>
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/iface_config_utils.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/iface_config_utils.cpp
new file mode 100755
index 0000000..4d3f29c
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/iface_config_utils.cpp
@@ -0,0 +1,179 @@
+/*
+ * WPA Supplicant - Iface configuration methods
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "aidl_manager.h"
+#include "aidl_return_util.h"
+#include "iface_config_utils.h"
+#include "misc_utils.h"
+
+namespace {
+using aidl::android::hardware::wifi::supplicant::SupplicantStatusCode;
+using aidl::android::hardware::wifi::supplicant::WpsConfigMethods;
+
+constexpr uint32_t kMaxWpsDeviceNameSize = WPS_DEV_NAME_MAX_LEN;
+constexpr uint32_t kMaxWpsManufacturerSize = WPS_MANUFACTURER_MAX_LEN;
+constexpr uint32_t kMaxWpsModelNameSize = WPS_MODEL_NAME_MAX_LEN;
+constexpr uint32_t kMaxWpsModelNumberSize = WPS_MODEL_NUMBER_MAX_LEN;
+constexpr uint32_t kMaxWpsSerialNumberSize = WPS_SERIAL_NUMBER_MAX_LEN;
+
+void processConfigUpdate(struct wpa_supplicant* wpa_s, uint32_t changed_param)
+{
+	wpa_s->conf->changed_parameters |= changed_param;
+	wpa_supplicant_update_config(wpa_s);
+}
+
+// Free any existing pointer stored in |dst| and store the provided string value
+// there.
+int freeAndSetStringConfigParam(
+	struct wpa_supplicant* wpa_s, const std::string& value, uint32_t max_size,
+	uint32_t changed_param, char** dst)
+{
+	if (value.size() > max_size) {
+		return -1;
+	}
+	WPA_ASSERT(dst);
+	os_free(static_cast<void*>(*dst));
+	*dst = os_strdup(value.c_str());
+	processConfigUpdate(wpa_s, changed_param);
+	return 0;
+}
+
+std::string convertWpsConfigMethodsMaskToString(uint16_t config_methods)
+{
+	std::string config_methods_str;
+	for (const auto& flag_and_name :
+		 {std::make_pair(WpsConfigMethods::USBA, "usba"),
+		  {WpsConfigMethods::ETHERNET, "ethernet"},
+		  {WpsConfigMethods::LABEL, "label"},
+		  {WpsConfigMethods::DISPLAY, "display"},
+		  {WpsConfigMethods::INT_NFC_TOKEN, "int_nfc_token"},
+		  {WpsConfigMethods::EXT_NFC_TOKEN, "ext_nfc_token"},
+		  {WpsConfigMethods::NFC_INTERFACE, "nfc_interface"},
+		  {WpsConfigMethods::PUSHBUTTON, "push_button"},
+		  {WpsConfigMethods::KEYPAD, "keypad"},
+		  {WpsConfigMethods::VIRT_PUSHBUTTON, "virtual_push_button"},
+		  {WpsConfigMethods::PHY_PUSHBUTTON, "physical_push_button"},
+		  {WpsConfigMethods::P2PS, "p2ps"},
+		  {WpsConfigMethods::VIRT_DISPLAY, "virtual_display"},
+		  {WpsConfigMethods::PHY_DISPLAY, "physical_display"}}) {
+		const auto flag =
+			static_cast<std::underlying_type<WpsConfigMethods>::type>(
+			flag_and_name.first);
+		if ((config_methods & flag) == flag) {
+			config_methods_str += flag_and_name.second;
+			config_methods_str += " ";
+		}
+	}
+	return config_methods_str;
+}
+}  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+namespace iface_config_utils {
+using misc_utils::createStatus;
+
+ndk::ScopedAStatus setWpsDeviceName(
+	struct wpa_supplicant* wpa_s, const std::string& name)
+{
+	WPA_ASSERT(wpa_s);
+	if (freeAndSetStringConfigParam(
+		wpa_s, name, kMaxWpsDeviceNameSize, CFG_CHANGED_DEVICE_NAME,
+		&wpa_s->conf->device_name)) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus setWpsDeviceType(
+	struct wpa_supplicant* wpa_s, const std::array<uint8_t, WPS_DEV_TYPE_LEN>& type)
+{
+	WPA_ASSERT(wpa_s);
+	WPA_ASSERT(type.size() == WPS_DEV_TYPE_LEN);
+	os_memcpy(wpa_s->conf->device_type, type.data(), WPS_DEV_TYPE_LEN);
+	processConfigUpdate(wpa_s, CFG_CHANGED_DEVICE_TYPE);
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus setWpsManufacturer(
+	struct wpa_supplicant* wpa_s, const std::string& manufacturer)
+{
+	WPA_ASSERT(wpa_s);
+	if (freeAndSetStringConfigParam(
+		wpa_s, manufacturer, kMaxWpsManufacturerSize,
+		CFG_CHANGED_WPS_STRING, &wpa_s->conf->manufacturer)) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus setWpsModelName(
+	struct wpa_supplicant* wpa_s, const std::string& model_name)
+{
+	WPA_ASSERT(wpa_s);
+	if (freeAndSetStringConfigParam(
+		wpa_s, model_name, kMaxWpsModelNameSize, CFG_CHANGED_WPS_STRING,
+		&wpa_s->conf->model_name)) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus setWpsModelNumber(
+	struct wpa_supplicant* wpa_s, const std::string& model_number)
+{
+	WPA_ASSERT(wpa_s);
+	if (freeAndSetStringConfigParam(
+		wpa_s, model_number, kMaxWpsModelNumberSize,
+		CFG_CHANGED_WPS_STRING, &wpa_s->conf->model_number)) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus setWpsSerialNumber(
+	struct wpa_supplicant* wpa_s, const std::string& serial_number)
+{
+	WPA_ASSERT(wpa_s);
+	if (freeAndSetStringConfigParam(
+		wpa_s, serial_number, kMaxWpsSerialNumberSize,
+		CFG_CHANGED_WPS_STRING, &wpa_s->conf->serial_number)) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus setWpsConfigMethods(
+	struct wpa_supplicant* wpa_s, uint16_t config_methods)
+{
+	WPA_ASSERT(wpa_s);
+	if (freeAndSetStringConfigParam(
+		wpa_s, convertWpsConfigMethodsMaskToString(config_methods),
+		UINT32_MAX, CFG_CHANGED_CONFIG_METHODS,
+		&wpa_s->conf->config_methods)) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus setExternalSim(
+	struct wpa_supplicant* wpa_s, bool useExternalSim)
+{
+	WPA_ASSERT(wpa_s);
+	wpa_s->conf->external_sim = useExternalSim ? 1 : 0;
+	return ndk::ScopedAStatus::ok();
+}
+}  // namespace iface_config_utils
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/iface_config_utils.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/iface_config_utils.h
new file mode 100755
index 0000000..c17dbb4
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/iface_config_utils.h
@@ -0,0 +1,55 @@
+/*
+ * WPA Supplicant - Iface configuration methods
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef WPA_SUPPLICANT_AIDL_IFACE_CONFIG_UTILS_H
+#define WPA_SUPPLICANT_AIDL_IFACE_CONFIG_UTILS_H
+
+#include <android-base/macros.h>
+
+extern "C"
+{
+#include "utils/common.h"
+#include "utils/includes.h"
+#include "wpa_supplicant_i.h"
+#include "config.h"
+}
+
+/**
+ * Utility functions to set various config parameters of an iface via AIDL
+ * methods.
+ */
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+namespace iface_config_utils {
+ndk::ScopedAStatus setWpsDeviceName(
+	struct wpa_supplicant* wpa_s, const std::string& name);
+ndk::ScopedAStatus setWpsDeviceType(
+	struct wpa_supplicant* wpa_s, const std::array<uint8_t, 8>& type);
+ndk::ScopedAStatus setWpsManufacturer(
+	struct wpa_supplicant* wpa_s, const std::string& manufacturer);
+ndk::ScopedAStatus setWpsModelName(
+	struct wpa_supplicant* wpa_s, const std::string& model_name);
+ndk::ScopedAStatus setWpsModelNumber(
+	struct wpa_supplicant* wpa_s, const std::string& model_number);
+ndk::ScopedAStatus setWpsSerialNumber(
+	struct wpa_supplicant* wpa_s, const std::string& serial_number);
+ndk::ScopedAStatus setWpsConfigMethods(
+	struct wpa_supplicant* wpa_s, uint16_t config_methods);
+ndk::ScopedAStatus setExternalSim(
+	struct wpa_supplicant* wpa_s, bool useExternalSim);
+}  // namespace iface_config_utils
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WPA_SUPPLICANT_AIDL_IFACE_CONFIG_UTILS_H
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/misc_utils.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/misc_utils.h
new file mode 100755
index 0000000..5c5b68c
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/misc_utils.h
@@ -0,0 +1,127 @@
+/*
+ * WPA Supplicant - Helper methods for Aidl
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef MISC_UTILS_H_
+#define MISC_UTILS_H_
+
+#include <iostream>
+#include <aidl/android/hardware/wifi/supplicant/SupplicantStatusCode.h>
+
+extern "C"
+{
+#include "wpabuf.h"
+}
+
+namespace {
+constexpr size_t kWpsPinNumDigits = 8;
+// Custom deleter for wpabuf.
+void freeWpaBuf(wpabuf *ptr) { wpabuf_free(ptr); }
+}  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+namespace misc_utils {
+using wpabuf_unique_ptr = std::unique_ptr<wpabuf, void (*)(wpabuf *)>;
+
+// Creates a unique_ptr for wpabuf ptr with a custom deleter.
+inline wpabuf_unique_ptr createWpaBufUniquePtr(struct wpabuf *raw_ptr)
+{
+	return {raw_ptr, freeWpaBuf};
+}
+
+// Creates a wpabuf ptr with a custom deleter copying the data from the provided
+// vector.
+inline wpabuf_unique_ptr convertVectorToWpaBuf(const std::vector<uint8_t> &data)
+{
+	return createWpaBufUniquePtr(
+		wpabuf_alloc_copy(data.data(), data.size()));
+}
+
+// Copies the provided wpabuf contents to a std::vector.
+inline std::vector<uint8_t> convertWpaBufToVector(const struct wpabuf *buf)
+{
+	if (buf) {
+		return std::vector<uint8_t>(
+			wpabuf_head_u8(buf), wpabuf_head_u8(buf) + wpabuf_len(buf));
+	} else {
+		return std::vector<uint8_t>();
+	}
+}
+
+// Returns a string holding the wps pin.
+inline std::string convertWpsPinToString(int pin)
+{
+	char pin_str[kWpsPinNumDigits + 1];
+	snprintf(pin_str, sizeof(pin_str), "%08d", pin);
+	return pin_str;
+}
+
+// Wrappers to create a ScopedAStatus using a SupplicantStatusCode
+inline ndk::ScopedAStatus createStatus(SupplicantStatusCode status_code) {
+	return ndk::ScopedAStatus::fromServiceSpecificError(
+		static_cast<int32_t>(status_code));
+}
+
+inline ndk::ScopedAStatus createStatusWithMsg(
+	SupplicantStatusCode status_code, std::string msg)
+{
+	return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+		static_cast<int32_t>(status_code), msg.c_str());
+}
+
+// Creates an std::string from a char*, which could be null
+inline std::string charBufToString(const char* buf) {
+	return buf ? std::string(buf) : "";
+}
+
+inline std::stringstream& serializePmkCacheEntry(
+	std::stringstream &ss, struct rsn_pmksa_cache_entry *pmksa_entry) {
+	ss.write((char *) &pmksa_entry->pmk_len, sizeof(pmksa_entry->pmk_len));
+	ss.write((char *) pmksa_entry->pmk, pmksa_entry->pmk_len);
+	ss.write((char *) pmksa_entry->pmkid, PMKID_LEN);
+	ss.write((char *) pmksa_entry->aa, ETH_ALEN);
+	// Omit wpa_ssid field because the network is created on connecting to a access point.
+	ss.write((char *) &pmksa_entry->akmp, sizeof(pmksa_entry->akmp));
+	ss.write((char *) &pmksa_entry->reauth_time, sizeof(pmksa_entry->reauth_time));
+	ss.write((char *) &pmksa_entry->expiration, sizeof(pmksa_entry->expiration));
+	ss.write((char *) &pmksa_entry->opportunistic, sizeof(pmksa_entry->opportunistic));
+	char byte = (pmksa_entry->fils_cache_id_set) ? 1 : 0;
+	ss.write((char *) &byte, sizeof(byte));
+	ss.write((char *) pmksa_entry->fils_cache_id, FILS_CACHE_ID_LEN);
+	ss << std::flush;
+	return ss;
+}
+
+inline std::stringstream& deserializePmkCacheEntry(
+	std::stringstream &ss, struct rsn_pmksa_cache_entry *pmksa_entry) {
+	ss.seekg(0);
+	ss.read((char *) &pmksa_entry->pmk_len, sizeof(pmksa_entry->pmk_len));
+	ss.read((char *) pmksa_entry->pmk, pmksa_entry->pmk_len);
+	ss.read((char *) pmksa_entry->pmkid, PMKID_LEN);
+	ss.read((char *) pmksa_entry->aa, ETH_ALEN);
+	// Omit wpa_ssid field because the network is created on connecting to a access point.
+	ss.read((char *) &pmksa_entry->akmp, sizeof(pmksa_entry->akmp));
+	ss.read((char *) &pmksa_entry->reauth_time, sizeof(pmksa_entry->reauth_time));
+	ss.read((char *) &pmksa_entry->expiration, sizeof(pmksa_entry->expiration));
+	ss.read((char *) &pmksa_entry->opportunistic, sizeof(pmksa_entry->opportunistic));
+	char byte = 0;
+	ss.read((char *) &byte, sizeof(byte));
+	pmksa_entry->fils_cache_id_set = (byte) ? 1 : 0;
+	ss.read((char *) pmksa_entry->fils_cache_id, FILS_CACHE_ID_LEN);
+	return ss;
+}
+}  // namespace misc_utils
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+#endif  // MISC_UTILS_H_
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/p2p_iface.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/p2p_iface.cpp
new file mode 100755
index 0000000..06c4545
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/p2p_iface.cpp
@@ -0,0 +1,2171 @@
+/*
+ * WPA Supplicant - P2P Iface Aidl interface
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "aidl_manager.h"
+#include "aidl_return_util.h"
+#include "iface_config_utils.h"
+#include "misc_utils.h"
+#include "p2p_iface.h"
+#include "sta_network.h"
+
+extern "C"
+{
+#include "ap.h"
+#include "wps_supplicant.h"
+#include "wifi_display.h"
+#include "utils/eloop.h"
+#include "wpa_supplicant_i.h"
+#include "driver_i.h"
+}
+
+#define P2P_MAX_JOIN_SCAN_ATTEMPTS 3
+// Wait time before triggering the single channel scan to discover Auto GO.
+// Use a shorter wait time when the given frequency is GO operating frequency.
+// The idea is to quickly finish scans and return the status to application.
+#define P2P_JOIN_SINGLE_CHANNEL_SCAN_INTERVAL_USECS 200000
+// Wait time before triggering the multiple channel scan to discover Auto GO.
+#define P2P_JOIN_MULTIPLE_CHANNEL_SCAN_INTERVAL_USECS 1000000
+
+namespace {
+const char kConfigMethodStrPbc[] = "pbc";
+const char kConfigMethodStrDisplay[] = "display";
+const char kConfigMethodStrKeypad[] = "keypad";
+constexpr char kSetMiracastMode[] = "MIRACAST ";
+constexpr uint8_t kWfdDeviceInfoSubelemId = 0;
+constexpr uint8_t kWfdR2DeviceInfoSubelemId = 11;
+constexpr char kWfdDeviceInfoSubelemLenHexStr[] = "0006";
+
+std::function<void()> pending_join_scan_callback = NULL;
+std::function<void()> pending_scan_res_join_callback = NULL;
+
+using aidl::android::hardware::wifi::supplicant::ISupplicantP2pIface;
+using aidl::android::hardware::wifi::supplicant::ISupplicantStaNetwork;
+using aidl::android::hardware::wifi::supplicant::MiracastMode;
+using aidl::android::hardware::wifi::supplicant::P2pFrameTypeMask;
+
+uint8_t convertAidlMiracastModeToInternal(
+	MiracastMode mode)
+{
+	switch (mode) {
+	case MiracastMode::DISABLED:
+		return 0;
+	case MiracastMode::SOURCE:
+		return 1;
+	case MiracastMode::SINK:
+		return 2;
+	};
+	WPA_ASSERT(false);
+}
+
+/**
+ * Check if the provided ssid is valid or not.
+ *
+ * Returns 1 if valid, 0 otherwise.
+ */
+int isSsidValid(const std::vector<uint8_t>& ssid)
+{
+	if (ssid.size() == 0 ||
+		ssid.size() >
+		static_cast<uint32_t>(ISupplicantStaNetwork::
+					  SSID_MAX_LEN_IN_BYTES)) {
+		return 0;
+	}
+	return 1;
+}
+
+/**
+ * Check if the provided psk passhrase is valid or not.
+ *
+ * Returns 1 if valid, 0 otherwise.
+ */
+int isPskPassphraseValid(const std::string &psk)
+{
+	if (psk.size() <
+		static_cast<uint32_t>(ISupplicantStaNetwork::
+					  PSK_PASSPHRASE_MIN_LEN_IN_BYTES) ||
+		psk.size() >
+		static_cast<uint32_t>(ISupplicantStaNetwork::
+					  PSK_PASSPHRASE_MAX_LEN_IN_BYTES)) {
+		return 0;
+	}
+	if (has_ctrl_char((u8 *)psk.c_str(), psk.size())) {
+		return 0;
+	}
+	return 1;
+}
+
+static int setBandScanFreqsList(
+	struct wpa_supplicant *wpa_s,
+	enum hostapd_hw_mode hw_mode,
+	bool exclude_dfs,
+	struct wpa_driver_scan_params *params)
+{
+	struct hostapd_hw_modes *mode;
+	int count, i;
+
+	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, hw_mode, 0);
+	if (mode == NULL || !mode->num_channels) {
+		wpa_printf(MSG_ERROR,
+			"P2P: No channels supported in this hw_mode: %d", hw_mode);
+		return -1;
+	}
+
+	/*
+	 * Allocate memory for frequency array, allocate one extra
+	 * slot for the zero-terminator.
+	 */
+	params->freqs = (int *) os_calloc(mode->num_channels + 1, sizeof(int));
+	if (params->freqs == NULL) {
+		return -ENOMEM;
+	}
+	for (count = 0, i = 0; i < mode->num_channels; i++) {
+		if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED) {
+			continue;
+		}
+		if (exclude_dfs && (mode->channels[i].flag & HOSTAPD_CHAN_RADAR)) {
+			continue;
+		}
+		params->freqs[count++] = mode->channels[i].freq;
+	}
+	if (!count && params->freqs) {
+		wpa_printf(MSG_ERROR,
+			"P2P: All channels(exclude_dfs: %d) are disabled in this hw_mode: %d",
+			exclude_dfs, hw_mode);
+		os_free(params->freqs);
+		return -1;
+	}
+	return 0;
+}
+
+static int setScanFreq(struct wpa_supplicant *wpa_s, struct wpa_driver_scan_params *params,
+	int freq, int operating_freq)
+{
+	int frequency = operating_freq ? operating_freq : freq;
+	if (disabled_freq(wpa_s, frequency)) {
+		wpa_printf(MSG_ERROR,
+				"P2P: freq %d is not supported for a client.", frequency);
+		return -1;
+	}
+	/*
+	 * Allocate memory for frequency array, with one extra
+	 * slot for the zero-terminator.
+	 */
+	params->freqs = new int[2] {frequency, 0};
+	return 0;
+}
+
+/**
+ * setP2pCliOptimizedScanFreqsList - Fill the frequencies to scan in Scan
+ * parameters.
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @params: Pointer to Scan parameters.
+ * @freq: Frequency/Band requested to scan by the application, possible values are,
+ *		0 - All the frequencies - full scan
+ *		2 - Frequencies in 2.4GHz
+ *		5 - Frequencies in 5GHz
+ *		- Valid frequency
+ * @operating_freq: Frequency of BSS if found in scan cache
+ * Returns: Pointer to the BSS entry or %NULL if not found
+ */
+static int setP2pCliOptimizedScanFreqsList(struct wpa_supplicant *wpa_s,
+	struct wpa_driver_scan_params *params, int freq, int operating_freq)
+{
+	int ret;
+	/* If BSS is found in scan cache, first scan its operating frequency */
+	if (!wpa_s->p2p_join_scan_count && operating_freq) {
+		ret = setScanFreq(wpa_s, params, freq, operating_freq);
+		if (!ret) {
+			return ret;
+		}
+	}
+
+	/* Empty freq params means scan all the frequencies */
+	if (freq == 0) {
+		return 0;
+	}
+	else if (freq == 2 || freq == 5) {
+		/* Scan the frequencies in the band */
+		enum hostapd_hw_mode mode;
+		int ret;
+		if (wpa_s->hw.modes == NULL) {
+			wpa_printf(MSG_DEBUG,
+				   "P2P: Unknown what %dG channels the driver supports.", freq);
+			return 0;
+		}
+		mode = freq == 5 ? HOSTAPD_MODE_IEEE80211A : HOSTAPD_MODE_IEEE80211G;
+		if (wpa_s->p2p_join_scan_count < 2) {
+			// scan all non DFS channels in the first two attempts
+			ret = setBandScanFreqsList(wpa_s, mode, true, params);
+			if (ret < 0 && (-ENOMEM != ret)) {
+				// try to scan all channels before returning error
+				ret = setBandScanFreqsList(wpa_s, mode, false, params);
+			}
+		} else {
+			// scan all channels
+			ret = setBandScanFreqsList(wpa_s, mode, false, params);
+		}
+		return ret;
+	} else {
+		/* Scan the frequency requested by the application */
+		ret = setScanFreq(wpa_s, params, freq, 0);
+		return ret;
+	}
+	return 0;
+}
+
+/**
+ * getP2pJoinScanInterval - Get the delay in triggering the scan to discover
+ * Auto GO.
+ */
+static int getP2pJoinScanIntervalUsecs(int freq)
+{
+	if (freq == 5 || freq == 2 || freq == 0) {
+		return P2P_JOIN_MULTIPLE_CHANNEL_SCAN_INTERVAL_USECS;
+	} else {
+		return P2P_JOIN_SINGLE_CHANNEL_SCAN_INTERVAL_USECS;
+	}
+}
+
+/*
+ * isAnyEtherAddr - match any ether address
+ *
+ */
+int isAnyEtherAddr(const u8 *a)
+{
+	// 02:00:00:00:00:00
+	return (a[0] == 2) && !(a[1] | a[2] | a[3] | a[4] | a[5]);
+}
+
+/**
+ * findBssBySsid - Fetch a BSS table entry based on SSID and optional BSSID.
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @bssid: BSSID, 02:00:00:00:00:00 matches any bssid
+ * @ssid: SSID
+ * @ssid_len: Length of @ssid
+ * Returns: Pointer to the BSS entry or %NULL if not found
+ */
+struct wpa_bss* findBssBySsid(
+	struct wpa_supplicant *wpa_s, const u8 *bssid,
+	const u8 *ssid, size_t ssid_len)
+{
+	struct wpa_bss *bss;
+	dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
+		if ((isAnyEtherAddr(bssid) ||
+			os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0) &&
+			bss->ssid_len == ssid_len &&
+			os_memcmp(bss->ssid, ssid, ssid_len) == 0)
+			return bss;
+	}
+	return NULL;
+}
+
+/**
+ * findBssBySsidFromAnyInterface - Fetch a BSS table entry based on SSID and optional BSSID
+ * by iterating through all the interfaces.
+ * @head: Head of Pointer to wpa_supplicant data
+ * @bssid: BSSID, 02:00:00:00:00:00 matches any bssid
+ * @ssid: SSID
+ * @ssid_len: Length of @ssid
+ * Returns: Pointer to the BSS entry or %NULL if not found
+ */
+struct wpa_bss* findBssBySsidFromAnyInterface(
+	struct wpa_supplicant *head, const u8 *bssid,
+	const u8 *ssid, size_t ssid_len)
+{
+	struct wpa_supplicant *wpa_s;
+	struct wpa_bss *bss = NULL;
+	for (wpa_s = head; wpa_s; wpa_s = wpa_s->next) {
+		bss = findBssBySsid(wpa_s, bssid, ssid, ssid_len);
+		if (bss != NULL) {
+			return bss;
+		}
+	}
+	return bss;
+}
+
+struct wpa_ssid* addGroupClientNetwork(
+	struct wpa_supplicant* wpa_s,
+	uint8_t *group_owner_bssid,
+	const std::vector<uint8_t>& ssid,
+	const std::string& passphrase)
+{
+	struct wpa_ssid* wpa_network = wpa_config_add_network(wpa_s->conf);
+	if (!wpa_network) {
+		return NULL;
+	}
+	// set general network defaults
+	wpa_config_set_network_defaults(wpa_network);
+
+	// set P2p network defaults
+	wpa_network->p2p_group = 1;
+	wpa_network->mode = wpas_mode::WPAS_MODE_INFRA;
+
+	wpa_network->auth_alg = WPA_AUTH_ALG_OPEN;
+	wpa_network->key_mgmt = WPA_KEY_MGMT_PSK;
+	wpa_network->proto = WPA_PROTO_RSN;
+	wpa_network->pairwise_cipher = WPA_CIPHER_CCMP;
+	wpa_network->group_cipher = WPA_CIPHER_CCMP;
+	wpa_network->disabled = 2;
+
+	// set necessary fields
+	os_memcpy(wpa_network->bssid, group_owner_bssid, ETH_ALEN);
+	wpa_network->bssid_set = 1;
+
+	wpa_network->ssid = (uint8_t *)os_malloc(ssid.size());
+	if (wpa_network->ssid == NULL) {
+		wpa_config_remove_network(wpa_s->conf, wpa_network->id);
+		return  NULL;
+	}
+	memcpy(wpa_network->ssid, ssid.data(), ssid.size());
+	wpa_network->ssid_len = ssid.size();
+
+	wpa_network->psk_set = 0;
+	wpa_network->passphrase = dup_binstr(passphrase.c_str(), passphrase.length());
+	if (wpa_network->passphrase == NULL) {
+		wpa_config_remove_network(wpa_s->conf, wpa_network->id);
+		return  NULL;
+	}
+	wpa_config_update_psk(wpa_network);
+
+	return wpa_network;
+
+}
+
+void joinScanWrapper(void *eloop_ctx, void *timeout_ctx)
+{
+	struct wpa_supplicant *wpa_s = (struct wpa_supplicant *) eloop_ctx;
+
+	if (pending_join_scan_callback != NULL) {
+		pending_join_scan_callback();
+	}
+}
+
+void scanResJoinWrapper(
+	struct wpa_supplicant *wpa_s,
+	struct wpa_scan_results *scan_res)
+{
+	if (wpa_s->p2p_scan_work) {
+		struct wpa_radio_work *work = wpa_s->p2p_scan_work;
+		wpa_s->p2p_scan_work = NULL;
+		radio_work_done(work);
+	}
+
+	if (pending_scan_res_join_callback) {
+		pending_scan_res_join_callback();
+	}
+}
+
+int joinScanReq(
+	struct wpa_supplicant* wpa_s,
+	const std::vector<uint8_t>& ssid,
+	int freq, int operating_freq)
+{
+	int ret;
+	struct wpa_driver_scan_params params;
+	struct wpabuf *ies;
+	size_t ielen;
+	unsigned int bands;
+
+	if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled) {
+		wpa_printf(MSG_ERROR,
+			"P2P: P2P interface is gone, cancel join scan");
+		return -ENXIO;
+	}
+
+	os_memset(&params, 0, sizeof(params));
+	if (ssid.size() > 0) {
+		params.ssids[0].ssid = ssid.data();
+		params.ssids[0].ssid_len = ssid.size();
+	} else {
+		params.ssids[0].ssid = (u8 *) P2P_WILDCARD_SSID;
+		params.ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN;
+	}
+	wpa_printf(MSG_DEBUG, "Scan SSID %s for join with frequency %d"
+		"BSS operating_freq from scan cache %d",
+		wpa_ssid_txt(params.ssids[0].ssid, params.ssids[0].ssid_len), freq, operating_freq);
+
+	/* Construct an optimized p2p scan channel list */
+	ret = setP2pCliOptimizedScanFreqsList(wpa_s, &params, freq, operating_freq);
+	if (ret < 0) {
+		wpa_printf(MSG_ERROR,
+				   "Failed to set frequency in p2p scan params, error = %d", ret);
+		return -1;
+	}
+
+	ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
+	ies = wpabuf_alloc(ielen);
+	if (ies == NULL) {
+		if (params.freqs) {
+			os_free(params.freqs);
+		}
+		return -1;
+	}
+
+	bands = wpas_get_bands(wpa_s, params.freqs);
+	p2p_scan_ie(wpa_s->global->p2p, ies, NULL, bands);
+
+	params.p2p_probe = 1;
+	params.extra_ies = (u8 *) wpabuf_head(ies);
+	params.extra_ies_len = wpabuf_len(ies);
+	if (wpa_s->clear_driver_scan_cache) {
+		wpa_printf(MSG_DEBUG,
+			"Request driver to clear scan cache due to local BSS flush");
+		params.only_new_results = 1;
+	}
+
+	ret = wpa_drv_scan(wpa_s, &params);
+	if (!ret) {
+		os_get_reltime(&wpa_s->scan_trigger_time);
+		if (wpa_s->scan_res_handler) {
+			wpa_printf(MSG_DEBUG, "Replace current running scan result handler");
+		}
+		wpa_s->p2p_join_scan_count++;
+		wpa_s->scan_res_handler = scanResJoinWrapper;
+		wpa_s->own_scan_requested = 1;
+		wpa_s->clear_driver_scan_cache = 0;
+	}
+
+	if (params.freqs) {
+		os_free(params.freqs);
+	}
+
+	wpabuf_free(ies);
+
+	return ret;
+}
+
+static bool is6GhzAllowed(struct wpa_supplicant *wpa_s) {
+	if (!wpa_s->global->p2p) return false;
+	return wpa_s->global->p2p->allow_6ghz;
+}
+
+int joinGroup(
+	struct wpa_supplicant* wpa_s,
+	uint8_t *group_owner_bssid,
+	const std::vector<uint8_t>& ssid,
+	const std::string& passphrase)
+{
+	int ret = 0;
+	int he = wpa_s->conf->p2p_go_he;
+	int vht = wpa_s->conf->p2p_go_vht;
+	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
+
+	// Construct a network for adding group.
+	// Group client follows the persistent attribute of Group Owner.
+	// If joined group is persistent, it adds a persistent network on GroupStarted.
+	struct wpa_ssid *wpa_network = addGroupClientNetwork(
+		wpa_s, group_owner_bssid, ssid, passphrase);
+	if (wpa_network == NULL) {
+		wpa_printf(MSG_ERROR, "P2P: Cannot construct a network for group join.");
+		return -1;
+	}
+
+	// this is temporary network only for establishing the connection.
+	wpa_network->temporary = 1;
+
+	if (wpas_p2p_group_add_persistent(
+		wpa_s, wpa_network, 0, 0, 0, 0, ht40, vht,
+		CHANWIDTH_USE_HT, he, 0, NULL, 0, 0, is6GhzAllowed(wpa_s))) {
+		ret = -1;
+	}
+
+	// Always remove this temporary network at the end.
+	wpa_config_remove_network(wpa_s->conf, wpa_network->id);
+	return ret;
+}
+
+void notifyGroupJoinFailure(
+	struct wpa_supplicant* wpa_s)
+{
+	u8 zero_addr[ETH_ALEN] = {0};
+	std::vector<uint8_t> ssid = {'D', 'I', 'R', 'E','C', 'T', '-'};
+	std::string passphrase = "";
+	struct wpa_ssid *wpa_network = addGroupClientNetwork(
+		wpa_s, zero_addr, ssid, passphrase);
+	if (wpa_network) {
+		wpa_network->temporary = 1;
+		wpas_notify_p2p_group_formation_failure(wpa_s, "Failed to find the group.");
+		wpas_notify_p2p_group_removed(
+			wpa_s, wpa_network, "client");
+		wpa_config_remove_network(
+			wpa_s->conf, wpa_network->id);
+	} else {
+		wpa_printf(MSG_ERROR,
+			"P2P: Cannot construct a network.");
+	}
+}
+
+void scanResJoinIgnore(struct wpa_supplicant *wpa_s, struct wpa_scan_results *scan_res) {
+	wpa_printf(MSG_DEBUG, "P2P: Ignore group join scan results.");
+
+	if (wpa_s->p2p_scan_work) {
+		struct wpa_radio_work *work = wpa_s->p2p_scan_work;
+		wpa_s->p2p_scan_work = NULL;
+		radio_work_done(work);
+	}
+
+}
+
+static void updateP2pVendorElem(struct wpa_supplicant* wpa_s, enum wpa_vendor_elem_frame frameType,
+	const std::vector<uint8_t>& vendorElemBytes) {
+
+	wpa_printf(MSG_INFO, "Set vendor elements to frames %d", frameType);
+	struct wpa_supplicant* vendor_elem_wpa_s = wpas_vendor_elem(wpa_s, frameType);
+	if (vendor_elem_wpa_s->vendor_elem[frameType]) {
+		wpabuf_free(vendor_elem_wpa_s->vendor_elem[frameType]);
+		vendor_elem_wpa_s->vendor_elem[frameType] = NULL;
+	}
+	if (vendorElemBytes.size() > 0) {
+		vendor_elem_wpa_s->vendor_elem[frameType] =
+			wpabuf_alloc_copy(vendorElemBytes.data(), vendorElemBytes.size());
+	}
+	wpas_vendor_elem_update(vendor_elem_wpa_s);
+}
+
+uint32_t convertWpaP2pFrameTypeToHalP2pFrameTypeBit(int frameType) {
+	switch (frameType) {
+	case VENDOR_ELEM_PROBE_REQ_P2P:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_PROBE_REQ_P2P);
+	case VENDOR_ELEM_PROBE_RESP_P2P:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_PROBE_RESP_P2P);
+	case VENDOR_ELEM_PROBE_RESP_P2P_GO:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_PROBE_RESP_P2P_GO);
+	case VENDOR_ELEM_BEACON_P2P_GO:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_BEACON_P2P_GO);
+	case VENDOR_ELEM_P2P_PD_REQ:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_PD_REQ);
+	case VENDOR_ELEM_P2P_PD_RESP:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_PD_RESP);
+	case VENDOR_ELEM_P2P_GO_NEG_REQ:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_GO_NEG_REQ);
+	case VENDOR_ELEM_P2P_GO_NEG_RESP:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_GO_NEG_RESP);
+	case VENDOR_ELEM_P2P_GO_NEG_CONF:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_GO_NEG_CONF);
+	case VENDOR_ELEM_P2P_INV_REQ:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_INV_REQ);
+	case VENDOR_ELEM_P2P_INV_RESP:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_INV_RESP);
+	case VENDOR_ELEM_P2P_ASSOC_REQ:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_ASSOC_REQ);
+	case VENDOR_ELEM_P2P_ASSOC_RESP:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_ASSOC_RESP);
+	}
+	return 0;
+}
+}  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+using aidl_return_util::validateAndCall;
+using misc_utils::createStatus;
+using misc_utils::createStatusWithMsg;
+
+P2pIface::P2pIface(struct wpa_global* wpa_global, const char ifname[])
+	: wpa_global_(wpa_global), ifname_(ifname), is_valid_(true)
+{}
+
+void P2pIface::invalidate() { is_valid_ = false; }
+bool P2pIface::isValid()
+{
+	return (is_valid_ && (retrieveIfacePtr() != nullptr));
+}
+
+::ndk::ScopedAStatus P2pIface::getName(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::getNameInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pIface::getType(
+	IfaceType* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::getTypeInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pIface::addNetwork(
+	std::shared_ptr<ISupplicantP2pNetwork>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::addNetworkInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pIface::removeNetwork(
+	int32_t in_id)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::removeNetworkInternal, in_id);
+}
+
+::ndk::ScopedAStatus P2pIface::getNetwork(
+	int32_t in_id, std::shared_ptr<ISupplicantP2pNetwork>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::getNetworkInternal, _aidl_return, in_id);
+}
+
+::ndk::ScopedAStatus P2pIface::listNetworks(
+	std::vector<int32_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::listNetworksInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pIface::registerCallback(
+	const std::shared_ptr<ISupplicantP2pIfaceCallback>& in_callback)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::registerCallbackInternal, in_callback);
+}
+
+::ndk::ScopedAStatus P2pIface::getDeviceAddress(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::getDeviceAddressInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pIface::setSsidPostfix(
+	const std::vector<uint8_t>& in_postfix)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setSsidPostfixInternal, in_postfix);
+}
+
+::ndk::ScopedAStatus P2pIface::setGroupIdle(
+	const std::string& in_groupIfName, int32_t in_timeoutInSec)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setGroupIdleInternal, in_groupIfName,
+		in_timeoutInSec);
+}
+
+::ndk::ScopedAStatus P2pIface::setPowerSave(
+	const std::string& in_groupIfName, bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setPowerSaveInternal, in_groupIfName, in_enable);
+}
+
+::ndk::ScopedAStatus P2pIface::find(
+	int32_t in_timeoutInSec)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::findInternal, in_timeoutInSec);
+}
+
+::ndk::ScopedAStatus P2pIface::stopFind()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::stopFindInternal);
+}
+
+::ndk::ScopedAStatus P2pIface::flush()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::flushInternal);
+}
+
+::ndk::ScopedAStatus P2pIface::connect(
+	const std::vector<uint8_t>& in_peerAddress,
+	WpsProvisionMethod in_provisionMethod,
+	const std::string& in_preSelectedPin, bool in_joinExistingGroup,
+	bool in_persistent, int32_t in_goIntent, std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::connectInternal, _aidl_return, in_peerAddress,
+		in_provisionMethod, in_preSelectedPin, in_joinExistingGroup,
+		in_persistent, in_goIntent);
+}
+
+::ndk::ScopedAStatus P2pIface::cancelConnect()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::cancelConnectInternal);
+}
+
+::ndk::ScopedAStatus P2pIface::provisionDiscovery(
+	const std::vector<uint8_t>& in_peerAddress,
+	WpsProvisionMethod in_provisionMethod)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::provisionDiscoveryInternal, in_peerAddress,
+		in_provisionMethod);
+}
+
+ndk::ScopedAStatus P2pIface::addGroup(
+	bool in_persistent, int32_t in_persistentNetworkId)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::addGroupInternal, in_persistent,
+		in_persistentNetworkId);
+}
+
+::ndk::ScopedAStatus P2pIface::addGroupWithConfig(
+	const std::vector<uint8_t>& in_ssid,
+	const std::string& in_pskPassphrase, bool in_persistent,
+	int32_t in_freq, const std::vector<uint8_t>& in_peerAddress,
+	bool in_joinExistingGroup)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::addGroupWithConfigInternal, in_ssid,
+		in_pskPassphrase, in_persistent, in_freq,
+		in_peerAddress, in_joinExistingGroup);
+}
+
+::ndk::ScopedAStatus P2pIface::removeGroup(
+	const std::string& in_groupIfName)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::removeGroupInternal, in_groupIfName);
+}
+
+::ndk::ScopedAStatus P2pIface::reject(
+	const std::vector<uint8_t>& in_peerAddress)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::rejectInternal, in_peerAddress);
+}
+
+::ndk::ScopedAStatus P2pIface::invite(
+	const std::string& in_groupIfName,
+	const std::vector<uint8_t>& in_goDeviceAddress,
+	const std::vector<uint8_t>& in_peerAddress)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::inviteInternal, in_groupIfName,
+		in_goDeviceAddress, in_peerAddress);
+}
+
+::ndk::ScopedAStatus P2pIface::reinvoke(
+	int32_t in_persistentNetworkId,
+	const std::vector<uint8_t>& in_peerAddress)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::reinvokeInternal, in_persistentNetworkId,
+		in_peerAddress);
+}
+
+::ndk::ScopedAStatus P2pIface::configureExtListen(
+	int32_t in_periodInMillis, int32_t in_intervalInMillis)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::configureExtListenInternal, in_periodInMillis,
+		in_intervalInMillis);
+}
+
+::ndk::ScopedAStatus P2pIface::setListenChannel(
+	int32_t in_channel, int32_t in_operatingClass)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setListenChannelInternal, in_channel,
+		in_operatingClass);
+}
+
+::ndk::ScopedAStatus P2pIface::setDisallowedFrequencies(
+	const std::vector<FreqRange>& in_ranges)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setDisallowedFrequenciesInternal, in_ranges);
+}
+
+::ndk::ScopedAStatus P2pIface::getSsid(
+	const std::vector<uint8_t>& in_peerAddress,
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::getSsidInternal, _aidl_return, in_peerAddress);
+}
+
+::ndk::ScopedAStatus P2pIface::getGroupCapability(
+	const std::vector<uint8_t>& in_peerAddress,
+	P2pGroupCapabilityMask* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::getGroupCapabilityInternal, _aidl_return, in_peerAddress);
+}
+
+::ndk::ScopedAStatus P2pIface::addBonjourService(
+	const std::vector<uint8_t>& in_query,
+	const std::vector<uint8_t>& in_response)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::addBonjourServiceInternal, in_query, in_response);
+}
+
+::ndk::ScopedAStatus P2pIface::removeBonjourService(
+	const std::vector<uint8_t>& in_query)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::removeBonjourServiceInternal, in_query);
+}
+
+::ndk::ScopedAStatus P2pIface::addUpnpService(
+	int32_t in_version, const std::string& in_serviceName)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::addUpnpServiceInternal, in_version, in_serviceName);
+}
+
+::ndk::ScopedAStatus P2pIface::removeUpnpService(
+	int32_t in_version, const std::string& in_serviceName)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::removeUpnpServiceInternal, in_version,
+		in_serviceName);
+}
+
+::ndk::ScopedAStatus P2pIface::flushServices()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::flushServicesInternal);
+}
+
+::ndk::ScopedAStatus P2pIface::requestServiceDiscovery(
+	const std::vector<uint8_t>& in_peerAddress,
+	const std::vector<uint8_t>& in_query,
+	int64_t* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::requestServiceDiscoveryInternal, _aidl_return,
+		in_peerAddress, in_query);
+}
+
+::ndk::ScopedAStatus P2pIface::cancelServiceDiscovery(
+	int64_t in_identifier)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::cancelServiceDiscoveryInternal, in_identifier);
+}
+
+::ndk::ScopedAStatus P2pIface::setMiracastMode(
+	MiracastMode in_mode)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setMiracastModeInternal, in_mode);
+}
+
+::ndk::ScopedAStatus P2pIface::startWpsPbc(
+	const std::string& in_groupIfName,
+	const std::vector<uint8_t>& in_bssid)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::startWpsPbcInternal, in_groupIfName, in_bssid);
+}
+
+::ndk::ScopedAStatus P2pIface::startWpsPinKeypad(
+	const std::string& in_groupIfName,
+	const std::string& in_pin)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::startWpsPinKeypadInternal, in_groupIfName, in_pin);
+}
+
+::ndk::ScopedAStatus P2pIface::startWpsPinDisplay(
+	const std::string& in_groupIfName,
+	const std::vector<uint8_t>& in_bssid,
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::startWpsPinDisplayInternal, _aidl_return,
+		in_groupIfName, in_bssid);
+}
+
+::ndk::ScopedAStatus P2pIface::cancelWps(
+	const std::string& in_groupIfName)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::cancelWpsInternal, in_groupIfName);
+}
+
+::ndk::ScopedAStatus P2pIface::setWpsDeviceName(
+	const std::string& in_name)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setWpsDeviceNameInternal, in_name);
+}
+
+::ndk::ScopedAStatus P2pIface::setWpsDeviceType(
+	const std::vector<uint8_t>& in_type)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setWpsDeviceTypeInternal, in_type);
+}
+
+::ndk::ScopedAStatus P2pIface::setWpsManufacturer(
+	const std::string& in_manufacturer)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setWpsManufacturerInternal, in_manufacturer);
+}
+
+::ndk::ScopedAStatus P2pIface::setWpsModelName(
+	const std::string& in_modelName)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setWpsModelNameInternal, in_modelName);
+}
+
+::ndk::ScopedAStatus P2pIface::setWpsModelNumber(
+	const std::string& in_modelNumber)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setWpsModelNumberInternal, in_modelNumber);
+}
+
+::ndk::ScopedAStatus P2pIface::setWpsSerialNumber(
+	const std::string& in_serialNumber)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setWpsSerialNumberInternal, in_serialNumber);
+}
+
+::ndk::ScopedAStatus P2pIface::setWpsConfigMethods(
+	WpsConfigMethods in_configMethods)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setWpsConfigMethodsInternal, in_configMethods);
+}
+
+::ndk::ScopedAStatus P2pIface::enableWfd(
+	bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::enableWfdInternal, in_enable);
+}
+
+::ndk::ScopedAStatus P2pIface::setWfdDeviceInfo(
+	const std::vector<uint8_t>& in_info)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setWfdDeviceInfoInternal, in_info);
+}
+
+::ndk::ScopedAStatus P2pIface::createNfcHandoverRequestMessage(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::createNfcHandoverRequestMessageInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pIface::createNfcHandoverSelectMessage(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::createNfcHandoverSelectMessageInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pIface::reportNfcHandoverResponse(
+	const std::vector<uint8_t>& in_request)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::reportNfcHandoverResponseInternal, in_request);
+}
+
+::ndk::ScopedAStatus P2pIface::reportNfcHandoverInitiation(
+	const std::vector<uint8_t>& in_select)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::reportNfcHandoverInitiationInternal, in_select);
+}
+
+::ndk::ScopedAStatus P2pIface::saveConfig()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::saveConfigInternal);
+}
+
+::ndk::ScopedAStatus P2pIface::setMacRandomization(
+	bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setMacRandomizationInternal, in_enable);
+}
+
+::ndk::ScopedAStatus P2pIface::setEdmg(
+	bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&P2pIface::setEdmgInternal, in_enable);
+}
+
+::ndk::ScopedAStatus P2pIface::getEdmg(
+	bool* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&P2pIface::getEdmgInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pIface::setWfdR2DeviceInfo(
+	const std::vector<uint8_t>& in_info)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setWfdR2DeviceInfoInternal, in_info);
+}
+
+::ndk::ScopedAStatus P2pIface::removeClient(
+        const std::vector<uint8_t>& peer_address, bool isLegacyClient)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::removeClientInternal, peer_address, isLegacyClient);
+}
+
+::ndk::ScopedAStatus P2pIface::findOnSocialChannels(
+	int32_t in_timeoutInSec)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::findOnSocialChannelsInternal, in_timeoutInSec);
+}
+
+::ndk::ScopedAStatus P2pIface::findOnSpecificFrequency(
+	int32_t in_freq,
+	int32_t in_timeoutInSec)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::findOnSpecificFrequencyInternal,
+		in_freq, in_timeoutInSec);
+}
+
+::ndk::ScopedAStatus P2pIface::setVendorElements(
+	P2pFrameTypeMask in_frameTypeMask,
+	const std::vector<uint8_t>& in_vendorElemBytes)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setVendorElementsInternal, in_frameTypeMask, in_vendorElemBytes);
+}
+
+std::pair<std::string, ndk::ScopedAStatus> P2pIface::getNameInternal()
+{
+	return {ifname_, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<IfaceType, ndk::ScopedAStatus> P2pIface::getTypeInternal()
+{
+	return {IfaceType::P2P, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::shared_ptr<ISupplicantP2pNetwork>, ndk::ScopedAStatus>
+P2pIface::addNetworkInternal()
+{
+	std::shared_ptr<ISupplicantP2pNetwork> network;
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	struct wpa_ssid* ssid = wpa_supplicant_add_network(wpa_s);
+	if (!ssid) {
+		return {network, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	AidlManager* aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager ||
+		aidl_manager->getP2pNetworkAidlObjectByIfnameAndNetworkId(
+		wpa_s->ifname, ssid->id, &network)) {
+		return {network, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {network, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus P2pIface::removeNetworkInternal(int32_t id)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	int result = wpa_supplicant_remove_network(wpa_s, id);
+	if (result == -1) {
+		return createStatus(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN);
+	} else if (result != 0) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::shared_ptr<ISupplicantP2pNetwork>, ndk::ScopedAStatus>
+P2pIface::getNetworkInternal(int32_t id)
+{
+	std::shared_ptr<ISupplicantP2pNetwork> network;
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	struct wpa_ssid* ssid = wpa_config_get_network(wpa_s->conf, id);
+	if (!ssid) {
+		return {network, createStatus(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN)};
+	}
+	AidlManager* aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager ||
+		aidl_manager->getP2pNetworkAidlObjectByIfnameAndNetworkId(
+		wpa_s->ifname, ssid->id, &network)) {
+		return {network, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {network, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<int32_t>, ndk::ScopedAStatus>
+P2pIface::listNetworksInternal()
+{
+	std::vector<int32_t> network_ids;
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	for (struct wpa_ssid* wpa_ssid = wpa_s->conf->ssid; wpa_ssid;
+		 wpa_ssid = wpa_ssid->next) {
+		network_ids.emplace_back(wpa_ssid->id);
+	}
+	return {std::move(network_ids), ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus P2pIface::registerCallbackInternal(
+	const std::shared_ptr<ISupplicantP2pIfaceCallback>& callback)
+{
+	AidlManager* aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager ||
+		aidl_manager->addP2pIfaceCallbackAidlObject(ifname_, callback)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+P2pIface::getDeviceAddressInternal()
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	std::vector<uint8_t> addr(
+		wpa_s->global->p2p_dev_addr,
+		wpa_s->global->p2p_dev_addr + ETH_ALEN);
+	return {addr, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus P2pIface::setSsidPostfixInternal(
+	const std::vector<uint8_t>& postfix)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (p2p_set_ssid_postfix(
+		wpa_s->global->p2p, postfix.data(), postfix.size())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::setGroupIdleInternal(
+	const std::string& group_ifname, uint32_t timeout_in_sec)
+{
+	struct wpa_supplicant* wpa_group_s =
+		retrieveGroupIfacePtr(group_ifname);
+	if (!wpa_group_s) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
+	}
+	wpa_group_s->conf->p2p_group_idle = timeout_in_sec;
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::setPowerSaveInternal(
+	const std::string& group_ifname, bool enable)
+{
+	struct wpa_supplicant* wpa_group_s =
+		retrieveGroupIfacePtr(group_ifname);
+	if (!wpa_group_s) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
+	}
+	if (wpa_drv_set_p2p_powersave(wpa_group_s, enable, -1, -1)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::findInternal(uint32_t timeout_in_sec)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
+	}
+	uint32_t search_delay = wpas_p2p_search_delay(wpa_s);
+	if (wpas_p2p_find(
+		wpa_s, timeout_in_sec, P2P_FIND_START_WITH_FULL, 0, nullptr,
+		nullptr, search_delay, 0, nullptr, 0, is6GhzAllowed(wpa_s))) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::stopFindInternal()
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
+	}
+	if (wpa_s->scan_res_handler == scanResJoinWrapper) {
+		wpa_printf(MSG_DEBUG, "P2P: Stop pending group scan for stopping find).");
+		pending_scan_res_join_callback = NULL;
+		wpa_s->scan_res_handler = scanResJoinIgnore;
+	}
+	wpas_p2p_stop_find(wpa_s);
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::flushInternal()
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
+	wpa_s->force_long_sd = 0;
+	wpas_p2p_stop_find(wpa_s);
+	wpa_s->parent->p2ps_method_config_any = 0;
+	wpa_bss_flush(wpa_s);
+	if (wpa_s->global->p2p)
+		p2p_flush(wpa_s->global->p2p);
+	return ndk::ScopedAStatus::ok();
+}
+
+// This method only implements support for subset (needed by Android framework)
+// of parameters that can be specified for connect.
+std::pair<std::string, ndk::ScopedAStatus> P2pIface::connectInternal(
+	const std::vector<uint8_t>& peer_address,
+	WpsProvisionMethod provision_method,
+	const std::string& pre_selected_pin, bool join_existing_group,
+	bool persistent, uint32_t go_intent)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (go_intent > 15) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID)};
+	}
+	int go_intent_signed = join_existing_group ? -1 : go_intent;
+	p2p_wps_method wps_method = {};
+	switch (provision_method) {
+	case WpsProvisionMethod::PBC:
+		wps_method = WPS_PBC;
+		break;
+	case WpsProvisionMethod::DISPLAY:
+		wps_method = WPS_PIN_DISPLAY;
+		break;
+	case WpsProvisionMethod::KEYPAD:
+		wps_method = WPS_PIN_KEYPAD;
+		break;
+	}
+	int he = wpa_s->conf->p2p_go_he;
+	int vht = wpa_s->conf->p2p_go_vht;
+	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
+	const char* pin =
+		pre_selected_pin.length() > 0 ? pre_selected_pin.data() : nullptr;
+	bool auto_join = !join_existing_group;
+	int new_pin = wpas_p2p_connect(
+		wpa_s, peer_address.data(), pin, wps_method, persistent, auto_join,
+		join_existing_group, false, go_intent_signed, 0, 0, -1, false, ht40,
+		vht, CHANWIDTH_USE_HT, he, 0, nullptr, 0, is6GhzAllowed(wpa_s));
+	if (new_pin < 0) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	std::string pin_ret;
+	if (provision_method == WpsProvisionMethod::DISPLAY &&
+		pre_selected_pin.empty()) {
+		pin_ret = misc_utils::convertWpsPinToString(new_pin);
+	}
+	return {pin_ret, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus P2pIface::cancelConnectInternal()
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (wpa_s->scan_res_handler == scanResJoinWrapper) {
+		wpa_printf(MSG_DEBUG, "P2P: Stop pending group scan for canceling connect");
+		pending_scan_res_join_callback = NULL;
+		wpa_s->scan_res_handler = scanResJoinIgnore;
+	}
+	if (wpas_p2p_cancel(wpa_s)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::provisionDiscoveryInternal(
+	const std::vector<uint8_t>& peer_address,
+	WpsProvisionMethod provision_method)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	p2ps_provision* prov_param;
+	const char* config_method_str = nullptr;
+	switch (provision_method) {
+	case WpsProvisionMethod::PBC:
+		config_method_str = kConfigMethodStrPbc;
+		break;
+	case WpsProvisionMethod::DISPLAY:
+		config_method_str = kConfigMethodStrDisplay;
+		break;
+	case WpsProvisionMethod::KEYPAD:
+		config_method_str = kConfigMethodStrKeypad;
+		break;
+	}
+	if (wpas_p2p_prov_disc(
+		wpa_s, peer_address.data(), config_method_str,
+		WPAS_P2P_PD_FOR_GO_NEG, nullptr)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::removeGroupInternal(const std::string& group_ifname)
+{
+	struct wpa_supplicant* wpa_group_s =
+		retrieveGroupIfacePtr(group_ifname);
+	if (!wpa_group_s) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
+	}
+	wpa_group_s->global->p2p_go_found_external_scan = 0;
+	if (wpas_p2p_group_remove(wpa_group_s, group_ifname.c_str())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::rejectInternal(
+	const std::vector<uint8_t>& peer_address)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
+	}
+	if (wpas_p2p_reject(wpa_s, peer_address.data())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::inviteInternal(
+	const std::string& group_ifname,
+	const std::vector<uint8_t>& go_device_address,
+	const std::vector<uint8_t>& peer_address)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (wpas_p2p_invite_group(
+		wpa_s, group_ifname.c_str(), peer_address.data(),
+		go_device_address.data(), is6GhzAllowed(wpa_s))) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::reinvokeInternal(
+	int32_t persistent_network_id,
+	const std::vector<uint8_t>& peer_address)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	int he = wpa_s->conf->p2p_go_he;
+	int vht = wpa_s->conf->p2p_go_vht;
+	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
+	struct wpa_ssid* ssid =
+		wpa_config_get_network(wpa_s->conf, persistent_network_id);
+	if (ssid == NULL || ssid->disabled != 2) {
+		return createStatus(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN);
+	}
+	if (wpas_p2p_invite(
+		wpa_s, peer_address.data(), ssid, NULL, 0, 0, ht40, vht,
+		CHANWIDTH_USE_HT, 0, he, 0, is6GhzAllowed(wpa_s))) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::configureExtListenInternal(
+	uint32_t period_in_millis, uint32_t interval_in_millis)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (wpas_p2p_ext_listen(wpa_s, period_in_millis, interval_in_millis)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::setListenChannelInternal(
+	uint32_t channel, uint32_t operating_class)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (p2p_set_listen_channel(
+		wpa_s->global->p2p, operating_class, channel, 1)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::setDisallowedFrequenciesInternal(
+	const std::vector<FreqRange>& ranges)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	using DestT = struct wpa_freq_range_list::wpa_freq_range;
+	DestT* freq_ranges = nullptr;
+	// Empty ranges is used to enable all frequencies.
+	if (ranges.size() != 0) {
+		freq_ranges = static_cast<DestT*>(
+			os_malloc(sizeof(DestT) * ranges.size()));
+		if (!freq_ranges) {
+			return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+		}
+		uint32_t i = 0;
+		for (const auto& range : ranges) {
+			freq_ranges[i].min = range.min;
+			freq_ranges[i].max = range.max;
+			i++;
+		}
+	}
+
+	os_free(wpa_s->global->p2p_disallow_freq.range);
+	wpa_s->global->p2p_disallow_freq.range = freq_ranges;
+	wpa_s->global->p2p_disallow_freq.num = ranges.size();
+	wpas_p2p_update_channel_list(wpa_s, WPAS_P2P_CHANNEL_UPDATE_DISALLOW);
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> P2pIface::getSsidInternal(
+	const std::vector<uint8_t>& peer_address)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	const struct p2p_peer_info* info =
+		p2p_get_peer_info(wpa_s->global->p2p, peer_address.data(), 0);
+	if (!info) {
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	const struct p2p_device* dev =
+		reinterpret_cast<const struct p2p_device*>(
+		(reinterpret_cast<const uint8_t*>(info)) -
+		offsetof(struct p2p_device, info));
+	std::vector<uint8_t> ssid;
+	if (dev && dev->oper_ssid_len) {
+		ssid.assign(
+			dev->oper_ssid, dev->oper_ssid + dev->oper_ssid_len);
+	}
+	return {ssid, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<P2pGroupCapabilityMask, ndk::ScopedAStatus> P2pIface::getGroupCapabilityInternal(
+	const std::vector<uint8_t>& peer_address)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	const struct p2p_peer_info* info =
+		p2p_get_peer_info(wpa_s->global->p2p, peer_address.data(), 0);
+	if (!info) {
+		return {static_cast<P2pGroupCapabilityMask>(0),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {static_cast<P2pGroupCapabilityMask>(info->group_capab),
+		ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus P2pIface::addBonjourServiceInternal(
+	const std::vector<uint8_t>& query, const std::vector<uint8_t>& response)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	auto query_buf = misc_utils::convertVectorToWpaBuf(query);
+	auto response_buf = misc_utils::convertVectorToWpaBuf(response);
+	if (!query_buf || !response_buf) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	if (wpas_p2p_service_add_bonjour(
+		wpa_s, query_buf.get(), response_buf.get())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	// If successful, the wpabuf is referenced internally and hence should
+	// not be freed.
+	query_buf.release();
+	response_buf.release();
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::removeBonjourServiceInternal(
+	const std::vector<uint8_t>& query)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	auto query_buf = misc_utils::convertVectorToWpaBuf(query);
+	if (!query_buf) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	if (wpas_p2p_service_del_bonjour(wpa_s, query_buf.get())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::addUpnpServiceInternal(
+	uint32_t version, const std::string& service_name)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (wpas_p2p_service_add_upnp(wpa_s, version, service_name.c_str())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::removeUpnpServiceInternal(
+	uint32_t version, const std::string& service_name)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (wpas_p2p_service_del_upnp(wpa_s, version, service_name.c_str())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::flushServicesInternal()
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	wpas_p2p_service_flush(wpa_s);
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<uint64_t, ndk::ScopedAStatus> P2pIface::requestServiceDiscoveryInternal(
+	const std::vector<uint8_t>& peer_address,
+	const std::vector<uint8_t>& query)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	auto query_buf = misc_utils::convertVectorToWpaBuf(query);
+	if (!query_buf) {
+		return {0, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	const uint8_t* dst_addr = is_zero_ether_addr(peer_address.data())
+					  ? nullptr
+					  : peer_address.data();
+	uint64_t identifier =
+		wpas_p2p_sd_request(wpa_s, dst_addr, query_buf.get());
+	if (identifier == 0) {
+		return {0, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {identifier, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus P2pIface::cancelServiceDiscoveryInternal(uint64_t identifier)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (wpas_p2p_sd_cancel_request(wpa_s, identifier)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::setMiracastModeInternal(
+	MiracastMode mode)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	uint8_t mode_internal = convertAidlMiracastModeToInternal(mode);
+	const std::string cmd_str =
+		kSetMiracastMode + std::to_string(mode_internal);
+	std::vector<char> cmd(
+		cmd_str.c_str(), cmd_str.c_str() + cmd_str.size() + 1);
+	char driver_cmd_reply_buf[4096] = {};
+	if (wpa_drv_driver_cmd(
+		wpa_s, cmd.data(), driver_cmd_reply_buf,
+		sizeof(driver_cmd_reply_buf))) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::startWpsPbcInternal(
+	const std::string& group_ifname, const std::vector<uint8_t>& bssid)
+{
+	struct wpa_supplicant* wpa_group_s =
+		retrieveGroupIfacePtr(group_ifname);
+	if (!wpa_group_s) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
+	}
+	const uint8_t* bssid_addr =
+		is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
+#ifdef CONFIG_AP
+	if (wpa_group_s->ap_iface) {
+		if (wpa_supplicant_ap_wps_pbc(wpa_group_s, bssid_addr, NULL)) {
+			return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+		}
+		return ndk::ScopedAStatus::ok();
+	}
+#endif /* CONFIG_AP */
+	if (wpas_wps_start_pbc(wpa_group_s, bssid_addr, 0, 0)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::startWpsPinKeypadInternal(
+	const std::string& group_ifname, const std::string& pin)
+{
+	struct wpa_supplicant* wpa_group_s =
+		retrieveGroupIfacePtr(group_ifname);
+	if (!wpa_group_s) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
+	}
+#ifdef CONFIG_AP
+	if (wpa_group_s->ap_iface) {
+		if (wpa_supplicant_ap_wps_pin(
+			wpa_group_s, nullptr, pin.c_str(), nullptr, 0, 0) < 0) {
+			return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+		}
+		return ndk::ScopedAStatus::ok();
+	}
+#endif /* CONFIG_AP */
+	if (wpas_wps_start_pin(
+		wpa_group_s, nullptr, pin.c_str(), 0, DEV_PW_DEFAULT)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::string, ndk::ScopedAStatus> P2pIface::startWpsPinDisplayInternal(
+	const std::string& group_ifname, const std::vector<uint8_t>& bssid)
+{
+	struct wpa_supplicant* wpa_group_s =
+		retrieveGroupIfacePtr(group_ifname);
+	if (!wpa_group_s) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN)};
+	}
+	const uint8_t* bssid_addr =
+		is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
+	int pin = wpas_wps_start_pin(
+		wpa_group_s, bssid_addr, nullptr, 0, DEV_PW_DEFAULT);
+	if (pin < 0) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::convertWpsPinToString(pin), ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus P2pIface::cancelWpsInternal(const std::string& group_ifname)
+{
+	struct wpa_supplicant* wpa_group_s =
+		retrieveGroupIfacePtr(group_ifname);
+	if (!wpa_group_s) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
+	}
+	if (wpas_wps_cancel(wpa_group_s)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::setWpsDeviceNameInternal(const std::string& name)
+{
+	return iface_config_utils::setWpsDeviceName(retrieveIfacePtr(), name);
+}
+
+ndk::ScopedAStatus P2pIface::setWpsDeviceTypeInternal(
+	const std::vector<uint8_t>& type)
+{
+	std::array<uint8_t, 8> type_arr;
+	std::copy_n(type.begin(), 8, type_arr.begin());
+	return iface_config_utils::setWpsDeviceType(retrieveIfacePtr(), type_arr);
+}
+
+ndk::ScopedAStatus P2pIface::setWpsManufacturerInternal(
+	const std::string& manufacturer)
+{
+	return iface_config_utils::setWpsManufacturer(
+		retrieveIfacePtr(), manufacturer);
+}
+
+ndk::ScopedAStatus P2pIface::setWpsModelNameInternal(
+	const std::string& model_name)
+{
+	return iface_config_utils::setWpsModelName(
+		retrieveIfacePtr(), model_name);
+}
+
+ndk::ScopedAStatus P2pIface::setWpsModelNumberInternal(
+	const std::string& model_number)
+{
+	return iface_config_utils::setWpsModelNumber(
+		retrieveIfacePtr(), model_number);
+}
+
+ndk::ScopedAStatus P2pIface::setWpsSerialNumberInternal(
+	const std::string& serial_number)
+{
+	return iface_config_utils::setWpsSerialNumber(
+		retrieveIfacePtr(), serial_number);
+}
+
+ndk::ScopedAStatus P2pIface::setWpsConfigMethodsInternal(WpsConfigMethods config_methods)
+{
+
+	return iface_config_utils::setWpsConfigMethods(
+		retrieveIfacePtr(), static_cast<uint16_t>(config_methods));
+}
+
+ndk::ScopedAStatus P2pIface::enableWfdInternal(bool enable)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	wifi_display_enable(wpa_s->global, enable);
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::setWfdDeviceInfoInternal(
+	const std::vector<uint8_t>& info)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	std::vector<char> wfd_device_info_hex(info.size() * 2 + 1);
+	wpa_snprintf_hex(
+		wfd_device_info_hex.data(), wfd_device_info_hex.size(), info.data(),
+		info.size());
+	// |wifi_display_subelem_set| expects the first 2 bytes
+	// to hold the lenght of the subelement. In this case it's
+	// fixed to 6, so prepend that.
+	std::string wfd_device_info_set_cmd_str =
+		std::to_string(kWfdDeviceInfoSubelemId) + " " +
+		kWfdDeviceInfoSubelemLenHexStr + wfd_device_info_hex.data();
+	std::vector<char> wfd_device_info_set_cmd(
+		wfd_device_info_set_cmd_str.c_str(),
+		wfd_device_info_set_cmd_str.c_str() +
+		wfd_device_info_set_cmd_str.size() + 1);
+	if (wifi_display_subelem_set(
+		wpa_s->global, wfd_device_info_set_cmd.data())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+P2pIface::createNfcHandoverRequestMessageInternal()
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	auto buf = misc_utils::createWpaBufUniquePtr(
+		wpas_p2p_nfc_handover_req(wpa_s, 1));
+	if (!buf) {
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::convertWpaBufToVector(buf.get()),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+P2pIface::createNfcHandoverSelectMessageInternal()
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	auto buf = misc_utils::createWpaBufUniquePtr(
+		wpas_p2p_nfc_handover_sel(wpa_s, 1, 0));
+	if (!buf) {
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::convertWpaBufToVector(buf.get()),
+		ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus P2pIface::reportNfcHandoverResponseInternal(
+	const std::vector<uint8_t>& request)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	auto req = misc_utils::convertVectorToWpaBuf(request);
+	auto sel = misc_utils::convertVectorToWpaBuf(std::vector<uint8_t>{0});
+	if (!req || !sel) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	if (wpas_p2p_nfc_report_handover(wpa_s, 0, req.get(), sel.get(), 0)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::reportNfcHandoverInitiationInternal(
+	const std::vector<uint8_t>& select)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	auto req = misc_utils::convertVectorToWpaBuf(std::vector<uint8_t>{0});
+	auto sel = misc_utils::convertVectorToWpaBuf(select);
+	if (!req || !sel) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	if (wpas_p2p_nfc_report_handover(wpa_s, 1, req.get(), sel.get(), 0)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::saveConfigInternal()
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (!wpa_s->conf->update_config) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	if (wpa_config_write(wpa_s->confname, wpa_s->conf)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::addGroupInternal(
+	bool persistent, int32_t persistent_network_id)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	int he = wpa_s->conf->p2p_go_he;
+	int vht = wpa_s->conf->p2p_go_vht;
+	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
+	struct wpa_ssid* ssid =
+		wpa_config_get_network(wpa_s->conf, persistent_network_id);
+	if (ssid == NULL) {
+		if (wpas_p2p_group_add(
+			wpa_s, persistent, 0, 0, ht40, vht,
+			CHANWIDTH_USE_HT, he, 0, is6GhzAllowed(wpa_s))) {
+			return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+		} else {
+			return ndk::ScopedAStatus::ok();
+		}
+	} else if (ssid->disabled == 2) {
+		if (wpas_p2p_group_add_persistent(
+			wpa_s, ssid, 0, 0, 0, 0, ht40, vht,
+			CHANWIDTH_USE_HT, he, 0, NULL, 0, 0, is6GhzAllowed(wpa_s))) {
+			return createStatus(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN);
+		} else {
+			return ndk::ScopedAStatus::ok();
+		}
+	}
+	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+}
+
+ndk::ScopedAStatus P2pIface::addGroupWithConfigInternal(
+	const std::vector<uint8_t>& ssid, const std::string& passphrase,
+	bool persistent, uint32_t freq, const std::vector<uint8_t>& peer_address,
+	bool joinExistingGroup)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	int he = wpa_s->conf->p2p_go_he;
+	int vht = wpa_s->conf->p2p_go_vht;
+	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
+
+	if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
+	}
+
+	if (!isSsidValid(ssid)) {
+		return createStatusWithMsg(SupplicantStatusCode::FAILURE_ARGS_INVALID,
+			"SSID is invalid.");
+	}
+
+	if (!isPskPassphraseValid(passphrase)) {
+		return createStatusWithMsg(SupplicantStatusCode::FAILURE_ARGS_INVALID,
+			"Passphrase is invalid.");
+	}
+
+	if (!joinExistingGroup) {
+		struct p2p_data *p2p = wpa_s->global->p2p;
+		os_memcpy(p2p->ssid, ssid.data(), ssid.size());
+		p2p->ssid_len = ssid.size();
+		p2p->ssid_set = 1;
+
+		os_memset(p2p->passphrase, 0, sizeof(p2p->passphrase));
+		os_memcpy(p2p->passphrase, passphrase.c_str(), passphrase.length());
+		p2p->passphrase_set = 1;
+
+		if (wpas_p2p_group_add(
+			wpa_s, persistent, freq, 0, ht40, vht,
+			CHANWIDTH_USE_HT, he, 0, is6GhzAllowed(wpa_s))) {
+			return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+		}
+		return ndk::ScopedAStatus::ok();
+	}
+
+	// The rest is for group join.
+	wpa_printf(MSG_DEBUG, "P2P: Stop any on-going P2P FIND before group join.");
+	wpas_p2p_stop_find(wpa_s);
+
+	if (pending_scan_res_join_callback != NULL) {
+		wpa_printf(MSG_WARNING, "P2P: Renew scan result callback with new request.");
+	}
+
+	pending_join_scan_callback =
+		[wpa_s, ssid, peer_address, freq]() {
+		if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled) {
+			return;
+		}
+		int operating_freq = 0;
+		struct wpa_bss *bss = findBssBySsidFromAnyInterface(
+			wpa_s->global->ifaces, peer_address.data(), ssid.data(), ssid.size());
+		if (bss != NULL) {
+			wpa_printf(MSG_DEBUG, "P2P: Found Group owner " MACSTR "in scan cache",
+				MAC2STR(bss->bssid));
+			operating_freq = bss->freq;
+		}
+
+		int ret = joinScanReq(wpa_s, ssid, freq, operating_freq);
+		// for BUSY case, the scan might be occupied by WiFi.
+		// Do not give up immediately, but try again later.
+		if (-EBUSY == ret) {
+			// re-schedule this join scan
+			eloop_cancel_timeout(joinScanWrapper, wpa_s, NULL);
+			eloop_register_timeout(0, P2P_JOIN_SINGLE_CHANNEL_SCAN_INTERVAL_USECS,
+					joinScanWrapper, wpa_s, NULL);
+		} else if (0 != ret) {
+			notifyGroupJoinFailure(wpa_s);
+			pending_scan_res_join_callback = NULL;
+		}
+	};
+
+	pending_scan_res_join_callback = [wpa_s, ssid, passphrase, peer_address, freq, this]() {
+		if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled) {
+			return;
+		}
+
+		wpa_printf(MSG_DEBUG, "P2P: Scan results received for join (reinvoke).");
+
+		struct wpa_bss *bss = findBssBySsid(
+			wpa_s, peer_address.data(), ssid.data(), ssid.size());
+		if (bss) {
+			wpa_s->global->p2p_go_found_external_scan = 1;
+			if (0 != joinGroup(wpa_s, bss->bssid, ssid, passphrase)) {
+				wpa_printf(MSG_ERROR, "P2P: Failed to join a group.");
+				wpa_s->global->p2p_go_found_external_scan = 0;
+			}
+			// no need to notify group join failure here,
+			// it will be handled by wpas_p2p_group_add_persistent
+			// called in joinGroup.
+			pending_scan_res_join_callback = NULL;
+			return;
+		}
+		wpa_printf(MSG_DEBUG, "P2P: Join scan count %d.", wpa_s->p2p_join_scan_count);
+		eloop_cancel_timeout(joinScanWrapper, wpa_s, NULL);
+		if (wpa_s->p2p_join_scan_count < P2P_MAX_JOIN_SCAN_ATTEMPTS) {
+			wpa_printf(MSG_DEBUG, "P2P: Try join again later.");
+			eloop_register_timeout(0, getP2pJoinScanIntervalUsecs(freq),
+				joinScanWrapper, wpa_s, this);
+			return;
+		}
+
+		wpa_printf(MSG_ERROR, "P2P: Failed to find the group with "
+			"network name %s - stop join attempt",
+			wpa_ssid_txt(ssid.data(), ssid.size()));
+		notifyGroupJoinFailure(wpa_s);
+		pending_scan_res_join_callback = NULL;
+	};
+
+	wpa_s->p2p_join_scan_count = 0;
+	pending_join_scan_callback();
+	if (pending_scan_res_join_callback == NULL) {
+		return createStatusWithMsg(SupplicantStatusCode::FAILURE_UNKNOWN,
+			"Failed to start scan.");
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::setMacRandomizationInternal(bool enable)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	bool currentEnabledState = !!wpa_s->conf->p2p_device_random_mac_addr;
+	u8 *addr = NULL;
+
+	// The same state, no change is needed.
+	if (currentEnabledState == enable) {
+		wpa_printf(MSG_DEBUG, "The random MAC is %s already.",
+			(enable) ? "enabled" : "disabled");
+		return ndk::ScopedAStatus::ok();
+	}
+
+	if (enable) {
+		wpa_s->conf->p2p_device_random_mac_addr = 1;
+		wpa_s->conf->p2p_interface_random_mac_addr = 1;
+
+		// restore config if it failed to set up MAC address.
+		if (wpas_p2p_mac_setup(wpa_s) < 0) {
+			wpa_s->conf->p2p_device_random_mac_addr = 0;
+			wpa_s->conf->p2p_interface_random_mac_addr = 0;
+			return createStatusWithMsg(SupplicantStatusCode::FAILURE_UNKNOWN,
+				"Failed to set up MAC address.");
+		}
+	} else {
+		// disable random MAC will use original MAC address
+		// regardless of any saved persistent groups.
+		if (wpa_drv_set_mac_addr(wpa_s, NULL) < 0) {
+			wpa_printf(MSG_ERROR, "Failed to restore MAC address");
+			return createStatusWithMsg(SupplicantStatusCode::FAILURE_UNKNOWN,
+				"Failed to restore MAC address.");
+		}
+
+		if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
+			wpa_printf(MSG_INFO, "Could not update MAC address information");
+			return createStatusWithMsg(SupplicantStatusCode::FAILURE_UNKNOWN,
+				"Failed to update MAC address.");
+		}
+		wpa_s->conf->p2p_device_random_mac_addr = 0;
+		wpa_s->conf->p2p_interface_random_mac_addr = 0;
+	}
+
+	// update internal data to send out correct device address in action frame.
+	os_memcpy(wpa_s->global->p2p_dev_addr, wpa_s->own_addr, ETH_ALEN);
+	os_memcpy(wpa_s->global->p2p->cfg->dev_addr, wpa_s->global->p2p_dev_addr, ETH_ALEN);
+
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::setEdmgInternal(bool enable)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	wpa_printf(MSG_DEBUG, "set p2p_go_edmg to %d", enable);
+	wpa_s->conf->p2p_go_edmg = enable ? 1 : 0;
+	wpa_s->p2p_go_edmg = enable ? 1 : 0;
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<bool, ndk::ScopedAStatus> P2pIface::getEdmgInternal()
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	return {(wpa_s->p2p_go_edmg == 1), ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus P2pIface::setWfdR2DeviceInfoInternal(
+	const std::vector<uint8_t>& info)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	uint32_t wfd_r2_device_info_hex_len = info.size() * 2 + 1;
+	std::vector<char> wfd_r2_device_info_hex(wfd_r2_device_info_hex_len);
+	wpa_snprintf_hex(
+		wfd_r2_device_info_hex.data(), wfd_r2_device_info_hex.size(),
+		info.data(),info.size());
+	std::string wfd_r2_device_info_set_cmd_str =
+		 std::to_string(kWfdR2DeviceInfoSubelemId) + " " +
+		 wfd_r2_device_info_hex.data();
+	std::vector<char> wfd_r2_device_info_set_cmd(
+		 wfd_r2_device_info_set_cmd_str.c_str(),
+		 wfd_r2_device_info_set_cmd_str.c_str() +
+		 wfd_r2_device_info_set_cmd_str.size() + 1);
+	if (wifi_display_subelem_set(
+		wpa_s->global, wfd_r2_device_info_set_cmd.data())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::removeClientInternal(
+    const std::vector<uint8_t>& peer_address, bool isLegacyClient)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	wpas_p2p_remove_client(wpa_s, peer_address.data(), isLegacyClient? 1 : 0);
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::findOnSocialChannelsInternal(uint32_t timeout_in_sec)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
+	}
+	uint32_t search_delay = wpas_p2p_search_delay(wpa_s);
+	if (wpas_p2p_find(
+		wpa_s, timeout_in_sec, P2P_FIND_ONLY_SOCIAL, 0, nullptr,
+		nullptr, search_delay, 0, nullptr, 0, is6GhzAllowed(wpa_s))) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::findOnSpecificFrequencyInternal(
+	uint32_t freq, uint32_t timeout_in_sec)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
+	}
+	uint32_t search_delay = wpas_p2p_search_delay(wpa_s);
+	if (wpas_p2p_find(
+		wpa_s, timeout_in_sec, P2P_FIND_START_WITH_FULL, 0, nullptr,
+		nullptr, search_delay, 0, nullptr, freq, is6GhzAllowed(wpa_s))) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::setVendorElementsInternal(
+	P2pFrameTypeMask frameTypeMask,
+	const std::vector<uint8_t>& vendorElemBytes)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	for (int i = 0; i < NUM_VENDOR_ELEM_FRAMES; i++) {
+		uint32_t bit = convertWpaP2pFrameTypeToHalP2pFrameTypeBit(i);
+		if (0 == bit) continue;
+
+		if (static_cast<uint32_t>(frameTypeMask) & bit) {
+			updateP2pVendorElem(wpa_s, (enum wpa_vendor_elem_frame) i, vendorElemBytes);
+		}
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+/**
+ * Retrieve the underlying |wpa_supplicant| struct
+ * pointer for this iface.
+ * If the underlying iface is removed, then all RPC method calls on this object
+ * will return failure.
+ */
+wpa_supplicant* P2pIface::retrieveIfacePtr()
+{
+	return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str());
+}
+
+/**
+ * Retrieve the underlying |wpa_supplicant| struct
+ * pointer for this group iface.
+ */
+wpa_supplicant* P2pIface::retrieveGroupIfacePtr(const std::string& group_ifname)
+{
+	return wpa_supplicant_get_iface(wpa_global_, group_ifname.c_str());
+}
+
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/p2p_iface.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/p2p_iface.h
new file mode 100755
index 0000000..5f9903c
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/p2p_iface.h
@@ -0,0 +1,316 @@
+/*
+ * WPA Supplicant - P2P Iface Aidl interface
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef WPA_SUPPLICANT_AIDL_P2P_IFACE_H
+#define WPA_SUPPLICANT_AIDL_P2P_IFACE_H
+
+#include <array>
+#include <vector>
+
+#include <android-base/macros.h>
+
+#include <aidl/android/hardware/wifi/supplicant/BnSupplicantP2pIface.h>
+#include <aidl/android/hardware/wifi/supplicant/FreqRange.h>
+#include <aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.h>
+#include <aidl/android/hardware/wifi/supplicant/ISupplicantP2pNetwork.h>
+#include <aidl/android/hardware/wifi/supplicant/MiracastMode.h>
+#include <aidl/android/hardware/wifi/supplicant/WpsProvisionMethod.h>
+
+extern "C"
+{
+#include "utils/common.h"
+#include "utils/includes.h"
+#include "p2p/p2p.h"
+#include "p2p/p2p_i.h"
+#include "p2p_supplicant.h"
+#include "p2p_supplicant.h"
+#include "config.h"
+}
+
+#define P2P_MGMT_DEVICE_PREFIX	   "p2p-dev-"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+
+/**
+ * Implementation of P2pIface aidl object. Each unique aidl
+ * object is used for control operations on a specific interface
+ * controlled by wpa_supplicant.
+ */
+class P2pIface : public BnSupplicantP2pIface
+{
+public:
+	P2pIface(struct wpa_global* wpa_global, const char ifname[]);
+	~P2pIface() override = default;
+	// Refer to |StaIface::invalidate()|.
+	void invalidate();
+	bool isValid();
+
+	// Aidl methods exposed.
+	::ndk::ScopedAStatus getName(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getType(IfaceType* _aidl_return) override;
+	::ndk::ScopedAStatus addNetwork(
+		std::shared_ptr<ISupplicantP2pNetwork>* _aidl_return) override;
+	::ndk::ScopedAStatus removeNetwork(int32_t in_id) override;
+	::ndk::ScopedAStatus getNetwork(
+		int32_t in_id, std::shared_ptr<ISupplicantP2pNetwork>* _aidl_return) override;
+	::ndk::ScopedAStatus listNetworks(std::vector<int32_t>* _aidl_return) override;
+	::ndk::ScopedAStatus registerCallback(
+		const std::shared_ptr<ISupplicantP2pIfaceCallback>& in_callback) override;
+	::ndk::ScopedAStatus getDeviceAddress(std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus setSsidPostfix(const std::vector<uint8_t>& in_postfix) override;
+	::ndk::ScopedAStatus setGroupIdle(
+		const std::string& in_groupIfName, int32_t in_timeoutInSec) override;
+	::ndk::ScopedAStatus setPowerSave(
+		const std::string& in_groupIfName, bool in_enable) override;
+	::ndk::ScopedAStatus find(int32_t in_timeoutInSec) override;
+	::ndk::ScopedAStatus stopFind() override;
+	::ndk::ScopedAStatus flush() override;
+	::ndk::ScopedAStatus connect(
+		const std::vector<uint8_t>& in_peerAddress, WpsProvisionMethod in_provisionMethod,
+		const std::string& in_preSelectedPin, bool in_joinExistingGroup,
+		bool in_persistent, int32_t in_goIntent, std::string* _aidl_return) override;
+	::ndk::ScopedAStatus cancelConnect() override;
+	::ndk::ScopedAStatus provisionDiscovery(
+		const std::vector<uint8_t>& in_peerAddress,
+		WpsProvisionMethod in_provisionMethod) override;
+	::ndk::ScopedAStatus addGroup(bool in_persistent, int32_t in_persistentNetworkId) override;
+	::ndk::ScopedAStatus addGroupWithConfig(
+		const std::vector<uint8_t>& in_ssid, const std::string& in_pskPassphrase,
+		bool in_persistent, int32_t in_freq, const std::vector<uint8_t>& in_peerAddress,
+		bool in_joinExistingGroup) override;
+	::ndk::ScopedAStatus removeGroup(const std::string& in_groupIfName) override;
+	::ndk::ScopedAStatus reject(const std::vector<uint8_t>& in_peerAddress) override;
+	::ndk::ScopedAStatus invite(
+		const std::string& in_groupIfName,
+		const std::vector<uint8_t>& in_goDeviceAddress,
+		const std::vector<uint8_t>& in_peerAddress) override;
+	::ndk::ScopedAStatus reinvoke(
+		int32_t in_persistentNetworkId,
+		const std::vector<uint8_t>& in_peerAddress) override;
+	::ndk::ScopedAStatus configureExtListen(
+		int32_t in_periodInMillis, int32_t in_intervalInMillis) override;
+	::ndk::ScopedAStatus setListenChannel(
+		int32_t in_channel, int32_t in_operatingClass) override;
+	::ndk::ScopedAStatus setDisallowedFrequencies(
+		const std::vector<FreqRange>& in_ranges) override;
+	::ndk::ScopedAStatus getSsid(
+		const std::vector<uint8_t>& in_peerAddress,
+		std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus getGroupCapability(
+		const std::vector<uint8_t>& in_peerAddress,
+		P2pGroupCapabilityMask* _aidl_return) override;
+	::ndk::ScopedAStatus addBonjourService(
+		const std::vector<uint8_t>& in_query,
+		const std::vector<uint8_t>& in_response) override;
+	::ndk::ScopedAStatus removeBonjourService(
+		const std::vector<uint8_t>& in_query) override;
+	::ndk::ScopedAStatus addUpnpService(
+		int32_t in_version, const std::string& in_serviceName) override;
+	::ndk::ScopedAStatus removeUpnpService(
+		int32_t in_version, const std::string& in_serviceName) override;
+	::ndk::ScopedAStatus flushServices() override;
+	::ndk::ScopedAStatus requestServiceDiscovery(
+		const std::vector<uint8_t>& in_peerAddress,
+		const std::vector<uint8_t>& in_query, int64_t* _aidl_return) override;
+	::ndk::ScopedAStatus cancelServiceDiscovery(int64_t in_identifier) override;
+	::ndk::ScopedAStatus setMiracastMode(MiracastMode in_mode) override;
+	::ndk::ScopedAStatus startWpsPbc(
+		const std::string& in_groupIfName,
+		const std::vector<uint8_t>& in_bssid) override;
+	::ndk::ScopedAStatus startWpsPinKeypad(
+		const std::string& in_groupIfName, const std::string& in_pin) override;
+	::ndk::ScopedAStatus startWpsPinDisplay(
+		const std::string& in_groupIfName,
+		const std::vector<uint8_t>& in_bssid,
+		std::string* _aidl_return) override;
+	::ndk::ScopedAStatus cancelWps(const std::string& in_groupIfName) override;
+	::ndk::ScopedAStatus setWpsDeviceName(
+		const std::string& in_name) override;
+	::ndk::ScopedAStatus setWpsDeviceType(
+		const std::vector<uint8_t>& in_type) override;
+	::ndk::ScopedAStatus setWpsManufacturer(
+		const std::string& in_manufacturer) override;
+	::ndk::ScopedAStatus setWpsModelName(
+		const std::string& in_modelName) override;
+	::ndk::ScopedAStatus setWpsModelNumber(
+		const std::string& in_modelNumber) override;
+	::ndk::ScopedAStatus setWpsSerialNumber(
+		const std::string& in_serialNumber) override;
+	::ndk::ScopedAStatus setWpsConfigMethods(
+		WpsConfigMethods in_configMethods) override;
+	::ndk::ScopedAStatus enableWfd(bool in_enable) override;
+	::ndk::ScopedAStatus setWfdDeviceInfo(
+		const std::vector<uint8_t>& in_info) override;
+	::ndk::ScopedAStatus createNfcHandoverRequestMessage(
+		std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus createNfcHandoverSelectMessage(
+		std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus reportNfcHandoverInitiation(
+		const std::vector<uint8_t>& in_select) override;
+	::ndk::ScopedAStatus reportNfcHandoverResponse(
+		const std::vector<uint8_t>& in_request) override;
+	::ndk::ScopedAStatus saveConfig() override;
+	::ndk::ScopedAStatus setMacRandomization(bool in_enable) override;
+	::ndk::ScopedAStatus setEdmg(bool in_enable) override;
+	::ndk::ScopedAStatus getEdmg(bool* _aidl_return) override;
+	::ndk::ScopedAStatus setWfdR2DeviceInfo(
+		const std::vector<uint8_t>& in_info) override;
+	::ndk::ScopedAStatus removeClient(
+		const std::vector<uint8_t>& peer_address, bool isLegacyClient) override;
+	::ndk::ScopedAStatus findOnSocialChannels(int32_t in_timeoutInSec) override;
+	::ndk::ScopedAStatus findOnSpecificFrequency(
+		int32_t in_freq, int32_t in_timeoutInSec) override;
+	::ndk::ScopedAStatus setVendorElements(
+		P2pFrameTypeMask in_frameTypeMask,
+		const std::vector<uint8_t>& in_vendorElemBytes) override;
+
+private:
+	// Corresponding worker functions for the AIDL methods.
+	std::pair<std::string, ndk::ScopedAStatus> getNameInternal();
+	std::pair<IfaceType, ndk::ScopedAStatus> getTypeInternal();
+	std::pair<std::shared_ptr<ISupplicantP2pNetwork>, ndk::ScopedAStatus>
+		addNetworkInternal();
+	ndk::ScopedAStatus removeNetworkInternal(int32_t id);
+	std::pair<std::shared_ptr<ISupplicantP2pNetwork>, ndk::ScopedAStatus>
+		getNetworkInternal(int32_t id);
+	std::pair<std::vector<int32_t>, ndk::ScopedAStatus>
+		listNetworksInternal();
+	ndk::ScopedAStatus registerCallbackInternal(
+		const std::shared_ptr<ISupplicantP2pIfaceCallback>& callback);
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+		getDeviceAddressInternal();
+	ndk::ScopedAStatus setSsidPostfixInternal(
+		const std::vector<uint8_t>& postfix);
+	ndk::ScopedAStatus setGroupIdleInternal(
+		const std::string& group_ifname, uint32_t timeout_in_sec);
+	ndk::ScopedAStatus setPowerSaveInternal(
+		const std::string& group_ifname, bool enable);
+	ndk::ScopedAStatus findInternal(uint32_t timeout_in_sec);
+	ndk::ScopedAStatus stopFindInternal();
+	ndk::ScopedAStatus flushInternal();
+	std::pair<std::string, ndk::ScopedAStatus> connectInternal(
+		const std::vector<uint8_t>& peer_address,
+		WpsProvisionMethod provision_method,
+		const std::string& pre_selected_pin, bool join_existing_group,
+		bool persistent, uint32_t go_intent);
+	ndk::ScopedAStatus cancelConnectInternal();
+	ndk::ScopedAStatus provisionDiscoveryInternal(
+		const std::vector<uint8_t>& peer_address,
+		WpsProvisionMethod provision_method);
+	ndk::ScopedAStatus addGroupInternal(bool in_persistent, int32_t in_persistentNetworkId);
+	ndk::ScopedAStatus addGroupWithConfigInternal(
+		const std::vector<uint8_t>& ssid, const std::string& passphrase,
+		bool persistent, uint32_t freq, const std::vector<uint8_t>& peer_address,
+		bool joinExistingGroup);
+	ndk::ScopedAStatus removeGroupInternal(const std::string& group_ifname);
+	ndk::ScopedAStatus rejectInternal(
+		const std::vector<uint8_t>& peer_address);
+	ndk::ScopedAStatus inviteInternal(
+		const std::string& group_ifname,
+		const std::vector<uint8_t>& go_device_address,
+		const std::vector<uint8_t>& peer_address);
+	ndk::ScopedAStatus reinvokeInternal(
+		int32_t persistent_network_id,
+		const std::vector<uint8_t>& peer_address);
+	ndk::ScopedAStatus configureExtListenInternal(
+		uint32_t period_in_millis, uint32_t interval_in_millis);
+	ndk::ScopedAStatus setListenChannelInternal(
+		uint32_t channel, uint32_t operating_class);
+	ndk::ScopedAStatus setDisallowedFrequenciesInternal(
+		const std::vector<FreqRange>& ranges);
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> getSsidInternal(
+		const std::vector<uint8_t>& peer_address);
+	std::pair<P2pGroupCapabilityMask, ndk::ScopedAStatus> getGroupCapabilityInternal(
+		const std::vector<uint8_t>& peer_address);
+	ndk::ScopedAStatus addBonjourServiceInternal(
+		const std::vector<uint8_t>& query,
+		const std::vector<uint8_t>& response);
+	ndk::ScopedAStatus removeBonjourServiceInternal(
+		const std::vector<uint8_t>& query);
+	ndk::ScopedAStatus addUpnpServiceInternal(
+		uint32_t version, const std::string& service_name);
+	ndk::ScopedAStatus removeUpnpServiceInternal(
+		uint32_t version, const std::string& service_name);
+	ndk::ScopedAStatus flushServicesInternal();
+	std::pair<uint64_t, ndk::ScopedAStatus> requestServiceDiscoveryInternal(
+		const std::vector<uint8_t>& peer_address,
+		const std::vector<uint8_t>& query);
+	ndk::ScopedAStatus cancelServiceDiscoveryInternal(uint64_t identifier);
+	ndk::ScopedAStatus setMiracastModeInternal(
+		MiracastMode mode);
+	ndk::ScopedAStatus startWpsPbcInternal(
+		const std::string& group_ifname,
+		const std::vector<uint8_t>& bssid);
+	ndk::ScopedAStatus startWpsPinKeypadInternal(
+		const std::string& group_ifname, const std::string& pin);
+	std::pair<std::string, ndk::ScopedAStatus> startWpsPinDisplayInternal(
+		const std::string& group_ifname,
+		const std::vector<uint8_t>& bssid);
+	ndk::ScopedAStatus cancelWpsInternal(const std::string& group_ifname);
+	ndk::ScopedAStatus setWpsDeviceNameInternal(const std::string& name);
+	ndk::ScopedAStatus setWpsDeviceTypeInternal(
+		const std::vector<uint8_t>& type);
+	ndk::ScopedAStatus setWpsManufacturerInternal(
+		const std::string& manufacturer);
+	ndk::ScopedAStatus setWpsModelNameInternal(const std::string& model_name);
+	ndk::ScopedAStatus setWpsModelNumberInternal(
+		const std::string& model_number);
+	ndk::ScopedAStatus setWpsSerialNumberInternal(
+		const std::string& serial_number);
+	ndk::ScopedAStatus setWpsConfigMethodsInternal(WpsConfigMethods config_methods);
+	ndk::ScopedAStatus enableWfdInternal(bool enable);
+	ndk::ScopedAStatus setWfdDeviceInfoInternal(
+		const std::vector<uint8_t>& info);
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+		createNfcHandoverRequestMessageInternal();
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+		createNfcHandoverSelectMessageInternal();
+	ndk::ScopedAStatus reportNfcHandoverResponseInternal(
+		const std::vector<uint8_t>& request);
+	ndk::ScopedAStatus reportNfcHandoverInitiationInternal(
+		const std::vector<uint8_t>& select);
+	ndk::ScopedAStatus saveConfigInternal();
+	ndk::ScopedAStatus setMacRandomizationInternal(bool enable);
+	ndk::ScopedAStatus setEdmgInternal(bool enable);
+	std::pair<bool, ndk::ScopedAStatus> getEdmgInternal();
+	ndk::ScopedAStatus setWfdR2DeviceInfoInternal(
+		const std::vector<uint8_t>& info);
+	ndk::ScopedAStatus removeClientInternal(
+		const std::vector<uint8_t>& peer_address, bool isLegacyClient);
+	ndk::ScopedAStatus findOnSocialChannelsInternal(uint32_t timeout_in_sec);
+	ndk::ScopedAStatus findOnSpecificFrequencyInternal(
+		uint32_t freq, uint32_t timeout_in_sec);
+	ndk::ScopedAStatus setVendorElementsInternal(
+		P2pFrameTypeMask frameTypeMask,
+		const std::vector<uint8_t>& vendorElemBytes);
+
+	struct wpa_supplicant* retrieveIfacePtr();
+	struct wpa_supplicant* retrieveGroupIfacePtr(
+		const std::string& group_ifname);
+
+	// Reference to the global wpa_struct. This is assumed to be valid for
+	// the lifetime of the process.
+	struct wpa_global* wpa_global_;
+	// Name of the iface this aidl object controls
+	const std::string ifname_;
+	bool is_valid_;
+
+	DISALLOW_COPY_AND_ASSIGN(P2pIface);
+};
+
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WPA_SUPPLICANT_AIDL_P2P_IFACE_H
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/p2p_network.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/p2p_network.cpp
new file mode 100755
index 0000000..9288382
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/p2p_network.cpp
@@ -0,0 +1,252 @@
+/*
+ * WPA Supplicant - P2P network Aidl interface
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "aidl_manager.h"
+#include "aidl_return_util.h"
+#include "misc_utils.h"
+#include "p2p_network.h"
+
+extern "C"
+{
+#include "config_ssid.h"
+}
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+using aidl_return_util::validateAndCall;
+using misc_utils::createStatus;
+
+P2pNetwork::P2pNetwork(
+	struct wpa_global *wpa_global, const char ifname[], int network_id)
+	: wpa_global_(wpa_global),
+	  ifname_(ifname),
+	  network_id_(network_id),
+	  is_valid_(true)
+{}
+
+void P2pNetwork::invalidate() { is_valid_ = false; }
+bool P2pNetwork::isValid()
+{
+	return (is_valid_ && (retrieveNetworkPtr() != nullptr));
+}
+
+::ndk::ScopedAStatus P2pNetwork::getId(
+	int32_t* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&P2pNetwork::getIdInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pNetwork::getInterfaceName(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&P2pNetwork::getInterfaceNameInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pNetwork::getType(
+	IfaceType* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&P2pNetwork::getTypeInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pNetwork::getSsid(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&P2pNetwork::getSsidInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pNetwork::getBssid(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&P2pNetwork::getBssidInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pNetwork::isCurrent(
+	bool* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&P2pNetwork::isCurrentInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pNetwork::isPersistent(
+	bool* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&P2pNetwork::isPersistentInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pNetwork::isGroupOwner(
+	bool* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&P2pNetwork::isGroupOwnerInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pNetwork::setClientList(
+	const std::vector<MacAddress>& in_clients)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&P2pNetwork::setClientListInternal, in_clients);
+}
+
+::ndk::ScopedAStatus P2pNetwork::getClientList(
+	std::vector<MacAddress>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&P2pNetwork::getClientListInternal, _aidl_return);
+}
+
+std::pair<uint32_t, ndk::ScopedAStatus> P2pNetwork::getIdInternal()
+{
+	return {network_id_, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus> P2pNetwork::getInterfaceNameInternal()
+{
+	return {ifname_, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<IfaceType, ndk::ScopedAStatus> P2pNetwork::getTypeInternal()
+{
+	return {IfaceType::P2P, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> P2pNetwork::getSsidInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	std::vector<uint8_t> ssid(
+		wpa_ssid->ssid, wpa_ssid->ssid + wpa_ssid->ssid_len);
+	return {ssid, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+P2pNetwork::getBssidInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	std::vector<uint8_t> bssid;
+	if (wpa_ssid->bssid_set) {
+		bssid.assign(wpa_ssid->bssid, wpa_ssid->bssid + ETH_ALEN);
+	}
+	return {bssid, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<bool, ndk::ScopedAStatus> P2pNetwork::isCurrentInternal()
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	return {(wpa_s->current_ssid == wpa_ssid),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<bool, ndk::ScopedAStatus> P2pNetwork::isPersistentInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	return {(wpa_ssid->disabled == 2), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<bool, ndk::ScopedAStatus> P2pNetwork::isGroupOwnerInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	return {(wpa_ssid->mode == wpas_mode::WPAS_MODE_P2P_GO),
+		ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus P2pNetwork::setClientListInternal(
+	const std::vector<MacAddress> &clients)
+{
+	for (const auto &client : clients) {
+		if (client.data.size() != ETH_ALEN) {
+			return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+		}
+	}
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	os_free(wpa_ssid->p2p_client_list);
+	// Internal representation uses a generic MAC addr/mask storage format
+	// (even though the mask is always 0xFF'ed for p2p_client_list). So, the
+	// first 6 bytes holds the client MAC address and the next 6 bytes are
+	// OxFF'ed.
+	wpa_ssid->p2p_client_list =
+		(u8 *)os_malloc(ETH_ALEN * 2 * clients.size());
+	if (!wpa_ssid->p2p_client_list) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	u8 *list = wpa_ssid->p2p_client_list;
+	for (const auto &client : clients) {
+		os_memcpy(list, client.data.data(), ETH_ALEN);
+		list += ETH_ALEN;
+		os_memset(list, 0xFF, ETH_ALEN);
+		list += ETH_ALEN;
+	}
+	wpa_ssid->num_p2p_clients = clients.size();
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::vector<MacAddress>, ndk::ScopedAStatus>
+P2pNetwork::getClientListInternal()
+{
+	std::vector<MacAddress> clients;
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->p2p_client_list) {
+		return {clients, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	u8 *list = wpa_ssid->p2p_client_list;
+	for (size_t i = 0; i < wpa_ssid->num_p2p_clients; i++) {
+		MacAddress client = MacAddress{};
+		client.data = std::vector<uint8_t>(list, list + ETH_ALEN);
+		clients.emplace_back(client);
+		list += 2 * ETH_ALEN;
+	}
+	return {clients, ndk::ScopedAStatus::ok()};
+}
+
+/**
+ * Retrieve the underlying |wpa_ssid| struct pointer for
+ * this network.
+ * If the underlying network is removed or the interface
+ * this network belong to is removed, all RPC method calls
+ * on this object will return failure.
+ */
+struct wpa_ssid *P2pNetwork::retrieveNetworkPtr()
+{
+	wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (!wpa_s)
+		return nullptr;
+	return wpa_config_get_network(wpa_s->conf, network_id_);
+}
+
+/**
+ * Retrieve the underlying |wpa_supplicant| struct
+ * pointer for this network.
+ */
+struct wpa_supplicant *P2pNetwork::retrieveIfacePtr()
+{
+	return wpa_supplicant_get_iface(
+		(struct wpa_global *)wpa_global_, ifname_.c_str());
+}
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/p2p_network.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/p2p_network.h
new file mode 100755
index 0000000..3b7ec5a
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/p2p_network.h
@@ -0,0 +1,94 @@
+/*
+ * WPA Supplicant - P2P network Aidl interface
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef WPA_SUPPLICANT_AIDL_P2P_NETWORK_H
+#define WPA_SUPPLICANT_AIDL_P2P_NETWORK_H
+
+#include <android-base/macros.h>
+
+#include <aidl/android/hardware/wifi/supplicant/BnSupplicantP2pNetwork.h>
+
+extern "C"
+{
+#include "utils/common.h"
+#include "utils/includes.h"
+#include "wpa_supplicant_i.h"
+}
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+
+/**
+ * Implementation of P2pNetwork aidl object. Each unique aidl
+ * object is used for control operations on a specific network
+ * controlled by wpa_supplicant.
+ */
+class P2pNetwork : public BnSupplicantP2pNetwork
+{
+public:
+	P2pNetwork(
+		struct wpa_global* wpa_global, const char ifname[], int network_id);
+	~P2pNetwork() override = default;
+	// Refer to |StaIface::invalidate()|.
+	void invalidate();
+	bool isValid();
+
+	// Aidl methods exposed.
+  	::ndk::ScopedAStatus getId(int32_t* _aidl_return) override;
+	::ndk::ScopedAStatus getInterfaceName(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getType(IfaceType* _aidl_return) override;
+	::ndk::ScopedAStatus getSsid(std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus getBssid(std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus isCurrent(bool* _aidl_return) override;
+	::ndk::ScopedAStatus isPersistent(bool* _aidl_return) override;
+	::ndk::ScopedAStatus isGroupOwner(bool* _aidl_return) override;
+	::ndk::ScopedAStatus setClientList(
+		const std::vector<MacAddress>& in_clients) override;
+	::ndk::ScopedAStatus getClientList(
+		std::vector<MacAddress>* _aidl_return) override;
+
+private:
+	// Corresponding worker functions for the AIDL methods.
+	std::pair<uint32_t, ndk::ScopedAStatus> getIdInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getInterfaceNameInternal();
+	std::pair<IfaceType, ndk::ScopedAStatus> getTypeInternal();
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> getSsidInternal();
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> getBssidInternal();
+	std::pair<bool, ndk::ScopedAStatus> isCurrentInternal();
+	std::pair<bool, ndk::ScopedAStatus> isPersistentInternal();
+	std::pair<bool, ndk::ScopedAStatus> isGroupOwnerInternal();
+	ndk::ScopedAStatus setClientListInternal(
+		const std::vector<MacAddress>& clients);
+	std::pair<std::vector<MacAddress>, ndk::ScopedAStatus>
+		getClientListInternal();
+
+	struct wpa_ssid* retrieveNetworkPtr();
+	struct wpa_supplicant* retrieveIfacePtr();
+
+	// Reference to the global wpa_struct. This is assumed to be valid
+	// for the lifetime of the process.
+	const struct wpa_global* wpa_global_;
+	// Name of the iface this network belongs to.
+	const std::string ifname_;
+	// Id of the network this aidl object controls.
+	const int network_id_;
+	bool is_valid_;
+
+	DISALLOW_COPY_AND_ASSIGN(P2pNetwork);
+};
+
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WPA_SUPPLICANT_AIDL_P2P_NETWORK_H
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/sta_iface.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/sta_iface.cpp
new file mode 100755
index 0000000..f2cad19
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/sta_iface.cpp
@@ -0,0 +1,1955 @@
+/*
+ * WPA Supplicant - Sta Iface Aidl interface
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "aidl_manager.h"
+#include "aidl_return_util.h"
+#include "iface_config_utils.h"
+#include "misc_utils.h"
+#include "sta_iface.h"
+
+extern "C"
+{
+#include "utils/eloop.h"
+#include "gas_query.h"
+#include "interworking.h"
+#include "hs20_supplicant.h"
+#include "wps_supplicant.h"
+#ifdef CONFIG_DPP
+#include "dpp.h"
+#include "dpp_supplicant.h"
+#endif
+#include "rsn_supp/wpa.h"
+#include "rsn_supp/pmksa_cache.h"
+}
+
+namespace {
+using aidl::android::hardware::wifi::supplicant::AidlManager;
+using aidl::android::hardware::wifi::supplicant::BtCoexistenceMode;
+using aidl::android::hardware::wifi::supplicant::ConnectionCapabilities;
+using aidl::android::hardware::wifi::supplicant::DppCurve;
+using aidl::android::hardware::wifi::supplicant::DppResponderBootstrapInfo;
+using aidl::android::hardware::wifi::supplicant::ISupplicant;
+using aidl::android::hardware::wifi::supplicant::ISupplicantStaIface;
+using aidl::android::hardware::wifi::supplicant::ISupplicantStaNetwork;
+using aidl::android::hardware::wifi::supplicant::KeyMgmtMask;
+using aidl::android::hardware::wifi::supplicant::LegacyMode;
+using aidl::android::hardware::wifi::supplicant::RxFilterType;
+using aidl::android::hardware::wifi::supplicant::SupplicantStatusCode;
+using aidl::android::hardware::wifi::supplicant::WifiTechnology;
+using aidl::android::hardware::wifi::supplicant::misc_utils::createStatus;
+
+// TODO (b/204810426): Import from wifi vendor AIDL interface when it exists
+enum WifiChannelWidthInMhz {
+  WIDTH_20	= 0,
+  WIDTH_40	= 1,
+  WIDTH_80	= 2,
+  WIDTH_160   = 3,
+  WIDTH_80P80 = 4,
+  WIDTH_5	 = 5,
+  WIDTH_10	= 6,
+  WIDTH_INVALID = -1
+};
+
+constexpr uint32_t kMaxAnqpElems = 100;
+constexpr char kGetMacAddress[] = "MACADDR";
+constexpr char kStartRxFilter[] = "RXFILTER-START";
+constexpr char kStopRxFilter[] = "RXFILTER-STOP";
+constexpr char kAddRxFilter[] = "RXFILTER-ADD";
+constexpr char kRemoveRxFilter[] = "RXFILTER-REMOVE";
+constexpr char kSetBtCoexistenceMode[] = "BTCOEXMODE";
+constexpr char kSetBtCoexistenceScanStart[] = "BTCOEXSCAN-START";
+constexpr char kSetBtCoexistenceScanStop[] = "BTCOEXSCAN-STOP";
+constexpr char kSetSupendModeEnabled[] = "SETSUSPENDMODE 1";
+constexpr char kSetSupendModeDisabled[] = "SETSUSPENDMODE 0";
+constexpr char kSetCountryCode[] = "COUNTRY";
+constexpr uint32_t kExtRadioWorkDefaultTimeoutInSec =
+	static_cast<uint32_t>(ISupplicant::EXT_RADIO_WORK_TIMEOUT_IN_SECS);
+constexpr char kExtRadioWorkNamePrefix[] = "ext:";
+
+uint8_t convertAidlRxFilterTypeToInternal(
+	RxFilterType type)
+{
+	switch (type) {
+	case RxFilterType::V4_MULTICAST:
+		return 2;
+	case RxFilterType::V6_MULTICAST:
+		return 3;
+	};
+	WPA_ASSERT(false);
+}
+
+uint8_t convertAidlBtCoexModeToInternal(
+	BtCoexistenceMode mode)
+{
+	switch (mode) {
+	case BtCoexistenceMode::ENABLED:
+		return 0;
+	case BtCoexistenceMode::DISABLED:
+		return 1;
+	case BtCoexistenceMode::SENSE:
+		return 2;
+	};
+	WPA_ASSERT(false);
+}
+
+ndk::ScopedAStatus doZeroArgDriverCommand(
+	struct wpa_supplicant *wpa_s, const char *cmd)
+{
+	std::vector<char> cmd_vec(cmd, cmd + strlen(cmd) + 1);
+	char driver_cmd_reply_buf[4096] = {};
+	if (wpa_drv_driver_cmd(
+		wpa_s, cmd_vec.data(), driver_cmd_reply_buf,
+		sizeof(driver_cmd_reply_buf))<0) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus doOneArgDriverCommand(
+	struct wpa_supplicant *wpa_s, const char *cmd, uint8_t arg)
+{
+	std::string cmd_str = std::string(cmd) + " " + std::to_string(arg);
+	return doZeroArgDriverCommand(wpa_s, cmd_str.c_str());
+}
+
+ndk::ScopedAStatus doOneArgDriverCommand(
+	struct wpa_supplicant *wpa_s, const char *cmd, const std::string &arg)
+{
+	std::string cmd_str = std::string(cmd) + " " + arg;
+	return doZeroArgDriverCommand(wpa_s, cmd_str.c_str());
+}
+
+void endExtRadioWork(struct wpa_radio_work *work)
+{
+	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
+	work->wpa_s->ext_work_in_progress = 0;
+	radio_work_done(work);
+	os_free(ework);
+}
+
+void extRadioWorkTimeoutCb(void *eloop_ctx, void *timeout_ctx)
+{
+	auto *work = static_cast<struct wpa_radio_work *>(eloop_ctx);
+	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
+	wpa_dbg(
+		work->wpa_s, MSG_DEBUG, "Timing out external radio work %u (%s)",
+		ework->id, work->type);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	WPA_ASSERT(aidl_manager);
+	aidl_manager->notifyExtRadioWorkTimeout(work->wpa_s, ework->id);
+
+	endExtRadioWork(work);
+}
+
+void startExtRadioWork(struct wpa_radio_work *work)
+{
+	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
+	work->wpa_s->ext_work_in_progress = 1;
+	if (!ework->timeout) {
+		ework->timeout = kExtRadioWorkDefaultTimeoutInSec;
+	}
+	eloop_register_timeout(
+		ework->timeout, 0, extRadioWorkTimeoutCb, work, nullptr);
+}
+
+void extRadioWorkStartCb(struct wpa_radio_work *work, int deinit)
+{
+	// deinit==1 is invoked during interface removal. Since the AIDL
+	// interface does not support interface addition/removal, we don't
+	// need to handle this scenario.
+	WPA_ASSERT(!deinit);
+
+	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
+	wpa_dbg(
+		work->wpa_s, MSG_DEBUG, "Starting external radio work %u (%s)",
+		ework->id, ework->type);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	WPA_ASSERT(aidl_manager);
+	aidl_manager->notifyExtRadioWorkStart(work->wpa_s, ework->id);
+
+	startExtRadioWork(work);
+}
+
+KeyMgmtMask convertWpaKeyMgmtCapabilitiesToAidl (
+	struct wpa_supplicant *wpa_s, struct wpa_driver_capa *capa) {
+
+	uint32_t mask = 0;
+	/* Logic from ctrl_iface.c, NONE and IEEE8021X have no capability
+	 * flags and always enabled.
+	 */
+	mask |=
+		(static_cast<uint32_t>(KeyMgmtMask::NONE) |
+		 static_cast<uint32_t>(KeyMgmtMask::IEEE8021X));
+
+	if (capa->key_mgmt &
+		(WPA_DRIVER_CAPA_KEY_MGMT_WPA | WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
+		mask |= static_cast<uint32_t>(KeyMgmtMask::WPA_EAP);
+	}
+
+	if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
+				 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
+		mask |= static_cast<uint32_t>(KeyMgmtMask::WPA_PSK);
+	}
+#ifdef CONFIG_SUITEB192
+	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192) {
+		mask |= static_cast<uint32_t>(KeyMgmtMask::SUITE_B_192);
+	}
+#endif /* CONFIG_SUITEB192 */
+#ifdef CONFIG_OWE
+	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_OWE) {
+		mask |= static_cast<uint32_t>(KeyMgmtMask::OWE);
+	}
+#endif /* CONFIG_OWE */
+#ifdef CONFIG_SAE
+	if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE) {
+		mask |= static_cast<uint32_t>(KeyMgmtMask::SAE);
+	}
+#endif /* CONFIG_SAE */
+#ifdef CONFIG_DPP
+	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_DPP) {
+		mask |= static_cast<uint32_t>(KeyMgmtMask::DPP);
+	}
+#endif
+#ifdef CONFIG_WAPI_INTERFACE
+	mask |= static_cast<uint32_t>(KeyMgmtMask::WAPI_PSK);
+	mask |= static_cast<uint32_t>(KeyMgmtMask::WAPI_CERT);
+#endif /* CONFIG_WAPI_INTERFACE */
+#ifdef CONFIG_FILS
+	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256) {
+		mask |= static_cast<uint32_t>(KeyMgmtMask::FILS_SHA256);
+	}
+	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384) {
+		mask |= static_cast<uint32_t>(KeyMgmtMask::FILS_SHA384);
+	}
+#endif /* CONFIG_FILS */
+	return static_cast<KeyMgmtMask>(mask);
+}
+
+#ifdef CONFIG_DPP
+const std::string getDppListenChannel(struct wpa_supplicant *wpa_s, int32_t *listen_channel)
+{
+	struct hostapd_hw_modes *mode;
+	int chan44 = 0, chan149 = 0;
+	*listen_channel = 0;
+
+	/* Check if device support 2.4GHz band*/
+	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
+			HOSTAPD_MODE_IEEE80211G, 0);
+	if (mode) {
+		*listen_channel = 6;
+		return "81/6";
+	}
+	/* Check if device support 5GHz band */
+	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
+			HOSTAPD_MODE_IEEE80211A, 0);
+	if (mode) {
+		for (int i = 0; i < mode->num_channels; i++) {
+			struct hostapd_channel_data *chan = &mode->channels[i];
+
+			if (chan->flag & (HOSTAPD_CHAN_DISABLED |
+					  HOSTAPD_CHAN_RADAR))
+				continue;
+			if (chan->freq == 5220)
+				chan44 = 1;
+			if (chan->freq == 5745)
+				chan149 = 1;
+		}
+		if (chan149) {
+			*listen_channel = 149;
+			return "124/149";
+		} else if (chan44) {
+			*listen_channel = 44;
+			return "115/44";
+		}
+	}
+
+	return "";
+}
+
+const std::string convertCurveTypeToName(DppCurve curve)
+{
+	switch (curve) {
+	case DppCurve::PRIME256V1:
+		return "prime256v1";
+	case DppCurve::SECP384R1:
+		return "secp384r1";
+	case DppCurve::SECP521R1:
+		return "secp521r1";
+	case DppCurve::BRAINPOOLP256R1:
+		return "brainpoolP256r1";
+	case DppCurve::BRAINPOOLP384R1:
+		return "brainpoolP384r1";
+	case DppCurve::BRAINPOOLP512R1:
+		return "brainpoolP512r1";
+	}
+	WPA_ASSERT(false);
+}
+#endif
+
+}  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+using aidl_return_util::validateAndCall;
+using misc_utils::createStatus;
+
+StaIface::StaIface(struct wpa_global *wpa_global, const char ifname[])
+	: wpa_global_(wpa_global), ifname_(ifname), is_valid_(true)
+{}
+
+void StaIface::invalidate() { is_valid_ = false; }
+bool StaIface::isValid()
+{
+	return (is_valid_ && (retrieveIfacePtr() != nullptr));
+}
+
+::ndk::ScopedAStatus StaIface::getName(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::getNameInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaIface::getType(
+	IfaceType* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::getTypeInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaIface::addNetwork(
+	std::shared_ptr<ISupplicantStaNetwork>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::addNetworkInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaIface::removeNetwork(
+	int32_t in_id)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::removeNetworkInternal, in_id);
+}
+
+::ndk::ScopedAStatus StaIface::filsHlpFlushRequest()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::filsHlpFlushRequestInternal);
+}
+
+::ndk::ScopedAStatus StaIface::filsHlpAddRequest(
+	const std::vector<uint8_t>& in_dst_mac,
+	const std::vector<uint8_t>& in_pkt)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::filsHlpAddRequestInternal, in_dst_mac, in_pkt);
+}
+
+::ndk::ScopedAStatus StaIface::getNetwork(
+	int32_t in_id, std::shared_ptr<ISupplicantStaNetwork>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::getNetworkInternal, _aidl_return, in_id);
+}
+
+::ndk::ScopedAStatus StaIface::listNetworks(
+	std::vector<int32_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::listNetworksInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaIface::registerCallback(
+	const std::shared_ptr<ISupplicantStaIfaceCallback>& in_callback)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::registerCallbackInternal, in_callback);
+}
+
+::ndk::ScopedAStatus StaIface::reassociate()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::reassociateInternal);
+}
+
+::ndk::ScopedAStatus StaIface::reconnect()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::reconnectInternal);
+}
+
+::ndk::ScopedAStatus StaIface::disconnect()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::disconnectInternal);
+}
+
+::ndk::ScopedAStatus StaIface::setPowerSave(
+	bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setPowerSaveInternal, in_enable);
+}
+
+::ndk::ScopedAStatus StaIface::initiateTdlsDiscover(
+	const std::vector<uint8_t>& in_macAddress)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::initiateTdlsDiscoverInternal, in_macAddress);
+}
+
+::ndk::ScopedAStatus StaIface::initiateTdlsSetup(
+	const std::vector<uint8_t>& in_macAddress)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::initiateTdlsSetupInternal, in_macAddress);
+}
+
+::ndk::ScopedAStatus StaIface::initiateTdlsTeardown(
+	const std::vector<uint8_t>& in_macAddress)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::initiateTdlsTeardownInternal, in_macAddress);
+}
+
+::ndk::ScopedAStatus StaIface::initiateAnqpQuery(
+	const std::vector<uint8_t>& in_macAddress,
+	const std::vector<AnqpInfoId>& in_infoElements,
+	const std::vector<Hs20AnqpSubtypes>& in_subTypes)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::initiateAnqpQueryInternal, in_macAddress,
+		in_infoElements, in_subTypes);
+}
+
+::ndk::ScopedAStatus StaIface::initiateVenueUrlAnqpQuery(
+	const std::vector<uint8_t>& in_macAddress)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::initiateVenueUrlAnqpQueryInternal, in_macAddress);
+}
+
+::ndk::ScopedAStatus StaIface::initiateHs20IconQuery(
+	const std::vector<uint8_t>& in_macAddress,
+	const std::string& in_fileName)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::initiateHs20IconQueryInternal, in_macAddress,
+		in_fileName);
+}
+
+::ndk::ScopedAStatus StaIface::getMacAddress(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::getMacAddressInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaIface::startRxFilter()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::startRxFilterInternal);
+}
+
+::ndk::ScopedAStatus StaIface::stopRxFilter()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::stopRxFilterInternal);
+}
+
+::ndk::ScopedAStatus StaIface::addRxFilter(
+	RxFilterType in_type)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::addRxFilterInternal, in_type);
+}
+
+::ndk::ScopedAStatus StaIface::removeRxFilter(
+	RxFilterType in_type)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::removeRxFilterInternal, in_type);
+}
+
+::ndk::ScopedAStatus StaIface::setBtCoexistenceMode(
+	BtCoexistenceMode in_mode)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setBtCoexistenceModeInternal, in_mode);
+}
+
+::ndk::ScopedAStatus StaIface::setBtCoexistenceScanModeEnabled(
+	bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setBtCoexistenceScanModeEnabledInternal,
+		in_enable);
+}
+
+::ndk::ScopedAStatus StaIface::setSuspendModeEnabled(
+	bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setSuspendModeEnabledInternal, in_enable);
+}
+
+::ndk::ScopedAStatus StaIface::setCountryCode(
+	const std::vector<uint8_t>& in_code)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setCountryCodeInternal, in_code);
+}
+
+::ndk::ScopedAStatus StaIface::startWpsRegistrar(
+	const std::vector<uint8_t>& in_bssid,
+	const std::string& in_pin)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::startWpsRegistrarInternal, in_bssid, in_pin);
+}
+
+::ndk::ScopedAStatus StaIface::startWpsPbc(
+	const std::vector<uint8_t>& in_bssid)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::startWpsPbcInternal, in_bssid);
+}
+
+::ndk::ScopedAStatus StaIface::startWpsPinKeypad(
+	const std::string& in_pin)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::startWpsPinKeypadInternal, in_pin);
+}
+
+::ndk::ScopedAStatus StaIface::startWpsPinDisplay(
+	const std::vector<uint8_t>& in_bssid,
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::startWpsPinDisplayInternal, _aidl_return, in_bssid);
+}
+
+::ndk::ScopedAStatus StaIface::cancelWps()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::cancelWpsInternal);
+}
+
+::ndk::ScopedAStatus StaIface::setWpsDeviceName(
+	const std::string& in_name)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setWpsDeviceNameInternal, in_name);
+}
+
+::ndk::ScopedAStatus StaIface::setWpsDeviceType(
+	const std::vector<uint8_t>& in_type)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setWpsDeviceTypeInternal, in_type);
+}
+
+::ndk::ScopedAStatus StaIface::setWpsManufacturer(
+	const std::string& in_manufacturer)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setWpsManufacturerInternal, in_manufacturer);
+}
+
+::ndk::ScopedAStatus StaIface::setWpsModelName(
+	const std::string& in_modelName)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setWpsModelNameInternal, in_modelName);
+}
+
+::ndk::ScopedAStatus StaIface::setWpsModelNumber(
+	const std::string& in_modelNumber)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setWpsModelNumberInternal, in_modelNumber);
+}
+
+::ndk::ScopedAStatus StaIface::setWpsSerialNumber(
+	const std::string& in_serialNumber)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setWpsSerialNumberInternal, in_serialNumber);
+}
+
+::ndk::ScopedAStatus StaIface::setWpsConfigMethods(
+	WpsConfigMethods in_configMethods)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setWpsConfigMethodsInternal, in_configMethods);
+}
+
+::ndk::ScopedAStatus StaIface::setExternalSim(
+	bool in_useExternalSim)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setExternalSimInternal, in_useExternalSim);
+}
+
+::ndk::ScopedAStatus StaIface::addExtRadioWork(
+	const std::string& in_name, int32_t in_freqInMhz,
+	int32_t in_timeoutInSec,
+	int32_t* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::addExtRadioWorkInternal, _aidl_return, in_name, in_freqInMhz,
+		in_timeoutInSec);
+}
+
+::ndk::ScopedAStatus StaIface::removeExtRadioWork(
+	int32_t in_id)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::removeExtRadioWorkInternal, in_id);
+}
+
+::ndk::ScopedAStatus StaIface::enableAutoReconnect(
+	bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::enableAutoReconnectInternal, in_enable);
+}
+
+::ndk::ScopedAStatus StaIface::getKeyMgmtCapabilities(
+	KeyMgmtMask* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaIface::getKeyMgmtCapabilitiesInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaIface::addDppPeerUri(
+	const std::string& in_uri, int32_t* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaIface::addDppPeerUriInternal, _aidl_return, in_uri);
+}
+
+::ndk::ScopedAStatus StaIface::removeDppUri(
+	int32_t in_id)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaIface::removeDppUriInternal, in_id);
+}
+
+::ndk::ScopedAStatus StaIface::startDppConfiguratorInitiator(
+	int32_t in_peerBootstrapId, int32_t in_ownBootstrapId,
+	const std::string& in_ssid, const std::string& in_password,
+	const std::string& in_psk, DppNetRole in_netRole,
+	DppAkm in_securityAkm, const std::vector<uint8_t>& in_privEcKey,
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaIface::startDppConfiguratorInitiatorInternal, _aidl_return,
+		in_peerBootstrapId,in_ownBootstrapId, in_ssid, in_password,
+		in_psk, in_netRole, in_securityAkm, in_privEcKey);
+}
+
+::ndk::ScopedAStatus StaIface::startDppEnrolleeInitiator(
+	int32_t in_peerBootstrapId, int32_t in_ownBootstrapId)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaIface::startDppEnrolleeInitiatorInternal, in_peerBootstrapId,
+		in_ownBootstrapId);
+}
+
+::ndk::ScopedAStatus StaIface::stopDppInitiator()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaIface::stopDppInitiatorInternal);
+}
+
+::ndk::ScopedAStatus StaIface::getConnectionCapabilities(
+	ConnectionCapabilities* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_UNKNOWN,
+		&StaIface::getConnectionCapabilitiesInternal,
+		_aidl_return);
+}
+
+::ndk::ScopedAStatus StaIface::generateDppBootstrapInfoForResponder(
+	const std::vector<uint8_t>& in_macAddress, const std::string& in_deviceInfo,
+	DppCurve in_curve, DppResponderBootstrapInfo* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::generateDppBootstrapInfoForResponderInternal, _aidl_return, 
+		in_macAddress, in_deviceInfo, in_curve);
+}
+
+::ndk::ScopedAStatus StaIface::startDppEnrolleeResponder(
+	int32_t in_listenChannel)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::startDppEnrolleeResponderInternal, in_listenChannel);
+}
+
+::ndk::ScopedAStatus StaIface::stopDppResponder(
+	int32_t in_ownBootstrapId)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::stopDppResponderInternal, in_ownBootstrapId);
+}
+
+::ndk::ScopedAStatus StaIface::generateSelfDppConfiguration(
+	const std::string& in_ssid, const std::vector<uint8_t>& in_privEcKey)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::generateSelfDppConfigurationInternal, in_ssid, in_privEcKey);
+}
+
+::ndk::ScopedAStatus StaIface::getWpaDriverCapabilities(
+	WpaDriverCapabilitiesMask* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_UNKNOWN,
+		&StaIface::getWpaDriverCapabilitiesInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaIface::setMboCellularDataStatus(
+	bool in_available)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_UNKNOWN,
+		&StaIface::setMboCellularDataStatusInternal, in_available);
+}
+
+::ndk::ScopedAStatus StaIface::setQosPolicyFeatureEnabled(
+	bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_UNKNOWN,
+		&StaIface::setQosPolicyFeatureEnabledInternal, in_enable);
+}
+
+::ndk::ScopedAStatus StaIface::sendQosPolicyResponse(
+	int32_t in_qosPolicyRequestId, bool in_morePolicies,
+	const std::vector<QosPolicyStatus>& in_qosPolicyStatusList)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_UNKNOWN,
+		&StaIface::sendQosPolicyResponseInternal, in_qosPolicyRequestId,
+		in_morePolicies, in_qosPolicyStatusList);
+}
+
+::ndk::ScopedAStatus StaIface::removeAllQosPolicies()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_UNKNOWN,
+		&StaIface::removeAllQosPoliciesInternal);
+}
+
+::ndk::ScopedAStatus StaIface::getConnectionMloLinksInfo(MloLinksInfo* _aidl_return) {
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_UNKNOWN,
+		&StaIface::getConnectionMloLinksInfoInternal, _aidl_return);
+}
+
+std::pair<std::string, ndk::ScopedAStatus> StaIface::getNameInternal()
+{
+	return {ifname_, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<IfaceType, ndk::ScopedAStatus> StaIface::getTypeInternal()
+{
+	return {IfaceType::STA, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaIface::filsHlpFlushRequestInternal()
+{
+#ifdef CONFIG_FILS
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+
+	wpas_flush_fils_hlp_req(wpa_s);
+	return ndk::ScopedAStatus::ok();
+#else /* CONFIG_FILS */
+	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+#endif /* CONFIG_FILS */
+}
+
+ndk::ScopedAStatus StaIface::filsHlpAddRequestInternal(
+	const std::vector<uint8_t> &dst_mac, const std::vector<uint8_t> &pkt)
+{
+#ifdef CONFIG_FILS
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	struct fils_hlp_req *req;
+
+	if (!pkt.size())
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	if (dst_mac.size() != ETH_ALEN)
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+
+
+	req = (struct fils_hlp_req *)os_zalloc(sizeof(*req));
+	if (!req)
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+
+	os_memcpy(req->dst, dst_mac.data(), ETH_ALEN);
+
+	req->pkt = wpabuf_alloc_copy(pkt.data(), pkt.size());
+	if (!req->pkt) {
+		os_free(req);
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	dl_list_add_tail(&wpa_s->fils_hlp_req, &req->list);
+	return ndk::ScopedAStatus::ok();
+#else /* CONFIG_FILS */
+	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+#endif /* CONFIG_FILS */
+}
+
+std::pair<std::shared_ptr<ISupplicantStaNetwork>, ndk::ScopedAStatus>
+StaIface::addNetworkInternal()
+{
+	std::shared_ptr<ISupplicantStaNetwork> network;
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	struct wpa_ssid *ssid = wpa_supplicant_add_network(wpa_s);
+	if (!ssid) {
+		return {network, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager ||
+		aidl_manager->getStaNetworkAidlObjectByIfnameAndNetworkId(
+		wpa_s->ifname, ssid->id, &network)) {
+		return {network, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {network, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaIface::removeNetworkInternal(int32_t id)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	int result = wpa_supplicant_remove_network(wpa_s, id);
+	if (result == -1) {
+		return createStatus(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN);
+	}
+	if (result != 0) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::shared_ptr<ISupplicantStaNetwork>, ndk::ScopedAStatus>
+StaIface::getNetworkInternal(int32_t id)
+{
+	std::shared_ptr<ISupplicantStaNetwork> network;
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	struct wpa_ssid *ssid = wpa_config_get_network(wpa_s->conf, id);
+	if (!ssid) {
+		return {network, createStatus(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN)};
+	}
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager ||
+		aidl_manager->getStaNetworkAidlObjectByIfnameAndNetworkId(
+		wpa_s->ifname, ssid->id, &network)) {
+		return {network, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {network, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<int32_t>, ndk::ScopedAStatus>
+StaIface::listNetworksInternal()
+{
+	std::vector<int32_t> network_ids;
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	for (struct wpa_ssid *wpa_ssid = wpa_s->conf->ssid; wpa_ssid;
+		 wpa_ssid = wpa_ssid->next) {
+		network_ids.emplace_back(wpa_ssid->id);
+	}
+	return {std::move(network_ids), ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaIface::registerCallbackInternal(
+	const std::shared_ptr<ISupplicantStaIfaceCallback> &callback)
+{
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager ||
+		aidl_manager->addStaIfaceCallbackAidlObject(ifname_, callback)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::reassociateInternal()
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
+	}
+	wpas_request_connection(wpa_s);
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::reconnectInternal()
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
+	}
+	if (!wpa_s->disconnected) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_NOT_DISCONNECTED);
+	}
+	wpas_request_connection(wpa_s);
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::disconnectInternal()
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
+	}
+	wpas_request_disconnection(wpa_s);
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::setPowerSaveInternal(bool enable)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
+	}
+	if (wpa_drv_set_p2p_powersave(wpa_s, enable, -1, -1)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::initiateTdlsDiscoverInternal(
+	const std::vector<uint8_t> &mac_address)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	int ret;
+	const u8 *peer = mac_address.data();
+	if (wpa_tdls_is_external_setup(wpa_s->wpa)) {
+		ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer);
+	} else {
+		ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer);
+	}
+	if (ret) {
+		wpa_printf(MSG_INFO, "StaIface: TDLS discover failed: %d", ret);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::initiateTdlsSetupInternal(
+	const std::vector<uint8_t> &mac_address)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	int ret;
+	const u8 *peer = mac_address.data();
+	if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
+		!(wpa_s->conf->tdls_external_control)) {
+		wpa_tdls_remove(wpa_s->wpa, peer);
+		ret = wpa_tdls_start(wpa_s->wpa, peer);
+	} else {
+		ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
+	}
+	if (ret) {
+		wpa_printf(MSG_INFO, "StaIface: TDLS setup failed: %d", ret);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::initiateTdlsTeardownInternal(
+	const std::vector<uint8_t> &mac_address)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	int ret;
+	const u8 *peer = mac_address.data();
+	if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
+		!(wpa_s->conf->tdls_external_control)) {
+		ret = wpa_tdls_teardown_link(
+			wpa_s->wpa, peer, WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
+	} else {
+		ret = wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer);
+	}
+	if (ret) {
+		wpa_printf(MSG_INFO, "StaIface: TDLS teardown failed: %d", ret);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::initiateAnqpQueryInternal(
+	const std::vector<uint8_t> &mac_address,
+	const std::vector<AnqpInfoId> &info_elements,
+	const std::vector<Hs20AnqpSubtypes> &sub_types)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (info_elements.size() > kMaxAnqpElems) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	uint16_t info_elems_buf[kMaxAnqpElems];
+	uint32_t num_info_elems = 0;
+	for (const auto &info_element : info_elements) {
+		info_elems_buf[num_info_elems++] =
+			static_cast<std::underlying_type<
+			AnqpInfoId>::type>(info_element);
+	}
+	uint32_t sub_types_bitmask = 0;
+	for (const auto &type : sub_types) {
+		sub_types_bitmask |= BIT(
+			static_cast<std::underlying_type<
+			Hs20AnqpSubtypes>::type>(type));
+	}
+
+	if (anqp_send_req(
+		wpa_s, mac_address.data(), 0, info_elems_buf, num_info_elems,
+		sub_types_bitmask, 0)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::initiateVenueUrlAnqpQueryInternal(
+	const std::vector<uint8_t> &mac_address)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	uint16_t info_elems_buf[1] = {ANQP_VENUE_URL};
+
+	if (anqp_send_req(
+		wpa_s, mac_address.data(), 0, info_elems_buf, 1, 0, 0)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::initiateHs20IconQueryInternal(
+	const std::vector<uint8_t> &mac_address, const std::string &file_name)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	wpa_s->fetch_osu_icon_in_progress = 0;
+	if (hs20_anqp_send_req(
+		wpa_s, mac_address.data(), BIT(HS20_STYPE_ICON_REQUEST),
+		reinterpret_cast<const uint8_t *>(file_name.c_str()),
+		file_name.size(), true)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+StaIface::getMacAddressInternal()
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	std::vector<char> cmd(
+		kGetMacAddress, kGetMacAddress + sizeof(kGetMacAddress));
+	char driver_cmd_reply_buf[4096] = {};
+	int ret = wpa_drv_driver_cmd(
+		wpa_s, cmd.data(), driver_cmd_reply_buf,
+		sizeof(driver_cmd_reply_buf));
+	// Reply is of the format: "Macaddr = XX:XX:XX:XX:XX:XX"
+	std::string reply_str = driver_cmd_reply_buf;
+	if (ret < 0 || reply_str.empty() ||
+		reply_str.find("=") == std::string::npos) {
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	// Remove all whitespace first and then split using the delimiter "=".
+	reply_str.erase(
+		remove_if(reply_str.begin(), reply_str.end(), isspace),
+		reply_str.end());
+	std::string mac_addr_str =
+		reply_str.substr(reply_str.find("=") + 1, reply_str.size());
+	std::vector<uint8_t> mac_addr(6);
+	if (hwaddr_aton(mac_addr_str.c_str(), mac_addr.data())) {
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {mac_addr, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaIface::startRxFilterInternal()
+{
+	return doZeroArgDriverCommand(retrieveIfacePtr(), kStartRxFilter);
+}
+
+ndk::ScopedAStatus StaIface::stopRxFilterInternal()
+{
+	return doZeroArgDriverCommand(retrieveIfacePtr(), kStopRxFilter);
+}
+
+ndk::ScopedAStatus StaIface::addRxFilterInternal(
+	RxFilterType type)
+{
+	return doOneArgDriverCommand(
+		retrieveIfacePtr(), kAddRxFilter,
+		convertAidlRxFilterTypeToInternal(type));
+}
+
+ndk::ScopedAStatus StaIface::removeRxFilterInternal(
+	RxFilterType type)
+{
+	return doOneArgDriverCommand(
+		retrieveIfacePtr(), kRemoveRxFilter,
+		convertAidlRxFilterTypeToInternal(type));
+}
+
+ndk::ScopedAStatus StaIface::setBtCoexistenceModeInternal(
+	BtCoexistenceMode mode)
+{
+	return doOneArgDriverCommand(
+		retrieveIfacePtr(), kSetBtCoexistenceMode,
+		convertAidlBtCoexModeToInternal(mode));
+}
+
+ndk::ScopedAStatus StaIface::setBtCoexistenceScanModeEnabledInternal(bool enable)
+{
+	const char *cmd;
+	if (enable) {
+		cmd = kSetBtCoexistenceScanStart;
+	} else {
+		cmd = kSetBtCoexistenceScanStop;
+	}
+	return doZeroArgDriverCommand(retrieveIfacePtr(), cmd);
+}
+
+ndk::ScopedAStatus StaIface::setSuspendModeEnabledInternal(bool enable)
+{
+	const char *cmd;
+	if (enable) {
+		cmd = kSetSupendModeEnabled;
+	} else {
+		cmd = kSetSupendModeDisabled;
+	}
+	return doZeroArgDriverCommand(retrieveIfacePtr(), cmd);
+}
+
+ndk::ScopedAStatus StaIface::setCountryCodeInternal(
+	const std::vector<uint8_t> &code)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	ndk::ScopedAStatus status = doOneArgDriverCommand(
+		wpa_s, kSetCountryCode,
+		std::string(std::begin(code), std::end(code)));
+	if (!status.isOk()) {
+		return status;
+	}
+	struct p2p_data *p2p = wpa_s->global->p2p;
+	if (p2p) {
+		char country[3];
+		country[0] = code[0];
+		country[1] = code[1];
+		country[2] = 0x04;
+		p2p_set_country(p2p, country);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::startWpsRegistrarInternal(
+	const std::vector<uint8_t> &bssid, const std::string &pin)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (wpas_wps_start_reg(wpa_s, bssid.data(), pin.c_str(), nullptr)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::startWpsPbcInternal(
+	const std::vector<uint8_t> &bssid)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	const uint8_t *bssid_addr =
+		is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
+	if (wpas_wps_start_pbc(wpa_s, bssid_addr, 0, 0)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::startWpsPinKeypadInternal(const std::string &pin)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (wpas_wps_start_pin(
+		wpa_s, nullptr, pin.c_str(), 0, DEV_PW_DEFAULT)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::string, ndk::ScopedAStatus> StaIface::startWpsPinDisplayInternal(
+	const std::vector<uint8_t> &bssid)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	const uint8_t *bssid_addr =
+		is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
+	int pin =
+		wpas_wps_start_pin(wpa_s, bssid_addr, nullptr, 0, DEV_PW_DEFAULT);
+	if (pin < 0) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::convertWpsPinToString(pin),
+		ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaIface::cancelWpsInternal()
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (wpas_wps_cancel(wpa_s)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::setWpsDeviceNameInternal(const std::string &name)
+{
+	return iface_config_utils::setWpsDeviceName(retrieveIfacePtr(), name);
+}
+
+ndk::ScopedAStatus StaIface::setWpsDeviceTypeInternal(
+	const std::vector<uint8_t> &type)
+{
+	std::array<uint8_t, 8> type_arr;
+	std::copy_n(type.begin(), 8, type_arr.begin());
+	return iface_config_utils::setWpsDeviceType(retrieveIfacePtr(), type_arr);
+}
+
+ndk::ScopedAStatus StaIface::setWpsManufacturerInternal(
+	const std::string &manufacturer)
+{
+	return iface_config_utils::setWpsManufacturer(
+		retrieveIfacePtr(), manufacturer);
+}
+
+ndk::ScopedAStatus StaIface::setWpsModelNameInternal(
+	const std::string &model_name)
+{
+	return iface_config_utils::setWpsModelName(
+		retrieveIfacePtr(), model_name);
+}
+
+ndk::ScopedAStatus StaIface::setWpsModelNumberInternal(
+	const std::string &model_number)
+{
+	return iface_config_utils::setWpsModelNumber(
+		retrieveIfacePtr(), model_number);
+}
+
+ndk::ScopedAStatus StaIface::setWpsSerialNumberInternal(
+	const std::string &serial_number)
+{
+	return iface_config_utils::setWpsSerialNumber(
+		retrieveIfacePtr(), serial_number);
+}
+
+ndk::ScopedAStatus StaIface::setWpsConfigMethodsInternal(WpsConfigMethods config_methods)
+{
+	return iface_config_utils::setWpsConfigMethods(
+		retrieveIfacePtr(), static_cast<uint16_t>(config_methods));
+}
+
+ndk::ScopedAStatus StaIface::setExternalSimInternal(bool useExternalSim)
+{
+	return iface_config_utils::setExternalSim(
+		retrieveIfacePtr(), useExternalSim);
+}
+
+std::pair<uint32_t, ndk::ScopedAStatus> StaIface::addExtRadioWorkInternal(
+	const std::string &name, uint32_t freq_in_mhz, uint32_t timeout_in_sec)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	auto *ework = static_cast<struct wpa_external_work *>(
+		os_zalloc(sizeof(struct wpa_external_work)));
+	if (!ework) {
+		return {UINT32_MAX, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+
+	std::string radio_work_name = kExtRadioWorkNamePrefix + name;
+	os_strlcpy(ework->type, radio_work_name.c_str(), sizeof(ework->type));
+	ework->timeout = timeout_in_sec;
+	wpa_s->ext_work_id++;
+	if (wpa_s->ext_work_id == 0) {
+		wpa_s->ext_work_id++;
+	}
+	ework->id = wpa_s->ext_work_id;
+
+	if (radio_add_work(
+		wpa_s, freq_in_mhz, ework->type, 0, extRadioWorkStartCb,
+		ework)) {
+		os_free(ework);
+		return {UINT32_MAX, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {ework->id, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaIface::removeExtRadioWorkInternal(uint32_t id)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	struct wpa_radio_work *work;
+	dl_list_for_each(work, &wpa_s->radio->work, struct wpa_radio_work, list)
+	{
+		if (os_strncmp(
+			work->type, kExtRadioWorkNamePrefix,
+			sizeof(kExtRadioWorkNamePrefix)) != 0)
+			continue;
+
+		auto *ework =
+			static_cast<struct wpa_external_work *>(work->ctx);
+		if (ework->id != id)
+			continue;
+
+		wpa_dbg(
+			wpa_s, MSG_DEBUG, "Completed external radio work %u (%s)",
+			ework->id, ework->type);
+		eloop_cancel_timeout(extRadioWorkTimeoutCb, work, NULL);
+		endExtRadioWork(work);
+
+		return ndk::ScopedAStatus::ok();
+	}
+	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+}
+
+ndk::ScopedAStatus StaIface::enableAutoReconnectInternal(bool enable)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	wpa_s->auto_reconnect_disabled = enable ? 0 : 1;
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<uint32_t, ndk::ScopedAStatus>
+StaIface::addDppPeerUriInternal(const std::string& uri)
+{
+#ifdef CONFIG_DPP
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	int32_t id;
+
+	id = wpas_dpp_qr_code(wpa_s, uri.c_str());
+
+	if (id > 0) {
+		return {id, ndk::ScopedAStatus::ok()};
+	}
+#endif
+	return {-1, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+}
+
+ndk::ScopedAStatus StaIface::removeDppUriInternal(uint32_t bootstrap_id)
+{
+#ifdef CONFIG_DPP
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	std::string bootstrap_id_str;
+
+	if (bootstrap_id == 0) {
+		bootstrap_id_str = "*";
+	}
+	else {
+		bootstrap_id_str = std::to_string(bootstrap_id);
+	}
+
+	if (dpp_bootstrap_remove(wpa_s->dpp, bootstrap_id_str.c_str()) >= 0) {
+		return ndk::ScopedAStatus::ok();
+	}
+#endif
+	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+StaIface::startDppConfiguratorInitiatorInternal(
+		uint32_t peer_bootstrap_id, uint32_t own_bootstrap_id,
+		const std::string& ssid, const std::string& password,
+		const std::string& psk, DppNetRole net_role, DppAkm security_akm,
+		const std::vector<uint8_t> &privEcKey)
+{
+#ifdef CONFIG_DPP
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	std::string cmd = "";
+	std::string cmd2 = "";
+	int32_t id;
+	char key[1024];
+
+	if (net_role != DppNetRole::AP &&
+			net_role != DppNetRole::STA) {
+		wpa_printf(MSG_ERROR,
+			   "DPP: Error: Invalid network role specified: %d", net_role);
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+
+	cmd += " peer=" + std::to_string(peer_bootstrap_id);
+	cmd += (own_bootstrap_id > 0) ?
+			" own=" + std::to_string(own_bootstrap_id) : "";
+
+	/* Check for supported AKMs */
+	if (security_akm != DppAkm::PSK && security_akm != DppAkm::SAE &&
+			security_akm != DppAkm::PSK_SAE && security_akm != DppAkm::DPP) {
+		wpa_printf(MSG_ERROR, "DPP: Error: invalid AKM specified: %d",
+				security_akm);
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+
+	/* SAE AKM requires SSID and password to be initialized */
+	if ((security_akm == DppAkm::SAE ||
+			security_akm == DppAkm::PSK_SAE) &&
+			(ssid.empty() || password.empty())) {
+		wpa_printf(MSG_ERROR, "DPP: Error: Password or SSID not specified");
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	} else if (security_akm == DppAkm::PSK ||
+			security_akm == DppAkm::PSK_SAE) {
+		/* PSK AKM requires SSID and password/psk to be initialized */
+		if (ssid.empty()) {
+			wpa_printf(MSG_ERROR, "DPP: Error: SSID not specified");
+			return {std::vector<uint8_t>(),
+				createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+		}
+		if (password.empty() && psk.empty()) {
+			wpa_printf(MSG_ERROR, "DPP: Error: Password or PSK not specified");
+			return {std::vector<uint8_t>(),
+				createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+		}
+	}
+
+	cmd += " role=configurator";
+	cmd += (ssid.empty()) ? "" : " ssid=" + ssid;
+
+	if (!psk.empty()) {
+		cmd += " psk=" + psk;
+	} else {
+		cmd += (password.empty()) ? "" : " pass=" + password;
+	}
+
+	std::string role = "";
+	if (net_role == DppNetRole::AP) {
+		role = "ap-";
+	}
+	else {
+		role = "sta-";
+	}
+
+	switch (security_akm) {
+	case DppAkm::PSK:
+		role += "psk";
+		break;
+
+	case DppAkm::SAE:
+		role += "sae";
+		break;
+
+	case DppAkm::PSK_SAE:
+		role += "psk-sae";
+		break;
+
+	case DppAkm::DPP:
+		role += "dpp";
+		break;
+
+	default:
+		wpa_printf(MSG_ERROR,
+			   "DPP: Invalid or unsupported security AKM specified: %d", security_akm);
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+
+	cmd += " conf=";
+	cmd += role;
+
+	if (net_role == DppNetRole::STA) {
+		/* DPP R2 connection status request */
+		cmd += " conn_status=1";
+	}
+
+	if (security_akm == DppAkm::DPP) {
+		if (!privEcKey.empty()) {
+			cmd2 += " key=" + std::string(privEcKey.begin(), privEcKey.end());
+		}
+		id = dpp_configurator_add(wpa_s->dpp, cmd2.c_str());
+		if (id < 0 || (privEcKey.empty() &&
+			       (dpp_configurator_get_key_id(wpa_s->dpp, id, key, sizeof(key)) < 0)))
+		{
+			wpa_printf(MSG_ERROR, "DPP configurator add failed. "
+			           "Input key might be incorrect");
+			return {std::vector<uint8_t>(),
+				createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+		}
+
+		cmd += " configurator=" + std::to_string(id);
+	}
+
+	wpa_printf(MSG_DEBUG,
+		   "DPP initiator command: %s", cmd.c_str());
+
+	if (wpas_dpp_auth_init(wpa_s, cmd.c_str()) == 0) {
+		// Return key if input privEcKey was null/empty.
+		if (security_akm == DppAkm::DPP && privEcKey.empty()) {
+			std::string k(key);
+			std::vector<uint8_t> vKey(k.begin(), k.end());
+			return {vKey, ndk::ScopedAStatus::ok()};
+		}
+		return {std::vector<uint8_t>(), ndk::ScopedAStatus::ok()};
+	}
+#endif
+	return {std::vector<uint8_t>(), createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+}
+
+ndk::ScopedAStatus StaIface::startDppEnrolleeInitiatorInternal(
+	uint32_t peer_bootstrap_id, uint32_t own_bootstrap_id) {
+#ifdef CONFIG_DPP
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	std::string cmd = "";
+
+	/* Report received configuration to AIDL and create an internal profile */
+	wpa_s->conf->dpp_config_processing = 1;
+
+	cmd += " peer=" + std::to_string(peer_bootstrap_id);
+	cmd += (own_bootstrap_id > 0) ?
+			" own=" + std::to_string(own_bootstrap_id) : "";
+
+	cmd += " role=enrollee";
+
+	wpa_printf(MSG_DEBUG,
+		   "DPP initiator command: %s", cmd.c_str());
+
+	if (wpas_dpp_auth_init(wpa_s, cmd.c_str()) == 0) {
+		return ndk::ScopedAStatus::ok();
+	}
+#endif
+	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+}
+ndk::ScopedAStatus StaIface::stopDppInitiatorInternal()
+{
+#ifdef CONFIG_DPP
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+
+	wpas_dpp_stop(wpa_s);
+	return ndk::ScopedAStatus::ok();
+#else
+	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+#endif
+}
+
+std::pair<DppResponderBootstrapInfo, ndk::ScopedAStatus>
+StaIface::generateDppBootstrapInfoForResponderInternal(
+	const std::vector<uint8_t> &mac_address, 
+	const std::string& device_info, DppCurve curve)
+{
+	DppResponderBootstrapInfo bootstrap_info;
+#ifdef CONFIG_DPP
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	std::string cmd = "type=qrcode";
+	int32_t id;
+	int32_t listen_channel = 0;
+	const char *uri;
+	std::string listen_channel_str;
+	std::string mac_addr_str;
+	char buf[3] = {0};
+
+	cmd += (device_info.empty()) ? "" : " info=" + device_info;
+
+	listen_channel_str = getDppListenChannel(wpa_s, &listen_channel);
+	if (listen_channel == 0) {
+		wpa_printf(MSG_ERROR, "StaIface: Failed to derive DPP listen channel");
+		return {bootstrap_info, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	cmd += " chan=" + listen_channel_str;
+
+	cmd += " mac=";
+	for (int i = 0;i < 6;i++) {
+		snprintf(buf, sizeof(buf), "%02x", mac_address[i]);
+		mac_addr_str.append(buf);
+	}
+	cmd += mac_addr_str;
+
+	cmd += " curve=" + convertCurveTypeToName(curve);
+
+	id = dpp_bootstrap_gen(wpa_s->dpp, cmd.c_str());
+	wpa_printf(MSG_DEBUG,
+		   "DPP generate bootstrap QR code command: %s id: %d", cmd.c_str(), id);
+	if (id > 0) {
+		uri = dpp_bootstrap_get_uri(wpa_s->dpp, id);
+		if (uri) {
+			wpa_printf(MSG_DEBUG, "DPP Bootstrap info: id: %d "
+				   "listen_channel: %d uri: %s", id, listen_channel, uri);
+			bootstrap_info.bootstrapId = id;
+			bootstrap_info.listenChannel = listen_channel;
+			bootstrap_info.uri = uri;
+			return {bootstrap_info, ndk::ScopedAStatus::ok()};
+		}
+	}
+	return {bootstrap_info, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+#else
+	return {bootstrap_info, createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED)};
+#endif
+}
+
+ndk::ScopedAStatus StaIface::startDppEnrolleeResponderInternal(uint32_t listen_channel)
+{
+#ifdef CONFIG_DPP
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	std::string cmd = "";
+	uint32_t freq = (listen_channel <= 14 ? 2407 : 5000) + listen_channel * 5;
+
+	/* Report received configuration to AIDL and create an internal profile */
+	wpa_s->conf->dpp_config_processing = 1;
+
+	cmd += std::to_string(freq);
+	cmd += " role=enrollee netrole=sta";
+
+	wpa_printf(MSG_DEBUG,
+		   "DPP Enrollee Responder command: %s", cmd.c_str());
+
+	if (wpas_dpp_listen(wpa_s, cmd.c_str()) == 0) {
+		return ndk::ScopedAStatus::ok();
+	}
+	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+#else
+	return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
+#endif
+}
+
+ndk::ScopedAStatus StaIface::stopDppResponderInternal(uint32_t own_bootstrap_id)
+{
+#ifdef CONFIG_DPP
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	std::string bootstrap_id_str;
+
+	if (own_bootstrap_id == 0) {
+		bootstrap_id_str = "*";
+	}
+	else {
+		bootstrap_id_str = std::to_string(own_bootstrap_id);
+	}
+
+	wpa_printf(MSG_DEBUG, "DPP Stop DPP Responder id: %d ", own_bootstrap_id);
+	wpas_dpp_stop(wpa_s);
+	wpas_dpp_listen_stop(wpa_s);
+
+	if (dpp_bootstrap_remove(wpa_s->dpp, bootstrap_id_str.c_str()) < 0) {
+		wpa_printf(MSG_ERROR, "StaIface: dpp_bootstrap_remove failed");
+	}
+
+	return ndk::ScopedAStatus::ok();
+#else
+	return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
+#endif
+}
+
+ndk::ScopedAStatus StaIface::generateSelfDppConfigurationInternal(const std::string& ssid,
+		const std::vector<uint8_t> &privEcKey)
+{
+#ifdef CONFIG_DPP
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	std::string cmd = "";
+	char *ssid_hex_str;
+	int len;
+	int32_t id;
+
+	if (ssid.empty() || privEcKey.empty()) {
+		wpa_printf(MSG_ERROR, "DPP generate self configuration failed. ssid/key empty");
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	cmd += " key=" + std::string(privEcKey.begin(), privEcKey.end());
+
+	id = dpp_configurator_add(wpa_s->dpp, cmd.c_str());
+	if (id < 0) {
+		wpa_printf(MSG_ERROR, "DPP configurator add failed. Input key might be incorrect");
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	cmd = " conf=sta-dpp";
+	cmd += " configurator=" + std::to_string(id);
+
+	ssid_hex_str = (char *) os_zalloc(ssid.size() * 2 + 1);
+	if (!ssid_hex_str) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	wpa_snprintf_hex(ssid_hex_str, ssid.size() * 2 + 1, (u8*)ssid.data(), ssid.size());
+	cmd += " ssid=" + std::string(ssid_hex_str);
+
+	/* Report received configuration to AIDL and create an internal profile */
+	wpa_s->conf->dpp_config_processing = 1;
+
+	if (wpas_dpp_configurator_sign(wpa_s, cmd.c_str()) == 0) {
+		os_free(ssid_hex_str);
+		return ndk::ScopedAStatus::ok();
+	}
+
+	os_free(ssid_hex_str);
+	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+#else
+	return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
+#endif
+}
+
+std::pair<ConnectionCapabilities, ndk::ScopedAStatus>
+StaIface::getConnectionCapabilitiesInternal()
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	ConnectionCapabilities capa;
+
+	if (wpa_s->connection_set) {
+		capa.legacyMode = LegacyMode::UNKNOWN;
+		if (wpa_s->connection_he) {
+			capa.technology = WifiTechnology::HE;
+		} else if (wpa_s->connection_vht) {
+			capa.technology = WifiTechnology::VHT;
+		} else if (wpa_s->connection_ht) {
+			capa.technology = WifiTechnology::HT;
+		} else {
+			capa.technology = WifiTechnology::LEGACY;
+			if (wpas_freq_to_band(wpa_s->assoc_freq) == BAND_2_4_GHZ) {
+				capa.legacyMode = (wpa_s->connection_11b_only) ? LegacyMode::B_MODE
+						: LegacyMode::G_MODE; 
+			} else {
+				capa.legacyMode = LegacyMode::A_MODE;
+			}
+		}
+		switch (wpa_s->connection_channel_bandwidth) {
+		case CHAN_WIDTH_20:
+			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_20;
+			break;
+		case CHAN_WIDTH_40:
+			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_40;
+			break;
+		case CHAN_WIDTH_80:
+			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_80;
+			break;
+		case CHAN_WIDTH_160:
+			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_160;
+			break;
+		case CHAN_WIDTH_80P80:
+			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_80P80;
+			break;
+		default:
+			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_20;
+			break;
+		}
+		capa.maxNumberRxSpatialStreams = wpa_s->connection_max_nss_rx;
+		capa.maxNumberTxSpatialStreams = wpa_s->connection_max_nss_tx;
+	} else {
+		capa.technology = WifiTechnology::UNKNOWN;
+		capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_20;
+		capa.maxNumberTxSpatialStreams = 1;
+		capa.maxNumberRxSpatialStreams = 1;
+		capa.legacyMode = LegacyMode::UNKNOWN;
+	}
+	return {capa, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<WpaDriverCapabilitiesMask, ndk::ScopedAStatus>
+StaIface::getWpaDriverCapabilitiesInternal()
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	uint32_t mask = 0;
+
+#ifdef CONFIG_MBO
+	/* MBO has no capability flags. It's mainly legacy 802.11v BSS
+	 * transition + Cellular steering. 11v is a default feature in
+	 * supplicant. And cellular steering is handled in framework.
+	 */
+	mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::MBO);
+	if (wpa_s->enable_oce & OCE_STA) {
+		mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::OCE);
+	}
+#endif
+#ifdef CONFIG_SAE_PK
+	mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::SAE_PK);
+#endif
+	mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::WFD_R2);
+
+	mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::TRUST_ON_FIRST_USE);
+
+	wpa_printf(MSG_DEBUG, "Driver capability mask: 0x%x", mask);
+
+	return {static_cast<WpaDriverCapabilitiesMask>(mask),
+		ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaIface::setMboCellularDataStatusInternal(bool available)
+{
+#ifdef CONFIG_MBO
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	enum mbo_cellular_capa mbo_cell_capa;
+
+	if (available) {
+		mbo_cell_capa = MBO_CELL_CAPA_AVAILABLE;
+	} else {
+		mbo_cell_capa = MBO_CELL_CAPA_NOT_AVAILABLE;
+	}
+
+#ifdef ENABLE_PRIV_CMD_UPDATE_MBO_CELL_STATUS
+	char mbo_cmd[32];
+	char buf[32];
+
+	os_snprintf(mbo_cmd, sizeof(mbo_cmd), "%s %d", "MBO CELL_DATA_CAP", mbo_cell_capa);
+	if (wpa_drv_driver_cmd(wpa_s, mbo_cmd, buf, sizeof(buf)) < 0) {
+		wpa_printf(MSG_ERROR, "MBO CELL_DATA_CAP cmd failed CAP:%d", mbo_cell_capa);
+	}
+#else
+	wpas_mbo_update_cell_capa(wpa_s, mbo_cell_capa);
+#endif
+
+	return ndk::ScopedAStatus::ok();
+#else
+	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+#endif
+}
+
+std::pair<KeyMgmtMask, ndk::ScopedAStatus>
+StaIface::getKeyMgmtCapabilitiesInternal()
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	struct wpa_driver_capa capa;
+
+	/* Get capabilities from driver and populate the key management mask */
+	if (wpa_drv_get_capa(wpa_s, &capa) < 0) {
+		return {static_cast<KeyMgmtMask>(0),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+
+	return {convertWpaKeyMgmtCapabilitiesToAidl(wpa_s, &capa),
+		ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaIface::setQosPolicyFeatureEnabledInternal(bool enable)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	wpa_s->enable_dscp_policy_capa = enable ? 1 : 0;
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::sendQosPolicyResponseInternal(
+	int32_t qos_policy_request_id, bool more_policies,
+	const std::vector<QosPolicyStatus>& qos_policy_status_list)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	struct dscp_resp_data resp_data;
+	int num_policies = qos_policy_status_list.size();
+
+	memset(&resp_data, 0, sizeof(resp_data));
+
+	resp_data.more = more_policies ? 1 : 0;
+	resp_data.policy = (struct dscp_policy_status *) malloc(
+		sizeof(struct dscp_policy_status) * num_policies);
+	if (num_policies && !resp_data.policy){
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	resp_data.solicited = true;
+	wpa_s->dscp_req_dialog_token = qos_policy_request_id;
+
+	for (int i = 0; i < num_policies; i++) {
+		resp_data.policy[i].id = qos_policy_status_list.at(i).policyId;
+		resp_data.policy[i].status =
+			static_cast<uint8_t>(qos_policy_status_list.at(i).status);
+	}
+	resp_data.num_policies = num_policies;
+
+	if (wpas_send_dscp_response(wpa_s, &resp_data)) {
+		free(resp_data.policy);
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	free(resp_data.policy);
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::removeAllQosPoliciesInternal()
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	struct dscp_resp_data resp_data;
+
+	memset(&resp_data, 0, sizeof(resp_data));
+	resp_data.reset = true;
+	resp_data.solicited = false;
+	wpa_s->dscp_req_dialog_token = 0;
+
+	if (wpas_send_dscp_response(wpa_s, &resp_data)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<MloLinksInfo, ndk::ScopedAStatus> StaIface::getConnectionMloLinksInfoInternal()
+{
+	MloLinksInfo linksInfo;
+	return {linksInfo, ndk::ScopedAStatus::ok()};
+}
+
+/**
+ * Retrieve the underlying |wpa_supplicant| struct
+ * pointer for this iface.
+ * If the underlying iface is removed, then all RPC method calls on this object
+ * will return failure.
+ */
+wpa_supplicant *StaIface::retrieveIfacePtr()
+{
+	return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str());
+}
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/sta_iface.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/sta_iface.h
new file mode 100755
index 0000000..0ed29d8
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/sta_iface.h
@@ -0,0 +1,282 @@
+/*
+ * WPA Supplicant - Sta Iface Aidl interface
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef WPA_SUPPLICANT_AIDL_STA_IFACE_H
+#define WPA_SUPPLICANT_AIDL_STA_IFACE_H
+
+#include <array>
+#include <vector>
+
+#include <android-base/macros.h>
+
+#include <aidl/android/hardware/wifi/supplicant/AnqpInfoId.h>
+#include <aidl/android/hardware/wifi/supplicant/BnSupplicantStaIface.h>
+#include <aidl/android/hardware/wifi/supplicant/BtCoexistenceMode.h>
+#include <aidl/android/hardware/wifi/supplicant/Hs20AnqpSubtypes.h>
+#include <aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.h>
+#include <aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.h>
+#include <aidl/android/hardware/wifi/supplicant/MloLinksInfo.h>
+#include <aidl/android/hardware/wifi/supplicant/QosPolicyStatus.h>
+#include <aidl/android/hardware/wifi/supplicant/RxFilterType.h>
+
+extern "C"
+{
+#include "utils/common.h"
+#include "utils/includes.h"
+#include "wpa_supplicant_i.h"
+#include "config.h"
+#include "driver_i.h"
+#include "wpa.h"
+}
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+
+/**
+ * Implementation of StaIface aidl object. Each unique aidl
+ * object is used for control operations on a specific interface
+ * controlled by wpa_supplicant.
+ */
+class StaIface : public BnSupplicantStaIface
+{
+public:
+	StaIface(struct wpa_global* wpa_global, const char ifname[]);
+	~StaIface() override = default;
+	// AIDL does not provide a built-in mechanism to let the server
+	// invalidate a AIDL interface object after creation. If any client
+	// process holds onto a reference to the object in their context,
+	// any method calls on that reference will continue to be directed to
+	// the server.
+	// However Supplicant HAL needs to control the lifetime of these
+	// objects. So, add a public |invalidate| method to all |Iface| and
+	// |Network| objects.
+	// This will be used to mark an object invalid when the corresponding
+	// iface or network is removed.
+	// All AIDL method implementations should check if the object is still
+	// marked valid before processing them.
+	void invalidate();
+	bool isValid();
+
+	// Aidl methods exposed.
+  	::ndk::ScopedAStatus getName(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getType(IfaceType* _aidl_return) override;
+	::ndk::ScopedAStatus addNetwork(
+		std::shared_ptr<ISupplicantStaNetwork>* _aidl_return) override;
+	::ndk::ScopedAStatus removeNetwork(int32_t in_id) override;
+	::ndk::ScopedAStatus filsHlpFlushRequest() override;
+	::ndk::ScopedAStatus filsHlpAddRequest(
+		const std::vector<uint8_t>& in_dst_mac,
+		const std::vector<uint8_t>& in_pkt) override;
+	::ndk::ScopedAStatus getNetwork(
+		int32_t in_id, std::shared_ptr<ISupplicantStaNetwork>* _aidl_return) override;
+	::ndk::ScopedAStatus listNetworks(std::vector<int32_t>* _aidl_return) override;
+	::ndk::ScopedAStatus registerCallback(
+		const std::shared_ptr<ISupplicantStaIfaceCallback>& in_callback) override;
+	::ndk::ScopedAStatus reassociate() override;
+	::ndk::ScopedAStatus reconnect() override;
+	::ndk::ScopedAStatus disconnect() override;
+	::ndk::ScopedAStatus setPowerSave(bool in_enable) override;
+	::ndk::ScopedAStatus initiateTdlsDiscover(
+		const std::vector<uint8_t>& in_macAddress) override;
+	::ndk::ScopedAStatus initiateTdlsSetup(
+		const std::vector<uint8_t>& in_macAddress) override;
+	::ndk::ScopedAStatus initiateTdlsTeardown(
+		const std::vector<uint8_t>& in_macAddress) override;
+	::ndk::ScopedAStatus initiateAnqpQuery(
+		const std::vector<uint8_t>& in_macAddress,
+		const std::vector<AnqpInfoId>& in_infoElements,
+		const std::vector<Hs20AnqpSubtypes>& in_subTypes) override;
+	::ndk::ScopedAStatus initiateVenueUrlAnqpQuery(
+		const std::vector<uint8_t>& in_macAddress) override;
+	::ndk::ScopedAStatus initiateHs20IconQuery(
+		const std::vector<uint8_t>& in_macAddress, const std::string& in_fileName) override;
+	::ndk::ScopedAStatus getMacAddress(std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus startRxFilter() override;
+	::ndk::ScopedAStatus stopRxFilter() override;
+	::ndk::ScopedAStatus addRxFilter(RxFilterType in_type) override;
+	::ndk::ScopedAStatus removeRxFilter(RxFilterType in_type) override;
+	::ndk::ScopedAStatus setBtCoexistenceMode(BtCoexistenceMode in_mode) override;
+	::ndk::ScopedAStatus setBtCoexistenceScanModeEnabled(bool in_enable) override;
+	::ndk::ScopedAStatus setSuspendModeEnabled(bool in_enable) override;
+	::ndk::ScopedAStatus setCountryCode(const std::vector<uint8_t>& in_code) override;
+	::ndk::ScopedAStatus startWpsRegistrar(
+		const std::vector<uint8_t>& in_bssid, const std::string& in_pin) override;
+	::ndk::ScopedAStatus startWpsPbc(const std::vector<uint8_t>& in_bssid) override;
+	::ndk::ScopedAStatus startWpsPinDisplay(
+		const std::vector<uint8_t>& in_bssid, std::string* _aidl_return) override;
+	::ndk::ScopedAStatus startWpsPinKeypad(const std::string& in_pin) override;
+	::ndk::ScopedAStatus cancelWps() override;
+	::ndk::ScopedAStatus setWpsDeviceName(const std::string& in_name) override;
+	::ndk::ScopedAStatus setWpsDeviceType(const std::vector<uint8_t>& in_type) override;
+	::ndk::ScopedAStatus setWpsManufacturer(const std::string& in_manufacturer) override;
+	::ndk::ScopedAStatus setWpsModelName(const std::string& in_modelName) override;
+	::ndk::ScopedAStatus setWpsModelNumber(const std::string& in_modelNumber) override;
+	::ndk::ScopedAStatus setWpsSerialNumber(const std::string& in_serialNumber) override;
+	::ndk::ScopedAStatus setWpsConfigMethods(WpsConfigMethods in_configMethods) override;
+	::ndk::ScopedAStatus setExternalSim(bool in_useExternalSim) override;
+	::ndk::ScopedAStatus addExtRadioWork(
+		const std::string& in_name, int32_t in_freqInMhz,
+		int32_t in_timeoutInSec, int32_t* _aidl_return) override;
+	::ndk::ScopedAStatus removeExtRadioWork(int32_t in_id) override;
+	::ndk::ScopedAStatus enableAutoReconnect(bool in_enable) override;
+	::ndk::ScopedAStatus getKeyMgmtCapabilities(KeyMgmtMask* _aidl_return) override;
+	::ndk::ScopedAStatus addDppPeerUri(
+		const std::string& in_uri, int32_t* _aidl_return) override;
+	::ndk::ScopedAStatus removeDppUri(int32_t in_id) override;
+	::ndk::ScopedAStatus startDppConfiguratorInitiator(
+		int32_t in_peerBootstrapId, int32_t in_ownBootstrapId,
+		const std::string& in_ssid, const std::string& in_password,
+		const std::string& in_psk, DppNetRole in_netRole, DppAkm in_securityAkm,
+		const std::vector<uint8_t>& in_privEcKey,
+		std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus startDppEnrolleeInitiator(
+		int32_t in_peerBootstrapId, int32_t in_ownBootstrapId) override;
+	::ndk::ScopedAStatus stopDppInitiator() override;
+	::ndk::ScopedAStatus getConnectionCapabilities(ConnectionCapabilities* _aidl_return) override;
+	::ndk::ScopedAStatus getWpaDriverCapabilities(WpaDriverCapabilitiesMask* _aidl_return) override;
+	::ndk::ScopedAStatus setMboCellularDataStatus(bool in_available) override;
+	::ndk::ScopedAStatus generateDppBootstrapInfoForResponder(
+		const std::vector<uint8_t>& in_macAddress,
+		const std::string& in_deviceInfo, DppCurve in_curve,
+		DppResponderBootstrapInfo* _aidl_return) override;
+	::ndk::ScopedAStatus startDppEnrolleeResponder(int32_t in_listenChannel) override;
+	::ndk::ScopedAStatus stopDppResponder(int32_t in_ownBootstrapId) override;
+	::ndk::ScopedAStatus generateSelfDppConfiguration(
+		const std::string& in_ssid, const std::vector<uint8_t>& in_privEcKey) override;
+	::ndk::ScopedAStatus setQosPolicyFeatureEnabled(bool in_enable) override;
+	::ndk::ScopedAStatus sendQosPolicyResponse(
+		int32_t in_qosPolicyRequestId, bool in_morePolicies,
+		const std::vector<QosPolicyStatus>& in_qosPolicyStatusList) override;
+	::ndk::ScopedAStatus removeAllQosPolicies() override;
+	::ndk::ScopedAStatus getConnectionMloLinksInfo(MloLinksInfo* _aidl_return) override;
+
+private:
+	// Corresponding worker functions for the AIDL methods.
+	std::pair<std::string, ndk::ScopedAStatus> getNameInternal();
+	std::pair<IfaceType, ndk::ScopedAStatus> getTypeInternal();
+	std::pair<std::shared_ptr<ISupplicantStaNetwork>, ndk::ScopedAStatus>
+		addNetworkInternal();
+	ndk::ScopedAStatus filsHlpFlushRequestInternal();
+	ndk::ScopedAStatus filsHlpAddRequestInternal(
+		const std::vector<uint8_t>& dst_mac,
+		const std::vector<uint8_t>& pkt);
+	ndk::ScopedAStatus removeNetworkInternal(int32_t id);
+	std::pair<std::shared_ptr<ISupplicantStaNetwork>, ndk::ScopedAStatus>
+		getNetworkInternal(int32_t id);
+	std::pair<std::vector<int32_t>, ndk::ScopedAStatus>
+		listNetworksInternal();
+	ndk::ScopedAStatus registerCallbackInternal(
+		const std::shared_ptr<ISupplicantStaIfaceCallback>& callback);
+	ndk::ScopedAStatus reassociateInternal();
+	ndk::ScopedAStatus reconnectInternal();
+	ndk::ScopedAStatus disconnectInternal();
+	ndk::ScopedAStatus setPowerSaveInternal(bool enable);
+	ndk::ScopedAStatus initiateTdlsDiscoverInternal(
+		const std::vector<uint8_t>& mac_address);
+	ndk::ScopedAStatus initiateTdlsSetupInternal(
+		const std::vector<uint8_t>& mac_address);
+	ndk::ScopedAStatus initiateTdlsTeardownInternal(
+		const std::vector<uint8_t>& mac_address);
+	ndk::ScopedAStatus initiateAnqpQueryInternal(
+		const std::vector<uint8_t>& mac_address,
+		const std::vector<AnqpInfoId>& info_elements,
+		const std::vector<Hs20AnqpSubtypes>&
+		sub_types);
+	ndk::ScopedAStatus initiateVenueUrlAnqpQueryInternal(
+		const std::vector<uint8_t>& mac_address);
+	ndk::ScopedAStatus initiateHs20IconQueryInternal(
+		const std::vector<uint8_t>& mac_address,
+		const std::string& file_name);
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+		getMacAddressInternal();
+	ndk::ScopedAStatus startRxFilterInternal();
+	ndk::ScopedAStatus stopRxFilterInternal();
+	ndk::ScopedAStatus addRxFilterInternal(
+		RxFilterType type);
+	ndk::ScopedAStatus removeRxFilterInternal(
+		RxFilterType type);
+	ndk::ScopedAStatus setBtCoexistenceModeInternal(
+		BtCoexistenceMode mode);
+	ndk::ScopedAStatus setBtCoexistenceScanModeEnabledInternal(bool enable);
+	ndk::ScopedAStatus setSuspendModeEnabledInternal(bool enable);
+	ndk::ScopedAStatus setCountryCodeInternal(
+		const std::vector<uint8_t>& code);
+	ndk::ScopedAStatus startWpsRegistrarInternal(
+		const std::vector<uint8_t>& bssid, const std::string& pin);
+	ndk::ScopedAStatus startWpsPbcInternal(
+		const std::vector<uint8_t>& bssid);
+	ndk::ScopedAStatus startWpsPinKeypadInternal(const std::string& pin);
+	std::pair<std::string, ndk::ScopedAStatus> startWpsPinDisplayInternal(
+		const std::vector<uint8_t>& bssid);
+	ndk::ScopedAStatus cancelWpsInternal();
+	ndk::ScopedAStatus setWpsDeviceNameInternal(const std::string& name);
+	ndk::ScopedAStatus setWpsDeviceTypeInternal(
+		const std::vector<uint8_t>& type);
+	ndk::ScopedAStatus setWpsManufacturerInternal(
+		const std::string& manufacturer);
+	ndk::ScopedAStatus setWpsModelNameInternal(const std::string& model_name);
+	ndk::ScopedAStatus setWpsModelNumberInternal(
+		const std::string& model_number);
+	ndk::ScopedAStatus setWpsSerialNumberInternal(
+		const std::string& serial_number);
+	ndk::ScopedAStatus setWpsConfigMethodsInternal(WpsConfigMethods config_methods);
+	ndk::ScopedAStatus setExternalSimInternal(bool useExternalSim);
+	std::pair<uint32_t, ndk::ScopedAStatus> addExtRadioWorkInternal(
+		const std::string& name, uint32_t freq_in_mhz,
+		uint32_t timeout_in_sec);
+	ndk::ScopedAStatus removeExtRadioWorkInternal(uint32_t id);
+	ndk::ScopedAStatus enableAutoReconnectInternal(bool enable);
+	std::pair<KeyMgmtMask, ndk::ScopedAStatus> getKeyMgmtCapabilitiesInternal();
+	std::pair<uint32_t, ndk::ScopedAStatus> addDppPeerUriInternal(const std::string& uri);
+	ndk::ScopedAStatus removeDppUriInternal(uint32_t bootstrap_id);
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> startDppConfiguratorInitiatorInternal(
+		uint32_t peer_bootstrap_id, uint32_t own_bootstrap_id, const std::string& ssid,
+		const std::string& password, const std::string& psk, DppNetRole net_role,
+		DppAkm security_akm, const std::vector<uint8_t> &privEcKey);
+	ndk::ScopedAStatus startDppEnrolleeInitiatorInternal(uint32_t peer_bootstrap_id,
+			uint32_t own_bootstrap_id);
+	ndk::ScopedAStatus stopDppInitiatorInternal();
+	std::pair<ConnectionCapabilities, ndk::ScopedAStatus> getConnectionCapabilitiesInternal();
+	std::pair<WpaDriverCapabilitiesMask, ndk::ScopedAStatus> getWpaDriverCapabilitiesInternal();
+	ndk::ScopedAStatus setMboCellularDataStatusInternal(bool available);
+	std::pair<DppResponderBootstrapInfo, ndk::ScopedAStatus>
+			generateDppBootstrapInfoForResponderInternal(
+			const std::vector<uint8_t>& mac_address, const std::string& device_info,
+			DppCurve curve);
+	ndk::ScopedAStatus startDppEnrolleeResponderInternal(uint32_t listen_channel);
+	ndk::ScopedAStatus stopDppResponderInternal(uint32_t own_bootstrap_id);
+	ndk::ScopedAStatus generateSelfDppConfigurationInternal(
+		const std::string& ssid, const std::vector<uint8_t> &privEcKey);
+	ndk::ScopedAStatus setQosPolicyFeatureEnabledInternal(bool enable);
+	ndk::ScopedAStatus sendQosPolicyResponseInternal(
+		int32_t qos_policy_request_id, bool more_policies,
+		const std::vector<QosPolicyStatus>& qos_policy_status_list);
+	ndk::ScopedAStatus removeAllQosPoliciesInternal();
+	std::pair<MloLinksInfo, ndk::ScopedAStatus> getConnectionMloLinksInfoInternal();
+	struct wpa_supplicant* retrieveIfacePtr();
+
+	// Reference to the global wpa_struct. This is assumed to be valid for
+	// the lifetime of the process.
+	struct wpa_global* wpa_global_;
+	// Name of the iface this aidl object controls
+	const std::string ifname_;
+	bool is_valid_;
+
+	DISALLOW_COPY_AND_ASSIGN(StaIface);
+};
+
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WPA_SUPPLICANT_AIDL_STA_IFACE_H
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/sta_network.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/sta_network.cpp
new file mode 100755
index 0000000..fe4a760
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/sta_network.cpp
@@ -0,0 +1,2568 @@
+/*
+ * WPA Supplicant - Sta network Aidl interface
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "aidl_manager.h"
+#include "aidl_return_util.h"
+#include "misc_utils.h"
+#include "sta_network.h"
+
+extern "C"
+{
+#include "wps_supplicant.h"
+}
+
+namespace {
+using aidl::android::hardware::wifi::supplicant::AuthAlgMask;
+using aidl::android::hardware::wifi::supplicant::EapMethod;
+using aidl::android::hardware::wifi::supplicant::EapPhase2Method;
+using aidl::android::hardware::wifi::supplicant::GroupCipherMask;
+using aidl::android::hardware::wifi::supplicant::GroupMgmtCipherMask;
+using aidl::android::hardware::wifi::supplicant::ISupplicantStaNetwork;
+using aidl::android::hardware::wifi::supplicant::KeyMgmtMask;
+using aidl::android::hardware::wifi::supplicant::PairwiseCipherMask;
+using aidl::android::hardware::wifi::supplicant::ProtoMask;
+
+constexpr uint8_t kZeroBssid[6] = {0, 0, 0, 0, 0, 0};
+
+constexpr uint32_t kAllowedKeyMgmtMask =
+	(static_cast<uint32_t>(KeyMgmtMask::NONE) |
+	 static_cast<uint32_t>(KeyMgmtMask::WPA_PSK) |
+	 static_cast<uint32_t>(KeyMgmtMask::WPA_EAP) |
+	 static_cast<uint32_t>(KeyMgmtMask::IEEE8021X) |
+	 static_cast<uint32_t>(KeyMgmtMask::FT_EAP) |
+	 static_cast<uint32_t>(KeyMgmtMask::FT_PSK) |
+	 static_cast<uint32_t>(KeyMgmtMask::OSEN) |
+	 static_cast<uint32_t>(KeyMgmtMask::SAE) |
+	 static_cast<uint32_t>(KeyMgmtMask::SUITE_B_192) |
+	 static_cast<uint32_t>(KeyMgmtMask::OWE) |
+	 static_cast<uint32_t>(KeyMgmtMask::WPA_PSK_SHA256) |
+	 static_cast<uint32_t>(KeyMgmtMask::WPA_EAP_SHA256) |
+	 static_cast<uint32_t>(KeyMgmtMask::WAPI_PSK) |
+	 static_cast<uint32_t>(KeyMgmtMask::WAPI_CERT) |
+	 static_cast<uint32_t>(KeyMgmtMask::FILS_SHA256) |
+	 static_cast<uint32_t>(KeyMgmtMask::FILS_SHA384) |
+	 static_cast<uint32_t>(KeyMgmtMask::DPP));
+constexpr uint32_t kAllowedProtoMask =
+	(static_cast<uint32_t>(ProtoMask::WPA) |
+	 static_cast<uint32_t>(ProtoMask::RSN) |
+	 static_cast<uint32_t>(ProtoMask::OSEN) |
+	 static_cast<uint32_t>(ProtoMask::WAPI));
+constexpr uint32_t kAllowedAuthAlgMask =
+	(static_cast<uint32_t>(AuthAlgMask::OPEN) |
+	 static_cast<uint32_t>(AuthAlgMask::SHARED) |
+	 static_cast<uint32_t>(AuthAlgMask::LEAP) |
+	 static_cast<uint32_t>(AuthAlgMask::SAE));
+constexpr uint32_t kAllowedGroupCipherMask =
+	(static_cast<uint32_t>(GroupCipherMask::WEP40) |
+	 static_cast<uint32_t>(GroupCipherMask::WEP104) |
+	 static_cast<uint32_t>(GroupCipherMask::TKIP) |
+	 static_cast<uint32_t>(GroupCipherMask::CCMP) |
+	 static_cast<uint32_t>(
+	 GroupCipherMask::GTK_NOT_USED) |
+	 static_cast<uint32_t>(GroupCipherMask::GCMP_256) |
+	 static_cast<uint32_t>(GroupCipherMask::SMS4) |
+	 static_cast<uint32_t>(GroupCipherMask::GCMP_128));
+constexpr uint32_t kAllowedPairwisewCipherMask =
+	(static_cast<uint32_t>(PairwiseCipherMask::NONE) |
+	 static_cast<uint32_t>(PairwiseCipherMask::TKIP) |
+	 static_cast<uint32_t>(PairwiseCipherMask::CCMP) |
+	 static_cast<uint32_t>(
+	 PairwiseCipherMask::GCMP_256) |
+	 static_cast<uint32_t>(
+	 PairwiseCipherMask::SMS4) |
+	 static_cast<uint32_t>(PairwiseCipherMask::GCMP_128));
+constexpr uint32_t kAllowedGroupMgmtCipherMask =
+	(static_cast<uint32_t>(
+			GroupMgmtCipherMask::BIP_GMAC_128) |
+	 static_cast<uint32_t>(
+			 GroupMgmtCipherMask::BIP_GMAC_256) |
+	 static_cast<uint32_t>(
+			 GroupMgmtCipherMask::BIP_CMAC_256));
+
+constexpr uint32_t kEapMethodMax =
+	static_cast<uint32_t>(EapMethod::WFA_UNAUTH_TLS) + 1;
+constexpr char const *kEapMethodStrings[kEapMethodMax] = {
+	"PEAP", "TLS", "TTLS", "PWD", "SIM", "AKA", "AKA'", "WFA-UNAUTH-TLS"};
+constexpr uint32_t kEapPhase2MethodMax =
+	static_cast<uint32_t>(EapPhase2Method::AKA_PRIME) + 1;
+constexpr char const *kEapPhase2MethodStrings[kEapPhase2MethodMax] = {
+	"", "PAP", "MSCHAP", "MSCHAPV2", "GTC", "SIM", "AKA", "AKA'"};
+constexpr char kEapPhase2AuthPrefix[] = "auth=";
+constexpr char kEapPhase2AuthEapPrefix[] = "autheap=";
+constexpr char kNetworkEapSimGsmAuthResponse[] = "GSM-AUTH";
+constexpr char kNetworkEapSimUmtsAuthResponse[] = "UMTS-AUTH";
+constexpr char kNetworkEapSimUmtsAutsResponse[] = "UMTS-AUTS";
+constexpr char kNetworkEapSimGsmAuthFailure[] = "GSM-FAIL";
+constexpr char kNetworkEapSimUmtsAuthFailure[] = "UMTS-FAIL";
+
+#ifdef CONFIG_WAPI_INTERFACE
+std::string dummyWapiCertSuite;
+std::vector<uint8_t> dummyWapiPsk;
+#endif /* CONFIG_WAPI_INTERFACE */
+}  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+using aidl_return_util::validateAndCall;
+using misc_utils::createStatus;
+using misc_utils::createStatusWithMsg;
+
+StaNetwork::StaNetwork(
+	struct wpa_global *wpa_global, const char ifname[], int network_id)
+	: wpa_global_(wpa_global),
+	  ifname_(ifname),
+	  network_id_(network_id),
+	  is_valid_(true)
+{}
+
+void StaNetwork::invalidate() { is_valid_ = false; }
+bool StaNetwork::isValid()
+{
+	return (is_valid_ && (retrieveNetworkPtr() != nullptr));
+}
+
+::ndk::ScopedAStatus StaNetwork::getId(
+	int32_t* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getIdInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getInterfaceName(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getInterfaceNameInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getType(
+	IfaceType* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getTypeInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::registerCallback(
+	const std::shared_ptr<ISupplicantStaNetworkCallback>& in_callback)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::registerCallbackInternal, in_callback);
+}
+
+::ndk::ScopedAStatus StaNetwork::setSsid(
+	const std::vector<uint8_t>& in_ssid)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setSsidInternal, in_ssid);
+}
+
+::ndk::ScopedAStatus StaNetwork::setBssid(
+	const std::vector<uint8_t>& in_bssid)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setBssidInternal, in_bssid);
+}
+
+::ndk::ScopedAStatus StaNetwork::setDppKeys(const DppConnectionKeys& in_keys)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setDppKeysInternal, in_keys);
+}
+
+::ndk::ScopedAStatus StaNetwork::setScanSsid(bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setScanSsidInternal, in_enable);
+}
+
+::ndk::ScopedAStatus StaNetwork::setKeyMgmt(
+	KeyMgmtMask in_keyMgmtMask)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setKeyMgmtInternal, in_keyMgmtMask);
+}
+
+::ndk::ScopedAStatus StaNetwork::setProto(
+	ProtoMask in_protoMask)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setProtoInternal, in_protoMask);
+}
+
+::ndk::ScopedAStatus StaNetwork::setAuthAlg(
+	AuthAlgMask in_authAlgMask)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setAuthAlgInternal, in_authAlgMask);
+}
+
+::ndk::ScopedAStatus StaNetwork::setGroupCipher(
+	GroupCipherMask in_groupCipherMask)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setGroupCipherInternal, in_groupCipherMask);
+}
+
+::ndk::ScopedAStatus StaNetwork::setPairwiseCipher(
+	PairwiseCipherMask in_pairwiseCipherMask)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setPairwiseCipherInternal,
+		in_pairwiseCipherMask);
+}
+
+::ndk::ScopedAStatus StaNetwork::setPskPassphrase(
+	const std::string& in_psk)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setPskPassphraseInternal, in_psk);
+}
+
+::ndk::ScopedAStatus StaNetwork::setPsk(
+	const std::vector<uint8_t>& in_psk)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setPskInternal, in_psk);
+}
+
+::ndk::ScopedAStatus StaNetwork::setWepKey(
+	int32_t in_keyIdx, const std::vector<uint8_t>& in_wepKey)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setWepKeyInternal, in_keyIdx, in_wepKey);
+}
+
+::ndk::ScopedAStatus StaNetwork::setWepTxKeyIdx(
+	int32_t in_keyIdx)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setWepTxKeyIdxInternal, in_keyIdx);
+}
+
+::ndk::ScopedAStatus StaNetwork::setRequirePmf(bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setRequirePmfInternal, in_enable);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapMethod(
+	EapMethod in_method)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapMethodInternal, in_method);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapPhase2Method(
+	EapPhase2Method in_method)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapPhase2MethodInternal, in_method);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapIdentity(
+	const std::vector<uint8_t>& in_identity)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapIdentityInternal, in_identity);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapEncryptedImsiIdentity(
+	const std::vector<uint8_t>& in_identity)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapEncryptedImsiIdentityInternal,
+		in_identity);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapAnonymousIdentity(
+	const std::vector<uint8_t>& in_identity)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapAnonymousIdentityInternal, in_identity);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapPassword(
+	const std::vector<uint8_t>& in_password)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapPasswordInternal, in_password);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapCACert(
+	const std::string& in_path)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapCACertInternal, in_path);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapCAPath(
+	const std::string& in_path)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapCAPathInternal, in_path);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapClientCert(
+	const std::string& in_path)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapClientCertInternal, in_path);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapPrivateKeyId(
+	const std::string& in_id)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapPrivateKeyIdInternal, in_id);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapSubjectMatch(
+	const std::string& in_match)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapSubjectMatchInternal, in_match);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapAltSubjectMatch(
+	const std::string& in_match)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapAltSubjectMatchInternal, in_match);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapEngine(bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapEngineInternal, in_enable);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapEngineID(
+	const std::string& in_id)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapEngineIDInternal, in_id);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapDomainSuffixMatch(
+	const std::string& in_match)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapDomainSuffixMatchInternal, in_match);
+}
+
+::ndk::ScopedAStatus StaNetwork::setProactiveKeyCaching(
+	bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setProactiveKeyCachingInternal, in_enable);
+}
+
+::ndk::ScopedAStatus StaNetwork::setIdStr(
+	const std::string& in_idStr)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setIdStrInternal, in_idStr);
+}
+
+::ndk::ScopedAStatus StaNetwork::setUpdateIdentifier(
+	int32_t in_id)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setUpdateIdentifierInternal, in_id);
+}
+
+::ndk::ScopedAStatus StaNetwork::setWapiCertSuite(
+	const std::string& in_suite)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setWapiCertSuiteInternal, in_suite);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEdmg(bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEdmgInternal, in_enable);
+}
+
+::ndk::ScopedAStatus StaNetwork::getSsid(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getSsidInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus StaNetwork::getBssid(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getBssidInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getScanSsid(
+	bool* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getScanSsidInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getKeyMgmt(
+	KeyMgmtMask* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getKeyMgmtInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getProto(
+	ProtoMask* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getProtoInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getAuthAlg(
+	AuthAlgMask* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getAuthAlgInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getGroupCipher(
+	GroupCipherMask* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getGroupCipherInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getPairwiseCipher(
+	PairwiseCipherMask* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getPairwiseCipherInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getPskPassphrase(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getPskPassphraseInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getPsk(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getPskInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getSaePassword(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getSaePasswordInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getSaePasswordId(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getSaePasswordIdInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getWepKey(
+	int32_t in_keyIdx,
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getWepKeyInternal, _aidl_return, in_keyIdx);
+}
+
+::ndk::ScopedAStatus StaNetwork::getWepTxKeyIdx(
+	int32_t* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getWepTxKeyIdxInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getRequirePmf(
+	bool* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getRequirePmfInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapMethod(
+	EapMethod* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapMethodInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapPhase2Method(
+	EapPhase2Method* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapPhase2MethodInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapIdentity(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapIdentityInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapAnonymousIdentity(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapAnonymousIdentityInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapPassword(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapPasswordInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapCACert(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapCACertInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapCAPath(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapCAPathInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapClientCert(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapClientCertInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapPrivateKeyId(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapPrivateKeyIdInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapSubjectMatch(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapSubjectMatchInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapAltSubjectMatch(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapAltSubjectMatchInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapEngine(
+	bool* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapEngineInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapEngineId(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapEngineIdInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapDomainSuffixMatch(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapDomainSuffixMatchInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getIdStr(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getIdStrInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getWpsNfcConfigurationToken(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getWpsNfcConfigurationTokenInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getWapiCertSuite(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getWapiCertSuiteInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEdmg(
+	bool* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEdmgInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::enable(bool in_noConnect)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::enableInternal, in_noConnect);
+}
+
+::ndk::ScopedAStatus StaNetwork::disable()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::disableInternal);
+}
+
+::ndk::ScopedAStatus StaNetwork::select()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::selectInternal);
+}
+
+::ndk::ScopedAStatus StaNetwork::sendNetworkEapSimGsmAuthResponse(
+	const std::vector<NetworkResponseEapSimGsmAuthParams>& in_params)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::sendNetworkEapSimGsmAuthResponseInternal,
+		in_params);
+}
+
+::ndk::ScopedAStatus StaNetwork::sendNetworkEapSimGsmAuthFailure()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::sendNetworkEapSimGsmAuthFailureInternal);
+}
+
+::ndk::ScopedAStatus StaNetwork::sendNetworkEapSimUmtsAuthResponse(
+	const NetworkResponseEapSimUmtsAuthParams& in_params)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::sendNetworkEapSimUmtsAuthResponseInternal,
+		in_params);
+}
+
+::ndk::ScopedAStatus StaNetwork::sendNetworkEapSimUmtsAutsResponse(
+	const std::vector<uint8_t>& in_auts)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::sendNetworkEapSimUmtsAutsResponseInternal,
+		in_auts);
+}
+
+::ndk::ScopedAStatus StaNetwork::sendNetworkEapSimUmtsAuthFailure()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::sendNetworkEapSimUmtsAuthFailureInternal);
+}
+
+::ndk::ScopedAStatus StaNetwork::sendNetworkEapIdentityResponse(
+	const std::vector<uint8_t>& in_identity,
+	const std::vector<uint8_t>& in_encryptedIdentity)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::sendNetworkEapIdentityResponseInternal,
+		in_identity, in_encryptedIdentity);
+}
+
+::ndk::ScopedAStatus StaNetwork::setGroupMgmtCipher(
+	GroupMgmtCipherMask in_groupMgmtCipherMask)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setGroupMgmtCipherInternal,
+		in_groupMgmtCipherMask);
+}
+
+::ndk::ScopedAStatus StaNetwork::getGroupMgmtCipher(
+	GroupMgmtCipherMask* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getGroupMgmtCipherInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::enableTlsSuiteBEapPhase1Param(
+	bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::enableTlsSuiteBEapPhase1ParamInternal, in_enable);
+}
+
+::ndk::ScopedAStatus StaNetwork::enableSuiteBEapOpenSslCiphers()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::enableSuiteBEapOpenSslCiphersInternal);
+}
+
+::ndk::ScopedAStatus StaNetwork::setSaePassword(
+	const std::string& in_saePassword)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setSaePasswordInternal, in_saePassword);
+}
+
+::ndk::ScopedAStatus StaNetwork::setSaePasswordId(
+	const std::string& in_saePasswordId)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setSaePasswordIdInternal, in_saePasswordId);
+}
+
+::ndk::ScopedAStatus StaNetwork::setOcsp(
+	OcspType in_ocspType)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setOcspInternal, in_ocspType);
+}
+
+::ndk::ScopedAStatus StaNetwork::getOcsp(
+	OcspType* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getOcspInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::setPmkCache(
+	const std::vector<uint8_t>& in_serializedEntry)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setPmkCacheInternal, in_serializedEntry);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapErp(
+	bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapErpInternal, in_enable);
+}
+
+::ndk::ScopedAStatus StaNetwork::setSaeH2eMode(
+	SaeH2eMode in_mode)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setSaeH2eModeInternal, in_mode);
+}
+
+::ndk::ScopedAStatus StaNetwork::enableSaePkOnlyMode(
+	bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::enableSaePkOnlyModeInternal, in_enable);
+}
+
+::ndk::ScopedAStatus StaNetwork::setRoamingConsortiumSelection(
+	const std::vector<uint8_t>& in_selectedRcoi)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setRoamingConsortiumSelectionInternal, in_selectedRcoi);
+}
+
+std::pair<uint32_t, ndk::ScopedAStatus> StaNetwork::getIdInternal()
+{
+	return {network_id_, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus> StaNetwork::getInterfaceNameInternal()
+{
+	return {ifname_, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<IfaceType, ndk::ScopedAStatus> StaNetwork::getTypeInternal()
+{
+	return {IfaceType::STA, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaNetwork::registerCallbackInternal(
+	const std::shared_ptr<ISupplicantStaNetworkCallback> &callback)
+{
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager || aidl_manager->addStaNetworkCallbackAidlObject(
+				 ifname_, network_id_, callback)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setSsidInternal(const std::vector<uint8_t> &ssid)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (ssid.size() == 0 ||
+		ssid.size() >
+		static_cast<uint32_t>(ISupplicantStaNetwork::
+					  SSID_MAX_LEN_IN_BYTES)) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	if (setByteArrayFieldAndResetState(
+		ssid.data(), ssid.size(), &(wpa_ssid->ssid),
+		&(wpa_ssid->ssid_len), "ssid")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	if (wpa_ssid->passphrase) {
+		wpa_config_update_psk(wpa_ssid);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setBssidInternal(
+	const std::vector<uint8_t> &bssid)
+{
+	if (bssid.size() != ETH_ALEN) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	int prev_bssid_set = wpa_ssid->bssid_set;
+	u8 prev_bssid[ETH_ALEN];
+	os_memcpy(prev_bssid, wpa_ssid->bssid, ETH_ALEN);
+	// Zero'ed array is used to clear out the BSSID value.
+	if (os_memcmp(bssid.data(), kZeroBssid, ETH_ALEN) == 0) {
+		wpa_ssid->bssid_set = 0;
+		wpa_printf(MSG_MSGDUMP, "BSSID any");
+	} else {
+		os_memcpy(wpa_ssid->bssid, bssid.data(), ETH_ALEN);
+		wpa_ssid->bssid_set = 1;
+		wpa_hexdump(MSG_MSGDUMP, "BSSID", wpa_ssid->bssid, ETH_ALEN);
+	}
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if ((wpa_ssid->bssid_set != prev_bssid_set ||
+		 os_memcmp(wpa_ssid->bssid, prev_bssid, ETH_ALEN) != 0)) {
+		wpas_notify_network_bssid_set_changed(wpa_s, wpa_ssid);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setDppKeysInternal(const DppConnectionKeys& keys)
+{
+#ifdef CONFIG_DPP
+	if (keys.connector.empty() || keys.cSign.empty() || keys.netAccessKey.empty()) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	std::string connector_str(keys.connector.begin(), keys.connector.end());
+
+	if (setStringFieldAndResetState(
+		connector_str.c_str(), &(wpa_ssid->dpp_connector), "dpp_connector")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	if (setByteArrayFieldAndResetState(
+		keys.cSign.data(), keys.cSign.size(), &(wpa_ssid->dpp_csign),
+		&(wpa_ssid->dpp_csign_len), "dpp csign")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	if (setByteArrayFieldAndResetState(
+		keys.netAccessKey.data(), keys.netAccessKey.size(), &(wpa_ssid->dpp_netaccesskey),
+		&(wpa_ssid->dpp_netaccesskey_len), "dpp netAccessKey")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	return ndk::ScopedAStatus::ok();
+#else
+	return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
+#endif
+}
+
+ndk::ScopedAStatus StaNetwork::setScanSsidInternal(bool enable)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	wpa_ssid->scan_ssid = enable ? 1 : 0;
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setAuthAlgInternal(
+	AuthAlgMask mask)
+{
+	uint32_t auth_alg_mask = static_cast<uint32_t>(mask);
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (auth_alg_mask & ~kAllowedAuthAlgMask) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	wpa_ssid->auth_alg = auth_alg_mask;
+	wpa_printf(MSG_MSGDUMP, "auth_alg: 0x%x", wpa_ssid->auth_alg);
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEdmgInternal(bool enable)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	wpa_ssid->enable_edmg = enable ? 1 : 0;
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setPskPassphraseInternal(const std::string &rawPsk)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	std::string psk = rawPsk;
+#ifdef CONFIG_WAPI_INTERFACE
+	if (wpa_ssid->key_mgmt & WPA_KEY_MGMT_WAPI_PSK) {
+		if (rawPsk.size() > 2 && rawPsk.front()== '"' && rawPsk.back() == '"') {
+			psk = rawPsk.substr(1, rawPsk.size() - 2);
+		} else {
+			if ((rawPsk.size() & 1)) {
+				return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+			}
+			size_t len = psk.size() / 2;
+			uint8_t *buf = (uint8_t *) os_malloc(len);
+			if (hexstr2bin(psk.c_str(), buf, len) < 0) {
+					os_free(buf);
+				return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+			}
+			std::vector<uint8_t> bytes(buf, buf + len);
+			os_free(buf);
+			return setWapiPskInternal(bytes);
+		}
+	}
+#endif
+	if (isPskPassphraseValid(psk)) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	if (wpa_ssid->passphrase &&
+		os_strlen(wpa_ssid->passphrase) == psk.size() &&
+		os_memcmp(wpa_ssid->passphrase, psk.c_str(), psk.size()) == 0) {
+		return ndk::ScopedAStatus::ok();
+	}
+	// Flag to indicate if raw psk is calculated or not using
+	// |wpa_config_update_psk|. Deferred if ssid not already set.
+	wpa_ssid->psk_set = 0;
+	if (setStringKeyFieldAndResetState(
+		psk.c_str(), &(wpa_ssid->passphrase), "psk passphrase")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	if (wpa_ssid->ssid_len) {
+		wpa_config_update_psk(wpa_ssid);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setPskInternal(const std::vector<uint8_t> &psk)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	WPA_ASSERT(psk.size() == sizeof(wpa_ssid->psk));
+	str_clear_free(wpa_ssid->passphrase);
+	wpa_ssid->passphrase = nullptr;
+	os_memcpy(wpa_ssid->psk, psk.data(), sizeof(wpa_ssid->psk));
+	wpa_ssid->psk_set = 1;
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setWepKeyInternal(
+	uint32_t key_idx, const std::vector<uint8_t> &wep_key)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (key_idx >=
+		static_cast<uint32_t>(
+		ISupplicantStaNetwork::WEP_KEYS_MAX_NUM)) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	if (wep_key.size() !=
+		static_cast<uint32_t>(ISupplicantStaNetwork::
+					  WEP40_KEY_LEN_IN_BYTES) &&
+		wep_key.size() !=
+		static_cast<uint32_t>(ISupplicantStaNetwork::
+					  WEP104_KEY_LEN_IN_BYTES)) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	os_memcpy(wpa_ssid->wep_key[key_idx], wep_key.data(), wep_key.size());
+	wpa_ssid->wep_key_len[key_idx] = wep_key.size();
+	std::string msg_dump_title("wep_key" + std::to_string(key_idx));
+	wpa_hexdump_key(
+		MSG_MSGDUMP, msg_dump_title.c_str(), wpa_ssid->wep_key[key_idx],
+		wpa_ssid->wep_key_len[key_idx]);
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setWepTxKeyIdxInternal(uint32_t key_idx)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (key_idx >=
+		static_cast<uint32_t>(
+		ISupplicantStaNetwork::WEP_KEYS_MAX_NUM)) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	wpa_ssid->wep_tx_keyidx = key_idx;
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setRequirePmfInternal(bool enable)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (enable) {
+		wpa_ssid->ieee80211w = MGMT_FRAME_PROTECTION_REQUIRED;
+	}
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapMethodInternal(
+	EapMethod method)
+{
+	uint32_t eap_method_idx = static_cast<
+		std::underlying_type<EapMethod>::type>(
+		method);
+	if (eap_method_idx >= kEapMethodMax) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	int retrieved_vendor, retrieved_method;
+	const char *method_str = kEapMethodStrings[eap_method_idx];
+	// This string lookup is needed to check if the device supports the
+	// corresponding EAP type.
+	retrieved_method = eap_peer_get_type(method_str, &retrieved_vendor);
+	if (retrieved_vendor == EAP_VENDOR_IETF &&
+		retrieved_method == EAP_TYPE_NONE) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	if (wpa_ssid->eap.eap_methods) {
+		os_free(wpa_ssid->eap.eap_methods);
+	}
+	// wpa_supplicant can support setting multiple eap methods for each
+	// network. But, this is not really used by Android. So, just adding
+	// support for setting one EAP method for each network. The additional
+	// |eap_method_type| member in the array is used to indicate the end
+	// of list.
+	wpa_ssid->eap.eap_methods =
+		(eap_method_type *)os_malloc(sizeof(eap_method_type) * 2);
+	if (!wpa_ssid->eap.eap_methods) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	wpa_ssid->eap.eap_methods[0].vendor = retrieved_vendor;
+	wpa_ssid->eap.eap_methods[0].method = retrieved_method;
+	wpa_ssid->eap.eap_methods[1].vendor = EAP_VENDOR_IETF;
+	wpa_ssid->eap.eap_methods[1].method = EAP_TYPE_NONE;
+
+	wpa_ssid->leap = 0;
+	wpa_ssid->non_leap = 0;
+	if (retrieved_vendor == EAP_VENDOR_IETF &&
+		retrieved_method == EAP_TYPE_LEAP) {
+		wpa_ssid->leap++;
+	} else {
+		wpa_ssid->non_leap++;
+	}
+	wpa_hexdump(
+		MSG_MSGDUMP, "eap methods", (u8 *)wpa_ssid->eap.eap_methods,
+		sizeof(eap_method_type) * 2);
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapPhase2MethodInternal(
+	EapPhase2Method method)
+{
+	uint32_t eap_phase2_method_idx = static_cast<
+		std::underlying_type<EapPhase2Method>::type>(
+		method);
+	if (eap_phase2_method_idx >= kEapPhase2MethodMax) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	// EAP method needs to be set for us to construct the eap
+	// phase 2 method string.
+	ndk::ScopedAStatus status;
+	EapMethod eap_method;
+	std::tie(eap_method, status) = getEapMethodInternal();
+	if (!status.isOk()) {
+		return createStatusWithMsg(SupplicantStatusCode::FAILURE_UNKNOWN,
+			"EAP method not set");
+	}
+	std::string eap_phase2_str;
+	if (method == EapPhase2Method::NONE) {
+		eap_phase2_str = "";
+	} else if (
+		eap_method == EapMethod::TTLS &&
+		method == EapPhase2Method::GTC) {
+		eap_phase2_str = kEapPhase2AuthEapPrefix;
+	} else {
+		eap_phase2_str = kEapPhase2AuthPrefix;
+	}
+	eap_phase2_str += kEapPhase2MethodStrings[eap_phase2_method_idx];
+	if (setStringFieldAndResetState(
+		eap_phase2_str.c_str(), &(wpa_ssid->eap.phase2),
+		"eap phase2")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapIdentityInternal(
+	const std::vector<uint8_t> &identity)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (setByteArrayFieldAndResetState(
+		identity.data(), identity.size(), &(wpa_ssid->eap.identity),
+		&(wpa_ssid->eap.identity_len), "eap identity")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	// plain IMSI identity
+	if (setByteArrayFieldAndResetState(
+		identity.data(), identity.size(),
+		&(wpa_ssid->eap.imsi_identity),
+		&(wpa_ssid->eap.imsi_identity_len), "eap imsi identity")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapEncryptedImsiIdentityInternal(
+	const std::vector<uint8_t> &identity)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	// encrypted IMSI identity
+	if (setByteArrayFieldAndResetState(
+		identity.data(), identity.size(), &(wpa_ssid->eap.identity),
+		&(wpa_ssid->eap.identity_len), "eap encrypted imsi identity")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapAnonymousIdentityInternal(
+	const std::vector<uint8_t> &identity)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	// If current supplicant pseudonym is the prefix of new pseudonym,
+	// the credential is not changed, just update the decoration.
+	// As a result, no need to reset the state.
+	// The decorated identity will have a postfix like
+	// @mncXXX.mccYYY.3gppnetwork.org, so the length will be always
+	// greater than the current one.
+	bool resetState = wpa_ssid->eap.anonymous_identity == NULL
+		|| wpa_ssid->eap.anonymous_identity_len == 0
+		|| identity.size() == 0
+		|| wpa_ssid->eap.anonymous_identity_len >= identity.size()
+		|| os_strncmp((char *) identity.data(),
+			(char *) wpa_ssid->eap.anonymous_identity,
+			wpa_ssid->eap.anonymous_identity_len) != 0;
+	if (setByteArrayField(
+		identity.data(), identity.size(),
+		&(wpa_ssid->eap.anonymous_identity),
+		&(wpa_ssid->eap.anonymous_identity_len),
+		"eap anonymous_identity", resetState)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapPasswordInternal(
+	const std::vector<uint8_t> &password)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (setByteArrayKeyFieldAndResetState(
+		password.data(), password.size(), &(wpa_ssid->eap.password),
+		&(wpa_ssid->eap.password_len), "eap password")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	wpa_ssid->eap.flags &= ~EAP_CONFIG_FLAGS_PASSWORD_NTHASH;
+	wpa_ssid->eap.flags &= ~EAP_CONFIG_FLAGS_EXT_PASSWORD;
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapCACertInternal(const std::string &path)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (setStringFieldAndResetState(
+		path.c_str(), &(wpa_ssid->eap.cert.ca_cert), "eap ca_cert")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapCAPathInternal(const std::string &path)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (setStringFieldAndResetState(
+		path.c_str(), &(wpa_ssid->eap.cert.ca_path), "eap ca_path")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapClientCertInternal(const std::string &path)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (setStringFieldAndResetState(
+		path.c_str(), &(wpa_ssid->eap.cert.client_cert),
+		"eap client_cert")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapPrivateKeyIdInternal(const std::string &id)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (setStringFieldAndResetState(
+		id.c_str(), &(wpa_ssid->eap.cert.key_id), "eap key_id")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapSubjectMatchInternal(
+	const std::string &match)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (setStringFieldAndResetState(
+		match.c_str(), &(wpa_ssid->eap.cert.subject_match),
+		"eap subject_match")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapAltSubjectMatchInternal(
+	const std::string &match)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (setStringFieldAndResetState(
+		match.c_str(), &(wpa_ssid->eap.cert.altsubject_match),
+		"eap altsubject_match")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapEngineInternal(bool enable)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	wpa_ssid->eap.cert.engine = enable ? 1 : 0;
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapEngineIDInternal(const std::string &id)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (setStringFieldAndResetState(
+		id.c_str(), &(wpa_ssid->eap.cert.engine_id), "eap engine_id")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapDomainSuffixMatchInternal(
+	const std::string &match)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (setStringFieldAndResetState(
+		match.c_str(), &(wpa_ssid->eap.cert.domain_suffix_match),
+		"eap domain_suffix_match")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setProactiveKeyCachingInternal(bool enable)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	wpa_ssid->proactive_key_caching = enable ? 1 : 0;
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setIdStrInternal(const std::string &id_str)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (setStringFieldAndResetState(
+		id_str.c_str(), &(wpa_ssid->id_str), "id_str")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setUpdateIdentifierInternal(uint32_t id)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	wpa_ssid->update_identifier = id;
+	wpa_printf(
+		MSG_MSGDUMP, "update_identifier: %d", wpa_ssid->update_identifier);
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setWapiCertSuiteInternal(const std::string &suite)
+{
+#ifdef CONFIG_WAPI_INTERFACE
+	// Dummy implementation
+	dummyWapiCertSuite = suite;
+	return ndk::ScopedAStatus::ok();
+#else
+	return createStatusWithMsg(SupplicantStatusCode::FAILURE_UNKNOWN, "Not implemented");
+#endif
+}
+
+ndk::ScopedAStatus StaNetwork::setWapiPskInternal(const std::vector<uint8_t> &psk)
+{
+#ifdef CONFIG_WAPI_INTERFACE
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	str_clear_free(wpa_ssid->passphrase);
+	wpa_ssid->passphrase = nullptr;
+
+	// Dummy implementation
+	dummyWapiPsk = psk;
+
+	wpa_ssid->psk_set = 1;
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+#else
+	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+#endif
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> StaNetwork::getSsidInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	std::vector<uint8_t> ssid(
+		wpa_ssid->ssid,
+		wpa_ssid->ssid + wpa_ssid->ssid_len);
+	return {std::move(ssid), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+StaNetwork::getBssidInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	std::vector<uint8_t> bssid(kZeroBssid, kZeroBssid + ETH_ALEN);
+	if (wpa_ssid->bssid_set) {
+		bssid.assign(wpa_ssid->bssid, wpa_ssid->bssid + ETH_ALEN);
+	}
+	return {std::move(bssid), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<bool, ndk::ScopedAStatus> StaNetwork::getScanSsidInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	return {(wpa_ssid->scan_ssid == 1), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<AuthAlgMask, ndk::ScopedAStatus>
+StaNetwork::getAuthAlgInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	uint32_t auth_alg_mask = wpa_ssid->auth_alg & kAllowedAuthAlgMask;
+	return {static_cast<AuthAlgMask>(auth_alg_mask), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus> StaNetwork::getPskPassphraseInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+#ifdef CONFIG_WAPI_INTERFACE
+	if (wpa_ssid->key_mgmt & WPA_KEY_MGMT_WAPI_PSK) {
+		if (wpa_ssid->psk_set) {
+			std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> ret = getWapiPskInternal();
+			std::string psk;
+			char buf[3] = {0};
+			for (int i = 0; i < ret.second.size(); i++) {
+				snprintf(buf, sizeof(buf), "%02x", ret.second[i]);
+				psk.append(buf);
+			}
+			return {psk, ndk::ScopedAStatus::ok()};
+		} else {
+			if (!wpa_ssid->passphrase) {
+				return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+			}
+			std::string passphrase;
+			passphrase.append("\"");
+			passphrase.append(wpa_ssid->passphrase);
+			passphrase.append("\"");
+			return {passphrase, ndk::ScopedAStatus::ok()};
+		}
+	}
+#endif
+	if (!wpa_ssid->passphrase) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {wpa_ssid->passphrase, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+StaNetwork::getPskInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	WPA_ASSERT(psk.size() == sizeof(wpa_ssid->psk));
+	if (!wpa_ssid->psk_set) {
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	std::vector<uint8_t> psk(wpa_ssid->psk, wpa_ssid->psk + 32);
+	return {psk, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus> StaNetwork::getSaePasswordInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->sae_password) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::charBufToString(wpa_ssid->sae_password),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus> StaNetwork::getSaePasswordIdInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->sae_password_id) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::charBufToString(wpa_ssid->sae_password_id),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> StaNetwork::getWepKeyInternal(
+	uint32_t key_idx)
+{
+	std::vector<uint8_t> wep_key;
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (key_idx >=
+		static_cast<uint32_t>(
+		ISupplicantStaNetwork::WEP_KEYS_MAX_NUM)) {
+		return {wep_key,
+			createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID)};
+	}
+	wep_key.assign(
+		wpa_ssid->wep_key[key_idx],
+		wpa_ssid->wep_key[key_idx] + wpa_ssid->wep_key_len[key_idx]);
+	return {std::move(wep_key), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<uint32_t, ndk::ScopedAStatus> StaNetwork::getWepTxKeyIdxInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	return {wpa_ssid->wep_tx_keyidx, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<bool, ndk::ScopedAStatus> StaNetwork::getRequirePmfInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	return {(wpa_ssid->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<EapMethod, ndk::ScopedAStatus>
+StaNetwork::getEapMethodInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.eap_methods) {
+		return {static_cast<EapMethod>(0),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	// wpa_supplicant can support setting multiple eap methods for each
+	// network. But, this is not really used by Android. So, just reading
+	// the first EAP method for each network.
+	const std::string eap_method_str = eap_get_name(
+		wpa_ssid->eap.eap_methods[0].vendor,
+		static_cast<enum eap_type>(wpa_ssid->eap.eap_methods[0].method));
+	size_t eap_method_idx =
+		std::find(
+		std::begin(kEapMethodStrings), std::end(kEapMethodStrings),
+		eap_method_str) -
+		std::begin(kEapMethodStrings);
+	if (eap_method_idx >= kEapMethodMax) {
+		return {static_cast<EapMethod>(0),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {static_cast<EapMethod>(eap_method_idx), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<EapPhase2Method, ndk::ScopedAStatus>
+StaNetwork::getEapPhase2MethodInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.phase2) {
+		return {static_cast<EapPhase2Method>(0),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	const std::string eap_phase2_method_str_with_prefix =
+		wpa_ssid->eap.phase2;
+	std::string eap_phase2_method_str;
+	// Strip out the phase 2 method prefix before doing a reverse lookup
+	// of phase 2 string to the Eap Phase 2 type.
+	if (eap_phase2_method_str_with_prefix.find(kEapPhase2AuthPrefix) == 0) {
+		eap_phase2_method_str =
+			eap_phase2_method_str_with_prefix.substr(
+			strlen(kEapPhase2AuthPrefix),
+			eap_phase2_method_str_with_prefix.size());
+	} else if (
+		eap_phase2_method_str_with_prefix.find(kEapPhase2AuthEapPrefix) ==
+		0) {
+		eap_phase2_method_str =
+			eap_phase2_method_str_with_prefix.substr(
+			strlen(kEapPhase2AuthEapPrefix),
+			eap_phase2_method_str_with_prefix.size());
+	}
+	size_t eap_phase2_method_idx =
+		std::find(
+		std::begin(kEapPhase2MethodStrings),
+		std::end(kEapPhase2MethodStrings), eap_phase2_method_str) -
+		std::begin(kEapPhase2MethodStrings);
+	if (eap_phase2_method_idx >= kEapPhase2MethodMax) {
+		return {static_cast<EapPhase2Method>(0),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {static_cast<EapPhase2Method>(eap_phase2_method_idx),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+StaNetwork::getEapIdentityInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.identity) {
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {std::vector<uint8_t>(
+			wpa_ssid->eap.identity,
+			wpa_ssid->eap.identity + wpa_ssid->eap.identity_len),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+StaNetwork::getEapAnonymousIdentityInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.anonymous_identity) {
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {std::vector<uint8_t>(
+			wpa_ssid->eap.anonymous_identity,
+			wpa_ssid->eap.anonymous_identity +
+			wpa_ssid->eap.anonymous_identity_len),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+StaNetwork::getEapPasswordInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.password) {
+		return {std::vector<uint8_t>(), createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {std::vector<uint8_t>(
+			wpa_ssid->eap.password,
+			wpa_ssid->eap.password + wpa_ssid->eap.password_len),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus> StaNetwork::getEapCACertInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.cert.ca_cert) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::charBufToString(wpa_ssid->eap.cert.ca_cert),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus> StaNetwork::getEapCAPathInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.cert.ca_path) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::charBufToString(wpa_ssid->eap.cert.ca_path),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus> StaNetwork::getEapClientCertInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.cert.client_cert) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::charBufToString(wpa_ssid->eap.cert.client_cert),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus>
+StaNetwork::getEapPrivateKeyIdInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.cert.key_id) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::charBufToString(reinterpret_cast<char *>(wpa_ssid->eap.cert.key_id)),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus>
+StaNetwork::getEapSubjectMatchInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.cert.subject_match) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::charBufToString(wpa_ssid->eap.cert.subject_match),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus>
+StaNetwork::getEapAltSubjectMatchInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.cert.altsubject_match) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::charBufToString(wpa_ssid->eap.cert.altsubject_match),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<bool, ndk::ScopedAStatus> StaNetwork::getEapEngineInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	return {wpa_ssid->eap.cert.engine == 1, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus> StaNetwork::getEapEngineIdInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.cert.engine_id) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::charBufToString(wpa_ssid->eap.cert.engine_id),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus>
+StaNetwork::getEapDomainSuffixMatchInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.cert.domain_suffix_match) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::charBufToString(wpa_ssid->eap.cert.domain_suffix_match),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus> StaNetwork::getIdStrInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->id_str) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::charBufToString(wpa_ssid->id_str),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<bool, ndk::ScopedAStatus> StaNetwork::getEdmgInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	return {(wpa_ssid->enable_edmg == 1), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+StaNetwork::getWpsNfcConfigurationTokenInternal()
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	auto token_buf = misc_utils::createWpaBufUniquePtr(
+		wpas_wps_network_config_token(wpa_s, 0, wpa_ssid));
+	if (!token_buf) {
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::convertWpaBufToVector(token_buf.get()),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus> StaNetwork::getWapiCertSuiteInternal()
+{
+#ifdef CONFIG_WAPI_INTERFACE
+	// Dummy implementation
+	return {dummyWapiCertSuite, ndk::ScopedAStatus::ok()};
+#else
+	return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+#endif
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> StaNetwork::getWapiPskInternal()
+{
+#ifdef CONFIG_WAPI_INTERFACE
+	// Dummy implementation
+	return {dummyWapiPsk, ndk::ScopedAStatus::ok()};
+#else
+	return {std::vector<uint8_t>(),
+		createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+#endif
+}
+
+ndk::ScopedAStatus StaNetwork::enableInternal(bool no_connect)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (wpa_ssid->disabled == 2) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (no_connect) {
+		wpa_ssid->disabled = 0;
+	} else {
+		wpa_s->scan_min_time.sec = 0;
+		wpa_s->scan_min_time.usec = 0;
+		wpa_supplicant_enable_network(wpa_s, wpa_ssid);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::disableInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (wpa_ssid->disabled == 2) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	wpa_supplicant_disable_network(wpa_s, wpa_ssid);
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::selectInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (wpa_ssid->disabled == 2) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	wpa_s->scan_min_time.sec = 0;
+	wpa_s->scan_min_time.usec = 0;
+	wpa_supplicant_select_network(wpa_s, wpa_ssid);
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::sendNetworkEapSimGsmAuthResponseInternal(
+	const std::vector<NetworkResponseEapSimGsmAuthParams>
+	&vec_params)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	// Convert the incoming parameters to a string to pass to
+	// wpa_supplicant.
+	std::string ctrl_rsp_param = std::string(kNetworkEapSimGsmAuthResponse);
+	for (const auto &params : vec_params) {
+		uint32_t kc_hex_len = params.kc.size() * 2 + 1;
+		std::vector<char> kc_hex(kc_hex_len);
+		uint32_t sres_hex_len = params.sres.size() * 2 + 1;
+		std::vector<char> sres_hex(sres_hex_len);
+		wpa_snprintf_hex(
+			kc_hex.data(), kc_hex.size(), params.kc.data(),
+			params.kc.size());
+		wpa_snprintf_hex(
+			sres_hex.data(), sres_hex.size(), params.sres.data(),
+			params.sres.size());
+		ctrl_rsp_param += ":" + std::string(kc_hex.data()) + ":" +
+				  std::string(sres_hex.data());
+	}
+	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_SIM;
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (wpa_supplicant_ctrl_rsp_handle(
+		wpa_s, wpa_ssid, rtype, ctrl_rsp_param.c_str(),
+		ctrl_rsp_param.size())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	eapol_sm_notify_ctrl_response(wpa_s->eapol);
+	wpa_hexdump_ascii_key(
+		MSG_DEBUG, "network sim gsm auth response param",
+		(const u8 *)ctrl_rsp_param.c_str(), ctrl_rsp_param.size());
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::sendNetworkEapSimGsmAuthFailureInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_SIM;
+	if (wpa_supplicant_ctrl_rsp_handle(
+		wpa_s, wpa_ssid, rtype, kNetworkEapSimGsmAuthFailure,
+		strlen(kNetworkEapSimGsmAuthFailure))) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	eapol_sm_notify_ctrl_response(wpa_s->eapol);
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::sendNetworkEapSimUmtsAuthResponseInternal(
+	const NetworkResponseEapSimUmtsAuthParams &params)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	// Convert the incoming parameters to a string to pass to
+	// wpa_supplicant.
+	uint32_t ik_hex_len = params.ik.size() * 2 + 1;
+	std::vector<char> ik_hex(ik_hex_len);
+	uint32_t ck_hex_len = params.ck.size() * 2 + 1;
+	std::vector<char> ck_hex(ck_hex_len);
+	uint32_t res_hex_len = params.res.size() * 2 + 1;
+	std::vector<char> res_hex(res_hex_len);
+	wpa_snprintf_hex(
+		ik_hex.data(), ik_hex.size(), params.ik.data(), params.ik.size());
+	wpa_snprintf_hex(
+		ck_hex.data(), ck_hex.size(), params.ck.data(), params.ck.size());
+	wpa_snprintf_hex(
+		res_hex.data(), res_hex.size(), params.res.data(),
+		params.res.size());
+	std::string ctrl_rsp_param =
+		std::string(kNetworkEapSimUmtsAuthResponse) + ":" +
+		std::string(ik_hex.data()) + ":" + std::string(ck_hex.data()) +
+		":" + std::string(res_hex.data());
+	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_SIM;
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (wpa_supplicant_ctrl_rsp_handle(
+		wpa_s, wpa_ssid, rtype, ctrl_rsp_param.c_str(),
+		ctrl_rsp_param.size())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	eapol_sm_notify_ctrl_response(wpa_s->eapol);
+	wpa_hexdump_ascii_key(
+		MSG_DEBUG, "network sim umts auth response param",
+		(const u8 *)ctrl_rsp_param.c_str(), ctrl_rsp_param.size());
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::sendNetworkEapSimUmtsAutsResponseInternal(
+	const std::vector<uint8_t> &auts)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	uint32_t auts_hex_len = auts.size() * 2 + 1;
+	std::vector<char> auts_hex(auts_hex_len);
+	wpa_snprintf_hex(
+		auts_hex.data(), auts_hex.size(), auts.data(), auts.size());
+	std::string ctrl_rsp_param =
+		std::string(kNetworkEapSimUmtsAutsResponse) + ":" +
+		std::string(auts_hex.data());
+	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_SIM;
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (wpa_supplicant_ctrl_rsp_handle(
+		wpa_s, wpa_ssid, rtype, ctrl_rsp_param.c_str(),
+		ctrl_rsp_param.size())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	eapol_sm_notify_ctrl_response(wpa_s->eapol);
+	wpa_hexdump_ascii_key(
+		MSG_DEBUG, "network sim umts auts response param",
+		(const u8 *)ctrl_rsp_param.c_str(), ctrl_rsp_param.size());
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::sendNetworkEapSimUmtsAuthFailureInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_SIM;
+	if (wpa_supplicant_ctrl_rsp_handle(
+		wpa_s, wpa_ssid, rtype, kNetworkEapSimUmtsAuthFailure,
+		strlen(kNetworkEapSimUmtsAuthFailure))) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	eapol_sm_notify_ctrl_response(wpa_s->eapol);
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::sendNetworkEapIdentityResponseInternal(
+	const std::vector<uint8_t> &identity,
+	const std::vector<uint8_t> &encrypted_imsi_identity)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	std::string ctrl_rsp_param(identity.begin(), identity.end());
+	// If encrypted identity is included, format is:
+	// plain identity + ":" + encrypted_identity
+	if (encrypted_imsi_identity.size() != 0) {
+		ctrl_rsp_param += ":" + std::string(
+			encrypted_imsi_identity.begin(), encrypted_imsi_identity.end());
+	}
+	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_EAP_IDENTITY;
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (wpa_supplicant_ctrl_rsp_handle(
+		wpa_s, wpa_ssid, rtype, ctrl_rsp_param.c_str(),
+		ctrl_rsp_param.size())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	eapol_sm_notify_ctrl_response(wpa_s->eapol);
+	wpa_hexdump_ascii_key(
+		MSG_DEBUG, "network identity response param",
+		(const u8 *)ctrl_rsp_param.c_str(), ctrl_rsp_param.size());
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::enableTlsSuiteBEapPhase1ParamInternal(bool enable)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	int val = enable == true ? 1 : 0;
+	std::string suiteb_phase1("tls_suiteb=" + std::to_string(val));
+
+	if (setStringKeyFieldAndResetState(
+		suiteb_phase1.c_str(), &(wpa_ssid->eap.phase1), "phase1")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::enableSuiteBEapOpenSslCiphersInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	const char openssl_suiteb_cipher[] = "SUITEB192";
+
+	if (setStringKeyFieldAndResetState(
+		openssl_suiteb_cipher, &(wpa_ssid->eap.openssl_ciphers),
+		"openssl_ciphers")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setSaePasswordInternal(
+	const std::string &sae_password)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (sae_password.length() < 1) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	if (wpa_ssid->sae_password &&
+		os_strlen(wpa_ssid->sae_password) == sae_password.length() &&
+		os_memcmp(
+		wpa_ssid->sae_password, sae_password.c_str(),
+		sae_password.length()) == 0) {
+		return ndk::ScopedAStatus::ok();
+	}
+	wpa_ssid->psk_set = 1;
+	if (setStringKeyFieldAndResetState(
+		sae_password.c_str(), &(wpa_ssid->sae_password),
+		"sae password")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setSaePasswordIdInternal(
+	const std::string &sae_password_id)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (sae_password_id.length() < 1) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	if (wpa_ssid->sae_password_id &&
+		os_strlen(wpa_ssid->sae_password_id) == sae_password_id.length() &&
+		os_memcmp(
+		wpa_ssid->sae_password_id, sae_password_id.c_str(),
+		sae_password_id.length()) == 0) {
+		return ndk::ScopedAStatus::ok();
+	}
+	wpa_ssid->psk_set = 1;
+	if (setStringKeyFieldAndResetState(
+		sae_password_id.c_str(), &(wpa_ssid->sae_password_id),
+		"sae password id")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setGroupMgmtCipherInternal(
+		GroupMgmtCipherMask mask)
+{
+	uint32_t group_mgmt_cipher_mask = static_cast<uint32_t>(mask);
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (group_mgmt_cipher_mask & ~kAllowedGroupMgmtCipherMask) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	wpa_ssid->group_mgmt_cipher = group_mgmt_cipher_mask;
+	wpa_printf(MSG_MSGDUMP, "group_mgmt_cipher: 0x%x",
+			wpa_ssid->group_mgmt_cipher);
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<GroupMgmtCipherMask, ndk::ScopedAStatus>
+StaNetwork::getGroupMgmtCipherInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	uint32_t group_mgmt_cipher_mask =
+			wpa_ssid->group_mgmt_cipher & kAllowedGroupMgmtCipherMask;
+	return {static_cast<GroupMgmtCipherMask>(group_mgmt_cipher_mask),
+		ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaNetwork::setOcspInternal(OcspType ocspType) {
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (ocspType < OcspType::NONE || ocspType > OcspType::REQUIRE_ALL_CERTS_STATUS) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	wpa_ssid->eap.cert.ocsp = (int) ocspType;
+	wpa_printf(
+		MSG_MSGDUMP, "ocsp: %d", wpa_ssid->eap.cert.ocsp);
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<OcspType, ndk::ScopedAStatus> StaNetwork::getOcspInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	return {static_cast<OcspType>(wpa_ssid->eap.cert.ocsp),
+		ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaNetwork::setPmkCacheInternal(const std::vector<uint8_t>& serializedEntry) {
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	struct rsn_pmksa_cache_entry *new_entry = NULL;
+
+	new_entry = (struct rsn_pmksa_cache_entry *) os_zalloc(sizeof(*new_entry));
+	if (!new_entry) {
+		return createStatusWithMsg(SupplicantStatusCode::FAILURE_UNKNOWN,
+			"Allocating memory failed");
+	}
+
+	std::stringstream ss(
+		std::stringstream::in | std::stringstream::out | std::stringstream::binary);
+	ss.write((char *) serializedEntry.data(), std::streamsize(serializedEntry.size()));
+	misc_utils::deserializePmkCacheEntry(ss, new_entry);
+	new_entry->network_ctx = wpa_ssid;
+
+	// If there is an entry has a later expiration, ignore this one.
+	struct rsn_pmksa_cache_entry *existing_entry = wpa_sm_pmksa_cache_get(
+		wpa_s->wpa, new_entry->aa, NULL, NULL, new_entry->akmp);
+	if (NULL != existing_entry &&
+		existing_entry->expiration >= new_entry->expiration) {
+		return ndk::ScopedAStatus::ok();
+	}
+
+	wpa_sm_pmksa_cache_add_entry(wpa_s->wpa, new_entry);
+
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setKeyMgmtInternal(
+	KeyMgmtMask mask)
+{
+	uint32_t key_mgmt_mask = static_cast<uint32_t>(mask);
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (key_mgmt_mask & ~kAllowedKeyMgmtMask) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	setFastTransitionKeyMgmt(key_mgmt_mask);
+
+	if (key_mgmt_mask & WPA_KEY_MGMT_OWE) {
+		// Do not allow to connect to Open network when OWE is selected
+		wpa_ssid->owe_only = 1;
+	}
+	wpa_ssid->key_mgmt = key_mgmt_mask;
+	wpa_printf(MSG_MSGDUMP, "key_mgmt: 0x%x", wpa_ssid->key_mgmt);
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<KeyMgmtMask, ndk::ScopedAStatus>
+StaNetwork::getKeyMgmtInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	uint32_t key_mgmt_mask = wpa_ssid->key_mgmt & kAllowedKeyMgmtMask;
+
+	resetFastTransitionKeyMgmt(key_mgmt_mask);
+	return {static_cast<KeyMgmtMask>(key_mgmt_mask),
+		ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaNetwork::setProtoInternal(
+	ProtoMask mask)
+{
+	uint32_t proto_mask = static_cast<uint32_t>(mask);
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (proto_mask & ~kAllowedProtoMask) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	wpa_ssid->proto = proto_mask;
+	wpa_printf(MSG_MSGDUMP, "proto: 0x%x", wpa_ssid->proto);
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<ProtoMask, ndk::ScopedAStatus>
+StaNetwork::getProtoInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	uint32_t proto_mask = wpa_ssid->proto & kAllowedProtoMask;
+	return {static_cast<ProtoMask>(proto_mask), ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaNetwork::setGroupCipherInternal(
+	GroupCipherMask mask)
+{
+	uint32_t group_cipher_mask = static_cast<uint32_t>(mask);
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (group_cipher_mask & ~kAllowedGroupCipherMask) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	wpa_ssid->group_cipher = group_cipher_mask;
+	wpa_printf(MSG_MSGDUMP, "group_cipher: 0x%x", wpa_ssid->group_cipher);
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<GroupCipherMask, ndk::ScopedAStatus>
+StaNetwork::getGroupCipherInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	uint32_t group_cipher_mask = wpa_ssid->group_cipher & kAllowedGroupCipherMask;
+	return {static_cast<GroupCipherMask>(group_cipher_mask),
+		ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaNetwork::setPairwiseCipherInternal(
+	PairwiseCipherMask mask)
+{
+	uint32_t pairwise_cipher_mask = static_cast<uint32_t>(mask);
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (pairwise_cipher_mask & ~kAllowedPairwisewCipherMask) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	wpa_ssid->pairwise_cipher = pairwise_cipher_mask;
+	wpa_printf(
+		MSG_MSGDUMP, "pairwise_cipher: 0x%x", wpa_ssid->pairwise_cipher);
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<PairwiseCipherMask, ndk::ScopedAStatus>
+StaNetwork::getPairwiseCipherInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	uint32_t pairwise_cipher_mask = wpa_ssid->pairwise_cipher & kAllowedPairwisewCipherMask;
+	return {static_cast<PairwiseCipherMask>(pairwise_cipher_mask),
+		ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaNetwork::setRoamingConsortiumSelectionInternal(
+	const std::vector<uint8_t> &selectedRcoi)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (wpa_ssid == NULL) {
+		return createStatus(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (setByteArrayFieldAndResetState(
+		selectedRcoi.data(), selectedRcoi.size(),
+		&(wpa_ssid->roaming_consortium_selection),
+		&(wpa_ssid->roaming_consortium_selection_len),
+		"roaming_consortium_selection")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+/**
+ * Retrieve the underlying |wpa_ssid| struct pointer for
+ * this network.
+ * If the underlying network is removed or the interface
+ * this network belong to
+ * is removed, all RPC method calls on this object will
+ * return failure.
+ */
+struct wpa_ssid *StaNetwork::retrieveNetworkPtr()
+{
+	wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (!wpa_s)
+		return nullptr;
+	return wpa_config_get_network(wpa_s->conf, network_id_);
+}
+
+/**
+ * Retrieve the underlying |wpa_supplicant| struct
+ * pointer for
+ * this network.
+ */
+struct wpa_supplicant *StaNetwork::retrieveIfacePtr()
+{
+	return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str());
+}
+
+/**
+ * Check if the provided psk passhrase is valid or not.
+ *
+ * Returns 0 if valid, 1 otherwise.
+ */
+int StaNetwork::isPskPassphraseValid(const std::string &psk)
+{
+	if (psk.size() <
+		static_cast<uint32_t>(ISupplicantStaNetwork::
+					  PSK_PASSPHRASE_MIN_LEN_IN_BYTES) ||
+		psk.size() >
+		static_cast<uint32_t>(ISupplicantStaNetwork::
+					  PSK_PASSPHRASE_MAX_LEN_IN_BYTES)) {
+		return 1;
+	}
+	if (has_ctrl_char((u8 *)psk.c_str(), psk.size())) {
+		return 1;
+	}
+	return 0;
+}
+
+/**
+ * Reset internal wpa_supplicant state machine state
+ * after params update (except
+ * bssid).
+ */
+void StaNetwork::resetInternalStateAfterParamsUpdate()
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+
+	wpa_sm_pmksa_cache_flush(wpa_s->wpa, wpa_ssid);
+
+	if (wpa_s->current_ssid == wpa_ssid || wpa_s->current_ssid == NULL) {
+		/*
+		 * Invalidate the EAP session cache if
+		 * anything in the
+		 * current or previously used
+		 * configuration changes.
+		 */
+		eapol_sm_invalidate_cached_session(wpa_s->eapol);
+	}
+}
+
+/**
+ * Helper function to set value in a string field in |wpa_ssid| structue
+ * instance for this network.
+ * This function frees any existing data in these fields.
+ */
+int StaNetwork::setStringFieldAndResetState(
+	const char *value, uint8_t **to_update_field, const char *hexdump_prefix)
+{
+	return setStringFieldAndResetState(
+		value, (char **)to_update_field, hexdump_prefix);
+}
+
+/**
+ * Helper function to set value in a string field in |wpa_ssid| structue
+ * instance for this network.
+ * This function frees any existing data in these fields.
+ */
+int StaNetwork::setStringFieldAndResetState(
+	const char *value, char **to_update_field, const char *hexdump_prefix)
+{
+	int value_len = strlen(value);
+	if (*to_update_field) {
+		os_free(*to_update_field);
+	}
+	*to_update_field = dup_binstr(value, value_len);
+	if (!(*to_update_field)) {
+		return 1;
+	}
+	wpa_hexdump_ascii(
+		MSG_MSGDUMP, hexdump_prefix, *to_update_field, value_len);
+	resetInternalStateAfterParamsUpdate();
+	return 0;
+}
+
+/**
+ * Helper function to set value in a string key field in |wpa_ssid| structue
+ * instance for this network.
+ * This function frees any existing data in these fields.
+ */
+int StaNetwork::setStringKeyFieldAndResetState(
+	const char *value, char **to_update_field, const char *hexdump_prefix)
+{
+	int value_len = strlen(value);
+	if (*to_update_field) {
+		str_clear_free(*to_update_field);
+	}
+	*to_update_field = dup_binstr(value, value_len);
+	if (!(*to_update_field)) {
+		return 1;
+	}
+	wpa_hexdump_ascii_key(
+		MSG_MSGDUMP, hexdump_prefix, *to_update_field, value_len);
+	resetInternalStateAfterParamsUpdate();
+	return 0;
+}
+
+/**
+ * Helper function to set value in a string field with a corresponding length
+ * field in |wpa_ssid| structure instance for this network.
+ * This function frees any existing data in these fields.
+ */
+int StaNetwork::setByteArrayField(
+	const uint8_t *value, const size_t value_len, uint8_t **to_update_field,
+	size_t *to_update_field_len, const char *hexdump_prefix, bool resetState)
+{
+	if (*to_update_field) {
+		os_free(*to_update_field);
+	}
+	*to_update_field = (uint8_t *)os_malloc(value_len);
+	if (!(*to_update_field)) {
+		return 1;
+	}
+	os_memcpy(*to_update_field, value, value_len);
+	*to_update_field_len = value_len;
+
+	wpa_hexdump_ascii(
+		MSG_MSGDUMP, hexdump_prefix, *to_update_field,
+		*to_update_field_len);
+
+	if (resetState) {
+		resetInternalStateAfterParamsUpdate();
+	}
+	return 0;
+}
+
+/**
+ * Helper function to set value in a string field with a corresponding length
+ * field in |wpa_ssid| structure instance for this network.
+ * This function frees any existing data in these fields.
+ */
+int StaNetwork::setByteArrayFieldAndResetState(
+	const uint8_t *value, const size_t value_len, uint8_t **to_update_field,
+	size_t *to_update_field_len, const char *hexdump_prefix)
+{
+	return setByteArrayField(value, value_len, to_update_field,
+		to_update_field_len, hexdump_prefix, true);
+}
+
+/**
+ * Helper function to set value in a string key field with a corresponding
+ * length field in |wpa_ssid| structue instance for this network.
+ * This function frees any existing data in these fields.
+ */
+int StaNetwork::setByteArrayKeyFieldAndResetState(
+	const uint8_t *value, const size_t value_len, uint8_t **to_update_field,
+	size_t *to_update_field_len, const char *hexdump_prefix)
+{
+	if (*to_update_field) {
+		bin_clear_free(*to_update_field, *to_update_field_len);
+	}
+	*to_update_field = (uint8_t *)os_malloc(value_len);
+	if (!(*to_update_field)) {
+		return 1;
+	}
+	os_memcpy(*to_update_field, value, value_len);
+	*to_update_field_len = value_len;
+
+	wpa_hexdump_ascii_key(
+		MSG_MSGDUMP, hexdump_prefix, *to_update_field,
+		*to_update_field_len);
+	resetInternalStateAfterParamsUpdate();
+	return 0;
+}
+
+/**
+ * Helper function to set the fast transition bits in the key management
+ * bitmask, to allow FT support when possible.
+ */
+void StaNetwork::setFastTransitionKeyMgmt(uint32_t &key_mgmt_mask)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	int res;
+	struct wpa_driver_capa capa;
+
+	if (key_mgmt_mask & WPA_KEY_MGMT_PSK) {
+		key_mgmt_mask |= WPA_KEY_MGMT_FT_PSK;
+	}
+
+	if (key_mgmt_mask & WPA_KEY_MGMT_IEEE8021X) {
+		key_mgmt_mask |= WPA_KEY_MGMT_FT_IEEE8021X;
+	}
+
+	res = wpa_drv_get_capa(wpa_s, &capa);
+	if (res == 0) {
+#ifdef CONFIG_IEEE80211R
+#ifdef CONFIG_SAE
+		if ((key_mgmt_mask & WPA_KEY_MGMT_SAE) &&
+			(capa.key_mgmt_iftype[WPA_IF_STATION] & WPA_DRIVER_CAPA_KEY_MGMT_FT_SAE)) {
+			key_mgmt_mask |= WPA_KEY_MGMT_FT_SAE;
+		}
+#endif
+#endif
+	}
+
+}
+
+/**
+ * Helper function to reset the fast transition bits in the key management
+ * bitmask.
+ */
+void StaNetwork::resetFastTransitionKeyMgmt(uint32_t &key_mgmt_mask)
+{
+	if (key_mgmt_mask & WPA_KEY_MGMT_PSK) {
+		key_mgmt_mask &= ~WPA_KEY_MGMT_FT_PSK;
+	}
+
+	if (key_mgmt_mask & WPA_KEY_MGMT_IEEE8021X) {
+		key_mgmt_mask &= ~WPA_KEY_MGMT_FT_IEEE8021X;
+	}
+#ifdef CONFIG_IEEE80211R
+#ifdef CONFIG_SAE
+	if (key_mgmt_mask & WPA_KEY_MGMT_SAE) {
+		key_mgmt_mask &= ~WPA_KEY_MGMT_FT_SAE;
+	}
+#endif
+#endif
+}
+
+/**
+ * Helper function to enable erp keys generation while connecting to FILS
+ * enabled APs.
+ */
+ndk::ScopedAStatus StaNetwork::setEapErpInternal(bool enable)
+{
+#ifdef CONFIG_FILS
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	wpa_ssid->eap.erp = enable ? 1 : 0;
+	return ndk::ScopedAStatus::ok();
+#else /* CONFIG_FILS */
+	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+#endif /* CONFIG_FILS */
+}
+
+ndk::ScopedAStatus StaNetwork::setSaeH2eModeInternal(
+	SaeH2eMode mode)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	switch (mode) {
+	case SaeH2eMode::DISABLED:
+		wpa_s->conf->sae_pwe = 0;
+		break;
+	case SaeH2eMode::H2E_MANDATORY:
+		wpa_s->conf->sae_pwe = 1;
+		break;
+	case SaeH2eMode::H2E_OPTIONAL:
+		wpa_s->conf->sae_pwe = 2;
+		break;
+	}
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::enableSaePkOnlyModeInternal(bool enable)
+{
+#ifdef CONFIG_SAE_PK
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	wpa_ssid->sae_pk = enable ? SAE_PK_MODE_ONLY : SAE_PK_MODE_AUTOMATIC;
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+#else
+	return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
+#endif
+}
+
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/sta_network.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/sta_network.h
new file mode 100755
index 0000000..524f44a
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/sta_network.h
@@ -0,0 +1,353 @@
+/*
+ * WPA Supplicant - Sta network Aidl interface
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef WPA_SUPPLICANT_AIDL_STA_NETWORK_H
+#define WPA_SUPPLICANT_AIDL_STA_NETWORK_H
+
+#include <array>
+#include <vector>
+
+#include <android-base/macros.h>
+
+#include <aidl/android/hardware/wifi/supplicant/BnSupplicantStaNetwork.h>
+#include <aidl/android/hardware/wifi/supplicant/EapMethod.h>
+#include <aidl/android/hardware/wifi/supplicant/EapPhase2Method.h>
+#include <aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.h>
+#include <aidl/android/hardware/wifi/supplicant/NetworkRequestEapSimUmtsAuthParams.h>
+#include <aidl/android/hardware/wifi/supplicant/NetworkResponseEapSimUmtsAuthParams.h>
+#include <aidl/android/hardware/wifi/supplicant/SaeH2eMode.h>
+#include <aidl/android/hardware/wifi/supplicant/DppConnectionKeys.h>
+
+extern "C"
+{
+#include "utils/common.h"
+#include "utils/includes.h"
+#include "config.h"
+#include "wpa_supplicant_i.h"
+#include "notify.h"
+#include "eapol_supp/eapol_supp_sm.h"
+#include "eap_peer/eap.h"
+#include "rsn_supp/wpa.h"
+}
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+
+/**
+ * Implementation of StaNetwork aidl object. Each unique aidl
+ * object is used for control operations on a specific network
+ * controlled by wpa_supplicant.
+ */
+class StaNetwork : public BnSupplicantStaNetwork
+{
+public:
+	StaNetwork(
+		struct wpa_global* wpa_global, const char ifname[], int network_id);
+	~StaNetwork() override = default;
+	// Refer to |StaIface::invalidate()|.
+	void invalidate();
+	bool isValid();
+
+	// Aidl methods exposed.
+  	::ndk::ScopedAStatus getId(int32_t* _aidl_return) override;
+	::ndk::ScopedAStatus getInterfaceName(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getType(IfaceType* _aidl_return) override;
+	::ndk::ScopedAStatus registerCallback(
+		const std::shared_ptr<ISupplicantStaNetworkCallback>& in_callback) override;
+	::ndk::ScopedAStatus setSsid(const std::vector<uint8_t>& in_ssid) override;
+	::ndk::ScopedAStatus setBssid(const std::vector<uint8_t>& in_bssid) override;
+	::ndk::ScopedAStatus setDppKeys(const DppConnectionKeys& in_keys) override;
+	::ndk::ScopedAStatus setScanSsid(bool in_enable) override;
+	::ndk::ScopedAStatus setKeyMgmt(KeyMgmtMask in_keyMgmtMask) override;
+	::ndk::ScopedAStatus setProto(ProtoMask in_protoMask) override;
+	::ndk::ScopedAStatus setAuthAlg(AuthAlgMask in_authAlgMask) override;
+	::ndk::ScopedAStatus setGroupCipher(GroupCipherMask in_groupCipherMask) override;
+	::ndk::ScopedAStatus setPairwiseCipher(
+		PairwiseCipherMask in_pairwiseCipherMask) override;
+	::ndk::ScopedAStatus setPskPassphrase(const std::string& in_psk) override;
+	::ndk::ScopedAStatus setPsk(const std::vector<uint8_t>& in_psk) override;
+	::ndk::ScopedAStatus setWepKey(
+		int32_t in_keyIdx, const std::vector<uint8_t>& in_wepKey) override;
+	::ndk::ScopedAStatus setWepTxKeyIdx(int32_t in_keyIdx) override;
+	::ndk::ScopedAStatus setRequirePmf(bool in_enable) override;
+	::ndk::ScopedAStatus setEapMethod(EapMethod in_method) override;
+	::ndk::ScopedAStatus setEapPhase2Method(EapPhase2Method in_method) override;
+	::ndk::ScopedAStatus setEapIdentity(
+		const std::vector<uint8_t>& in_identity) override;
+	::ndk::ScopedAStatus setEapEncryptedImsiIdentity(
+		const std::vector<uint8_t>& in_identity) override;
+	::ndk::ScopedAStatus setEapAnonymousIdentity(
+		const std::vector<uint8_t>& in_identity) override;
+	::ndk::ScopedAStatus setEapPassword(
+		const std::vector<uint8_t>& in_password) override;
+	::ndk::ScopedAStatus setEapCACert(const std::string& in_path) override;
+	::ndk::ScopedAStatus setEapCAPath(const std::string& in_path) override;
+	::ndk::ScopedAStatus setEapClientCert(const std::string& in_path) override;
+	::ndk::ScopedAStatus setEapPrivateKeyId(const std::string& in_id) override;
+	::ndk::ScopedAStatus setEapSubjectMatch(const std::string& in_match) override;
+	::ndk::ScopedAStatus setEapAltSubjectMatch(const std::string& in_match) override;
+	::ndk::ScopedAStatus setEapEngine(bool in_enable) override;
+	::ndk::ScopedAStatus setEapEngineID(const std::string& in_id) override;
+	::ndk::ScopedAStatus setEapDomainSuffixMatch(
+		const std::string& in_match) override;
+	::ndk::ScopedAStatus setProactiveKeyCaching(bool in_enable) override;
+	::ndk::ScopedAStatus setIdStr(const std::string& in_idStr) override;
+	::ndk::ScopedAStatus setUpdateIdentifier(int32_t in_id) override;
+	::ndk::ScopedAStatus setEdmg(bool in_enable) override;
+	::ndk::ScopedAStatus getSsid(std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus getBssid(std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus getScanSsid(bool* _aidl_return) override;
+	::ndk::ScopedAStatus getKeyMgmt(KeyMgmtMask* _aidl_return) override;
+	::ndk::ScopedAStatus getProto(ProtoMask* _aidl_return) override;
+	::ndk::ScopedAStatus getAuthAlg(AuthAlgMask* _aidl_return) override;
+	::ndk::ScopedAStatus getGroupCipher(GroupCipherMask* _aidl_return) override;
+	::ndk::ScopedAStatus getPairwiseCipher(PairwiseCipherMask* _aidl_return) override;
+	::ndk::ScopedAStatus getPskPassphrase(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getPsk(std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus getSaePassword(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getSaePasswordId(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getWepKey(
+		int32_t in_keyIdx, std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus getWepTxKeyIdx(int32_t* _aidl_return) override;
+	::ndk::ScopedAStatus getRequirePmf(bool* _aidl_return) override;
+	::ndk::ScopedAStatus getEapMethod(EapMethod* _aidl_return) override;
+	::ndk::ScopedAStatus getEapPhase2Method(EapPhase2Method* _aidl_return) override;
+	::ndk::ScopedAStatus getEapIdentity(std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus getEapAnonymousIdentity(
+		std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus getEapPassword(std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus getEapCACert(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getEapCAPath(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getEapClientCert(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getEapPrivateKeyId(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getEapSubjectMatch(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getEapAltSubjectMatch(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getEapEngine(bool* _aidl_return) override;
+	::ndk::ScopedAStatus getEapEngineId(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getEapDomainSuffixMatch(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getIdStr(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getWpsNfcConfigurationToken(
+		std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus getEdmg(bool* _aidl_return) override;
+	::ndk::ScopedAStatus enable(bool in_noConnect) override;
+	::ndk::ScopedAStatus disable() override;
+	::ndk::ScopedAStatus select() override;
+	::ndk::ScopedAStatus sendNetworkEapSimGsmAuthResponse(
+		const std::vector<NetworkResponseEapSimGsmAuthParams>& in_params) override;
+	::ndk::ScopedAStatus sendNetworkEapSimGsmAuthFailure() override;
+	::ndk::ScopedAStatus sendNetworkEapSimUmtsAuthResponse(
+		const NetworkResponseEapSimUmtsAuthParams& in_params) override;
+	::ndk::ScopedAStatus sendNetworkEapSimUmtsAutsResponse(
+		const std::vector<uint8_t>& in_auts) override;
+	::ndk::ScopedAStatus sendNetworkEapSimUmtsAuthFailure() override;
+	::ndk::ScopedAStatus sendNetworkEapIdentityResponse(
+		const std::vector<uint8_t>& in_identity,
+		const std::vector<uint8_t>& in_encryptedIdentity) override;
+	::ndk::ScopedAStatus setGroupMgmtCipher(
+		GroupMgmtCipherMask in_groupMgmtCipherMask) override;
+	::ndk::ScopedAStatus getGroupMgmtCipher(
+		GroupMgmtCipherMask* _aidl_return) override;
+	::ndk::ScopedAStatus enableTlsSuiteBEapPhase1Param(
+		bool in_enable) override;
+	::ndk::ScopedAStatus enableSuiteBEapOpenSslCiphers() override;
+	::ndk::ScopedAStatus setSaePassword(
+		const std::string& in_saePassword) override;
+	::ndk::ScopedAStatus setSaePasswordId(
+		const std::string& in_saePasswordId) override;
+	::ndk::ScopedAStatus setOcsp(OcspType in_ocspType) override;
+	::ndk::ScopedAStatus getOcsp(OcspType* _aidl_return) override;
+	::ndk::ScopedAStatus setPmkCache(
+		const std::vector<uint8_t>& in_serializedEntry) override;
+	::ndk::ScopedAStatus setWapiCertSuite(const std::string& in_suite) override;
+	::ndk::ScopedAStatus getWapiCertSuite(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus setEapErp(bool in_enable) override;
+	::ndk::ScopedAStatus setSaeH2eMode(SaeH2eMode in_mode) override;
+	::ndk::ScopedAStatus enableSaePkOnlyMode(bool in_enable) override;
+	::ndk::ScopedAStatus setRoamingConsortiumSelection(
+		const std::vector<uint8_t>& in_selectedRcoi) override;
+
+private:
+	// Corresponding worker functions for the AIDL methods.
+	std::pair<uint32_t, ndk::ScopedAStatus> getIdInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getInterfaceNameInternal();
+	std::pair<IfaceType, ndk::ScopedAStatus> getTypeInternal();
+	ndk::ScopedAStatus registerCallbackInternal(
+		const std::shared_ptr<ISupplicantStaNetworkCallback>& callback);
+	ndk::ScopedAStatus setSsidInternal(const std::vector<uint8_t>& ssid);
+	ndk::ScopedAStatus setBssidInternal(const std::vector<uint8_t>& bssid);
+	ndk::ScopedAStatus setDppKeysInternal(const DppConnectionKeys& keys);
+	ndk::ScopedAStatus setScanSsidInternal(bool enable);
+	ndk::ScopedAStatus setKeyMgmtInternal(
+		KeyMgmtMask mask);
+	ndk::ScopedAStatus setProtoInternal(
+		ProtoMask mask);
+	ndk::ScopedAStatus setAuthAlgInternal(
+		AuthAlgMask mask);
+	ndk::ScopedAStatus setGroupCipherInternal(
+		GroupCipherMask mask);
+	ndk::ScopedAStatus setPairwiseCipherInternal(
+		PairwiseCipherMask mask);
+	ndk::ScopedAStatus setPskPassphraseInternal(const std::string& psk);
+	ndk::ScopedAStatus setPskInternal(const std::vector<uint8_t>& psk);
+	ndk::ScopedAStatus setWepKeyInternal(
+		uint32_t key_idx, const std::vector<uint8_t>& wep_key);
+	ndk::ScopedAStatus setWepTxKeyIdxInternal(uint32_t key_idx);
+	ndk::ScopedAStatus setRequirePmfInternal(bool enable);
+	ndk::ScopedAStatus setEapMethodInternal(
+		EapMethod method);
+	ndk::ScopedAStatus setEapPhase2MethodInternal(
+		EapPhase2Method method);
+	ndk::ScopedAStatus setEapIdentityInternal(
+		const std::vector<uint8_t>& identity);
+	ndk::ScopedAStatus setEapEncryptedImsiIdentityInternal(
+		const std::vector<uint8_t>& identity);
+	ndk::ScopedAStatus setEapAnonymousIdentityInternal(
+		const std::vector<uint8_t>& identity);
+	ndk::ScopedAStatus setEapPasswordInternal(
+		const std::vector<uint8_t>& password);
+	ndk::ScopedAStatus setEapCACertInternal(const std::string& path);
+	ndk::ScopedAStatus setEapCAPathInternal(const std::string& path);
+	ndk::ScopedAStatus setEapClientCertInternal(const std::string& path);
+	ndk::ScopedAStatus setEapPrivateKeyIdInternal(const std::string& id);
+	ndk::ScopedAStatus setEapSubjectMatchInternal(const std::string& match);
+	ndk::ScopedAStatus setEapAltSubjectMatchInternal(
+		const std::string& match);
+	ndk::ScopedAStatus setEapEngineInternal(bool enable);
+	ndk::ScopedAStatus setEapEngineIDInternal(const std::string& id);
+	ndk::ScopedAStatus setEapDomainSuffixMatchInternal(
+		const std::string& match);
+	ndk::ScopedAStatus setProactiveKeyCachingInternal(bool enable);
+	ndk::ScopedAStatus setIdStrInternal(const std::string& id_str);
+	ndk::ScopedAStatus setUpdateIdentifierInternal(uint32_t id);
+	ndk::ScopedAStatus setEdmgInternal(bool enable);
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> getSsidInternal();
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> getBssidInternal();
+	std::pair<bool, ndk::ScopedAStatus> getScanSsidInternal();
+	std::pair<KeyMgmtMask, ndk::ScopedAStatus> getKeyMgmtInternal();
+	std::pair<ProtoMask, ndk::ScopedAStatus> getProtoInternal();
+	std::pair<AuthAlgMask, ndk::ScopedAStatus> getAuthAlgInternal();
+	std::pair<GroupCipherMask, ndk::ScopedAStatus> getGroupCipherInternal();
+	std::pair<PairwiseCipherMask, ndk::ScopedAStatus> getPairwiseCipherInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getPskPassphraseInternal();
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> getPskInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getSaePasswordInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getSaePasswordIdInternal();
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> getWepKeyInternal(
+		uint32_t key_idx);
+	std::pair<uint32_t, ndk::ScopedAStatus> getWepTxKeyIdxInternal();
+	std::pair<bool, ndk::ScopedAStatus> getRequirePmfInternal();
+	std::pair<EapMethod, ndk::ScopedAStatus> getEapMethodInternal();
+	std::pair<EapPhase2Method, ndk::ScopedAStatus>
+		getEapPhase2MethodInternal();
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+		getEapIdentityInternal();
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+		getEapAnonymousIdentityInternal();
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+		getEapPasswordInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getEapCACertInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getEapCAPathInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getEapClientCertInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getEapPrivateKeyIdInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getEapSubjectMatchInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getEapAltSubjectMatchInternal();
+	std::pair<bool, ndk::ScopedAStatus> getEapEngineInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getEapEngineIdInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getEapDomainSuffixMatchInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getIdStrInternal();
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+		getWpsNfcConfigurationTokenInternal();
+	std::pair<bool, ndk::ScopedAStatus> getEdmgInternal();
+	ndk::ScopedAStatus enableInternal(bool no_connect);
+	ndk::ScopedAStatus disableInternal();
+	ndk::ScopedAStatus selectInternal();
+	ndk::ScopedAStatus sendNetworkEapSimGsmAuthResponseInternal(
+		const std::vector<NetworkResponseEapSimGsmAuthParams>&
+		vec_params);
+	ndk::ScopedAStatus sendNetworkEapSimGsmAuthFailureInternal();
+	ndk::ScopedAStatus sendNetworkEapSimUmtsAuthResponseInternal(
+		const NetworkResponseEapSimUmtsAuthParams& params);
+	ndk::ScopedAStatus sendNetworkEapSimUmtsAutsResponseInternal(
+		const std::vector<uint8_t>& auts);
+	ndk::ScopedAStatus sendNetworkEapSimUmtsAuthFailureInternal();
+	ndk::ScopedAStatus sendNetworkEapIdentityResponseInternal(
+		const std::vector<uint8_t>& identity,
+		const std::vector<uint8_t>& imsi_identity);
+	ndk::ScopedAStatus enableTlsSuiteBEapPhase1ParamInternal(bool enable);
+	ndk::ScopedAStatus enableSuiteBEapOpenSslCiphersInternal();
+	ndk::ScopedAStatus setSaePasswordInternal(
+		const std::string& sae_password);
+	ndk::ScopedAStatus setSaePasswordIdInternal(
+		const std::string& sae_password_id);
+	ndk::ScopedAStatus setGroupMgmtCipherInternal(
+		GroupMgmtCipherMask mask);
+	std::pair<GroupMgmtCipherMask, ndk::ScopedAStatus>
+		getGroupMgmtCipherInternal();
+	ndk::ScopedAStatus setOcspInternal(OcspType ocspType);
+	std::pair<OcspType, ndk::ScopedAStatus> getOcspInternal();
+	ndk::ScopedAStatus setPmkCacheInternal(const std::vector<uint8_t>& serializedEntry);
+	ndk::ScopedAStatus setWapiCertSuiteInternal(const std::string& suite);
+	std::pair<std::string, ndk::ScopedAStatus> getWapiCertSuiteInternal();
+	ndk::ScopedAStatus setWapiPskInternal(const std::vector<uint8_t>& psk);
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> getWapiPskInternal();
+	ndk::ScopedAStatus setSaeH2eModeInternal(SaeH2eMode mode);
+	ndk::ScopedAStatus enableSaePkOnlyModeInternal(bool enable);
+	ndk::ScopedAStatus setRoamingConsortiumSelectionInternal(
+		const std::vector<uint8_t>& selectedRcoi);
+
+	struct wpa_ssid* retrieveNetworkPtr();
+	struct wpa_supplicant* retrieveIfacePtr();
+	int isPskPassphraseValid(const std::string& psk);
+	void resetInternalStateAfterParamsUpdate();
+	int setStringFieldAndResetState(
+		const char* value, uint8_t** to_update_field,
+		const char* hexdump_prefix);
+	int setStringFieldAndResetState(
+		const char* value, char** to_update_field,
+		const char* hexdump_prefix);
+	int setStringKeyFieldAndResetState(
+		const char* value, char** to_update_field,
+		const char* hexdump_prefix);
+	int setByteArrayFieldAndResetState(
+		const uint8_t* value, const size_t value_len,
+		uint8_t** to_update_field, size_t* to_update_field_len,
+		const char* hexdump_prefix);
+	int setByteArrayKeyFieldAndResetState(
+		const uint8_t* value, const size_t value_len,
+		uint8_t** to_update_field, size_t* to_update_field_len,
+		const char* hexdump_prefix);
+	void setFastTransitionKeyMgmt(uint32_t &key_mgmt_mask);
+	void resetFastTransitionKeyMgmt(uint32_t &key_mgmt_mask);
+	ndk::ScopedAStatus setEapErpInternal(bool enable);
+	int setByteArrayField(
+		const uint8_t* value, const size_t value_len,
+		uint8_t** to_update_field, size_t* to_update_field_len,
+		const char* hexdump_prefix, bool resetState);
+
+	// Reference to the global wpa_struct. This is assumed to be valid
+	// for the lifetime of the process.
+	struct wpa_global* wpa_global_;
+	// Name of the iface this network belongs to.
+	const std::string ifname_;
+	// Id of the network this aidl object controls.
+	const int network_id_;
+	bool is_valid_;
+
+	DISALLOW_COPY_AND_ASSIGN(StaNetwork);
+};
+
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WPA_SUPPLICANT_AIDL_STA_NETWORK_H
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/supplicant.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/supplicant.cpp
new file mode 100755
index 0000000..ee6f809
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/supplicant.cpp
@@ -0,0 +1,545 @@
+/*
+ * WPA Supplicant - Supplicant Aidl interface
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "aidl_manager.h"
+#include "aidl_return_util.h"
+#include "misc_utils.h"
+#include "supplicant.h"
+#include "p2p_iface.h"
+
+#include <android-base/file.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+namespace {
+
+// Pre-populated interface params for interfaces controlled by wpa_supplicant.
+// Note: This may differ for other OEM's. So, modify this accordingly.
+constexpr char kIfaceDriverName[] = "nl80211";
+constexpr char kStaIfaceConfPath[] =
+	"/data/vendor/wifi/wpa/wpa_supplicant.conf";
+static const char* kStaIfaceConfOverlayPaths[] = {
+    "/apex/com.android.wifi.hal/etc/wifi/wpa_supplicant_overlay.conf",
+    "/vendor/etc/wifi/wpa_supplicant_overlay.conf",
+};
+constexpr char kP2pIfaceConfPath[] =
+	"/data/vendor/wifi/wpa/p2p_supplicant.conf";
+static const char* kP2pIfaceConfOverlayPaths[] = {
+    "/apex/com.android.wifi.hal/etc/wifi/p2p_supplicant_overlay.conf",
+    "/vendor/etc/wifi/p2p_supplicant_overlay.conf",
+};
+// Migrate conf files for existing devices.
+static const char* kTemplateConfPaths[] = {
+    "/apex/com.android.wifi.hal/etc/wifi/wpa_supplicant.conf",
+    "/vendor/etc/wifi/wpa_supplicant.conf",
+    "/system/etc/wifi/wpa_supplicant.conf",
+};
+constexpr char kOldStaIfaceConfPath[] = "/data/misc/wifi/wpa_supplicant.conf";
+constexpr char kOldP2pIfaceConfPath[] = "/data/misc/wifi/p2p_supplicant.conf";
+constexpr mode_t kConfigFileMode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
+
+const char* resolvePath(const char* paths[], size_t size)
+{
+	for (int i = 0; i < size; ++i) {
+		if (access(paths[i], R_OK) == 0) {
+			return paths[i];
+		}
+	}
+	return nullptr;
+}
+
+int copyFile(
+	const std::string& src_file_path, const std::string& dest_file_path)
+{
+	std::string file_contents;
+	if (!android::base::ReadFileToString(src_file_path, &file_contents)) {
+		wpa_printf(
+			MSG_ERROR, "Failed to read from %s. Errno: %s",
+			src_file_path.c_str(), strerror(errno));
+		return -1;
+	}
+	if (!android::base::WriteStringToFile(
+		file_contents, dest_file_path, kConfigFileMode, getuid(),
+		getgid())) {
+		wpa_printf(
+			MSG_ERROR, "Failed to write to %s. Errno: %s",
+			dest_file_path.c_str(), strerror(errno));
+		return -1;
+	}
+	return 0;
+}
+
+/**
+ * Copy |src_file_path| to |dest_file_path| if it exists.
+ *
+ * Returns 1 if |src_file_path| does not exist or not accessible,
+ * Returns -1 if the copy fails.
+ * Returns 0 if the copy succeeds.
+ */
+int copyFileIfItExists(
+	const std::string& src_file_path, const std::string& dest_file_path)
+{
+	int ret = access(src_file_path.c_str(), R_OK);
+	// Sepolicy denial (2018+ device) will return EACCESS instead of ENOENT.
+	if ((ret != 0) && ((errno == ENOENT) || (errno == EACCES))) {
+		return 1;
+	}
+	ret = copyFile(src_file_path, dest_file_path);
+	if (ret != 0) {
+		wpa_printf(
+			MSG_ERROR, "Failed copying %s to %s.",
+			src_file_path.c_str(), dest_file_path.c_str());
+		return -1;
+	}
+	return 0;
+}
+
+/**
+ * Ensure that the specified config file pointed by |config_file_path| exists.
+ * a) If the |config_file_path| exists with the correct permissions, return.
+ * b) If the |config_file_path| does not exist, but |old_config_file_path|
+ * exists, copy over the contents of the |old_config_file_path| to
+ * |config_file_path|.
+ * c) If the |config_file_path| & |old_config_file_path|
+ * does not exists, copy over the contents of |template_config_file_path|.
+ */
+int ensureConfigFileExists(
+	const std::string& config_file_path,
+	const std::string& old_config_file_path)
+{
+	int ret = access(config_file_path.c_str(), R_OK | W_OK);
+	if (ret == 0) {
+		return 0;
+	}
+	if (errno == EACCES) {
+		ret = chmod(config_file_path.c_str(), kConfigFileMode);
+		if (ret == 0) {
+			return 0;
+		} else {
+			wpa_printf(
+				MSG_ERROR, "Cannot set RW to %s. Errno: %s",
+				config_file_path.c_str(), strerror(errno));
+			return -1;
+		}
+	} else if (errno != ENOENT) {
+		wpa_printf(
+			MSG_ERROR, "Cannot acces %s. Errno: %s",
+			config_file_path.c_str(), strerror(errno));
+		return -1;
+	}
+	ret = copyFileIfItExists(old_config_file_path, config_file_path);
+	if (ret == 0) {
+		wpa_printf(
+			MSG_INFO, "Migrated conf file from %s to %s",
+			old_config_file_path.c_str(), config_file_path.c_str());
+		unlink(old_config_file_path.c_str());
+		return 0;
+	} else if (ret == -1) {
+		unlink(config_file_path.c_str());
+		return -1;
+	}
+	const char* path =
+	    resolvePath(kTemplateConfPaths,
+	    sizeof(kTemplateConfPaths)/sizeof(kTemplateConfPaths[0]));
+	if (path != nullptr) {
+		ret = copyFileIfItExists(path, config_file_path);
+		if (ret == 0) {
+			wpa_printf(
+			    MSG_INFO, "Copied template conf file from %s to %s",
+			    path, config_file_path.c_str());
+			return 0;
+		} else if (ret == -1) {
+			unlink(config_file_path.c_str());
+			return -1;
+		}
+	}
+	// Did not create the conf file.
+	return -1;
+}
+}  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+using aidl_return_util::validateAndCall;
+using misc_utils::createStatus;
+using misc_utils::createStatusWithMsg;
+
+Supplicant::Supplicant(struct wpa_global* global) : wpa_global_(global) {}
+bool Supplicant::isValid()
+{
+	// This top level object cannot be invalidated.
+	return true;
+}
+
+::ndk::ScopedAStatus Supplicant::addP2pInterface(
+	const std::string& in_name,
+	std::shared_ptr<ISupplicantP2pIface>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&Supplicant::addP2pInterfaceInternal, _aidl_return, in_name);
+}
+
+::ndk::ScopedAStatus Supplicant::addStaInterface(
+	const std::string& in_name,
+	std::shared_ptr<ISupplicantStaIface>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&Supplicant::addStaInterfaceInternal, _aidl_return, in_name);
+}
+
+::ndk::ScopedAStatus Supplicant::removeInterface(
+	const IfaceInfo& in_ifaceInfo)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&Supplicant::removeInterfaceInternal, in_ifaceInfo);
+}
+
+::ndk::ScopedAStatus Supplicant::getP2pInterface(
+	const std::string& in_name,
+	std::shared_ptr<ISupplicantP2pIface>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&Supplicant::getP2pInterfaceInternal, _aidl_return, in_name);
+}
+
+::ndk::ScopedAStatus Supplicant::getStaInterface(
+	const std::string& in_name,
+	std::shared_ptr<ISupplicantStaIface>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&Supplicant::getStaInterfaceInternal, _aidl_return, in_name);
+}
+
+::ndk::ScopedAStatus Supplicant::listInterfaces(
+	std::vector<IfaceInfo>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&Supplicant::listInterfacesInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus Supplicant::registerCallback(
+	const std::shared_ptr<ISupplicantCallback>& in_callback)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&Supplicant::registerCallbackInternal, in_callback);
+}
+
+::ndk::ScopedAStatus Supplicant::setDebugParams(
+	DebugLevel in_level, bool in_showTimestamp,
+	bool in_showKeys)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&Supplicant::setDebugParamsInternal, in_level,
+		in_showTimestamp, in_showKeys);
+}
+
+::ndk::ScopedAStatus Supplicant::setConcurrencyPriority(
+	IfaceType in_type)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&Supplicant::setConcurrencyPriorityInternal, in_type);
+}
+
+::ndk::ScopedAStatus Supplicant::getDebugLevel(DebugLevel* _aidl_return)
+{
+	*_aidl_return = static_cast<DebugLevel>(wpa_debug_level);
+	return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Supplicant::isDebugShowTimestampEnabled(bool* _aidl_return)
+{
+	*_aidl_return = ((wpa_debug_timestamp != 0) ? true : false);
+	return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Supplicant::isDebugShowKeysEnabled(bool* _aidl_return)
+{
+	*_aidl_return = ((wpa_debug_show_keys != 0) ? true : false);
+	return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Supplicant::terminate()
+{
+	wpa_printf(MSG_INFO, "Terminating...");
+	wpa_supplicant_terminate_proc(wpa_global_);
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Supplicant::addP2pDevInterface(struct wpa_interface iface_params)
+{
+	char primary_ifname[IFNAMSIZ];
+	u32 primary_ifname_len =
+		strlen(iface_params.ifname) - strlen(P2P_MGMT_DEVICE_PREFIX);
+
+	if(primary_ifname_len > IFNAMSIZ) {
+		wpa_printf(MSG_DEBUG, "%s, Invalid primary iface name ", __FUNCTION__);
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+
+	strncpy(primary_ifname, iface_params.ifname +
+		strlen(P2P_MGMT_DEVICE_PREFIX), primary_ifname_len);
+	wpa_printf(MSG_DEBUG, "%s, Initialize p2p-dev-wlan0 iface with"
+		"primary_iface = %s", __FUNCTION__, primary_ifname);
+	struct wpa_supplicant* wpa_s =
+		wpa_supplicant_get_iface(wpa_global_, primary_ifname);
+	if (!wpa_s) {
+		wpa_printf(MSG_DEBUG, "%s,NULL wpa_s for wlan0", __FUNCTION__);
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
+	}
+	if (wpas_p2p_add_p2pdev_interface(
+		wpa_s, wpa_s->global->params.conf_p2p_dev) < 0) {
+		wpa_printf(MSG_INFO,
+			"Failed to enable P2P Device");
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::shared_ptr<ISupplicantP2pIface>, ndk::ScopedAStatus>
+Supplicant::addP2pInterfaceInternal(const std::string& name)
+{
+	std::shared_ptr<ISupplicantP2pIface> iface;
+
+	// Check if required |ifname| argument is empty.
+	if (name.empty()) {
+		return {nullptr, createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID)};
+	}
+	// Try to get the wpa_supplicant record for this iface, return
+	// the iface object with the appropriate status code if it exists.
+	ndk::ScopedAStatus status;
+	std::tie(iface, status) = getP2pInterfaceInternal(name);
+	if (status.isOk()) {
+		wpa_printf(MSG_INFO, "Iface already exists, return existing");
+		return {iface, ndk::ScopedAStatus::ok()};
+	}
+
+	struct wpa_interface iface_params = {};
+	iface_params.driver = kIfaceDriverName;
+	if (ensureConfigFileExists(
+		kP2pIfaceConfPath, kOldP2pIfaceConfPath) != 0) {
+		wpa_printf(
+			MSG_ERROR, "Conf file does not exists: %s",
+			kP2pIfaceConfPath);
+		return {nullptr, createStatusWithMsg(
+			SupplicantStatusCode::FAILURE_UNKNOWN, "Conf file does not exist")};
+	}
+	iface_params.confname = kP2pIfaceConfPath;
+	const char* path = resolvePath(
+		    kP2pIfaceConfOverlayPaths,
+		    sizeof(kP2pIfaceConfOverlayPaths)/sizeof(kP2pIfaceConfOverlayPaths[0]));
+	if (path != nullptr) {
+		iface_params.confanother = path;
+	}
+
+	iface_params.ifname = name.c_str();
+	if (strncmp(iface_params.ifname, P2P_MGMT_DEVICE_PREFIX,
+		strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
+		status = addP2pDevInterface(iface_params);
+		if (!status.isOk()) {
+			return {iface, createStatus(static_cast<SupplicantStatusCode>(
+				status.getServiceSpecificError()))};
+		}
+	} else {
+		struct wpa_supplicant* wpa_s =
+			wpa_supplicant_add_iface(wpa_global_, &iface_params, NULL);
+		if (!wpa_s) {
+			return {nullptr, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+		}
+		// Request the current scan results from the driver and update
+		// the local BSS list wpa_s->bss. This is to avoid a full scan
+		// while processing the connect request on newly created interface.
+		wpa_supplicant_update_scan_results(wpa_s);
+	}
+	// The supplicant core creates a corresponding aidl object via
+	// AidlManager when |wpa_supplicant_add_iface| is called.
+	return getP2pInterfaceInternal(name);
+}
+
+std::pair<std::shared_ptr<ISupplicantStaIface>, ndk::ScopedAStatus>
+Supplicant::addStaInterfaceInternal(const std::string& name)
+{
+	std::shared_ptr<ISupplicantStaIface> iface;
+
+	// Check if required |ifname| argument is empty.
+	if (name.empty()) {
+		return {nullptr, createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID)};
+	}
+	// Try to get the wpa_supplicant record for this iface, return
+	// the iface object with the appropriate status code if it exists.
+	ndk::ScopedAStatus status;
+	std::tie(iface, status) = getStaInterfaceInternal(name);
+	if (status.isOk()) {
+		wpa_printf(MSG_INFO, "Iface already exists, return existing");
+		return {iface, ndk::ScopedAStatus::ok()};
+	}
+
+	struct wpa_interface iface_params = {};
+	iface_params.driver = kIfaceDriverName;
+	if (ensureConfigFileExists(
+		kStaIfaceConfPath, kOldStaIfaceConfPath) != 0) {
+		wpa_printf(
+			MSG_ERROR, "Conf file does not exists: %s",
+			kStaIfaceConfPath);
+		return {nullptr, createStatusWithMsg(
+			SupplicantStatusCode::FAILURE_UNKNOWN, "Conf file does not exist")};
+	}
+	iface_params.confname = kStaIfaceConfPath;
+	const char* path = resolvePath(
+		    kStaIfaceConfOverlayPaths,
+		    sizeof(kStaIfaceConfOverlayPaths)/sizeof(kStaIfaceConfOverlayPaths[0]));
+	if (path != nullptr) {
+		iface_params.confanother = path;
+	}
+
+	iface_params.ifname = name.c_str();
+	if (strncmp(iface_params.ifname, P2P_MGMT_DEVICE_PREFIX,
+		strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
+		status = addP2pDevInterface(iface_params);
+		if (!status.isOk()) {
+			return {iface, createStatus(static_cast<SupplicantStatusCode>(
+				status.getServiceSpecificError()))};
+		}
+	} else {
+		struct wpa_supplicant* wpa_s =
+			wpa_supplicant_add_iface(wpa_global_, &iface_params, NULL);
+		if (!wpa_s) {
+			return {nullptr, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+		}
+		// Request the current scan results from the driver and update
+		// the local BSS list wpa_s->bss. This is to avoid a full scan
+		// while processing the connect request on newly created interface.
+		wpa_supplicant_update_scan_results(wpa_s);
+	}
+	// The supplicant core creates a corresponding aidl object via
+	// AidlManager when |wpa_supplicant_add_iface| is called.
+	return getStaInterfaceInternal(name);
+}
+
+ndk::ScopedAStatus Supplicant::removeInterfaceInternal(
+	const IfaceInfo& iface_info)
+{
+	struct wpa_supplicant* wpa_s =
+		wpa_supplicant_get_iface(wpa_global_, iface_info.name.c_str());
+	if (!wpa_s) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
+	}
+	if (wpa_supplicant_remove_iface(wpa_global_, wpa_s, 0)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::shared_ptr<ISupplicantP2pIface>, ndk::ScopedAStatus>
+Supplicant::getP2pInterfaceInternal(const std::string& name)
+{
+	struct wpa_supplicant* wpa_s =
+		wpa_supplicant_get_iface(wpa_global_, name.c_str());
+	if (!wpa_s) {
+		return {nullptr, createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN)};
+	}
+	AidlManager* aidl_manager = AidlManager::getInstance();
+	std::shared_ptr<ISupplicantP2pIface> iface;
+	if (!aidl_manager ||
+		aidl_manager->getP2pIfaceAidlObjectByIfname(
+		wpa_s->ifname, &iface)) {
+		return {iface, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	// Set this flag true here, since there is no AIDL initialize
+	// method for the p2p config, and the supplicant interface is
+	// not ready when the p2p iface is created.
+	wpa_s->conf->persistent_reconnect = true;
+	return {iface, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::shared_ptr<ISupplicantStaIface>, ndk::ScopedAStatus>
+Supplicant::getStaInterfaceInternal(const std::string& name)
+{
+	struct wpa_supplicant* wpa_s =
+		wpa_supplicant_get_iface(wpa_global_, name.c_str());
+	if (!wpa_s) {
+		return {nullptr, createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN)};
+	}
+	AidlManager* aidl_manager = AidlManager::getInstance();
+	std::shared_ptr<ISupplicantStaIface> iface;
+	if (!aidl_manager ||
+		aidl_manager->getStaIfaceAidlObjectByIfname(
+		wpa_s->ifname, &iface)) {
+		return {iface, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {iface, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<IfaceInfo>, ndk::ScopedAStatus>
+Supplicant::listInterfacesInternal()
+{
+	std::vector<IfaceInfo> ifaces;
+	for (struct wpa_supplicant* wpa_s = wpa_global_->ifaces; wpa_s;
+		 wpa_s = wpa_s->next) {
+		if (wpa_s->global->p2p_init_wpa_s == wpa_s) {
+			ifaces.emplace_back(IfaceInfo{
+				IfaceType::P2P, wpa_s->ifname});
+		} else {
+			ifaces.emplace_back(IfaceInfo{
+				IfaceType::STA, wpa_s->ifname});
+		}
+	}
+	return {std::move(ifaces), ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus Supplicant::registerCallbackInternal(
+	const std::shared_ptr<ISupplicantCallback>& callback)
+{
+	AidlManager* aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager ||
+		aidl_manager->addSupplicantCallbackAidlObject(callback)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Supplicant::setDebugParamsInternal(
+	DebugLevel level, bool show_timestamp, bool show_keys)
+{
+	if (wpa_supplicant_set_debug_params(
+		wpa_global_, static_cast<uint32_t>(level), show_timestamp,
+		show_keys)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Supplicant::setConcurrencyPriorityInternal(IfaceType type)
+{
+	if (type == IfaceType::STA) {
+		wpa_global_->conc_pref =
+			wpa_global::wpa_conc_pref::WPA_CONC_PREF_STA;
+	} else if (type == IfaceType::P2P) {
+		wpa_global_->conc_pref =
+			wpa_global::wpa_conc_pref::WPA_CONC_PREF_P2P;
+	} else {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/supplicant.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/supplicant.h
new file mode 100755
index 0000000..cbe9a67
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/aidl/supplicant.h
@@ -0,0 +1,111 @@
+/*
+ * WPA Supplicant - Supplicant Aidl interface
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef WPA_SUPPLICANT_AIDL_SUPPLICANT_H
+#define WPA_SUPPLICANT_AIDL_SUPPLICANT_H
+
+#include <aidl/android/hardware/wifi/supplicant/BnSupplicant.h>
+#include <aidl/android/hardware/wifi/supplicant/DebugLevel.h>
+#include <aidl/android/hardware/wifi/supplicant/IfaceInfo.h>
+#include <aidl/android/hardware/wifi/supplicant/ISupplicantCallback.h>
+#include <aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.h>
+#include <aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.h>
+
+#include <android-base/macros.h>
+
+extern "C"
+{
+#include "utils/common.h"
+#include "utils/includes.h"
+#include "utils/wpa_debug.h"
+#include "wpa_supplicant_i.h"
+#include "scan.h"
+}
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+
+/**
+ * Implementation of the supplicant aidl object. This aidl
+ * object is used core for global control operations on
+ * wpa_supplicant.
+ */
+class Supplicant : public BnSupplicant
+{
+public:
+	Supplicant(struct wpa_global* global);
+	~Supplicant() override = default;
+	bool isValid();
+
+	// Aidl methods exposed.
+  	::ndk::ScopedAStatus addP2pInterface(
+		  const std::string& in_name,
+		  std::shared_ptr<ISupplicantP2pIface>* _aidl_return) override;
+	::ndk::ScopedAStatus addStaInterface(
+		const std::string& in_name,
+		std::shared_ptr<ISupplicantStaIface>* _aidl_return) override;
+	::ndk::ScopedAStatus removeInterface(
+		const IfaceInfo& in_ifaceInfo) override;
+	::ndk::ScopedAStatus getP2pInterface(
+		const std::string& in_name,
+		std::shared_ptr<ISupplicantP2pIface>* _aidl_return) override;
+	::ndk::ScopedAStatus getStaInterface(
+		const std::string& in_name,
+		std::shared_ptr<ISupplicantStaIface>* _aidl_return) override;
+	::ndk::ScopedAStatus listInterfaces(
+		std::vector<IfaceInfo>* _aidl_return) override;
+	::ndk::ScopedAStatus registerCallback(
+		const std::shared_ptr<ISupplicantCallback>& in_callback) override;
+	::ndk::ScopedAStatus setDebugParams(
+		DebugLevel in_level, bool in_showTimestamp, bool in_showKeys) override;
+	::ndk::ScopedAStatus getDebugLevel(DebugLevel* _aidl_return) override;
+	::ndk::ScopedAStatus isDebugShowTimestampEnabled(bool* _aidl_return) override;
+	::ndk::ScopedAStatus isDebugShowKeysEnabled(bool* _aidl_return) override;
+	::ndk::ScopedAStatus setConcurrencyPriority(IfaceType in_type) override;
+	::ndk::ScopedAStatus terminate() override;
+
+private:
+	// Corresponding worker functions for the AIDL methods.
+	std::pair<std::shared_ptr<ISupplicantP2pIface>, ndk::ScopedAStatus>
+		addP2pInterfaceInternal(const std::string& name);
+	std::pair<std::shared_ptr<ISupplicantStaIface>, ndk::ScopedAStatus>
+		addStaInterfaceInternal(const std::string& name);
+	std::pair<std::shared_ptr<ISupplicantP2pIface>, ndk::ScopedAStatus>
+		getP2pInterfaceInternal(const std::string& name);
+	std::pair<std::shared_ptr<ISupplicantStaIface>, ndk::ScopedAStatus>
+		getStaInterfaceInternal(const std::string& name);
+	
+	ndk::ScopedAStatus removeInterfaceInternal(const IfaceInfo& iface_info);
+	std::pair<std::vector<IfaceInfo>, ndk::ScopedAStatus> listInterfacesInternal();
+	ndk::ScopedAStatus registerCallbackInternal(
+		const std::shared_ptr<ISupplicantCallback>& callback);
+	ndk::ScopedAStatus setDebugParamsInternal(
+		DebugLevel level, bool show_timestamp, bool show_keys);
+	ndk::ScopedAStatus setConcurrencyPriorityInternal(IfaceType type);
+	ndk::ScopedAStatus addP2pDevInterface(struct wpa_interface iface_params);
+
+	// Raw pointer to the global structure maintained by the core.
+	struct wpa_global* wpa_global_;
+	// Driver name to be used for creating interfaces.
+	static const char kDriverName[];
+	// wpa_supplicant.conf file location on the device.
+	static const char kConfigFilePath[];
+
+	DISALLOW_COPY_AND_ASSIGN(Supplicant);
+};
+
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WPA_SUPPLICANT_AIDL_SUPPLICANT_H
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/android.config b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/android.config
index e02a789..91b2179 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/android.config
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/android.config
@@ -329,7 +329,11 @@
 
 # Add support for Hidl control interface
 # Only applicable for Android platforms.
-CONFIG_CTRL_IFACE_HIDL=y
+# CONFIG_CTRL_IFACE_HIDL=y
+
+# Add support for Aidl control interface
+# Only applicable for Android platforms.
+CONFIG_CTRL_IFACE_AIDL=y
 
 # Add support for loading EAP methods dynamically as shared libraries.
 # When this option is enabled, each EAP method can be either included
@@ -545,12 +549,14 @@
 # Experimental implementation of draft-harkins-owe-07.txt
 CONFIG_OWE=y
 
+# Set SAE Auth status early
+CONFIG_WPA3_SAE_AUTH_EARLY_SET=y
+
 # Easy Connect (Device Provisioning Protocol - DPP)
 #CONFIG_DPP=y
 
 # WPA3-Personal (SAE)
 CONFIG_SAE=y
-CONFIG_WPA3_SAE_AUTH_EARLY_SET=y
 # Host SAE via Vendor commands
 #CONFIG_WL_SAE=y
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ap.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ap.c
index 21f7531..1ab205b 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ap.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ap.c
@@ -44,6 +44,7 @@
 #endif /* CONFIG_WPS */
 
 
+#ifdef CONFIG_P2P
 static bool is_chanwidth160_supported(struct hostapd_hw_modes *mode,
 				      struct hostapd_config *conf)
 {
@@ -63,6 +64,7 @@
 		return true;
 	return false;
 }
+#endif /* CONFIG_P2P */
 
 
 static void wpas_conf_ap_vht(struct wpa_supplicant *wpa_s,
@@ -83,6 +85,25 @@
 	if (ssid->max_oper_chwidth)
 		hostapd_set_oper_chwidth(conf, ssid->max_oper_chwidth);
 
+	/* fix 5G softap bringup issue via supplicant */
+	if (hostapd_get_oper_chwidth(conf)) {
+		ieee80211_freq_to_channel_ext(ssid->frequency, 0,
+					      hostapd_get_oper_chwidth(conf),
+					      &conf->op_class,
+					      &conf->channel);
+#ifdef CONFIG_P2P
+		switch (hostapd_get_oper_chwidth(conf)) {
+			case CHANWIDTH_80MHZ:
+				ssid->vht_center_freq1 =
+					ieee80211_chan_to_freq(NULL,
+					conf->op_class,
+					wpas_p2p_get_vht80_center(wpa_s,
+					mode, conf->channel, conf->op_class));
+				break;
+		}
+#endif /* CONFIG_P2P */
+	}
+
 	if (hostapd_get_oper_chwidth(conf) == CHANWIDTH_80P80MHZ) {
 		ieee80211_freq_to_chan(ssid->vht_center_freq2,
 #ifdef CONFIG_AP_VHT
@@ -131,13 +152,15 @@
 	switch (hostapd_get_oper_chwidth(conf)) {
 	case CHANWIDTH_80MHZ:
 	case CHANWIDTH_80P80MHZ:
-		center_chan = wpas_p2p_get_vht80_center(wpa_s, mode, channel);
+		center_chan = wpas_p2p_get_vht80_center(wpa_s, mode, channel,
+							conf->op_class);
 		wpa_printf(MSG_DEBUG,
 			   "VHT center channel %u for 80 or 80+80 MHz bandwidth",
 			   center_chan);
 		break;
 	case CHANWIDTH_160MHZ:
-		center_chan = wpas_p2p_get_vht160_center(wpa_s, mode, channel);
+		center_chan = wpas_p2p_get_vht160_center(wpa_s, mode, channel,
+							 conf->op_class);
 		wpa_printf(MSG_DEBUG,
 			   "VHT center channel %u for 160 MHz bandwidth",
 			   center_chan);
@@ -149,15 +172,25 @@
 		 * not supported.
 		 */
 		hostapd_set_oper_chwidth(conf, CHANWIDTH_160MHZ);
-		center_chan = wpas_p2p_get_vht160_center(wpa_s, mode, channel);
+		ieee80211_freq_to_channel_ext(ssid->frequency, 0,
+					      conf->vht_oper_chwidth,
+					      &conf->op_class,
+					      &conf->channel);
+		center_chan = wpas_p2p_get_vht160_center(wpa_s, mode, channel,
+							 conf->op_class);
 		if (center_chan && is_chanwidth160_supported(mode, conf)) {
 			wpa_printf(MSG_DEBUG,
 				   "VHT center channel %u for auto-selected 160 MHz bandwidth",
 				   center_chan);
 		} else {
 			hostapd_set_oper_chwidth(conf, CHANWIDTH_80MHZ);
+			ieee80211_freq_to_channel_ext(ssid->frequency, 0,
+						      conf->vht_oper_chwidth,
+						      &conf->op_class,
+						      &conf->channel);
 			center_chan = wpas_p2p_get_vht80_center(wpa_s, mode,
-								channel);
+								channel,
+								conf->op_class);
 			wpa_printf(MSG_DEBUG,
 				   "VHT center channel %u for auto-selected 80 MHz bandwidth",
 				   center_chan);
@@ -225,13 +258,79 @@
 }
 #endif
 
+#ifdef CONFIG_P2P
+
+static int get_max_oper_chwidth_6ghz(int chwidth)
+{
+	switch (chwidth) {
+	case CHANWIDTH_USE_HT:
+		return 20;
+	case CHANWIDTH_40MHZ_6GHZ:
+		return 40;
+	case CHANWIDTH_80MHZ:
+		return 80;
+	case CHANWIDTH_80P80MHZ:
+	case CHANWIDTH_160MHZ:
+		return 160;
+	default:
+		return 0;
+	}
+}
+
+
+static void wpas_conf_ap_he_6ghz(struct wpa_supplicant *wpa_s,
+				 struct hostapd_hw_modes *mode,
+				 struct wpa_ssid *ssid,
+				 struct hostapd_config *conf)
+{
+	bool is_chanwidth_40_80, is_chanwidth_160;
+	int he_chanwidth;
+
+	he_chanwidth =
+		mode->he_capab[wpas_mode_to_ieee80211_mode(
+			ssid->mode)].phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX];
+	is_chanwidth_40_80 = he_chanwidth &
+		HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G;
+	is_chanwidth_160 = he_chanwidth &
+		HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G;
+
+	wpa_printf(MSG_DEBUG,
+		   "Enable HE support (p2p_group=%d he_chwidth_cap=%d)",
+		   ssid->p2p_group, he_chanwidth);
+
+	if (mode->he_capab[wpas_mode_to_ieee80211_mode(
+			    ssid->mode)].he_supported &&
+	    ssid->he)
+		conf->ieee80211ax = 1;
+
+	if (is_chanwidth_40_80 && ssid->p2p_group &&
+	    get_max_oper_chwidth_6ghz(ssid->max_oper_chwidth) >= 40) {
+		conf->secondary_channel =
+			wpas_p2p_get_sec_channel_offset_40mhz(
+				wpa_s, mode, conf->channel);
+		wpa_printf(MSG_DEBUG,
+			   "Secondary channel offset %d for P2P group",
+			   conf->secondary_channel);
+		if (ssid->max_oper_chwidth == CHANWIDTH_40MHZ_6GHZ)
+			ssid->max_oper_chwidth = CHANWIDTH_USE_HT;
+	}
+
+	if ((is_chanwidth_40_80 || is_chanwidth_160) && ssid->p2p_group &&
+	    get_max_oper_chwidth_6ghz(ssid->max_oper_chwidth) >= 80)
+		wpas_conf_ap_vht(wpa_s, ssid, conf, mode);
+}
+
+#endif /* CONFIG_P2P */
+
+
 int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s,
 			      struct wpa_ssid *ssid,
 			      struct hostapd_config *conf)
 {
-	conf->hw_mode = ieee80211_freq_to_chan(ssid->frequency,
-					       &conf->channel);
-
+	conf->hw_mode = ieee80211_freq_to_channel_ext(ssid->frequency, 0,
+						      CHANWIDTH_USE_HT,
+						      &conf->op_class,
+						      &conf->channel);
 	if (conf->hw_mode == NUM_HOSTAPD_MODES) {
 		wpa_printf(MSG_ERROR, "Unsupported AP mode frequency: %d MHz",
 			   ssid->frequency);
@@ -272,7 +371,8 @@
 			   "Determining HT/VHT options based on driver capabilities (freq=%u chan=%u)",
 			   ssid->frequency, conf->channel);
 
-		mode = wpa_supplicant_find_hw_mode(wpa_s, conf->hw_mode);
+		mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
+				conf->hw_mode, is_6ghz_freq(ssid->frequency));
 
 		/* May drop to IEEE 802.11b if the driver does not support IEEE
 		 * 802.11g */
@@ -303,7 +403,12 @@
 			no_ht = 1;
 		}
 
-		if (!no_ht && mode && mode->ht_capab) {
+		if (mode && is_6ghz_freq(ssid->frequency) &&
+		    conf->hw_mode == HOSTAPD_MODE_IEEE80211A) {
+#ifdef CONFIG_P2P
+			wpas_conf_ap_he_6ghz(wpa_s, mode, ssid, conf);
+#endif /* CONFIG_P2P */
+		} else if (!no_ht && mode && mode->ht_capab) {
 			wpa_printf(MSG_DEBUG,
 				   "Enable HT support (p2p_group=%d 11a=%d ht40_hw_capab=%d ssid->ht40=%d)",
 				   ssid->p2p_group,
@@ -327,11 +432,21 @@
 			     HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) &&
 			    ssid->ht40) {
 				conf->secondary_channel =
-					wpas_p2p_get_ht40_mode(wpa_s, mode,
-							       conf->channel);
+					wpas_p2p_get_sec_channel_offset_40mhz(
+						wpa_s, mode, conf->channel);
 				wpa_printf(MSG_DEBUG,
 					   "HT secondary channel offset %d for P2P group",
 					   conf->secondary_channel);
+			} else if (ssid->p2p_group && conf->secondary_channel &&
+				   conf->hw_mode != HOSTAPD_MODE_IEEE80211A) {
+				/* This ended up trying to configure invalid
+				 * 2.4 GHz channels (e.g., HT40+ on channel 11)
+				 * in some cases, so clear the secondary channel
+				 * configuration now to avoid such cases that
+				 * would lead to group formation failures. */
+				wpa_printf(MSG_DEBUG,
+					   "Disable HT secondary channel for P2P group on 2.4 GHz");
+				conf->secondary_channel = 0;
 			}
 #endif /* CONFIG_P2P */
 
@@ -341,7 +456,7 @@
 			     /* Fix to resolve softap creation failure on 5G/80 */
 			     HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) &&
 			     ssid->ht40) {
-				conf->secondary_channel = wpas_p2p_get_ht40_mode(wpa_s, mode,
+				conf->secondary_channel = wpas_p2p_get_sec_channel_offset_40mhz(wpa_s, mode,
                                                                  conf->channel);
 #else /* CONFIG_CY_AUTO_SET_BW */
 			     HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) {
@@ -576,7 +691,13 @@
 		bss->sae_passwords = pw;
 	}
 
-	bss->sae_pwe = wpa_s->conf->sae_pwe;
+	if (ssid->sae_pwe != DEFAULT_SAE_PWE)
+		bss->sae_pwe = ssid->sae_pwe;
+	else
+		bss->sae_pwe = wpa_s->conf->sae_pwe;
+	/* Refer commit 587411dd62: Fix for PMK expiration issue through
+	 * supplicant
+	 */
 	bss->dot11RSNAConfigPMKLifetime = wpa_s->conf->dot11RSNAConfigPMKLifetime;
 #endif /* CONFIG_SAE */
 
@@ -745,6 +866,10 @@
 		bss->vendor_elements =
 			wpabuf_dup(wpa_s->conf->ap_vendor_elements);
 	}
+	if (wpa_s->conf->ap_assocresp_elements) {
+		bss->assocresp_elements =
+			wpabuf_dup(wpa_s->conf->ap_assocresp_elements);
+	}
 
 	bss->ftm_responder = wpa_s->conf->ftm_responder;
 	bss->ftm_initiator = wpa_s->conf->ftm_initiator;
@@ -894,10 +1019,6 @@
 	struct hostapd_iface *hapd_iface;
 	struct hostapd_config *conf;
 	size_t i;
-#if !defined(HOSTAPD)
-	struct wpa_global *global;
-	struct wpa_supplicant *wpa_last;
-#endif /* !HOSTAPD && CONFIG_DRIVER_NL80211_IFX */
 #ifdef CONFIG_CY_AUTO_SET_BW
 	/* Fix to create supplicant based softap on best channel
 	instead of random channel when specifying freq=2 or freq=5 */
@@ -942,10 +1063,6 @@
 		return -1;
 	hapd_iface->owner = wpa_s;
 	hapd_iface->drv_flags = wpa_s->drv_flags;
-	/* Support for 4-way handshake offload to internal supplicant
-	 * for WPA/WPA2-PSK
-	 */
-	hapd_iface->drv_flags2 = wpa_s->drv_flags2;
 	hapd_iface->probe_resp_offloads = wpa_s->probe_resp_offloads;
 	hapd_iface->extended_capa = wpa_s->extended_capa;
 	hapd_iface->extended_capa_mask = wpa_s->extended_capa_mask;
@@ -996,6 +1113,8 @@
 	params.wpa_proto = ssid->proto;
 	if (ssid->key_mgmt & WPA_KEY_MGMT_PSK)
 		wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
+	else if (ssid->key_mgmt & WPA_KEY_MGMT_SAE)
+		wpa_s->key_mgmt = WPA_KEY_MGMT_SAE;
 	else
 		wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
 	params.key_mgmt_suite = wpa_s->key_mgmt;
@@ -1138,27 +1257,6 @@
 	}
 #endif /* CONFIG_P2P && CONFIG_ACS */
 
-#if !defined(HOSTAPD)
-	if (!wpa_s->global->rsdb_flag) {
-		global = wpa_s->global;
-		for (wpa_last = global->ifaces; wpa_last; wpa_last = wpa_last->next)
-			if (os_strcmp(wpa_s->ifname, wpa_last->ifname) == 0 ||
-				os_strcmp(wpa_last->ifname, "wlan0") == 0 ||
-				os_strcmp(wpa_last->ifname, "p2p-dev-wlan0") == 0)
-				continue;
-			else if (wpa_last->ap_iface->bss != NULL &&
-					wpa_last->ap_iface->bss[0]->num_sta > 0) {
-					ssid = wpa_config_get_network(wpa_s->conf, 0);
-					if (ssid == NULL)
-						return;
-					if (ssid->disabled == 2)
-						return;
-					wpa_supplicant_disable_network(wpa_s, ssid);
-					return -1;
-			}
-	}
-#endif /* !HOSTAPD && CONFIG_DRIVER_NL80211_IFX */
-
 	if (hostapd_setup_interface(wpa_s->ap_iface)) {
 		wpa_printf(MSG_ERROR, "Failed to initialize AP interface");
 		wpa_supplicant_ap_deinit(wpa_s);
@@ -1869,6 +1967,32 @@
 #endif /* CONFIG_MESH */
 #endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
 
+
+int wpas_ap_update_beacon(struct wpa_supplicant *wpa_s)
+{
+	struct hostapd_data *hapd;
+
+	if (!wpa_s->ap_iface)
+		return -1;
+	hapd = wpa_s->ap_iface->bss[0];
+
+	wpabuf_free(hapd->conf->assocresp_elements);
+	hapd->conf->assocresp_elements = NULL;
+	if (wpa_s->conf->ap_assocresp_elements) {
+		hapd->conf->assocresp_elements =
+			wpabuf_dup(wpa_s->conf->ap_assocresp_elements);
+	}
+
+	wpabuf_free(hapd->conf->vendor_elements);
+	hapd->conf->vendor_elements = NULL;
+	if (wpa_s->conf->ap_vendor_elements) {
+		hapd->conf->vendor_elements =
+			wpabuf_dup(wpa_s->conf->ap_vendor_elements);
+	}
+
+	return ieee802_11_set_beacon(hapd);
+}
+
 #endif /* CONFIG_CTRL_IFACE */
 
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ap.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ap.h
index caff3a2..aef9b93 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ap.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ap.h
@@ -88,6 +88,7 @@
 int wpas_ap_pmksa_cache_list_mesh(struct wpa_supplicant *wpa_s, const u8 *addr,
 				  char *buf, size_t len);
 int wpas_ap_pmksa_cache_add_external(struct wpa_supplicant *wpa_s, char *cmd);
+int wpas_ap_update_beacon(struct wpa_supplicant *wpa_s);
 
 void wpas_ap_event_dfs_radar_detected(struct wpa_supplicant *wpa_s,
 				      struct dfs_event *radar);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/bss.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/bss.c
index e9c2f82..3610aae 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/bss.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/bss.c
@@ -19,18 +19,6 @@
 #include "scan.h"
 #include "bss.h"
 
-
-#define WPA_BSS_FREQ_CHANGED_FLAG	BIT(0)
-#define WPA_BSS_SIGNAL_CHANGED_FLAG	BIT(1)
-#define WPA_BSS_PRIVACY_CHANGED_FLAG	BIT(2)
-#define WPA_BSS_MODE_CHANGED_FLAG	BIT(3)
-#define WPA_BSS_WPAIE_CHANGED_FLAG	BIT(4)
-#define WPA_BSS_RSNIE_CHANGED_FLAG	BIT(5)
-#define WPA_BSS_WPS_CHANGED_FLAG	BIT(6)
-#define WPA_BSS_RATES_CHANGED_FLAG	BIT(7)
-#define WPA_BSS_IES_CHANGED_FLAG	BIT(8)
-
-
 static void wpa_bss_set_hessid(struct wpa_bss *bss)
 {
 #ifdef CONFIG_INTERWORKING
@@ -463,6 +451,9 @@
 	os_memcpy(bss->ssid, ssid, ssid_len);
 	bss->ssid_len = ssid_len;
 	bss->ie_len = res->ie_len;
+#if defined(WAPI_ANDROID)
+        bss->wapi_ie_len = res->wapi_ie_len;
+#endif
 	bss->beacon_ie_len = res->beacon_ie_len;
 	os_memcpy(bss->ies, res + 1, res->ie_len + res->beacon_ie_len);
 	wpa_bss_set_hessid(bss);
@@ -588,8 +579,8 @@
 }
 
 
-static void notify_bss_changes(struct wpa_supplicant *wpa_s, u32 changes,
-			       const struct wpa_bss *bss)
+void notify_bss_changes(struct wpa_supplicant *wpa_s, u32 changes,
+			const struct wpa_bss *bss)
 {
 	if (changes & WPA_BSS_FREQ_CHANGED_FLAG)
 		wpas_notify_bss_freq_changed(wpa_s, bss->id);
@@ -1390,6 +1381,8 @@
 
 int wpa_bss_ext_capab(const struct wpa_bss *bss, unsigned int capab)
 {
+	if (!bss)
+		return 0;
 	return ieee802_11_ext_capab(wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB),
 				    capab);
 }
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/bss.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/bss.h
index af82ca3..64bd287 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/bss.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/bss.h
@@ -20,6 +20,16 @@
 #define WPA_BSS_ANQP_FETCH_TRIED	BIT(6)
 #define WPA_BSS_OWE_TRANSITION		BIT(7)
 
+#define WPA_BSS_FREQ_CHANGED_FLAG	BIT(0)
+#define WPA_BSS_SIGNAL_CHANGED_FLAG	BIT(1)
+#define WPA_BSS_PRIVACY_CHANGED_FLAG	BIT(2)
+#define WPA_BSS_MODE_CHANGED_FLAG	BIT(3)
+#define WPA_BSS_WPAIE_CHANGED_FLAG	BIT(4)
+#define WPA_BSS_RSNIE_CHANGED_FLAG	BIT(5)
+#define WPA_BSS_WPS_CHANGED_FLAG	BIT(6)
+#define WPA_BSS_RATES_CHANGED_FLAG	BIT(7)
+#define WPA_BSS_IES_CHANGED_FLAG	BIT(8)
+
 struct wpa_bss_anqp_elem {
 	struct dl_list list;
 	u16 infoid;
@@ -110,6 +120,9 @@
 	size_t ie_len;
 	/** Length of the following Beacon IE field in octets */
 	size_t beacon_ie_len;
+#if defined(WAPI_ANDROID)
+	size_t wapi_ie_len;
+#endif 
 	/* followed by ie_len octets of IEs */
 	/* followed by beacon_ie_len octets of IEs */
 	u8 ies[];
@@ -120,6 +133,8 @@
 	return bss->ies;
 }
 
+void notify_bss_changes(struct wpa_supplicant *wpa_s, u32 changes,
+			const struct wpa_bss *bss);
 void wpa_bss_update_start(struct wpa_supplicant *wpa_s);
 void wpa_bss_update_scan_res(struct wpa_supplicant *wpa_s,
 			     struct wpa_scan_res *res,
@@ -177,7 +192,7 @@
 
 static inline void wpa_bss_update_level(struct wpa_bss *bss, int new_level)
 {
-	if (bss != NULL && new_level < 0)
+	if (bss != NULL && new_level > -WPA_INVALID_NOISE && new_level < 0)
 		bss->level = new_level;
 }
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/bssid_ignore.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/bssid_ignore.c
new file mode 100755
index 0000000..e378577
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/bssid_ignore.c
@@ -0,0 +1,221 @@
+/*
+ * wpa_supplicant - List of temporarily ignored BSSIDs
+ * Copyright (c) 2003-2021, Jouni Malinen <j@w1.fi>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "wpa_supplicant_i.h"
+#include "bssid_ignore.h"
+
+/**
+ * wpa_bssid_ignore_get - Get the ignore list entry for a BSSID
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @bssid: BSSID
+ * Returns: Matching entry for the BSSID or %NULL if not found
+ */
+struct wpa_bssid_ignore * wpa_bssid_ignore_get(struct wpa_supplicant *wpa_s,
+					       const u8 *bssid)
+{
+	struct wpa_bssid_ignore *e;
+
+	if (wpa_s == NULL || bssid == NULL)
+		return NULL;
+
+	if (wpa_s->current_ssid &&
+	    wpa_s->current_ssid->was_recently_reconfigured) {
+		wpa_bssid_ignore_clear(wpa_s);
+		wpa_s->current_ssid->was_recently_reconfigured = false;
+		return NULL;
+	}
+
+	wpa_bssid_ignore_update(wpa_s);
+
+	e = wpa_s->bssid_ignore;
+	while (e) {
+		if (os_memcmp(e->bssid, bssid, ETH_ALEN) == 0)
+			return e;
+		e = e->next;
+	}
+
+	return NULL;
+}
+
+
+/**
+ * wpa_bssid_ignore_add - Add an BSSID to the ignore list
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @bssid: BSSID to be added to the ignore list
+ * Returns: Current ignore list count on success, -1 on failure
+ *
+ * This function adds the specified BSSID to the ignore list or increases the
+ * ignore count if the BSSID was already listed. It should be called when
+ * an association attempt fails either due to the selected BSS rejecting
+ * association or due to timeout.
+ *
+ * This ignore list is used to force %wpa_supplicant to go through all available
+ * BSSes before retrying to associate with an BSS that rejected or timed out
+ * association. It does not prevent the listed BSS from being used; it only
+ * changes the order in which they are tried.
+ */
+int wpa_bssid_ignore_add(struct wpa_supplicant *wpa_s, const u8 *bssid)
+{
+	struct wpa_bssid_ignore *e;
+	struct os_reltime now;
+
+	if (wpa_s == NULL || bssid == NULL)
+		return -1;
+
+	e = wpa_bssid_ignore_get(wpa_s, bssid);
+	os_get_reltime(&now);
+	if (e) {
+		e->start = now;
+		e->count++;
+		if (e->count > 5)
+			e->timeout_secs = 1800;
+		else if (e->count == 5)
+			e->timeout_secs = 600;
+		else if (e->count == 4)
+			e->timeout_secs = 120;
+		else if (e->count == 3)
+			e->timeout_secs = 60;
+		else
+			e->timeout_secs = 10;
+		wpa_printf(MSG_INFO, "BSSID " MACSTR
+			   " ignore list count incremented to %d, ignoring for %d seconds",
+			   MAC2STR(bssid), e->count, e->timeout_secs);
+		return e->count;
+	}
+
+	e = os_zalloc(sizeof(*e));
+	if (e == NULL)
+		return -1;
+	os_memcpy(e->bssid, bssid, ETH_ALEN);
+	e->count = 1;
+	e->timeout_secs = 10;
+	e->start = now;
+	e->next = wpa_s->bssid_ignore;
+	wpa_s->bssid_ignore = e;
+	wpa_printf(MSG_DEBUG, "Added BSSID " MACSTR
+		   " into ignore list, ignoring for %d seconds",
+		   MAC2STR(bssid), e->timeout_secs);
+
+	return e->count;
+}
+
+
+/**
+ * wpa_bssid_ignore_del - Remove an BSSID from the ignore list
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @bssid: BSSID to be removed from the ignore list
+ * Returns: 0 on success, -1 on failure
+ */
+int wpa_bssid_ignore_del(struct wpa_supplicant *wpa_s, const u8 *bssid)
+{
+	struct wpa_bssid_ignore *e, *prev = NULL;
+
+	if (wpa_s == NULL || bssid == NULL)
+		return -1;
+
+	e = wpa_s->bssid_ignore;
+	while (e) {
+		if (os_memcmp(e->bssid, bssid, ETH_ALEN) == 0) {
+			if (prev == NULL) {
+				wpa_s->bssid_ignore = e->next;
+			} else {
+				prev->next = e->next;
+			}
+			wpa_printf(MSG_DEBUG, "Removed BSSID " MACSTR
+				   " from ignore list", MAC2STR(bssid));
+			os_free(e);
+			return 0;
+		}
+		prev = e;
+		e = e->next;
+	}
+	return -1;
+}
+
+
+/**
+ * wpa_bssid_ignore_is_listed - Check whether a BSSID is ignored temporarily
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @bssid: BSSID to be checked
+ * Returns: count if BSS is currently considered to be ignored, 0 otherwise
+ */
+int wpa_bssid_ignore_is_listed(struct wpa_supplicant *wpa_s, const u8 *bssid)
+{
+	struct wpa_bssid_ignore *e;
+	struct os_reltime now;
+
+	e = wpa_bssid_ignore_get(wpa_s, bssid);
+	if (!e)
+		return 0;
+	os_get_reltime(&now);
+	if (os_reltime_expired(&now, &e->start, e->timeout_secs))
+		return 0;
+	return e->count;
+}
+
+
+/**
+ * wpa_bssid_ignore_clear - Clear the ignore list of all entries
+ * @wpa_s: Pointer to wpa_supplicant data
+ */
+void wpa_bssid_ignore_clear(struct wpa_supplicant *wpa_s)
+{
+	struct wpa_bssid_ignore *e, *prev;
+
+	e = wpa_s->bssid_ignore;
+	wpa_s->bssid_ignore = NULL;
+	while (e) {
+		prev = e;
+		e = e->next;
+		wpa_printf(MSG_DEBUG, "Removed BSSID " MACSTR
+			   " from ignore list (clear)", MAC2STR(prev->bssid));
+		os_free(prev);
+	}
+}
+
+
+/**
+ * wpa_bssid_ignore_update - Update the entries in the ignore list,
+ * deleting entries that have been expired for over an hour.
+ * @wpa_s: Pointer to wpa_supplicant data
+ */
+void wpa_bssid_ignore_update(struct wpa_supplicant *wpa_s)
+{
+	struct wpa_bssid_ignore *e, *prev = NULL;
+	struct os_reltime now;
+
+	if (!wpa_s)
+		return;
+
+	e = wpa_s->bssid_ignore;
+	os_get_reltime(&now);
+	while (e) {
+		if (os_reltime_expired(&now, &e->start,
+				       e->timeout_secs + 3600)) {
+			struct wpa_bssid_ignore *to_delete = e;
+
+			if (prev) {
+				prev->next = e->next;
+				e = prev->next;
+			} else {
+				wpa_s->bssid_ignore = e->next;
+				e = wpa_s->bssid_ignore;
+			}
+			wpa_printf(MSG_INFO, "Removed BSSID " MACSTR
+				   " from ignore list (expired)",
+				   MAC2STR(to_delete->bssid));
+			os_free(to_delete);
+		} else {
+			prev = e;
+			e = e->next;
+		}
+	}
+}
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/bssid_ignore.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/bssid_ignore.h
new file mode 100755
index 0000000..721b0e1
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/bssid_ignore.h
@@ -0,0 +1,33 @@
+/*
+ * wpa_supplicant - List of temporarily ignored BSSIDs
+ * Copyright (c) 2003-2021, Jouni Malinen <j@w1.fi>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef BSSID_IGNORE_H
+#define BSSID_IGNORE_H
+
+struct wpa_bssid_ignore {
+	struct wpa_bssid_ignore *next;
+	u8 bssid[ETH_ALEN];
+	int count;
+	/* Time of the most recent trigger to ignore this BSSID. */
+	struct os_reltime start;
+	/*
+	 * Number of seconds after start that the entey will be considered
+	 * valid.
+	 */
+	int timeout_secs;
+};
+
+struct wpa_bssid_ignore * wpa_bssid_ignore_get(struct wpa_supplicant *wpa_s,
+					 const u8 *bssid);
+int wpa_bssid_ignore_add(struct wpa_supplicant *wpa_s, const u8 *bssid);
+int wpa_bssid_ignore_del(struct wpa_supplicant *wpa_s, const u8 *bssid);
+int wpa_bssid_ignore_is_listed(struct wpa_supplicant *wpa_s, const u8 *bssid);
+void wpa_bssid_ignore_clear(struct wpa_supplicant *wpa_s);
+void wpa_bssid_ignore_update(struct wpa_supplicant *wpa_s);
+
+#endif /* BSSID_IGNORE_H */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/config.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/config.c
index 53f941e..aa53695 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/config.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/config.c
@@ -454,47 +454,99 @@
 #endif /* NO_CONFIG_WRITE */
 
 
+static int wpa_config_parse_bssid_ignore(const struct parse_data *data,
+					 struct wpa_ssid *ssid, int line,
+					 const char *value)
+{
+	return wpa_config_parse_addr_list(data, line, value,
+					  &ssid->bssid_ignore,
+					  &ssid->num_bssid_ignore,
+					  "bssid_ignore", 1, 1);
+}
+
+
+/* deprecated alias for bssid_ignore for backwards compatibility */
 static int wpa_config_parse_bssid_blacklist(const struct parse_data *data,
 					    struct wpa_ssid *ssid, int line,
 					    const char *value)
 {
 	return wpa_config_parse_addr_list(data, line, value,
-					  &ssid->bssid_blacklist,
-					  &ssid->num_bssid_blacklist,
-					  "bssid_blacklist", 1, 1);
+					  &ssid->bssid_ignore,
+					  &ssid->num_bssid_ignore,
+					  "bssid_ignore", 1, 1);
 }
 
 
 #ifndef NO_CONFIG_WRITE
+
+static char * wpa_config_write_bssid_ignore(const struct parse_data *data,
+					    struct wpa_ssid *ssid)
+{
+	return wpa_config_write_addr_list(data, ssid->bssid_ignore,
+					  ssid->num_bssid_ignore,
+					  "bssid_ignore");
+}
+
+
+/* deprecated alias for bssid_ignore for backwards compatibility */
 static char * wpa_config_write_bssid_blacklist(const struct parse_data *data,
 					       struct wpa_ssid *ssid)
 {
-	return wpa_config_write_addr_list(data, ssid->bssid_blacklist,
-					  ssid->num_bssid_blacklist,
-					  "bssid_blacklist");
+	return wpa_config_write_addr_list(data, ssid->bssid_ignore,
+					  ssid->num_bssid_ignore,
+					  "bssid_ignore");
 }
+
 #endif /* NO_CONFIG_WRITE */
 
 
+static int wpa_config_parse_bssid_accept(const struct parse_data *data,
+					 struct wpa_ssid *ssid, int line,
+					 const char *value)
+{
+	return wpa_config_parse_addr_list(data, line, value,
+					  &ssid->bssid_accept,
+					  &ssid->num_bssid_accept,
+					  "bssid_accept", 1, 1);
+}
+
+
+/* deprecated alias for bssid_accept for backwards compatibility */
 static int wpa_config_parse_bssid_whitelist(const struct parse_data *data,
 					    struct wpa_ssid *ssid, int line,
 					    const char *value)
 {
 	return wpa_config_parse_addr_list(data, line, value,
-					  &ssid->bssid_whitelist,
-					  &ssid->num_bssid_whitelist,
-					  "bssid_whitelist", 1, 1);
+					  &ssid->bssid_accept,
+					  &ssid->num_bssid_accept,
+					  "bssid_accept", 1, 1);
 }
 
 
 #ifndef NO_CONFIG_WRITE
+
+static char * wpa_config_write_bssid_accept(const struct parse_data *data,
+					    struct wpa_ssid *ssid)
+{
+	return wpa_config_write_addr_list(data, ssid->bssid_accept,
+					  ssid->num_bssid_accept,
+					  "bssid_accept");
+}
+
+
+/* deprecated alias for bssid_accept for backwards compatibility */
 static char * wpa_config_write_bssid_whitelist(const struct parse_data *data,
 					       struct wpa_ssid *ssid)
 {
-	return wpa_config_write_addr_list(data, ssid->bssid_whitelist,
-					  ssid->num_bssid_whitelist,
-					  "bssid_whitelist");
+	return wpa_config_write_addr_list(data, ssid->bssid_accept,
+					  ssid->num_bssid_accept,
+					  "bssid_accept");
 }
+
+#endif /* NO_CONFIG_WRITE */
+
+
+#ifndef NO_CONFIG_WRITE
 #endif /* NO_CONFIG_WRITE */
 
 
@@ -639,6 +691,12 @@
 			val |= WPA_PROTO_RSN;
 		else if (os_strcmp(start, "OSEN") == 0)
 			val |= WPA_PROTO_OSEN;
+#if defined(WAPI_ANDROID)
+		else if (os_strcmp(start, "WAPI") == 0) {
+			val |= WPA_PROTO_WAPI;
+			wpa_printf(MSG_DEBUG, "WAPI network\n");
+		}
+#endif 
 		else {
 			wpa_printf(MSG_ERROR, "Line %d: invalid proto '%s'",
 				   line, start);
@@ -701,6 +759,14 @@
 		pos += ret;
 	}
 
+#if defined(WAPI_ANDROID)
+	if (ssid->proto & WPA_PROTO_WAPI) {
+		ret = os_snprintf(pos, end - pos, "%sWAPI", pos == buf ? "" : " ");
+		if (ret < 0 || ret >= end - pos)
+			return buf;
+		pos += ret;
+	}
+#endif 
 	if (pos == buf) {
 		os_free(buf);
 		buf = NULL;
@@ -743,6 +809,13 @@
 			val |= WPA_KEY_MGMT_NONE;
 		else if (os_strcmp(start, "WPA-NONE") == 0)
 			val |= WPA_KEY_MGMT_WPA_NONE;
+#if defined(WAPI_ANDROID)
+		else if (os_strcmp(start, "WAPI-PSK") == 0)
+			val |= WPA_KEY_MGMT_WAPI_PSK;
+		else if (os_strcmp(start, "WAPI-CERT") == 0) {
+			val |= WPA_KEY_MGMT_WAPI_CERT;
+		}
+#endif 
 #ifdef CONFIG_IEEE80211R
 		else if (os_strcmp(start, "FT-PSK") == 0)
 			val |= WPA_KEY_MGMT_FT_PSK;
@@ -821,6 +894,16 @@
 		return 1;
 	wpa_printf(MSG_MSGDUMP, "key_mgmt: 0x%x", val);
 	ssid->key_mgmt = val;
+#if defined(WAPI_ANDROID)
+	if ( (ssid->key_mgmt & WPA_KEY_MGMT_WAPI_PSK) && (ssid->wapi != 7) ) {
+		ssid->wapi = 7;
+	        wpa_printf(MSG_DEBUG, "WPA_KEY_MGMT_WAPI_PSK");
+	}
+	if ( (ssid->key_mgmt & WPA_KEY_MGMT_WAPI_CERT) && (ssid->wapi != 11) ) {
+		ssid->wapi = 11;
+		wpa_printf(MSG_DEBUG, "WPA_KEY_MGMT_WAPI_CERT");
+	}
+#endif 
 	return errors ? -1 : 0;
 }
 
@@ -886,6 +969,26 @@
 		}
 		pos += ret;
 	}
+#if defined(WAPI_ANDROID)
+	if (ssid->key_mgmt & WPA_KEY_MGMT_WAPI_PSK) {
+		ret = os_snprintf(pos, end - pos, "%sWAPI-PSK",
+				  pos == buf ? "" : " ");
+		if (ret < 0 || ret >= end - pos) {
+			end[-1] = '\0';
+			return buf;
+		}
+		pos += ret;
+	}
+	if (ssid->key_mgmt & WPA_KEY_MGMT_WAPI_CERT) {
+		ret = os_snprintf(pos, end - pos, "%sWAPI-CERT",
+				  pos == buf ? "" : " ");
+		if (ret < 0 || ret >= end - pos) {
+			end[-1] = '\0';
+			return buf;
+		}
+		pos += ret;
+	}
+#endif 
 
 #ifdef CONFIG_IEEE80211R
 	if (ssid->key_mgmt & WPA_KEY_MGMT_FT_PSK) {
@@ -1136,7 +1239,12 @@
 	val = wpa_config_parse_cipher(line, value);
 	if (val == -1)
 		return -1;
+#if defined(WAPI_ANDROID)
+	if (val & ~(WPA_CIPHER_CCMP | WPA_CIPHER_GCMP | WPA_CIPHER_TKIP | 
+		    WPA_CIPHER_NONE | WPA_CIPHER_SMS4)) {
+#else
 	if (val & ~WPA_ALLOWED_PAIRWISE_CIPHERS) {
+#endif 
 		wpa_printf(MSG_ERROR, "Line %d: not allowed pairwise cipher "
 			   "(0x%x).", line, val);
 		return -1;
@@ -1167,6 +1275,10 @@
 	val = wpa_config_parse_cipher(line, value);
 	if (val == -1)
 		return -1;
+#if defined(WAPI_ANDROID)
+	if (val & ~(WPA_CIPHER_CCMP | WPA_CIPHER_GCMP | WPA_CIPHER_TKIP |
+		    WPA_CIPHER_WEP104 | WPA_CIPHER_WEP40 | WPA_CIPHER_SMS4)) {
+#else
 
 	/*
 	 * Backwards compatibility - filter out WEP ciphers that were previously
@@ -1175,6 +1287,7 @@
 	val &= ~(WPA_CIPHER_WEP104 | WPA_CIPHER_WEP40);
 
 	if (val & ~WPA_ALLOWED_GROUP_CIPHERS) {
+#endif 
 		wpa_printf(MSG_ERROR, "Line %d: not allowed group cipher "
 			   "(0x%x).", line, val);
 		return -1;
@@ -2374,8 +2487,10 @@
 	{ INT_RANGE(scan_ssid, 0, 1) },
 	{ FUNC(bssid) },
 	{ FUNC(bssid_hint) },
-	{ FUNC(bssid_blacklist) },
-	{ FUNC(bssid_whitelist) },
+	{ FUNC(bssid_ignore) },
+	{ FUNC(bssid_accept) },
+	{ FUNC(bssid_blacklist) }, /* deprecated alias for bssid_ignore */
+	{ FUNC(bssid_whitelist) }, /* deprecated alias for bssid_accept */
 	{ FUNC_KEY(psk) },
 	{ INT(mem_only_psk) },
 	{ STR_KEY(sae_password) },
@@ -2389,6 +2504,14 @@
 	{ FUNC(auth_alg) },
 	{ FUNC(scan_freq) },
 	{ FUNC(freq_list) },
+#if defined(WAPI_ANDROID)
+	{ INT(wapi) },
+	{ INT(psk_key_type) },
+	{ INT(cert_index) },
+	{ STR(wapi_user_cert) },
+	{ STR(wapi_as_cert) },
+	{ STR(cert_name) },
+#endif 
 	{ INT_RANGE(ht, 0, 1) },
 	{ INT_RANGE(vht, 0, 1) },
 	{ INT_RANGE(ht40, -1, 1) },
@@ -2485,6 +2608,7 @@
 #ifdef CONFIG_MESH
 	{ INT_RANGE(mode, 0, 5) },
 	{ INT_RANGE(no_auto_peer, 0, 1) },
+	{ INT_RANGE(mesh_fwding, 0, 1) },
 	{ INT_RANGE(mesh_rssi_threshold, -255, 1) },
 #else /* CONFIG_MESH */
 	{ INT_RANGE(mode, 0, 4) },
@@ -2596,7 +2720,9 @@
 	{ INT_RANGE(beacon_prot, 0, 1) },
 	{ INT_RANGE(transition_disable, 0, 255) },
 	{ INT_RANGE(sae_pk, 0, 2) },
-	/* Refer commit ed56a660: Suppress deauth for PMKSA caching disabled */
+	/* Refer commit 09f46ec2: wpa_supplicant: suppress deauth
+	 * for PMKSA caching disabled
+	 */
 	{ INT_RANGE(suppress_deauth_no_pmksa, 0, 1) },
 };
 
@@ -2776,9 +2902,14 @@
 	os_free(ssid->scan_freq);
 	os_free(ssid->freq_list);
 	os_free(ssid->bgscan);
+#if defined(WAPI_ANDROID)
+	os_free(ssid->cert_name);
+	os_free(ssid->wapi_user_cert);
+	os_free(ssid->wapi_as_cert);
+#endif 
 	os_free(ssid->p2p_client_list);
-	os_free(ssid->bssid_blacklist);
-	os_free(ssid->bssid_whitelist);
+	os_free(ssid->bssid_ignore);
+	os_free(ssid->bssid_accept);
 #ifdef CONFIG_HT_OVERRIDES
 	os_free(ssid->ht_mcs);
 #endif /* CONFIG_HT_OVERRIDES */
@@ -2815,6 +2946,10 @@
 	os_free(cred->client_cert);
 	os_free(cred->private_key);
 	str_clear_free(cred->private_key_passwd);
+	os_free(cred->engine_id);
+	os_free(cred->ca_cert_id);
+	os_free(cred->cert_id);
+	os_free(cred->key_id);
 	os_free(cred->imsi);
 	str_clear_free(cred->milenage);
 	for (i = 0; i < cred->num_domain; i++)
@@ -2904,12 +3039,14 @@
 	os_free(config->p2p_no_go_freq.range);
 	os_free(config->autoscan);
 	os_free(config->freq_list);
+	os_free(config->initial_freq_list);
 	wpabuf_free(config->wps_nfc_dh_pubkey);
 	wpabuf_free(config->wps_nfc_dh_privkey);
 	wpabuf_free(config->wps_nfc_dev_pw);
 	os_free(config->ext_password_backend);
 	os_free(config->sae_groups);
 	wpabuf_free(config->ap_vendor_elements);
+	wpabuf_free(config->ap_assocresp_elements);
 	os_free(config->osu_dir);
 	os_free(config->bgscan);
 	os_free(config->wowlan_triggers);
@@ -3061,11 +3198,15 @@
 	ssid->eap.fragment_size = DEFAULT_FRAGMENT_SIZE;
 	ssid->eap.sim_num = DEFAULT_USER_SELECTED_SIM;
 #endif /* IEEE8021X_EAPOL */
+#if defined(WAPI_ANDROID)
+	ssid->wapi = 0;
+#endif 
 #ifdef CONFIG_MESH
 	ssid->dot11MeshMaxRetries = DEFAULT_MESH_MAX_RETRIES;
 	ssid->dot11MeshRetryTimeout = DEFAULT_MESH_RETRY_TIMEOUT;
 	ssid->dot11MeshConfirmTimeout = DEFAULT_MESH_CONFIRM_TIMEOUT;
 	ssid->dot11MeshHoldingTimeout = DEFAULT_MESH_HOLDING_TIMEOUT;
+	ssid->mesh_fwding = DEFAULT_MESH_FWDING;
 	ssid->mesh_rssi_threshold = DEFAULT_MESH_RSSI_THRESHOLD;
 #endif /* CONFIG_MESH */
 #ifdef CONFIG_HT_OVERRIDES
@@ -3099,6 +3240,7 @@
 #endif /* CONFIG_VHT_OVERRIDES */
 	ssid->proactive_key_caching = -1;
 	ssid->ieee80211w = MGMT_FRAME_PROTECTION_DEFAULT;
+	ssid->sae_pwe = DEFAULT_SAE_PWE;
 #ifdef CONFIG_MACSEC
 	ssid->mka_priority = DEFAULT_PRIO_NOT_KEY_SERVER;
 #endif /* CONFIG_MACSEC */
@@ -3143,6 +3285,23 @@
 			}
 			ret = -1;
 		}
+#if defined(WAPI_ANDROID)
+		else {
+			wpa_printf(MSG_DEBUG, "parse(%s, %s) succeeded\n", var, value);
+			if (os_strcmp(var, "wapi_as_cert") == 0) {
+				wpa_printf(MSG_DEBUG, "%s: ssid->wapi_as_cert=%s\n",
+					   __FUNCTION__, ssid->wapi_as_cert);
+			}
+			if (os_strcmp(var, "wapi_user_cert") == 0) {
+				wpa_printf(MSG_DEBUG, "%s: ssid->wapi_user_cert=%s\n",
+					   __FUNCTION__, ssid->wapi_user_cert);
+			}
+			if (os_strcmp(var, "cert_name") == 0) {
+                                wpa_printf(MSG_DEBUG, "%s: ssid->cert_name=%s\n",
+                                           __FUNCTION__, ssid->cert_name);
+                        }
+		}
+#endif 
 #ifdef CONFIG_SAE
 		if (os_strcmp(var, "ssid") == 0 ||
 		    os_strcmp(var, "psk") == 0 ||
@@ -3576,6 +3735,11 @@
 		return 0;
 	}
 
+	if (os_strcmp(var, "engine") == 0) {
+		cred->engine = atoi(value);
+		return 0;
+	}
+
 	val = wpa_config_parse_string(value, &len);
 	if (val == NULL ||
 	    (os_strcmp(var, "excluded_ssid") != 0 &&
@@ -3631,6 +3795,30 @@
 		return 0;
 	}
 
+	if (os_strcmp(var, "engine_id") == 0) {
+		os_free(cred->engine_id);
+		cred->engine_id = val;
+		return 0;
+	}
+
+	if (os_strcmp(var, "ca_cert_id") == 0) {
+		os_free(cred->ca_cert_id);
+		cred->ca_cert_id = val;
+		return 0;
+	}
+
+	if (os_strcmp(var, "cert_id") == 0) {
+		os_free(cred->cert_id);
+		cred->cert_id = val;
+		return 0;
+	}
+
+	if (os_strcmp(var, "key_id") == 0) {
+		os_free(cred->key_id);
+		cred->key_id = val;
+		return 0;
+	}
+
 	if (os_strcmp(var, "imsi") == 0) {
 		os_free(cred->imsi);
 		cred->imsi = val;
@@ -4307,6 +4495,7 @@
 	config->user_mpm = DEFAULT_USER_MPM;
 	config->max_peer_links = DEFAULT_MAX_PEER_LINKS;
 	config->mesh_max_inactivity = DEFAULT_MESH_MAX_INACTIVITY;
+	config->mesh_fwding = DEFAULT_MESH_FWDING;
 	config->dot11RSNASAERetransPeriod =
 		DEFAULT_DOT11_RSNA_SAE_RETRANS_PERIOD;
 	config->fast_reauth = DEFAULT_FAST_REAUTH;
@@ -4323,6 +4512,7 @@
 	config->ap_isolate = DEFAULT_AP_ISOLATE;
 	config->access_network_type = DEFAULT_ACCESS_NETWORK_TYPE;
 	config->scan_cur_freq = DEFAULT_SCAN_CUR_FREQ;
+	config->scan_res_valid_for_connect = DEFAULT_SCAN_RES_VALID_FOR_CONNECT;
 	config->wmm_ac_params[0] = ac_be;
 	config->wmm_ac_params[1] = ac_bk;
 	config->wmm_ac_params[2] = ac_vi;
@@ -4565,6 +4755,26 @@
 }
 
 
+static int
+wpa_config_process_initial_freq_list(const struct global_parse_data *data,
+				     struct wpa_config *config, int line,
+				     const char *value)
+{
+	int *freqs;
+
+	freqs = wpa_config_parse_int_array(value);
+	if (!freqs)
+		return -1;
+	if (freqs[0] == 0) {
+		os_free(freqs);
+		freqs = NULL;
+	}
+	os_free(config->initial_freq_list);
+	config->initial_freq_list = freqs;
+	return 0;
+}
+
+
 #ifdef CONFIG_P2P
 static int wpa_global_config_parse_ipv4(const struct global_parse_data *data,
 					struct wpa_config *config, int line,
@@ -4851,33 +5061,46 @@
 	struct wpa_config *config, int line, const char *pos)
 {
 	struct wpabuf *tmp;
-	int len = os_strlen(pos) / 2;
-	u8 *p;
 
-	if (!len) {
+	if (!*pos) {
+		wpabuf_free(config->ap_vendor_elements);
+		config->ap_vendor_elements = NULL;
+		return 0;
+	}
+
+	tmp = wpabuf_parse_bin(pos);
+	if (!tmp) {
 		wpa_printf(MSG_ERROR, "Line %d: invalid ap_vendor_elements",
 			   line);
 		return -1;
 	}
+	wpabuf_free(config->ap_vendor_elements);
+	config->ap_vendor_elements = tmp;
 
-	tmp = wpabuf_alloc(len);
-	if (tmp) {
-		p = wpabuf_put(tmp, len);
+	return 0;
+}
 
-		if (hexstr2bin(pos, p, len)) {
-			wpa_printf(MSG_ERROR, "Line %d: invalid "
-				   "ap_vendor_elements", line);
-			wpabuf_free(tmp);
-			return -1;
-		}
 
-		wpabuf_free(config->ap_vendor_elements);
-		config->ap_vendor_elements = tmp;
-	} else {
-		wpa_printf(MSG_ERROR, "Cannot allocate memory for "
-			   "ap_vendor_elements");
+static int wpa_config_process_ap_assocresp_elements(
+	const struct global_parse_data *data,
+	struct wpa_config *config, int line, const char *pos)
+{
+	struct wpabuf *tmp;
+
+	if (!*pos) {
+		wpabuf_free(config->ap_assocresp_elements);
+		config->ap_assocresp_elements = NULL;
+		return 0;
+	}
+
+	tmp = wpabuf_parse_bin(pos);
+	if (!tmp) {
+		wpa_printf(MSG_ERROR, "Line %d: invalid ap_assocresp_elements",
+			   line);
 		return -1;
 	}
+	wpabuf_free(config->ap_assocresp_elements);
+	config->ap_assocresp_elements = tmp;
 
 	return 0;
 }
@@ -4984,11 +5207,15 @@
 	{ INT_RANGE(eapol_version, 1, 2), 0 },
 #endif /* CONFIG_MACSEC */
 	{ INT(ap_scan), 0 },
+#ifdef CONFIG_TWT_OFFLOAD_IFX
+	{ INT_RANGE(twt_def_algo, 0 , 2), 0 },
+#endif /* CONFIG_TWT_OFFLOAD_IFX */
 	{ FUNC(bgscan), CFG_CHANGED_BGSCAN },
 #ifdef CONFIG_MESH
 	{ INT(user_mpm), 0 },
 	{ INT_RANGE(max_peer_links, 0, 255), 0 },
 	{ INT(mesh_max_inactivity), 0 },
+	{ INT_RANGE(mesh_fwding, 0, 1), 0 },
 	{ INT(dot11RSNASAERetransPeriod), 0 },
 #endif /* CONFIG_MESH */
 	{ INT(disable_scan_offload), 0 },
@@ -5101,10 +5328,13 @@
 	{ INT_RANGE(sae_pmkid_in_assoc, 0, 1), 0 },
 	{ INT(dtim_period), 0 },
 	{ INT(beacon_int), 0 },
+	{ FUNC(ap_assocresp_elements), 0 },
 	{ FUNC(ap_vendor_elements), 0 },
 	{ INT_RANGE(ignore_old_scan_res, 0, 1), 0 },
 	{ FUNC(freq_list), 0 },
+	{ FUNC(initial_freq_list), 0},
 	{ INT(scan_cur_freq), 0 },
+	{ INT(scan_res_valid_for_connect), 0},
 	{ INT(sched_scan_interval), 0 },
 	{ INT(sched_scan_start_delay), 0 },
 	{ INT(tdls_external_control), 0},
@@ -5160,6 +5390,13 @@
 	{ INT_RANGE(disable_btm, 0, 1), CFG_CHANGED_DISABLE_BTM },
 	{ INT_RANGE(extended_key_id, 0, 1), 0 },
 #endif /* CONFIG_WNM */
+	{ INT_RANGE(wowlan_disconnect_on_deinit, 0, 1), 0},
+#ifdef CONFIG_PASN
+#ifdef CONFIG_TESTING_OPTIONS
+	{ INT_RANGE(force_kdk_derivation, 0, 1), 0 },
+	{ INT_RANGE(pasn_corrupt_mic, 0, 1), 0 },
+#endif /* CONFIG_TESTING_OPTIONS */
+#endif /* CONFIG_PASN */
 #ifdef CONFIG_DRIVER_NL80211_BRCM
 	{INT(offload_4way_handshake), CFG_CHANGED_4WAY_HS},
 #endif /* CONFIG_DRIVER_NL80211_BRCM */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/config.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/config.h
index 66eee98..f580b0c 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/config.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/config.h
@@ -18,6 +18,7 @@
 #define DEFAULT_USER_MPM 1
 #define DEFAULT_MAX_PEER_LINKS 99
 #define DEFAULT_MESH_MAX_INACTIVITY 300
+#define DEFAULT_MESH_FWDING 1
 /*
  * The default dot11RSNASAERetransPeriod is defined as 40 ms in the standard,
  * but use 1000 ms in practice to avoid issues on low power CPUs.
@@ -45,9 +46,10 @@
 #define DEFAULT_DISASSOC_IMMINENT_RSSI_THRESHOLD -75
 #define DEFAULT_OCE_SUPPORT OCE_STA
 #define DEFAULT_EXTENDED_KEY_ID 0
+#define DEFAULT_SCAN_RES_VALID_FOR_CONNECT 5
 
 #ifdef CONFIG_BRCM_AUTOMOTIVE
-#define IS_5GHZ(n) (n > 4000)
+#define IS_5GHZ(n) (n > 4000 && n < 5895)
 #endif
 #include "config_ssid.h"
 #include "wps/wps.h"
@@ -182,6 +184,31 @@
 	char *milenage;
 
 	/**
+	 * engine - Use an engine for private key operations
+	 */
+	int engine;
+
+	/**
+	 * engine_id - String identifying the engine to use
+	 */
+	char *engine_id;
+
+	/**
+	 * ca_cert_id - The CA certificate identifier when using an engine
+	 */
+	char *ca_cert_id;
+
+	/**
+	 * cert_id - The certificate identifier when using an engine
+	 */
+	char *cert_id;
+
+	/**
+	 * key_id - The private key identifier when using an engine
+	 */
+	char *key_id;
+
+	/**
 	 * domain_suffix_match - Constraint for server domain name
 	 *
 	 * If set, this FQDN is used as a suffix match requirement for the AAA
@@ -472,6 +499,17 @@
 	 */
 	int ap_scan;
 
+#ifdef CONFIG_TWT_OFFLOAD_IFX
+	/**
+	 * twt_def_algo - Default (Auto) TWT profile
+	 *
+	 * This provides the value of the default TWT profile to be setup
+	 * Values for this or 0-disable, 1-idle profile, 2-active profile TWT
+	 * session
+	 */
+	int twt_def_algo;
+#endif /* CONFIG_TWT_OFFLOAD_IFX */
+
 	/**
 	 * bgscan - Background scan and roaming parameters or %NULL if none
 	 *
@@ -936,6 +974,19 @@
 	int *freq_list;
 
 	/**
+	 * initial_freq_list - like freq_list but for initial scan
+	 *
+	 * This is an optional zero-terminated array of frequencies in
+	 * megahertz (MHz) to allow for narrowing scanning range when
+	 * the application is started.
+	 *
+	 * This can be used to speed up initial connection time if the
+	 * channel is known ahead of time, without limiting the scanned
+	 * frequencies during normal use.
+	 */
+	int *initial_freq_list;
+
+	/**
 	 * scan_cur_freq - Whether to scan only the current channel
 	 *
 	 * If true, attempt to scan only the current channel if any other
@@ -944,6 +995,15 @@
 	int scan_cur_freq;
 
 	/**
+	 * scan_res_valid_for_connect - Seconds scans are valid for association
+	 *
+	 * This configures the number of seconds old scan results are considered
+	 * valid for association. When scan results are older than this value
+	 * a new scan is triggered prior to the association.
+	 */
+	int scan_res_valid_for_connect;
+
+	/**
 	 * changed_parameters - Bitmap of changed parameters since last update
 	 */
 	unsigned int changed_parameters;
@@ -1224,6 +1284,17 @@
 	struct wpabuf *ap_vendor_elements;
 
 	/**
+	 * ap_assocresp_elements: Vendor specific elements for (Re)Association
+	 * Response frames
+	 *
+	 * This parameter can be used to define additional vendor specific
+	 * elements for (Re)Association Response frames in AP/P2P GO mode. The
+	 * format for these element(s) is a hexdump of the raw information
+	 * elements (id+len+payload for one or more elements).
+	 */
+	struct wpabuf *ap_assocresp_elements;
+
+	/**
 	 * ignore_old_scan_res - Ignore scan results older than request
 	 *
 	 * The driver may have a cache of scan results that makes it return
@@ -1366,6 +1437,14 @@
 #endif /* CONFIG_BRCM_RSN_CNTRS */
 
 	/**
+	 * mesh_fwding - Mesh network layer-2 forwarding (dot11MeshForwarding)
+	 *
+	 * This controls whether to enable layer-2 forwarding.
+	 * By default: 1: enabled
+	 */
+	int mesh_fwding;
+
+	/**
 	 * dot11RSNASAERetransPeriod - Timeout to retransmit SAE Auth frame
 	 *
 	 * This timeout value is used in mesh STA to retransmit
@@ -1558,9 +1637,31 @@
 	/**
 	 * p2p_device_random_mac_addr - P2P Device MAC address policy default
 	 *
-	 * 0 = use permanent MAC address
+	 * 0 = use permanent MAC address (the one set by default by the device
+	 *     driver). Notice that, if the device driver is configured to
+	 *     always use random MAC addresses, this flag breaks reinvoking a
+	 *     persistent group, so flags 1 or 2 should be used instead with
+	 *     such drivers if persistent groups are used.
 	 * 1 = use random MAC address on creating the interface if there is no
-	 * persistent groups.
+	 *     persistent group. Besides, if a persistent group is created,
+	 *     p2p_device_persistent_mac_addr is set to the MAC address of the
+	 *     P2P Device interface, so that this address will be subsequently
+	 *     used to change the MAC address of the P2P Device interface. With
+	 *     no persistent group, the random MAC address is created by
+	 *     wpa_supplicant, changing the one set by the device driver.
+	 *     The device driver shall support SIOCGIFFLAGS/SIOCSIFFLAGS ioctl
+	 *     interface control operations.
+	 * 2 = this flag should be used when the device driver uses random MAC
+	 *     addresses by default when a P2P Device interface is created.
+	 *     If p2p_device_persistent_mac_addr is set, use this MAC address
+	 *     on creating the P2P Device interface. If not set, use the
+	 *     default method adopted by the device driver (e.g., random MAC
+	 *     address). Besides, if a persistent group is created,
+	 *     p2p_device_persistent_mac_addr is set to the MAC address of the
+	 *     P2P Device interface, so that this address will be subsequently
+	 *     used in place of the default address set by the device driver.
+	 *     (This option does not need support of SIOCGIFFLAGS/SIOCSIFFLAGS
+	 *     ioctl interface control operations and uses NL80211_ATTR_MAC).
 	 *
 	 * By default, permanent MAC address is used.
 	 */
@@ -1612,6 +1713,28 @@
 	 * 1 = use Extended Key ID when possible
 	 */
 	int extended_key_id;
+	/**
+	 * wowlan_disconnect_on_deinit - Trigger disconnect on wpa_supplicant
+	 * interface deinit even if the driver has enabled WoWLAN.
+	 *
+	 * 0 = Do not disconnect
+	 * 1 = Trigger disconnection
+	 */
+	int wowlan_disconnect_on_deinit;
+
+#ifdef CONFIG_PASN
+#ifdef CONFIG_TESTING_OPTIONS
+	/*
+	 * Normally, KDK should be derived if and only if both sides support
+	 * secure LTF. Allow forcing KDK derivation for testing purposes.
+	 */
+	int force_kdk_derivation;
+
+	/* If set, corrupt the MIC in the 3rd Authentication frame of PASN */
+	int pasn_corrupt_mic;
+
+#endif /* CONFIG_TESTING_OPTIONS */
+#endif /* CONFIG_PASN*/
 #ifdef CONFIG_BRCM_AUTOMOTIVE
 	int ignore_broadcast_ssid;
 #endif /* CONFIG_BRCM_AUTOMOTIVE */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/config_file.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/config_file.c
index 47770da..64c414e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/config_file.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/config_file.c
@@ -23,110 +23,49 @@
 #include "p2p/p2p.h"
 #include "eap_peer/eap_methods.h"
 #include "eap_peer/eap.h"
-
-
-static int newline_terminated(const char *buf, size_t buflen)
-{
-	size_t len = os_strlen(buf);
-	if (len == 0)
-		return 0;
-	if (len == buflen - 1 && buf[buflen - 1] != '\r' &&
-	    buf[len - 1] != '\n')
-		return 0;
-	return 1;
-}
-
-
-static void skip_line_end(FILE *stream)
-{
-	char buf[100];
-	while (fgets(buf, sizeof(buf), stream)) {
-		buf[sizeof(buf) - 1] = '\0';
-		if (newline_terminated(buf, sizeof(buf)))
-			return;
-	}
-}
-
-
-/**
- * wpa_config_get_line - Read the next configuration file line
- * @s: Buffer for the line
- * @size: The buffer length
- * @stream: File stream to read from
- * @line: Pointer to a variable storing the file line number
- * @_pos: Buffer for the pointer to the beginning of data on the text line or
- * %NULL if not needed (returned value used instead)
- * Returns: Pointer to the beginning of data on the text line or %NULL if no
- * more text lines are available.
- *
- * This function reads the next non-empty line from the configuration file and
- * removes comments. The returned string is guaranteed to be null-terminated.
- */
-static char * wpa_config_get_line(char *s, int size, FILE *stream, int *line,
-				  char **_pos)
-{
-	char *pos, *end, *sstart;
-
-	while (fgets(s, size, stream)) {
-		(*line)++;
-		s[size - 1] = '\0';
-		if (!newline_terminated(s, size)) {
-			/*
-			 * The line was truncated - skip rest of it to avoid
-			 * confusing error messages.
-			 */
-			wpa_printf(MSG_INFO, "Long line in configuration file "
-				   "truncated");
-			skip_line_end(stream);
-		}
-		pos = s;
-
-		/* Skip white space from the beginning of line. */
-		while (*pos == ' ' || *pos == '\t' || *pos == '\r')
-			pos++;
-
-		/* Skip comment lines and empty lines */
-		if (*pos == '#' || *pos == '\n' || *pos == '\0')
-			continue;
-
-		/*
-		 * Remove # comments unless they are within a double quoted
-		 * string.
-		 */
-		sstart = os_strchr(pos, '"');
-		if (sstart)
-			sstart = os_strrchr(sstart + 1, '"');
-		if (!sstart)
-			sstart = pos;
-		end = os_strchr(sstart, '#');
-		if (end)
-			*end-- = '\0';
-		else
-			end = pos + os_strlen(pos) - 1;
-
-		/* Remove trailing white space. */
-		while (end > pos &&
-		       (*end == '\n' || *end == ' ' || *end == '\t' ||
-			*end == '\r'))
-			*end-- = '\0';
-
-		if (*pos == '\0')
-			continue;
-
-		if (_pos)
-			*_pos = pos;
-		return pos;
-	}
-
-	if (_pos)
-		*_pos = NULL;
-	return NULL;
-}
+#include "utils/config.h"
 
 
 static int wpa_config_validate_network(struct wpa_ssid *ssid, int line)
 {
 	int errors = 0;
+#if defined(WAPI_ANDROID)
+	if ( ((ssid->proto & WPA_PROTO_WAPI) || (ssid->wapi != 0)) &&
+		 (ssid->key_mgmt != WPA_KEY_MGMT_WAPI_PSK) && (ssid->key_mgmt != WPA_KEY_MGMT_WAPI_CERT) ) {
+		/* map original IWNCOMM .conf structure to WPA Supplicant style */
+		if (ssid->wapi & 0x08) {
+			ssid->key_mgmt = WPA_KEY_MGMT_WAPI_CERT;
+		} else if (ssid->wapi & 0x04) {
+			ssid->key_mgmt = WPA_KEY_MGMT_WAPI_PSK;
+		} else {
+			wpa_printf(MSG_ERROR, "Line %d: unknown wapi policy %d\n", line, ssid->wapi);
+			errors++;
+		}
+		if (ssid->pairwise_cipher != WPA_CIPHER_SMS4) {
+			ssid->pairwise_cipher = WPA_CIPHER_SMS4;
+		}
+		if (ssid->group_cipher != WPA_CIPHER_SMS4) {
+			ssid->group_cipher = WPA_CIPHER_SMS4;
+		}
+	} else if ( ((ssid->key_mgmt == WPA_KEY_MGMT_WAPI_PSK) || (ssid->key_mgmt == WPA_KEY_MGMT_WAPI_CERT)) &&
+			    (((ssid->proto & WPA_PROTO_WAPI) == 0) || (ssid->wapi==0)) ) {
+		/* map WPA supplicant style to IWNCOMM .conf structure */
+		if (ssid->key_mgmt == WPA_KEY_MGMT_WAPI_PSK) {
+			ssid->proto = WPA_PROTO_WAPI;
+			ssid->wapi = 7;
+		}
+		if (ssid->key_mgmt == WPA_KEY_MGMT_WAPI_CERT) {
+			ssid->proto = WPA_PROTO_WAPI;
+			ssid->wapi = 11;
+		}
+		if (ssid->pairwise_cipher != WPA_CIPHER_SMS4) {
+			ssid->pairwise_cipher = WPA_CIPHER_SMS4;
+		}
+		if (ssid->group_cipher != WPA_CIPHER_SMS4) {
+			ssid->group_cipher = WPA_CIPHER_SMS4;
+		}
+	} else {
+#endif 
 
 	if (ssid->passphrase) {
 		if (ssid->psk_set) {
@@ -151,6 +90,9 @@
 		ssid->group_cipher &= ~WPA_CIPHER_CCMP;
 	}
 
+#if defined(WAPI_ANDROID)
+	}
+#endif 
 	if (ssid->mode == WPAS_MODE_MESH &&
 	    (ssid->key_mgmt != WPA_KEY_MGMT_NONE &&
 	    ssid->key_mgmt != WPA_KEY_MGMT_SAE)) {
@@ -767,15 +709,30 @@
 	INT(scan_ssid);
 	write_bssid(f, ssid);
 	write_bssid_hint(f, ssid);
-	write_str(f, "bssid_blacklist", ssid);
-	write_str(f, "bssid_whitelist", ssid);
+	write_str(f, "bssid_ignore", ssid);
+	write_str(f, "bssid_accept", ssid);
 	write_psk(f, ssid);
 	INT(mem_only_psk);
 	STR(sae_password);
 	STR(sae_password_id);
+	write_int(f, "sae_pwe", ssid->sae_pwe, DEFAULT_SAE_PWE);
 	write_proto(f, ssid);
 	write_key_mgmt(f, ssid);
 	INT_DEF(bg_scan_period, DEFAULT_BG_SCAN_PERIOD);
+#if defined(WAPI_ANDROID)
+	INT(wapi);
+	if ( (ssid->wapi == 7) || (ssid->key_mgmt == WPA_KEY_MGMT_WAPI_PSK) ) {
+		/* WAPI PSK network */
+		INT(psk_key_type);
+	}
+	if ( (ssid->wapi == 11) || (ssid->key_mgmt == WPA_KEY_MGMT_WAPI_CERT) ) {
+		/* WAPI CERT network */
+		INT(cert_index);
+		STR(wapi_as_cert);
+		STR(wapi_user_cert);
+		STR(cert_name);
+	}
+#endif 
 	write_pairwise(f, ssid);
 	write_group(f, ssid);
 	write_group_mgmt(f, ssid);
@@ -866,6 +823,7 @@
 #endif /* IEEE8021X_EAPOL */
 	INT(mode);
 	INT(no_auto_peer);
+	INT(mesh_fwding);
 	INT(frequency);
 	INT(enable_edmg);
 	INT(edmg_channel);
@@ -940,7 +898,9 @@
 	INT(beacon_prot);
 	INT(transition_disable);
 	INT(sae_pk);
-	/* Refer commit ed56a660: Suppress deauth for PMKSA caching disabled */
+	/* Refer commit 09f46ec2: wpa_supplicant: suppress deauth
+	 * for PMKSA caching disabled
+	 */
 	INT(suppress_deauth_no_pmksa);
 #ifdef CONFIG_HT_OVERRIDES
 	INT_DEF(disable_ht, DEFAULT_DISABLE_HT);
@@ -1125,6 +1085,17 @@
 
 	if (cred->sim_num != DEFAULT_USER_SELECTED_SIM)
 		fprintf(f, "\tsim_num=%d\n", cred->sim_num);
+
+	if (cred->engine)
+		fprintf(f, "\tengine=%d\n", cred->engine);
+	if (cred->engine_id)
+		fprintf(f, "\tengine_id=\"%s\"\n", cred->engine_id);
+	if (cred->key_id)
+		fprintf(f, "\tkey_id=\"%s\"\n", cred->key_id);
+	if (cred->cert_id)
+		fprintf(f, "\tcert_id=\"%s\"\n", cred->cert_id);
+	if (cred->ca_cert_id)
+		fprintf(f, "\tca_cert_id=\"%s\"\n", cred->ca_cert_id);
 }
 
 
@@ -1474,6 +1445,18 @@
 		}
 	}
 
+	if (config->ap_assocresp_elements) {
+		int i, len = wpabuf_len(config->ap_assocresp_elements);
+		const u8 *p = wpabuf_head_u8(config->ap_assocresp_elements);
+
+		if (len > 0) {
+			fprintf(f, "ap_assocresp_elements=");
+			for (i = 0; i < len; i++)
+				fprintf(f, "%02x", *p++);
+			fprintf(f, "\n");
+		}
+	}
+
 	if (config->ignore_old_scan_res)
 		fprintf(f, "ignore_old_scan_res=%d\n",
 			config->ignore_old_scan_res);
@@ -1487,9 +1470,23 @@
 		}
 		fprintf(f, "\n");
 	}
+	if (config->initial_freq_list && config->initial_freq_list[0]) {
+		int i;
+		fprintf(f, "initial_freq_list=");
+		for (i = 0; config->initial_freq_list[i]; i++) {
+			fprintf(f, "%s%d", i > 0 ? " " : "",
+				config->initial_freq_list[i]);
+		}
+		fprintf(f, "\n");
+	}
 	if (config->scan_cur_freq != DEFAULT_SCAN_CUR_FREQ)
 		fprintf(f, "scan_cur_freq=%d\n", config->scan_cur_freq);
 
+	if (config->scan_res_valid_for_connect !=
+	    DEFAULT_SCAN_RES_VALID_FOR_CONNECT)
+		fprintf(f, "scan_res_valid_for_connect=%d\n",
+			config->scan_res_valid_for_connect);
+
 	if (config->sched_scan_interval)
 		fprintf(f, "sched_scan_interval=%u\n",
 			config->sched_scan_interval);
@@ -1545,6 +1542,9 @@
 		fprintf(f, "mesh_max_inactivity=%d\n",
 			config->mesh_max_inactivity);
 
+	if (config->mesh_fwding != DEFAULT_MESH_FWDING)
+		fprintf(f, "mesh_fwding=%d\n", config->mesh_fwding);
+
 	if (config->dot11RSNASAERetransPeriod !=
 	    DEFAULT_DOT11_RSNA_SAE_RETRANS_PERIOD)
 		fprintf(f, "dot11RSNASAERetransPeriod=%d\n",
@@ -1638,6 +1638,9 @@
 		fprintf(f, "bss_no_flush_when_down=%d\n",
 			config->bss_no_flush_when_down);
 #endif /* ABOVE_10 */
+	if (config->wowlan_disconnect_on_deinit)
+		fprintf(f, "wowlan_disconnect_on_deinit=%d\n",
+			config->wowlan_disconnect_on_deinit);
 }
 
 #endif /* CONFIG_NO_CONFIG_WRITE */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/config_none.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/config_none.c
index 2aac28f..0bc977e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/config_none.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/config_none.c
@@ -5,7 +5,7 @@
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
  *
- * This file implements dummy example of a configuration backend. None of the
+ * This file implements stub example of a configuration backend. None of the
  * functions are actually implemented so this can be used as a simple
  * compilation test or a starting point for a new configuration backend.
  */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/config_ssid.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/config_ssid.h
index d7b13f7..413a6c7 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/config_ssid.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/config_ssid.h
@@ -9,6 +9,9 @@
 #ifndef CONFIG_SSID_H
 #define CONFIG_SSID_H
 
+#if defined(WAPI_ANDROID)
+#include "utils/includes.h"
+#endif 
 #include "common/defs.h"
 #include "utils/list.h"
 #include "eap_peer/eap_config.h"
@@ -46,6 +49,9 @@
 #define DEFAULT_USER_SELECTED_SIM 1
 #define DEFAULT_MAX_OPER_CHWIDTH -1
 
+/* Consider global sae_pwe for SAE mechanism for PWE derivation */
+#define DEFAULT_SAE_PWE 4
+
 struct psk_list_entry {
 	struct dl_list list;
 	u8 addr[ETH_ALEN];
@@ -153,16 +159,16 @@
 	u8 bssid[ETH_ALEN];
 
 	/**
-	 * bssid_blacklist - List of inacceptable BSSIDs
+	 * bssid_ignore - List of inacceptable BSSIDs
 	 */
-	u8 *bssid_blacklist;
-	size_t num_bssid_blacklist;
+	u8 *bssid_ignore;
+	size_t num_bssid_ignore;
 
 	/**
-	 * bssid_blacklist - List of acceptable BSSIDs
+	 * bssid_accept - List of acceptable BSSIDs
 	 */
-	u8 *bssid_whitelist;
-	size_t num_bssid_whitelist;
+	u8 *bssid_accept;
+	size_t num_bssid_accept;
 
 	/**
 	 * bssid_set - Whether BSSID is configured for this network
@@ -535,12 +541,26 @@
 	int dot11MeshConfirmTimeout; /* msec */
 	int dot11MeshHoldingTimeout; /* msec */
 
+	/**
+	 * Mesh network layer-2 forwarding (dot11MeshForwarding)
+	 */
+	int mesh_fwding;
+
 	int ht;
 	int ht40;
 
 	int vht;
 
 	int he;
+#if defined(WAPI_ANDROID)
+	int wapi;
+	int psk_key_type;
+	int wapi_ie_len;
+	int cert_index;
+	char *wapi_user_cert;
+	char *wapi_as_cert;
+	char *cert_name;
+#endif 
 
 	int max_oper_chwidth;
 
@@ -1135,7 +1155,23 @@
 	 */
 	bool was_recently_reconfigured;
 
-	/* Refer commit ed56a660: Suppress deauth for PMKSA caching disabled */
+	/**
+	 * sae_pwe - SAE mechanism for PWE derivation
+	 *
+	 * Internally, special value 4 (DEFAULT_SAE_PWE) is used to indicate
+	 * that the parameter is not set and the global sae_pwe value needs to
+	 * be considered.
+	 *
+	 * 0 = hunting-and-pecking loop only
+	 * 1 = hash-to-element only
+	 * 2 = both hunting-and-pecking loop and hash-to-element enabled
+	 */
+	int sae_pwe;
+
+	/* Refer commit 09f46ec2: wpa_supplicant: suppress deauth
+	 * for PMKSA caching disabled
+	 */
+
 	/**
 	 * suppress_deauth_no_pmksa - Whether deauth when PMKSA is empty
 	 * 0 = To deauthenticate if there is no PMKSA entry (default)
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ctrl_iface.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ctrl_iface.c
index ab58c79..8652c46 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ctrl_iface.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ctrl_iface.c
@@ -22,6 +22,7 @@
 #ifdef CONFIG_DPP
 #include "common/dpp.h"
 #endif /* CONFIG_DPP */
+#include "common/ptksa_cache.h"
 #include "crypto/tls.h"
 #include "ap/hostapd.h"
 #include "eap_peer/eap.h"
@@ -33,11 +34,18 @@
 #include "wps/wps.h"
 #include "fst/fst.h"
 #include "fst/fst_ctrl_iface.h"
+#if defined(WAPI_ANDROID)
+#include "wapi/wapi_interface.h"
+#include "wapi_asue_i.h"
+#include "wapi_config.h"
+extern int wapi_state_to_wpa_state(int wapi_state);
+#endif 
 #include "config.h"
 #include "wpa_supplicant_i.h"
 #include "driver_i.h"
 #include "wps_supplicant.h"
 #include "ibss_rsn.h"
+#include "wpas_glue.h"
 #include "ap.h"
 #include "p2p_supplicant.h"
 #include "p2p/p2p.h"
@@ -51,7 +59,7 @@
 #include "scan.h"
 #include "ctrl_iface.h"
 #include "interworking.h"
-#include "blacklist.h"
+#include "bssid_ignore.h"
 #include "autoscan.h"
 #include "wnm_sta.h"
 #include "offchannel.h"
@@ -309,20 +317,30 @@
 }
 
 
-static int wpas_ctrl_set_band(struct wpa_supplicant *wpa_s, char *band)
+static int wpas_ctrl_set_band(struct wpa_supplicant *wpa_s, char *bands)
 {
 	union wpa_event_data event;
+	u32 setband_mask = WPA_SETBAND_AUTO;
 
-	if (os_strcmp(band, "AUTO") == 0)
-		wpa_s->setband = WPA_SETBAND_AUTO;
-	else if (os_strcmp(band, "5G") == 0)
-		wpa_s->setband = WPA_SETBAND_5G;
-	else if (os_strcmp(band, "2G") == 0)
-		wpa_s->setband = WPA_SETBAND_2G;
-	else
-		return -1;
+	/*
+	 * For example:
+	 *  SET setband 2G,6G
+	 *  SET setband 5G
+	 *  SET setband AUTO
+	 */
+	if (!os_strstr(bands, "AUTO")) {
+		if (os_strstr(bands, "5G"))
+			setband_mask |= WPA_SETBAND_5G;
+		if (os_strstr(bands, "6G"))
+			setband_mask |= WPA_SETBAND_6G;
+		if (os_strstr(bands, "2G"))
+			setband_mask |= WPA_SETBAND_2G;
+		if (setband_mask == WPA_SETBAND_AUTO)
+			return -1;
+	}
 
-	if (wpa_drv_setband(wpa_s, wpa_s->setband) == 0) {
+	wpa_s->setband_mask = setband_mask;
+	if (wpa_drv_setband(wpa_s, wpa_s->setband_mask) == 0) {
 		os_memset(&event, 0, sizeof(event));
 		event.channel_list_changed.initiator = REGDOM_SET_BY_USER;
 		event.channel_list_changed.type = REGDOM_TYPE_UNKNOWN;
@@ -511,6 +529,19 @@
 	} else if (os_strcasecmp(cmd, "EAPOL::maxStart") == 0) {
 		eapol_sm_configure(wpa_s->eapol,
 				   -1, -1, -1, atoi(value));
+#ifdef CONFIG_TESTING_OPTIONS
+	} else if (os_strcasecmp(cmd, "EAPOL::portControl") == 0) {
+		if (os_strcmp(value, "Auto") == 0)
+			eapol_sm_notify_portControl(wpa_s->eapol, Auto);
+		else if (os_strcmp(value, "ForceUnauthorized") == 0)
+			eapol_sm_notify_portControl(wpa_s->eapol,
+						    ForceUnauthorized);
+		else if (os_strcmp(value, "ForceAuthorized") == 0)
+			eapol_sm_notify_portControl(wpa_s->eapol,
+						    ForceAuthorized);
+		else
+			ret = -1;
+#endif /* CONFIG_TESTING_OPTIONS */
 	} else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKLifetime") == 0) {
 		if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
 				     atoi(value))) {
@@ -553,10 +584,10 @@
 				   (wps_version_number & 0xf0) >> 4,
 				   wps_version_number & 0x0f);
 		}
-	} else if (os_strcasecmp(cmd, "wps_testing_dummy_cred") == 0) {
-		wps_testing_dummy_cred = atoi(value);
-		wpa_printf(MSG_DEBUG, "WPS: Testing - dummy_cred=%d",
-			   wps_testing_dummy_cred);
+	} else if (os_strcasecmp(cmd, "wps_testing_stub_cred") == 0) {
+		wps_testing_stub_cred = atoi(value);
+		wpa_printf(MSG_DEBUG, "WPS: Testing - stub_cred=%d",
+			   wps_testing_stub_cred);
 	} else if (os_strcasecmp(cmd, "wps_corrupt_pkhash") == 0) {
 		wps_corrupt_pkhash = atoi(value);
 		wpa_printf(MSG_DEBUG, "WPS: Testing - wps_corrupt_pkhash=%d",
@@ -815,6 +846,10 @@
 			wpa_s->sae_commit_override = wpabuf_parse_bin(value);
 	} else if (os_strcasecmp(cmd, "driver_signal_override") == 0) {
 		ret = wpas_ctrl_iface_set_dso(wpa_s, value);
+	} else if (os_strcasecmp(cmd, "disable_scs_support") == 0) {
+		wpa_s->disable_scs_support = !!atoi(value);
+	} else if (os_strcasecmp(cmd, "disable_mscs_support") == 0) {
+		wpa_s->disable_mscs_support = !!atoi(value);
 #ifdef CONFIG_DPP
 	} else if (os_strcasecmp(cmd, "dpp_config_obj_override") == 0) {
 		os_free(wpa_s->dpp_config_obj_override);
@@ -908,6 +943,8 @@
 			return -1;
 		wnm_set_coloc_intf_elems(wpa_s, elems);
 #endif /* CONFIG_WNM */
+	} else if (os_strcasecmp(cmd, "enable_dscp_policy_capa") == 0) {
+		wpa_s->enable_dscp_policy_capa = !!atoi(value);
 	} else {
 		value[-1] = '=';
 		ret = wpa_config_process_global(wpa_s->conf, cmd, -1);
@@ -2185,6 +2222,35 @@
 #endif /* IEEE8021X_EAPOL */
 }
 
+#if defined(WAPI_ANDROID)
+static const char * wapi_key_mgmt_txt(int key_mgmt)
+{
+	switch (key_mgmt) {
+	case WPA_KEY_MGMT_WAPI_PSK:
+		return "WAPI-PSK";
+	case WPA_KEY_MGMT_WAPI_CERT:
+		return "WAPI-CERT";
+	default:
+		return "UNKNOWN";
+	}
+}
+
+static int wapi_get_cipher_key_mgmt(unsigned int key_mgmt, char *buf, size_t buflen, int verbose)
+{
+	char *pos = buf, *end = buf + buflen;
+	int ret;
+
+	ret = os_snprintf(pos, end - pos,
+			  "pairwise_cipher=SMS4\n"
+			  "group_cipher=SMS4\n"
+			  "key_mgmt=%s\n",
+			  wapi_key_mgmt_txt(key_mgmt));
+	if (ret < 0 || ret >= end - pos)
+		return pos - buf;
+	pos += ret;
+	return pos - buf;
+}
+#endif 
 
 static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
 					    const char *params,
@@ -2301,6 +2367,12 @@
 				return pos - buf;
 			pos += ret;
 		}
+#if defined(WAPI_ANDROID)
+        if (ssid && ssid->wapi) {
+            wpa_printf(MSG_DEBUG, "%s , wapi_get_cipher_key_mgmt", __FUNCTION__);
+            pos += wapi_get_cipher_key_mgmt(ssid->key_mgmt, pos, end - pos, verbose);
+        } else
+#endif 
 
 #ifdef CONFIG_AP
 		if (wpa_s->ap_iface) {
@@ -2571,20 +2643,20 @@
 }
 
 
-static int wpa_supplicant_ctrl_iface_blacklist(struct wpa_supplicant *wpa_s,
-					       char *cmd, char *buf,
-					       size_t buflen)
+static int wpa_supplicant_ctrl_iface_bssid_ignore(struct wpa_supplicant *wpa_s,
+						  char *cmd, char *buf,
+						  size_t buflen)
 {
 	u8 bssid[ETH_ALEN];
-	struct wpa_blacklist *e;
+	struct wpa_bssid_ignore *e;
 	char *pos, *end;
 	int ret;
 
-	/* cmd: "BLACKLIST [<BSSID>]" */
+	/* cmd: "BSSID_IGNORE [<BSSID>]" */
 	if (*cmd == '\0') {
 		pos = buf;
 		end = buf + buflen;
-		e = wpa_s->blacklist;
+		e = wpa_s->bssid_ignore;
 		while (e) {
 			ret = os_snprintf(pos, end - pos, MACSTR "\n",
 					  MAC2STR(e->bssid));
@@ -2598,12 +2670,12 @@
 
 	cmd++;
 	if (os_strncmp(cmd, "clear", 5) == 0) {
-		wpa_blacklist_clear(wpa_s);
+		wpa_bssid_ignore_clear(wpa_s);
 		os_memcpy(buf, "OK\n", 3);
 		return 3;
 	}
 
-	wpa_printf(MSG_DEBUG, "CTRL_IFACE: BLACKLIST bssid='%s'", cmd);
+	wpa_printf(MSG_DEBUG, "CTRL_IFACE: BSSID_IGNORE bssid='%s'", cmd);
 	if (hwaddr_aton(cmd, bssid)) {
 		wpa_printf(MSG_DEBUG, "CTRL_IFACE: invalid BSSID '%s'", cmd);
 		return -1;
@@ -2613,10 +2685,10 @@
 	 * Add the BSSID twice, so its count will be 2, causing it to be
 	 * skipped when processing scan results.
 	 */
-	ret = wpa_blacklist_add(wpa_s, bssid);
+	ret = wpa_bssid_ignore_add(wpa_s, bssid);
 	if (ret < 0)
 		return -1;
-	ret = wpa_blacklist_add(wpa_s, bssid);
+	ret = wpa_bssid_ignore_add(wpa_s, bssid);
 	if (ret < 0)
 		return -1;
 	os_memcpy(buf, "OK\n", 3);
@@ -3084,6 +3156,9 @@
 	char *pos, *end;
 	int ret;
 	const u8 *ie, *ie2, *osen_ie, *p2p, *mesh, *owe, *rsnxe;
+#if defined(WAPI_ANDROID)
+	const u8 *ie3;
+#endif 
 
 	mesh = wpa_bss_get_ie(bss, WLAN_EID_MESH_ID);
 	p2p = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE);
@@ -3111,19 +3186,17 @@
 					    ie2, 2 + ie2[1]);
 	}
 	rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
-	if (rsnxe && rsnxe[1] >= 1) {
-		if (rsnxe[2] & BIT(WLAN_RSNX_CAPAB_SAE_H2E)) {
-			ret = os_snprintf(pos, end - pos, "[SAE-H2E]");
-			if (os_snprintf_error(end - pos, ret))
-				return -1;
-			pos += ret;
-		}
-		if (rsnxe[2] & BIT(WLAN_RSNX_CAPAB_SAE_PK)) {
-			ret = os_snprintf(pos, end - pos, "[SAE-PK]");
-			if (os_snprintf_error(end - pos, ret))
-				return -1;
-			pos += ret;
-		}
+	if (ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SAE_H2E)) {
+		ret = os_snprintf(pos, end - pos, "[SAE-H2E]");
+		if (os_snprintf_error(end - pos, ret))
+			return -1;
+		pos += ret;
+	}
+	if (ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SAE_PK)) {
+		ret = os_snprintf(pos, end - pos, "[SAE-PK]");
+		if (os_snprintf_error(end - pos, ret))
+			return -1;
+		pos += ret;
 	}
 	osen_ie = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
 	if (osen_ie)
@@ -3137,8 +3210,34 @@
 			return -1;
 		pos += ret;
 	}
+#if defined(WAPI_ANDROID)
+	ie3 = wpa_bss_get_ie(bss, WLAN_EID_WAPI);
+	if (ie3)
+	{
+		wpa_printf(MSG_DEBUG, "wapi_ie: [%02x][%02x][%02x][%02x][%02x][%02x][%02x][%02x][%02x][%02x]\n",
+			   ie3[0], ie3[1], ie3[2], ie3[3], ie3[4],
+			   ie3[5], ie3[6], ie3[7], ie3[8], ie3[9] );
+		if (ie3[9] == 2) {
+			wpa_printf(MSG_DEBUG, "This is a WAPI PSK network");
+			ret = os_snprintf(pos, end - pos, "[WAPI-PSK]");
+		} else if (ie3[9] == 1) {
+			wpa_printf(MSG_DEBUG, "This is a WAPI CERT network");
+			ret = os_snprintf(pos, end - pos, "[WAPI-CERT]");
+		} else {
+			wpa_printf(MSG_ERROR, "Unknown WAPI network type");
+			ret = os_snprintf(pos, end - pos, "[WAPI-Unknown]");
+		}
+		if (ret < 0 || ret >= end - pos)
+			return -1;
+		pos += ret;
+	}
+#endif 
 	pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
+#if defined(WAPI_ANDROID)
+	if (!ie && !ie2 && !ie3 && !osen_ie && bss->caps & IEEE80211_CAP_PRIVACY) {
+#else
 	if (!ie && !ie2 && !osen_ie && (bss->caps & IEEE80211_CAP_PRIVACY)) {
+#endif 
 		ret = os_snprintf(pos, end - pos, "[WEP]");
 		if (os_snprintf_error(end - pos, ret))
 			return -1;
@@ -3202,6 +3301,14 @@
 			return -1;
 		pos += ret;
 	}
+#if defined(WAPI_ANDROID)
+        if (!ie && !ie2 && !ie3) {
+                ret = os_snprintf(pos, end - pos, "\t");
+                if (ret < 0 || ret >= end - pos)
+                        return pos - buf;
+                pos += ret;
+        }
+#endif 
 #ifdef CONFIG_HS20
 	if (wpa_bss_get_vendor_ie(bss, HS20_IE_VENDOR_TYPE) && ie2) {
 		ret = os_snprintf(pos, end - pos, "[HS20]");
@@ -3253,6 +3360,7 @@
 {
 	char *pos, *end;
 	struct wpa_bss *bss;
+	const u8 *owe, *ieowe;
 	int ret;
 
 	pos = buf;
@@ -3264,6 +3372,15 @@
 	pos += ret;
 
 	dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
+		ieowe = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+		owe = wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE);
+		/* As per OWE spec the STA should be not be shown
+		 * the OWE transition BSSID in its scan results
+		 */
+		if (owe && ieowe) {
+			wpa_printf(MSG_DEBUG, "\nWe are skipping transition OWE BSSID\n");
+			continue;
+		}
 		ret = wpa_supplicant_ctrl_iface_scan_result(wpa_s, bss, pos,
 							    end - pos);
 		if (ret < 0 || ret >= end - pos)
@@ -4099,47 +4216,6 @@
 }
 
 
-static int wpas_ctrl_remove_cred(struct wpa_supplicant *wpa_s,
-				 struct wpa_cred *cred)
-{
-	struct wpa_ssid *ssid;
-	char str[20];
-	int id;
-
-	if (cred == NULL) {
-		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find cred");
-		return -1;
-	}
-
-	id = cred->id;
-	if (wpa_config_remove_cred(wpa_s->conf, id) < 0) {
-		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find cred");
-		return -1;
-	}
-
-	wpa_msg(wpa_s, MSG_INFO, CRED_REMOVED "%d", id);
-
-	/* Remove any network entry created based on the removed credential */
-	ssid = wpa_s->conf->ssid;
-	while (ssid) {
-		if (ssid->parent_cred == cred) {
-			int res;
-
-			wpa_printf(MSG_DEBUG, "Remove network id %d since it "
-				   "used the removed credential", ssid->id);
-			res = os_snprintf(str, sizeof(str), "%d", ssid->id);
-			if (os_snprintf_error(sizeof(str), res))
-				str[sizeof(str) - 1] = '\0';
-			ssid = ssid->next;
-			wpa_supplicant_ctrl_iface_remove_network(wpa_s, str);
-		} else
-			ssid = ssid->next;
-	}
-
-	return 0;
-}
-
-
 static int wpa_supplicant_ctrl_iface_remove_cred(struct wpa_supplicant *wpa_s,
 						 char *cmd)
 {
@@ -4150,13 +4226,7 @@
 	 * "provisioning_sp=<FQDN> */
 	if (os_strcmp(cmd, "all") == 0) {
 		wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_CRED all");
-		cred = wpa_s->conf->cred;
-		while (cred) {
-			prev = cred;
-			cred = cred->next;
-			wpas_ctrl_remove_cred(wpa_s, prev);
-		}
-		return 0;
+		return wpas_remove_all_creds(wpa_s);
 	}
 
 	if (os_strncmp(cmd, "sp_fqdn=", 8) == 0) {
@@ -4172,7 +4242,7 @@
 					if (os_strcmp(prev->domain[i], cmd + 8)
 					    != 0)
 						continue;
-					wpas_ctrl_remove_cred(wpa_s, prev);
+					wpas_remove_cred(wpa_s, prev);
 					break;
 				}
 			}
@@ -4189,7 +4259,7 @@
 			cred = cred->next;
 			if (prev->provisioning_sp &&
 			    os_strcmp(prev->provisioning_sp, cmd + 16) == 0)
-				wpas_ctrl_remove_cred(wpa_s, prev);
+				wpas_remove_cred(wpa_s, prev);
 		}
 		return 0;
 	}
@@ -4198,7 +4268,7 @@
 	wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_CRED id=%d", id);
 
 	cred = wpa_config_get_cred(wpa_s->conf, id);
-	return wpas_ctrl_remove_cred(wpa_s, cred);
+	return wpas_remove_cred(wpa_s, cred);
 }
 
 
@@ -4823,6 +4893,15 @@
 #endif /* CONFIG_FILS_SK_PFS */
 #endif /* CONFIG_FILS */
 
+#ifdef CONFIG_PASN
+	ret = os_snprintf(pos, end - pos, "%sPASN",
+			  pos == buf ? "" : " ");
+	if (os_snprintf_error(end - pos, ret))
+		return pos - buf;
+	pos += ret;
+
+#endif /* CONFIG_PASN */
+
 	return pos - buf;
 }
 
@@ -5123,7 +5202,9 @@
 
 #ifdef CONFIG_DPP
 	if (os_strcmp(field, "dpp") == 0) {
-#ifdef CONFIG_DPP2
+#ifdef CONFIG_DPP3
+		res = os_snprintf(buf, buflen, "DPP=3");
+#elif defined(CONFIG_DPP2)
 		res = os_snprintf(buf, buflen, "DPP=2");
 #else /* CONFIG_DPP2 */
 		res = os_snprintf(buf, buflen, "DPP=1");
@@ -5148,6 +5229,31 @@
 	}
 #endif /* CONFIG_SAE */
 
+#ifdef CONFIG_OCV
+	if (os_strcmp(field, "ocv") == 0) {
+		if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) ||
+		    (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_OCV))
+			res = os_snprintf(buf, buflen, "supported");
+		else
+			res = os_snprintf(buf, buflen, "not supported");
+		if (os_snprintf_error(buflen, res))
+			return -1;
+		return res;
+	}
+#endif /* CONFIG_OCV */
+
+	if (os_strcmp(field, "beacon_prot") == 0) {
+		if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_BEACON_PROTECTION) ||
+		    (wpa_s->drv_flags2 &
+		     WPA_DRIVER_FLAGS2_BEACON_PROTECTION_CLIENT))
+			res = os_snprintf(buf, buflen, "supported");
+		else
+			res = os_snprintf(buf, buflen, "not supported");
+		if (os_snprintf_error(buflen, res))
+			return -1;
+		return res;
+	}
+
 	wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
 		   field);
 
@@ -5269,6 +5375,9 @@
 	int ret;
 	char *pos, *end;
 	const u8 *ie, *ie2, *osen_ie, *mesh, *owe, *rsnxe;
+#if defined(WAPI_ANDROID)
+        const u8 *ie3;
+#endif
 
 	pos = buf;
 	end = buf + buflen;
@@ -5389,19 +5498,17 @@
 						    mesh ? "RSN" : "WPA2", ie2,
 						    2 + ie2[1]);
 		rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
-		if (rsnxe && rsnxe[1] >= 1) {
-			if (rsnxe[2] & BIT(WLAN_RSNX_CAPAB_SAE_H2E)) {
-				ret = os_snprintf(pos, end - pos, "[SAE-H2E]");
-				if (os_snprintf_error(end - pos, ret))
-					return -1;
-				pos += ret;
-			}
-			if (rsnxe[2] & BIT(WLAN_RSNX_CAPAB_SAE_PK)) {
-				ret = os_snprintf(pos, end - pos, "[SAE-PK]");
-				if (os_snprintf_error(end - pos, ret))
-					return -1;
-				pos += ret;
-			}
+		if (ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SAE_H2E)) {
+			ret = os_snprintf(pos, end - pos, "[SAE-H2E]");
+			if (os_snprintf_error(end - pos, ret))
+				return -1;
+			pos += ret;
+		}
+		if (ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SAE_PK)) {
+			ret = os_snprintf(pos, end - pos, "[SAE-PK]");
+			if (os_snprintf_error(end - pos, ret))
+				return -1;
+			pos += ret;
 		}
 		osen_ie = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
 		if (osen_ie)
@@ -5417,7 +5524,32 @@
 			pos += ret;
 		}
 		pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
+#if defined(WAPI_ANDROID)
+                ie3 = wpa_bss_get_ie(bss, WLAN_EID_WAPI);
+                if (ie3)
+                {
+                        wpa_printf(MSG_DEBUG, "wapi_ie: [%02x][%02x][%02x][%02x][%02x][%02x][%02x][%02x][%02x][%02x]\n",
+                                   ie3[0], ie3[1], ie3[2], ie3[3], ie3[4],
+                                   ie3[5], ie3[6], ie3[7], ie3[8], ie3[9] );
+                        if (ie3[9] == 2) {
+                                wpa_printf(MSG_DEBUG, "This is a WAPI PSK network");
+                                ret = os_snprintf(pos, end - pos, "[WAPI-PSK]");
+                        } else if (ie3[9] == 1) {
+                                wpa_printf(MSG_DEBUG, "This is a WAPI CERT network");
+                                ret = os_snprintf(pos, end - pos, "[WAPI-CERT]");
+                        } else {
+                                wpa_printf(MSG_ERROR, "Unknown WAPI network type");
+                                ret = os_snprintf(pos, end - pos, "[WAPI-Unknown]");
+                        }
+
+                        if (os_snprintf_error(end - pos, ret))
+                                return 0;
+                        pos += ret;
+                }
+                if (!ie && !ie2 && !ie3 && !osen_ie &&
+#else
 		if (!ie && !ie2 && !osen_ie &&
+#endif 
 		    (bss->caps & IEEE80211_CAP_PRIVACY)) {
 			ret = os_snprintf(pos, end - pos, "[WEP]");
 			if (os_snprintf_error(end - pos, ret))
@@ -5946,6 +6078,7 @@
 	u8 bssid[ETH_ALEN];
 	struct wpa_bss *bss;
 	struct wpa_ssid *ssid = wpa_s->current_ssid;
+	struct wpa_radio_work *already_connecting;
 
 	if (hwaddr_aton(addr, bssid)) {
 		wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: invalid "
@@ -5973,9 +6106,18 @@
 	 * allow roaming to other networks
 	 */
 
+	already_connecting = radio_work_pending(wpa_s, "sme-connect");
 	wpa_s->reassociate = 1;
 	wpa_supplicant_connect(wpa_s, bss, ssid);
 
+	/*
+	 * Indicate that an explicitly requested roam is in progress so scan
+	 * results that come in before the 'sme-connect' radio work gets
+	 * executed do not override the original connection attempt.
+	 */
+	if (!already_connecting && radio_work_pending(wpa_s, "sme-connect"))
+		wpa_s->roam_in_progress = true;
+
 	return 0;
 #endif /* CONFIG_NO_SCAN_PROCESSING */
 }
@@ -6022,12 +6164,16 @@
 	const char *_seek[P2P_MAX_QUERY_HASH + 1], **seek = NULL;
 	u8 seek_count = 0;
 	int freq = 0;
+	bool include_6ghz = false;
 
 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
 		wpa_dbg(wpa_s, MSG_INFO,
 			"Reject P2P_FIND since interface is disabled");
 		return -1;
 	}
+
+	if (os_strstr(cmd, " include_6ghz"))
+		include_6ghz = true;
 	if (os_strstr(cmd, "type=social"))
 		type = P2P_FIND_ONLY_SOCIAL;
 	else if (os_strstr(cmd, "type=progressive"))
@@ -6087,7 +6233,8 @@
 	}
 
 	return wpas_p2p_find(wpa_s, timeout, type, _dev_type != NULL, _dev_type,
-			     _dev_id, search_delay, seek_count, seek, freq);
+			     _dev_id, search_delay, seek_count, seek, freq,
+			     include_6ghz);
 }
 
 
@@ -6212,7 +6359,7 @@
 	for (i = 0; p2ps_prov->cpt_priority[i]; i++)
 		p2ps_prov->cpt_mask |= p2ps_prov->cpt_priority[i];
 
-	/* force conncap with tstCap (no sanity checks) */
+	/* force conncap with tstCap (no validity checks) */
 	pos = os_strstr(cmd, "tstCap=");
 	if (pos) {
 		role = strtol(pos + 7, NULL, 16);
@@ -6340,6 +6487,7 @@
 	u8 _group_ssid[SSID_MAX_LEN], *group_ssid = NULL;
 	size_t group_ssid_len = 0;
 	int he;
+	bool allow_6ghz;
 
 	if (!wpa_s->global->p2p_init_wpa_s)
 		return -1;
@@ -6377,6 +6525,7 @@
 		}
 	}
 	join = os_strstr(pos, " join") != NULL;
+	allow_6ghz = os_strstr(pos, " allow_6ghz") != NULL;
 	auth = os_strstr(pos, " auth") != NULL;
 	automatic = os_strstr(pos, " auto") != NULL;
 	pd = os_strstr(pos, " provdisc") != NULL;
@@ -6419,6 +6568,9 @@
 	if (max_oper_chwidth < 0)
 		return -1;
 
+	if (allow_6ghz && chwidth == 40)
+		max_oper_chwidth = CHANWIDTH_40MHZ_6GHZ;
+
 	pos2 = os_strstr(pos, " ssid=");
 	if (pos2) {
 		char *end;
@@ -6461,7 +6613,7 @@
 				   persistent_group, automatic, join,
 				   auth, go_intent, freq, freq2, persistent_id,
 				   pd, ht40, vht, max_oper_chwidth, he, edmg,
-				   group_ssid, group_ssid_len);
+				   group_ssid, group_ssid_len, allow_6ghz);
 	if (new_pin == -2) {
 		os_memcpy(buf, "FAIL-CHANNEL-UNAVAILABLE\n", 25);
 		return 25;
@@ -7068,6 +7220,7 @@
 	int freq = 0, pref_freq = 0;
 	int ht40, vht, he, max_oper_chwidth, chwidth = 0, freq2 = 0;
 	int edmg;
+	bool allow_6ghz;
 
 	id = atoi(cmd);
 	pos = os_strstr(cmd, " peer=");
@@ -7127,8 +7280,14 @@
 	if (max_oper_chwidth < 0)
 		return -1;
 
+	allow_6ghz = os_strstr(cmd, " allow_6ghz") != NULL;
+
+	if (allow_6ghz && chwidth == 40)
+		max_oper_chwidth = CHANWIDTH_40MHZ_6GHZ;
+
 	return wpas_p2p_invite(wpa_s, _peer, ssid, NULL, freq, freq2, ht40, vht,
-			       max_oper_chwidth, pref_freq, he, edmg);
+			       max_oper_chwidth, pref_freq, he, edmg,
+			       allow_6ghz);
 }
 
 
@@ -7136,6 +7295,7 @@
 {
 	char *pos;
 	u8 peer[ETH_ALEN], go_dev_addr[ETH_ALEN], *go_dev = NULL;
+	bool allow_6ghz;
 
 	pos = os_strstr(cmd, " peer=");
 	if (!pos)
@@ -7148,6 +7308,8 @@
 		return -1;
 	}
 
+	allow_6ghz = os_strstr(pos, " allow_6ghz") != NULL;
+
 	pos = os_strstr(pos, " go_dev_addr=");
 	if (pos) {
 		pos += 13;
@@ -7159,7 +7321,7 @@
 		go_dev = go_dev_addr;
 	}
 
-	return wpas_p2p_invite_group(wpa_s, cmd, peer, go_dev);
+	return wpas_p2p_invite_group(wpa_s, cmd, peer, go_dev, allow_6ghz);
 }
 
 
@@ -7177,7 +7339,7 @@
 static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s,
 					 int id, int freq, int vht_center_freq2,
 					 int ht40, int vht, int vht_chwidth,
-					 int he, int edmg)
+					 int he, int edmg, bool allow_6ghz)
 {
 	struct wpa_ssid *ssid;
 
@@ -7192,13 +7354,14 @@
 	return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq,
 					     vht_center_freq2, 0, ht40, vht,
 					     vht_chwidth, he, edmg,
-					     NULL, 0, 0);
+					     NULL, 0, 0, allow_6ghz);
 }
 
 
 static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
 {
 	int freq = 0, persistent = 0, group_id = -1;
+	bool allow_6ghz = false;
 	int vht = wpa_s->conf->p2p_go_vht;
 	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
 	int he = wpa_s->conf->p2p_go_he;
@@ -7245,6 +7408,8 @@
 			edmg = 1;
 		} else if (os_strcmp(token, "persistent") == 0) {
 			persistent = 1;
+		} else if (os_strcmp(token, "allow_6ghz") == 0) {
+			allow_6ghz = true;
 		} else {
 			wpa_printf(MSG_DEBUG,
 				   "CTRL: Invalid P2P_GROUP_ADD parameter: '%s'",
@@ -7277,14 +7442,21 @@
 	if (max_oper_chwidth < 0)
 		return -1;
 
+	if (allow_6ghz && chwidth == 40)
+		max_oper_chwidth = CHANWIDTH_40MHZ_6GHZ;
+
+	/* Allow DFS to be used for Autonomous GO */
+	wpa_s->p2p_go_allow_dfs = !!(wpa_s->drv_flags &
+				     WPA_DRIVER_FLAGS_DFS_OFFLOAD);
+
 	if (group_id >= 0)
 		return p2p_ctrl_group_add_persistent(wpa_s, group_id,
 						     freq, freq2, ht40, vht,
 						     max_oper_chwidth, he,
-						     edmg);
+						     edmg, allow_6ghz);
 
 	return wpas_p2p_group_add(wpa_s, persistent, freq, freq2, ht40, vht,
-				  max_oper_chwidth, he, edmg);
+				  max_oper_chwidth, he, edmg, allow_6ghz);
 }
 
 
@@ -9145,7 +9317,7 @@
 
 #ifdef CONFIG_WPS_TESTING
 	wps_version_number = 0x20;
-	wps_testing_dummy_cred = 0;
+	wps_testing_stub_cred = 0;
 	wps_corrupt_pkhash = 0;
 	wps_force_auth_types_in_use = 0;
 	wps_force_encr_types_in_use = 0;
@@ -9175,7 +9347,9 @@
 	dpp_pkex_ephemeral_key_override_len = 0;
 	dpp_protocol_key_override_len = 0;
 	dpp_nonce_override_len = 0;
-#ifdef CONFIG_DPP2
+#ifdef CONFIG_DPP3
+	dpp_version_override = 3;
+#elif defined(CONFIG_DPP2)
 	dpp_version_override = 2;
 #else /* CONFIG_DPP2 */
 	dpp_version_override = 1;
@@ -9213,13 +9387,14 @@
 	wpa_s->consecutive_conn_failures = 0;
 
 	wpa_drv_radio_disable(wpa_s, 0);
-	wpa_blacklist_clear(wpa_s);
+	wpa_bssid_ignore_clear(wpa_s);
 	wpa_supplicant_ctrl_iface_remove_network(wpa_s, "all");
 	wpa_supplicant_ctrl_iface_remove_cred(wpa_s, "all");
 	wpa_config_flush_blobs(wpa_s->conf);
 	wpa_s->conf->auto_interworking = 0;
 	wpa_s->conf->okc = 0;
 
+	ptksa_cache_flush(wpa_s->ptksa, NULL, WPA_CIPHER_NONE);
 	wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
 	rsn_preauth_deinit(wpa_s->wpa);
 
@@ -9267,6 +9442,9 @@
 	wpabuf_free(wpa_s->rsnxe_override_eapol);
 	wpa_s->rsnxe_override_eapol = NULL;
 	wpas_clear_driver_signal_override(wpa_s);
+	wpa_s->disable_scs_support = 0;
+	wpa_s->disable_mscs_support = 0;
+	wpa_s->enable_dscp_policy_capa = 0;
 	wpa_s->oci_freq_override_eapol = 0;
 	wpa_s->oci_freq_override_saquery_req = 0;
 	wpa_s->oci_freq_override_saquery_resp = 0;
@@ -9320,6 +9498,13 @@
 	free_bss_tmp_disallowed(wpa_s);
 
 	os_memset(&wpa_s->robust_av, 0, sizeof(struct robust_av_data));
+
+#ifdef CONFIG_PASN
+	wpas_pasn_auth_stop(wpa_s);
+#endif /* CONFIG_PASN */
+
+	if (wpa_s->mac_addr_changed && wpa_s->conf->mac_addr == 0)
+		wpas_restore_permanent_mac_addr(wpa_s);
 }
 
 
@@ -9585,6 +9770,7 @@
 	unsigned int manual_scan_only_new = 0;
 	unsigned int scan_only = 0;
 	unsigned int scan_id_count = 0;
+	unsigned int manual_non_coloc_6ghz = 0;
 	int scan_id[MAX_SCAN_ID];
 	void (*scan_res_handler)(struct wpa_supplicant *wpa_s,
 				 struct wpa_scan_results *scan_res);
@@ -9662,6 +9848,10 @@
 				os_strstr(params, "wildcard_ssid=1") != NULL;
 		}
 
+		pos = os_strstr(params, "non_coloc_6ghz=");
+		if (pos)
+			manual_non_coloc_6ghz = !!atoi(pos + 15);
+
 		pos = params;
 		while (pos && *pos != '\0') {
 			if (os_strncmp(pos, "ssid ", 5) == 0) {
@@ -9731,6 +9921,7 @@
 		wpa_s->manual_scan_use_id = manual_scan_use_id;
 		wpa_s->manual_scan_only_new = manual_scan_only_new;
 		wpa_s->scan_id_count = scan_id_count;
+		wpa_s->manual_non_coloc_6ghz = manual_non_coloc_6ghz;
 		os_memcpy(wpa_s->scan_id, scan_id, scan_id_count * sizeof(int));
 		wpa_s->scan_res_handler = scan_res_handler;
 		os_free(wpa_s->manual_scan_freqs);
@@ -9754,6 +9945,7 @@
 		wpa_s->manual_scan_use_id = manual_scan_use_id;
 		wpa_s->manual_scan_only_new = manual_scan_only_new;
 		wpa_s->scan_id_count = scan_id_count;
+		wpa_s->manual_non_coloc_6ghz = manual_non_coloc_6ghz;
 		os_memcpy(wpa_s->scan_id, scan_id, scan_id_count * sizeof(int));
 		wpa_s->scan_res_handler = scan_res_handler;
 		os_free(wpa_s->manual_scan_freqs);
@@ -10065,6 +10257,132 @@
 }
 
 
+static int wpas_ctrl_iface_driver_event_assoc(struct wpa_supplicant *wpa_s,
+					      char *param)
+{
+	union wpa_event_data event;
+	struct assoc_info *ai;
+	char *ctx = NULL;
+	int ret = -1;
+	struct wpabuf *req_ies = NULL;
+	struct wpabuf *resp_ies = NULL;
+	struct wpabuf *resp_frame = NULL;
+	struct wpabuf *beacon_ies = NULL;
+	struct wpabuf *key_replay_ctr = NULL;
+	struct wpabuf *ptk_kck = NULL;
+	struct wpabuf *ptk_kek = NULL;
+	struct wpabuf *fils_pmk = NULL;
+	char *str, *pos;
+	u8 addr[ETH_ALEN];
+	u8 fils_pmkid[PMKID_LEN];
+
+	os_memset(&event, 0, sizeof(event));
+	ai = &event.assoc_info;
+
+	while ((str = str_token(param, " ", &ctx))) {
+		pos = os_strchr(str, '=');
+		if (!pos)
+			goto fail;
+		*pos++ = '\0';
+
+		if (os_strcmp(str, "reassoc") == 0) {
+			ai->reassoc = atoi(pos);
+		} else if (os_strcmp(str, "req_ies") == 0) {
+			wpabuf_free(req_ies);
+			req_ies = wpabuf_parse_bin(pos);
+			if (!req_ies)
+				goto fail;
+			ai->req_ies = wpabuf_head(req_ies);
+			ai->req_ies_len = wpabuf_len(req_ies);
+		} else if (os_strcmp(str, "resp_ies") == 0) {
+			wpabuf_free(resp_ies);
+			resp_ies = wpabuf_parse_bin(pos);
+			if (!resp_ies)
+				goto fail;
+			ai->resp_ies = wpabuf_head(resp_ies);
+			ai->resp_ies_len = wpabuf_len(resp_ies);
+		} else if (os_strcmp(str, "resp_frame") == 0) {
+			wpabuf_free(resp_frame);
+			resp_frame = wpabuf_parse_bin(pos);
+			if (!resp_frame)
+				goto fail;
+			ai->resp_frame = wpabuf_head(resp_frame);
+			ai->resp_frame_len = wpabuf_len(resp_frame);
+		} else if (os_strcmp(str, "beacon_ies") == 0) {
+			wpabuf_free(beacon_ies);
+			beacon_ies = wpabuf_parse_bin(pos);
+			if (!beacon_ies)
+				goto fail;
+			ai->beacon_ies = wpabuf_head(beacon_ies);
+			ai->beacon_ies_len = wpabuf_len(beacon_ies);
+		} else if (os_strcmp(str, "freq") == 0) {
+			ai->freq = atoi(pos);
+		} else if (os_strcmp(str, "wmm::info_bitmap") == 0) {
+			ai->wmm_params.info_bitmap = atoi(pos);
+		} else if (os_strcmp(str, "wmm::uapsd_queues") == 0) {
+			ai->wmm_params.uapsd_queues = atoi(pos);
+		} else if (os_strcmp(str, "addr") == 0) {
+			if (hwaddr_aton(pos, addr))
+				goto fail;
+			ai->addr = addr;
+		} else if (os_strcmp(str, "authorized") == 0) {
+			ai->authorized = atoi(pos);
+		} else if (os_strcmp(str, "key_replay_ctr") == 0) {
+			wpabuf_free(key_replay_ctr);
+			key_replay_ctr = wpabuf_parse_bin(pos);
+			if (!key_replay_ctr)
+				goto fail;
+			ai->key_replay_ctr = wpabuf_head(key_replay_ctr);
+			ai->key_replay_ctr_len = wpabuf_len(key_replay_ctr);
+		} else if (os_strcmp(str, "ptk_kck") == 0) {
+			wpabuf_free(ptk_kck);
+			ptk_kck = wpabuf_parse_bin(pos);
+			if (!ptk_kck)
+				goto fail;
+			ai->ptk_kck = wpabuf_head(ptk_kck);
+			ai->ptk_kck_len = wpabuf_len(ptk_kck);
+		} else if (os_strcmp(str, "ptk_kek") == 0) {
+			wpabuf_free(ptk_kek);
+			ptk_kek = wpabuf_parse_bin(pos);
+			if (!ptk_kek)
+				goto fail;
+			ai->ptk_kek = wpabuf_head(ptk_kek);
+			ai->ptk_kek_len = wpabuf_len(ptk_kek);
+		} else if (os_strcmp(str, "subnet_status") == 0) {
+			ai->subnet_status = atoi(pos);
+		} else if (os_strcmp(str, "fils_erp_next_seq_num") == 0) {
+			ai->fils_erp_next_seq_num = atoi(pos);
+		} else if (os_strcmp(str, "fils_pmk") == 0) {
+			wpabuf_free(fils_pmk);
+			fils_pmk = wpabuf_parse_bin(pos);
+			if (!fils_pmk)
+				goto fail;
+			ai->fils_pmk = wpabuf_head(fils_pmk);
+			ai->fils_pmk_len = wpabuf_len(fils_pmk);
+		} else if (os_strcmp(str, "fils_pmkid") == 0) {
+			if (hexstr2bin(pos, fils_pmkid, PMKID_LEN) < 0)
+				goto fail;
+			ai->fils_pmkid = fils_pmkid;
+		} else {
+			goto fail;
+		}
+	}
+
+	wpa_supplicant_event(wpa_s, EVENT_ASSOC, &event);
+	ret = 0;
+fail:
+	wpabuf_free(req_ies);
+	wpabuf_free(resp_ies);
+	wpabuf_free(resp_frame);
+	wpabuf_free(beacon_ies);
+	wpabuf_free(key_replay_ctr);
+	wpabuf_free(ptk_kck);
+	wpabuf_free(ptk_kek);
+	wpabuf_free(fils_pmk);
+	return ret;
+}
+
+
 static int wpas_ctrl_iface_driver_event(struct wpa_supplicant *wpa_s, char *cmd)
 {
 	char *pos, *param;
@@ -10097,6 +10415,8 @@
 		return 0;
 	} else if (os_strcmp(cmd, "SCAN_RES") == 0) {
 		return wpas_ctrl_iface_driver_scan_res(wpa_s, param);
+	} else if (os_strcmp(cmd, "ASSOC") == 0) {
+		return wpas_ctrl_iface_driver_event_assoc(wpa_s, param);
 	} else {
 		wpa_dbg(wpa_s, MSG_DEBUG, "Testing - unknown driver event: %s",
 			cmd);
@@ -10147,6 +10467,45 @@
 }
 
 
+static int wpas_ctrl_iface_eapol_tx(struct wpa_supplicant *wpa_s, char *cmd)
+{
+	char *pos;
+	u8 dst[ETH_ALEN], *buf;
+	int used, ret;
+	size_t len;
+	unsigned int prev;
+
+	wpa_printf(MSG_DEBUG, "External EAPOL TX: %s", cmd);
+
+	pos = cmd;
+	used = hwaddr_aton2(pos, dst);
+	if (used < 0)
+		return -1;
+	pos += used;
+	while (*pos == ' ')
+		pos++;
+
+	len = os_strlen(pos);
+	if (len & 1)
+		return -1;
+	len /= 2;
+
+	buf = os_malloc(len);
+	if (!buf || hexstr2bin(pos, buf, len) < 0) {
+		os_free(buf);
+		return -1;
+	}
+
+	prev = wpa_s->ext_eapol_frame_io;
+	wpa_s->ext_eapol_frame_io = 0;
+	ret = wpa_ether_send(wpa_s, dst, ETH_P_EAPOL, buf, len);
+	wpa_s->ext_eapol_frame_io = prev;
+	os_free(buf);
+
+	return ret;
+}
+
+
 static u16 ipv4_hdr_checksum(const void *buf, size_t len)
 {
 	size_t i;
@@ -10556,10 +10915,128 @@
 	return -1;
 #endif /* CONFIG_SME */
 }
-
 #endif /* CONFIG_TESTING_OPTIONS */
 
 
+static int wpas_ctrl_iface_send_twt_setup(struct wpa_supplicant *wpa_s,
+					  const char *cmd)
+{
+	u8 dtok = 1;
+	int exponent = 10;
+	int mantissa = 8192;
+	u8 min_twt = 255;
+	unsigned long long twt = 0;
+	unsigned long long twt_offset = 0;
+	bool requestor = true;
+	int setup_cmd = 0;
+	bool trigger = true;
+	bool implicit = true;
+	bool flow_type = true;
+#ifdef CONFIG_TWT_OFFLOAD_IFX
+	int flow_id = 0xFF;
+#else
+	int flow_id = 0;
+#endif /* CONFIG_TWT_OFFLOAD_IFX */
+	bool protection = false;
+	u8 twt_channel = 0;
+	u8 control = BIT(4); /* Control field (IEEE P802.11ax/D8.0 Figure
+			      * 9-687): B4 = TWT Information Frame Disabled */
+	const char *tok_s;
+
+	tok_s = os_strstr(cmd, " dialog=");
+	if (tok_s)
+		dtok = atoi(tok_s + os_strlen(" dialog="));
+
+	tok_s = os_strstr(cmd, " exponent=");
+	if (tok_s)
+		exponent = atoi(tok_s + os_strlen(" exponent="));
+
+	tok_s = os_strstr(cmd, " mantissa=");
+	if (tok_s)
+		mantissa = atoi(tok_s + os_strlen(" mantissa="));
+
+	tok_s = os_strstr(cmd, " min_twt=");
+	if (tok_s)
+		min_twt = atoi(tok_s + os_strlen(" min_twt="));
+
+	tok_s = os_strstr(cmd, " setup_cmd=");
+	if (tok_s)
+		setup_cmd = atoi(tok_s + os_strlen(" setup_cmd="));
+
+	tok_s = os_strstr(cmd, " twt=");
+	if (tok_s)
+		sscanf(tok_s + os_strlen(" twt="), "%llu", &twt);
+
+	tok_s = os_strstr(cmd, " twt_offset=");
+	if (tok_s)
+		sscanf(tok_s + os_strlen(" twt_offset="), "%llu", &twt_offset);
+
+	tok_s = os_strstr(cmd, " requestor=");
+	if (tok_s)
+		requestor = atoi(tok_s + os_strlen(" requestor="));
+
+	tok_s = os_strstr(cmd, " trigger=");
+	if (tok_s)
+		trigger = atoi(tok_s + os_strlen(" trigger="));
+
+	tok_s = os_strstr(cmd, " implicit=");
+	if (tok_s)
+		implicit = atoi(tok_s + os_strlen(" implicit="));
+
+	tok_s = os_strstr(cmd, " flow_type=");
+	if (tok_s)
+		flow_type = atoi(tok_s + os_strlen(" flow_type="));
+
+	tok_s = os_strstr(cmd, " flow_id=");
+	if (tok_s)
+		flow_id = atoi(tok_s + os_strlen(" flow_id="));
+
+	tok_s = os_strstr(cmd, " protection=");
+	if (tok_s)
+		protection = atoi(tok_s + os_strlen(" protection="));
+
+	tok_s = os_strstr(cmd, " twt_channel=");
+	if (tok_s)
+		twt_channel = atoi(tok_s + os_strlen(" twt_channel="));
+
+	tok_s = os_strstr(cmd, " control=");
+	if (tok_s)
+		control = atoi(tok_s + os_strlen(" control="));
+
+#ifdef CONFIG_TWT_OFFLOAD_IFX
+	return wpas_twt_offload_send_setup(wpa_s, dtok, exponent, mantissa,
+					   min_twt, setup_cmd, twt, twt_offset,
+					   requestor, trigger, implicit, flow_type,
+					   flow_id, protection, twt_channel,
+					   control);
+#else
+	return wpas_twt_send_setup(wpa_s, dtok, exponent, mantissa, min_twt,
+				   setup_cmd, twt, requestor, trigger, implicit,
+				   flow_type, flow_id, protection, twt_channel,
+				   control);
+#endif /* CONFIG_TWT_OFFLOAD_IFX */
+}
+
+
+static int wpas_ctrl_iface_send_twt_teardown(struct wpa_supplicant *wpa_s,
+					     const char *cmd)
+{
+	u8 flags = 0x1;
+	const char *tok_s;
+
+	tok_s = os_strstr(cmd, " flags=");
+	if (tok_s)
+		flags = atoi(tok_s + os_strlen(" flags="));
+
+#ifdef CONFIG_TWT_OFFLOAD_IFX
+	return wpas_twt_offload_send_teardown(wpa_s, flags);
+#else
+	return wpas_twt_send_teardown(wpa_s, flags);
+#endif /* CONFIG_TWT_OFFLOAD_IFX */
+}
+
+
+
 static int wpas_ctrl_vendor_elem_add(struct wpa_supplicant *wpa_s, char *cmd)
 {
 	char *pos = cmd;
@@ -10602,8 +11079,7 @@
 
 	if (wpa_s->vendor_elem[frame] == NULL) {
 		wpa_s->vendor_elem[frame] = buf;
-		wpas_vendor_elem_update(wpa_s);
-		return 0;
+		goto update_ies;
 	}
 
 	if (wpabuf_resize(&wpa_s->vendor_elem[frame], len) < 0) {
@@ -10613,8 +11089,14 @@
 
 	wpabuf_put_buf(wpa_s->vendor_elem[frame], buf);
 	wpabuf_free(buf);
+
+update_ies:
 	wpas_vendor_elem_update(wpa_s);
 
+	if (frame == VENDOR_ELEM_PROBE_REQ ||
+	    frame == VENDOR_ELEM_PROBE_REQ_P2P)
+		wpa_supplicant_set_default_scan_ies(wpa_s);
+
 	return 0;
 }
 
@@ -10921,6 +11403,7 @@
 
 static void wpas_ctrl_iface_pmksa_flush(struct wpa_supplicant *wpa_s)
 {
+	ptksa_cache_flush(wpa_s->ptksa, NULL, WPA_CIPHER_NONE);
 	wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
 #ifdef CONFIG_AP
 	wpas_ap_pmksa_cache_flush(wpa_s);
@@ -11070,6 +11553,8 @@
 	if (sscanf(pos, "%d %d %d %d", &reauth_time, &expiration,
 		   &entry->akmp, &entry->opportunistic) != 4)
 		goto fail;
+	if (reauth_time > expiration)
+		goto fail;
 	for (i = 0; i < 4; i++) {
 		pos = os_strchr(pos, ' ');
 		if (!pos) {
@@ -11091,6 +11576,8 @@
 
 	entry->network_ctx = ssid;
 
+	entry->external = true;
+
 	wpa_sm_pmksa_cache_add_entry(wpa_s->wpa, entry);
 	entry = NULL;
 	ret = 0;
@@ -11253,6 +11740,681 @@
 }
 
 
+#ifdef CONFIG_PASN
+static int wpas_ctrl_iface_pasn_start(struct wpa_supplicant *wpa_s, char *cmd)
+{
+	char *token, *context = NULL;
+	u8 bssid[ETH_ALEN];
+	int akmp = -1, cipher = -1, got_bssid = 0;
+	u16 group = 0xFFFF;
+	u8 *comeback = NULL;
+	size_t comeback_len = 0;
+	int id = 0, ret = -1;
+
+	/*
+	 * Entry format: bssid=<BSSID> akmp=<AKMP> cipher=<CIPHER> group=<group>
+	 *    [comeback=<hexdump>]
+	 */
+	while ((token = str_token(cmd, " ", &context))) {
+		if (os_strncmp(token, "bssid=", 6) == 0) {
+			if (hwaddr_aton(token + 6, bssid))
+				goto out;
+			got_bssid = 1;
+		} else if (os_strcmp(token, "akmp=PASN") == 0) {
+			akmp = WPA_KEY_MGMT_PASN;
+#ifdef CONFIG_IEEE80211R
+		} else if (os_strcmp(token, "akmp=FT-PSK") == 0) {
+			akmp = WPA_KEY_MGMT_FT_PSK;
+		} else if (os_strcmp(token, "akmp=FT-EAP-SHA384") == 0) {
+			akmp = WPA_KEY_MGMT_FT_IEEE8021X_SHA384;
+		} else if (os_strcmp(token, "akmp=FT-EAP") == 0) {
+			akmp = WPA_KEY_MGMT_FT_IEEE8021X;
+#endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_SAE
+		} else if (os_strcmp(token, "akmp=SAE") == 0) {
+			akmp = WPA_KEY_MGMT_SAE;
+#endif /* CONFIG_SAE */
+#ifdef CONFIG_FILS
+		} else if (os_strcmp(token, "akmp=FILS-SHA256") == 0) {
+			akmp = WPA_KEY_MGMT_FILS_SHA256;
+		} else if (os_strcmp(token, "akmp=FILS-SHA384") == 0) {
+			akmp = WPA_KEY_MGMT_FILS_SHA384;
+#endif /* CONFIG_FILS */
+		} else if (os_strcmp(token, "cipher=CCMP-256") == 0) {
+			cipher = WPA_CIPHER_CCMP_256;
+		} else if (os_strcmp(token, "cipher=GCMP-256") == 0) {
+			cipher = WPA_CIPHER_GCMP_256;
+		} else if (os_strcmp(token, "cipher=CCMP") == 0) {
+			cipher = WPA_CIPHER_CCMP;
+		} else if (os_strcmp(token, "cipher=GCMP") == 0) {
+			cipher = WPA_CIPHER_GCMP;
+		} else if (os_strncmp(token, "group=", 6) == 0) {
+			group = atoi(token + 6);
+		} else if (os_strncmp(token, "nid=", 4) == 0) {
+			id = atoi(token + 4);
+		} else if (os_strncmp(token, "comeback=", 9) == 0) {
+			comeback_len = os_strlen(token + 9);
+			if (comeback || !comeback_len || comeback_len % 2)
+				goto out;
+
+			comeback_len /= 2;
+			comeback = os_malloc(comeback_len);
+			if (!comeback ||
+			    hexstr2bin(token + 9, comeback, comeback_len))
+				goto out;
+		} else {
+			wpa_printf(MSG_DEBUG,
+				   "CTRL: PASN Invalid parameter: '%s'",
+				   token);
+			goto out;
+		}
+	}
+
+	if (!got_bssid || akmp == -1 || cipher == -1 || group == 0xFFFF) {
+		wpa_printf(MSG_DEBUG,"CTRL: PASN missing parameter");
+		goto out;
+	}
+
+	ret = wpas_pasn_auth_start(wpa_s, bssid, akmp, cipher, group, id,
+				   comeback, comeback_len);
+out:
+	os_free(comeback);
+	return ret;
+}
+
+
+static int wpas_ctrl_iface_pasn_deauthenticate(struct wpa_supplicant *wpa_s,
+					       const char *cmd)
+{
+	u8 bssid[ETH_ALEN];
+
+	if (os_strncmp(cmd, "bssid=", 6) != 0 || hwaddr_aton(cmd + 6, bssid)) {
+		wpa_printf(MSG_DEBUG,
+			   "CTRL: PASN_DEAUTH without valid BSSID");
+		return -1;
+	}
+
+	return wpas_pasn_deauthenticate(wpa_s, bssid);
+}
+
+#endif /* CONFIG_PASN */
+
+
+static int set_type4_frame_classifier(const char *cmd,
+				      struct type4_params *param)
+{
+	const char *pos, *end;
+	u8 classifier_mask = 0;
+	int ret;
+	char addr[INET6_ADDRSTRLEN];
+	size_t alen;
+
+	if (os_strstr(cmd, "ip_version=ipv4")) {
+		param->ip_version = IPV4;
+	} else if (os_strstr(cmd, "ip_version=ipv6")) {
+		param->ip_version = IPV6;
+	} else {
+		wpa_printf(MSG_ERROR, "IP version missing/invalid");
+		return -1;
+	}
+
+	classifier_mask |= BIT(0);
+
+	pos = os_strstr(cmd, "src_ip=");
+	if (pos) {
+		pos += 7;
+		end = os_strchr(pos, ' ');
+		if (!end)
+			end = pos + os_strlen(pos);
+
+		alen = end - pos;
+		if (alen >= INET6_ADDRSTRLEN)
+			return -1;
+		os_memcpy(addr, pos, alen);
+		addr[alen] = '\0';
+		if (param->ip_version == IPV4)
+			ret = inet_pton(AF_INET, addr,
+					&param->ip_params.v4.src_ip);
+		else
+			ret = inet_pton(AF_INET6, addr,
+					&param->ip_params.v6.src_ip);
+
+		if (ret != 1) {
+			wpa_printf(MSG_ERROR,
+				   "Error converting src IP address to binary ret=%d",
+				   ret);
+			return -1;
+		}
+
+		classifier_mask |= BIT(1);
+	}
+
+	pos = os_strstr(cmd, "dst_ip=");
+	if (pos) {
+		pos += 7;
+		end = os_strchr(pos, ' ');
+		if (!end)
+			end = pos + os_strlen(pos);
+
+		alen = end - pos;
+		if (alen >= INET6_ADDRSTRLEN)
+			return -1;
+		os_memcpy(addr, pos, alen);
+		addr[alen] = '\0';
+		if (param->ip_version == IPV4)
+			ret = inet_pton(AF_INET, addr,
+					&param->ip_params.v4.dst_ip);
+		else
+			ret = inet_pton(AF_INET6, addr,
+					&param->ip_params.v6.dst_ip);
+
+		if (ret != 1) {
+			wpa_printf(MSG_ERROR,
+				   "Error converting dst IP address to binary ret=%d",
+				   ret);
+			return -1;
+		}
+
+		classifier_mask |= BIT(2);
+	}
+
+	pos = os_strstr(cmd, "src_port=");
+	if (pos && atoi(pos + 9) > 0) {
+		if (param->ip_version == IPV4)
+			param->ip_params.v4.src_port = atoi(pos + 9);
+		else
+			param->ip_params.v6.src_port = atoi(pos + 9);
+		classifier_mask |= BIT(3);
+	}
+
+	pos = os_strstr(cmd, "dst_port=");
+	if (pos && atoi(pos + 9) > 0) {
+		if (param->ip_version == IPV4)
+			param->ip_params.v4.dst_port = atoi(pos + 9);
+		else
+			param->ip_params.v6.dst_port = atoi(pos + 9);
+		classifier_mask |= BIT(4);
+	}
+
+	pos = os_strstr(cmd, "dscp=");
+	if (pos && atoi(pos + 5) > 0) {
+		if (param->ip_version == IPV4)
+			param->ip_params.v4.dscp = atoi(pos + 5);
+		else
+			param->ip_params.v6.dscp = atoi(pos + 5);
+		classifier_mask |= BIT(5);
+	}
+
+	if (param->ip_version == IPV4) {
+		pos = os_strstr(cmd, "protocol=");
+		if (pos) {
+			if (os_strstr(pos, "udp")) {
+				param->ip_params.v4.protocol = 17;
+			} else if (os_strstr(pos, "tcp")) {
+				param->ip_params.v4.protocol = 6;
+			} else if (os_strstr(pos, "esp")) {
+				param->ip_params.v4.protocol = 50;
+			} else {
+				wpa_printf(MSG_ERROR, "Invalid protocol");
+				return -1;
+			}
+			classifier_mask |= BIT(6);
+		}
+	} else {
+		pos = os_strstr(cmd, "next_header=");
+		if (pos) {
+			if (os_strstr(pos, "udp")) {
+				param->ip_params.v6.next_header = 17;
+			} else if (os_strstr(pos, "tcp")) {
+				param->ip_params.v6.next_header = 6;
+			} else if (os_strstr(pos, "esp")) {
+				param->ip_params.v6.next_header = 50;
+			} else {
+				wpa_printf(MSG_ERROR, "Invalid next header");
+				return -1;
+			}
+
+			classifier_mask |= BIT(6);
+		}
+
+		pos = os_strstr(cmd, "flow_label=");
+		if (pos) {
+			pos += 11;
+			end = os_strchr(pos, ' ');
+			if (!end)
+				end = pos + os_strlen(pos);
+
+			if (end - pos != 6 ||
+			    hexstr2bin(pos, param->ip_params.v6.flow_label,
+				       3) ||
+			    param->ip_params.v6.flow_label[0] > 0x0F) {
+				wpa_printf(MSG_ERROR, "Invalid flow label");
+				return -1;
+			}
+
+			classifier_mask |= BIT(7);
+		}
+	}
+
+	param->classifier_mask = classifier_mask;
+	return 0;
+}
+
+
+static int set_type10_frame_classifier(const char *cmd,
+				       struct type10_params *param)
+{
+	const char *pos, *end;
+	size_t filter_len;
+
+	pos = os_strstr(cmd, "prot_instance=");
+	if (!pos) {
+		wpa_printf(MSG_ERROR, "Protocol instance missing");
+		return -1;
+	}
+	param->prot_instance = atoi(pos + 14);
+
+	pos = os_strstr(cmd, "prot_number=");
+	if (!pos) {
+		wpa_printf(MSG_ERROR, "Protocol number missing");
+		return -1;
+	}
+	if (os_strstr(pos, "udp")) {
+		param->prot_number = 17;
+	} else if (os_strstr(pos, "tcp")) {
+		param->prot_number = 6;
+	} else if (os_strstr(pos, "esp")) {
+		param->prot_number = 50;
+	} else {
+		wpa_printf(MSG_ERROR, "Invalid protocol number");
+		return -1;
+	}
+
+	pos = os_strstr(cmd, "filter_value=");
+	if (!pos) {
+		wpa_printf(MSG_ERROR,
+			   "Classifier parameter filter_value missing");
+		return -1;
+	}
+
+	pos += 13;
+	end = os_strchr(pos, ' ');
+	if (!end)
+		end = pos + os_strlen(pos);
+
+	filter_len = (end - pos) / 2;
+	param->filter_value = os_malloc(filter_len);
+	if (!param->filter_value)
+		return -1;
+
+	if (hexstr2bin(pos, param->filter_value, filter_len)) {
+		wpa_printf(MSG_ERROR, "Invalid filter_value %s", pos);
+		goto free;
+	}
+
+	pos = os_strstr(cmd, "filter_mask=");
+	if (!pos) {
+		wpa_printf(MSG_ERROR,
+			   "Classifier parameter filter_mask missing");
+		goto free;
+	}
+
+	pos += 12;
+	end = os_strchr(pos, ' ');
+	if (!end)
+		end = pos + os_strlen(pos);
+
+	if (filter_len != (size_t) (end - pos) / 2) {
+		wpa_printf(MSG_ERROR,
+			   "Filter mask length mismatch expected=%zu received=%zu",
+			   filter_len, (size_t) (end - pos) / 2);
+		goto free;
+	}
+
+	param->filter_mask = os_malloc(filter_len);
+	if (!param->filter_mask)
+		goto free;
+
+	if (hexstr2bin(pos, param->filter_mask, filter_len)) {
+		wpa_printf(MSG_ERROR, "Invalid filter mask %s", pos);
+		os_free(param->filter_mask);
+		param->filter_mask = NULL;
+		goto free;
+	}
+
+	param->filter_len = filter_len;
+	return 0;
+free:
+	os_free(param->filter_value);
+	param->filter_value = NULL;
+	return -1;
+}
+
+
+static int scs_parse_type4(struct tclas_element *elem, const char *pos)
+{
+	struct type4_params type4_param = { 0 };
+
+	if (set_type4_frame_classifier(pos, &type4_param) == -1) {
+		wpa_printf(MSG_ERROR, "Failed to set frame_classifier 4");
+		return -1;
+	}
+
+	os_memcpy(&elem->frame_classifier.type4_param,
+		  &type4_param, sizeof(struct type4_params));
+	return 0;
+}
+
+
+static int scs_parse_type10(struct tclas_element *elem, const char *pos)
+{
+	struct type10_params type10_param = { 0 };
+
+	if (set_type10_frame_classifier(pos, &type10_param) == -1) {
+		wpa_printf(MSG_ERROR, "Failed to set frame_classifier 10");
+		return -1;
+	}
+
+	os_memcpy(&elem->frame_classifier.type10_param,
+		  &type10_param, sizeof(struct type10_params));
+	return 0;
+}
+
+
+static int wpas_ctrl_iface_configure_scs(struct wpa_supplicant *wpa_s,
+					 char *cmd)
+{
+	char *pos1, *pos;
+	struct scs_robust_av_data *scs_data = &wpa_s->scs_robust_av_req;
+	struct scs_desc_elem desc_elem = { 0 };
+	int val;
+	unsigned int num_scs_desc = 0;
+
+	if (wpa_s->ongoing_scs_req) {
+		wpa_printf(MSG_ERROR, "%s: SCS Request already in queue",
+			   __func__);
+		return -1;
+	}
+
+	/**
+	 * format:
+	 * [scs_id=<decimal number>] <add|remove|change> [scs_up=<0-7>]
+	 * [classifier_type=<4|10>]
+	 * [classifier params based on classifier type]
+	 * [tclas_processing=<0|1>] [scs_id=<decimal number>] ...
+	 */
+	pos1 = os_strstr(cmd, "scs_id=");
+	if (!pos1) {
+		wpa_printf(MSG_ERROR, "SCSID not present");
+		return -1;
+	}
+
+	free_up_scs_desc(scs_data);
+
+	while (pos1) {
+		struct scs_desc_elem *n1;
+		struct active_scs_elem *active_scs_desc;
+		char *next_scs_desc;
+		unsigned int num_tclas_elem = 0;
+		bool scsid_active = false;
+
+		desc_elem.scs_id = atoi(pos1 + 7);
+		pos1 += 7;
+
+		next_scs_desc = os_strstr(pos1, "scs_id=");
+		if (next_scs_desc) {
+			char temp[20];
+
+			os_snprintf(temp, sizeof(temp), "scs_id=%d ",
+				    desc_elem.scs_id);
+			if (os_strstr(next_scs_desc, temp)) {
+				wpa_printf(MSG_ERROR,
+					   "Multiple SCS descriptors configured with same SCSID(=%d)",
+					   desc_elem.scs_id);
+				goto free_scs_desc;
+			}
+			pos1[next_scs_desc - pos1 - 1] = '\0';
+		}
+
+		dl_list_for_each(active_scs_desc, &wpa_s->active_scs_ids,
+				 struct active_scs_elem, list) {
+			if (desc_elem.scs_id == active_scs_desc->scs_id) {
+				scsid_active = true;
+				break;
+			}
+		}
+
+		if (os_strstr(pos1, "add ")) {
+			desc_elem.request_type = SCS_REQ_ADD;
+			if (scsid_active) {
+				wpa_printf(MSG_ERROR, "SCSID %d already active",
+					   desc_elem.scs_id);
+				return -1;
+			}
+		} else if (os_strstr(pos1, "remove")) {
+			desc_elem.request_type = SCS_REQ_REMOVE;
+			if (!scsid_active) {
+				wpa_printf(MSG_ERROR, "SCSID %d not active",
+					   desc_elem.scs_id);
+				return -1;
+			}
+			goto scs_desc_end;
+		} else if (os_strstr(pos1, "change ")) {
+			desc_elem.request_type = SCS_REQ_CHANGE;
+			if (!scsid_active) {
+				wpa_printf(MSG_ERROR, "SCSID %d not active",
+					   desc_elem.scs_id);
+				return -1;
+			}
+		} else {
+			wpa_printf(MSG_ERROR, "SCS Request type invalid");
+			goto free_scs_desc;
+		}
+
+		pos1 = os_strstr(pos1, "scs_up=");
+		if (!pos1) {
+			wpa_printf(MSG_ERROR,
+				   "Intra-Access user priority not present");
+			goto free_scs_desc;
+		}
+
+		val = atoi(pos1 + 7);
+		if (val < 0 || val > 7) {
+			wpa_printf(MSG_ERROR,
+				   "Intra-Access user priority invalid %d",
+				   val);
+			goto free_scs_desc;
+		}
+
+		desc_elem.intra_access_priority = val;
+		desc_elem.scs_up_avail = true;
+
+		pos = os_strstr(pos1, "classifier_type=");
+		if (!pos) {
+			wpa_printf(MSG_ERROR, "classifier type empty");
+			goto free_scs_desc;
+		}
+
+		while (pos) {
+			struct tclas_element elem = { 0 }, *n;
+			char *next_tclas_elem;
+
+			val = atoi(pos + 16);
+			if (val != 4 && val != 10) {
+				wpa_printf(MSG_ERROR,
+					   "classifier type invalid %d", val);
+				goto free_scs_desc;
+			}
+
+			elem.classifier_type = val;
+			pos += 16;
+
+			next_tclas_elem = os_strstr(pos, "classifier_type=");
+			if (next_tclas_elem) {
+				pos1 = next_tclas_elem;
+				pos[next_tclas_elem - pos - 1] = '\0';
+			}
+
+			switch (val) {
+			case 4:
+				if (scs_parse_type4(&elem, pos) < 0)
+					goto free_scs_desc;
+				break;
+			case 10:
+				if (scs_parse_type10(&elem, pos) < 0)
+					goto free_scs_desc;
+				break;
+			}
+
+			n = os_realloc(desc_elem.tclas_elems,
+				       (num_tclas_elem + 1) * sizeof(elem));
+			if (!n)
+				goto free_scs_desc;
+
+			desc_elem.tclas_elems = n;
+			os_memcpy((u8 *) desc_elem.tclas_elems +
+				  num_tclas_elem * sizeof(elem),
+				  &elem, sizeof(elem));
+			num_tclas_elem++;
+			desc_elem.num_tclas_elem = num_tclas_elem;
+			pos = next_tclas_elem;
+		}
+
+		if (desc_elem.num_tclas_elem > 1) {
+			pos1 = os_strstr(pos1, "tclas_processing=");
+			if (!pos1) {
+				wpa_printf(MSG_ERROR, "tclas_processing empty");
+				goto free_scs_desc;
+			}
+
+			val = atoi(pos1 + 17);
+			if (val != 0 && val != 1) {
+				wpa_printf(MSG_ERROR,
+					   "tclas_processing invalid");
+				goto free_scs_desc;
+			}
+
+			desc_elem.tclas_processing = val;
+		}
+
+scs_desc_end:
+		n1 = os_realloc(scs_data->scs_desc_elems, (num_scs_desc + 1) *
+				sizeof(struct scs_desc_elem));
+		if (!n1)
+			goto free_scs_desc;
+
+		scs_data->scs_desc_elems = n1;
+		os_memcpy((u8 *) scs_data->scs_desc_elems + num_scs_desc *
+			  sizeof(desc_elem), &desc_elem, sizeof(desc_elem));
+		num_scs_desc++;
+		scs_data->num_scs_desc = num_scs_desc;
+		pos1 = next_scs_desc;
+		os_memset(&desc_elem, 0, sizeof(desc_elem));
+	}
+
+	return wpas_send_scs_req(wpa_s);
+
+free_scs_desc:
+	free_up_tclas_elem(&desc_elem);
+	free_up_scs_desc(scs_data);
+	return -1;
+}
+
+
+static int wpas_ctrl_iface_send_dscp_resp(struct wpa_supplicant *wpa_s,
+					  const char *cmd)
+{
+	char *pos;
+	struct dscp_policy_status *policy = NULL, *n;
+	int num_policies = 0, ret = -1;
+	struct dscp_resp_data resp_data;
+
+	/*
+	 * format:
+	 * <[reset]>/<[solicited] [policy_id=1 status=0...]> [more]
+	 */
+
+	os_memset(&resp_data, 0, sizeof(resp_data));
+
+	resp_data.more = os_strstr(cmd, "more") != NULL;
+
+	if (os_strstr(cmd, "reset")) {
+		resp_data.reset = true;
+		resp_data.solicited = false;
+		goto send_resp;
+	}
+
+	resp_data.solicited = os_strstr(cmd, "solicited") != NULL;
+
+	pos = os_strstr(cmd, "policy_id=");
+	while (pos) {
+		n = os_realloc(policy, (num_policies + 1) * sizeof(*policy));
+		if (!n)
+			goto fail;
+
+		policy = n;
+		pos += 10;
+		policy[num_policies].id = atoi(pos);
+		if (policy[num_policies].id == 0) {
+			wpa_printf(MSG_ERROR, "DSCP: Invalid policy id");
+			goto fail;
+		}
+
+		pos = os_strstr(pos, "status=");
+		if (!pos) {
+			wpa_printf(MSG_ERROR,
+				   "DSCP: Status is not found for a policy");
+			goto fail;
+		}
+
+		pos += 7;
+		policy[num_policies].status = atoi(pos);
+		num_policies++;
+
+		pos = os_strstr(pos, "policy_id");
+	}
+
+	resp_data.policy = policy;
+	resp_data.num_policies = num_policies;
+send_resp:
+	ret = wpas_send_dscp_response(wpa_s, &resp_data);
+	if (ret)
+		wpa_printf(MSG_ERROR, "DSCP: Failed to send DSCP response");
+fail:
+	os_free(policy);
+	return ret;
+}
+
+
+static int wpas_ctrl_iface_send_dscp_query(struct wpa_supplicant *wpa_s,
+					   const char *cmd)
+{
+	char *pos;
+
+	/*
+	 * format:
+	 * Wildcard DSCP query
+	 * <wildcard>
+	 *
+	 * DSCP query with a domain name attribute:
+	 * [domain_name=<string>]
+	 */
+
+	if (os_strstr(cmd, "wildcard")) {
+		wpa_printf(MSG_DEBUG, "QM: Send wildcard DSCP policy query");
+		return wpas_send_dscp_query(wpa_s, NULL, 0);
+	}
+
+	pos = os_strstr(cmd, "domain_name=");
+	if (!pos || !os_strlen(pos + 12)) {
+		wpa_printf(MSG_ERROR, "QM: Domain name not preset");
+		return -1;
+	}
+
+	return wpas_send_dscp_query(wpa_s, pos + 12, os_strlen(pos + 12));
+}
+
+
 char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
 					 char *buf, size_t *resp_len)
 {
@@ -11742,8 +12904,12 @@
 	} else if (os_strncmp(buf, "BSSID ", 6) == 0) {
 		if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6))
 			reply_len = -1;
+	} else if (os_strncmp(buf, "BSSID_IGNORE", 12) == 0) {
+		reply_len = wpa_supplicant_ctrl_iface_bssid_ignore(
+			wpa_s, buf + 12, reply, reply_size);
 	} else if (os_strncmp(buf, "BLACKLIST", 9) == 0) {
-		reply_len = wpa_supplicant_ctrl_iface_blacklist(
+		/* deprecated backwards compatibility alias for BSSID_IGNORE */
+		reply_len = wpa_supplicant_ctrl_iface_bssid_ignore(
 			wpa_s, buf + 9, reply, reply_size);
 	} else if (os_strncmp(buf, "LOG_LEVEL", 9) == 0) {
 		reply_len = wpa_supplicant_ctrl_iface_log_level(
@@ -11851,6 +13017,9 @@
 	} else if (os_strcmp(buf, "STOP_AP") == 0) {
 		if (wpas_ap_stop_ap(wpa_s))
 			reply_len = -1;
+	} else if (os_strcmp(buf, "UPDATE_BEACON") == 0) {
+		if (wpas_ap_update_beacon(wpa_s))
+			reply_len = -1;
 #endif /* CONFIG_AP */
 	} else if (os_strcmp(buf, "SUSPEND") == 0) {
 		wpas_notify_suspend(wpa_s->global);
@@ -11966,6 +13135,9 @@
 	} else if (os_strncmp(buf, "EAPOL_RX ", 9) == 0) {
 		if (wpas_ctrl_iface_eapol_rx(wpa_s, buf + 9) < 0)
 			reply_len = -1;
+	} else if (os_strncmp(buf, "EAPOL_TX ", 9) == 0) {
+		if (wpas_ctrl_iface_eapol_tx(wpa_s, buf + 9) < 0)
+			reply_len = -1;
 	} else if (os_strncmp(buf, "DATA_TEST_CONFIG ", 17) == 0) {
 		if (wpas_ctrl_iface_data_test_config(wpa_s, buf + 17) < 0)
 			reply_len = -1;
@@ -12005,6 +13177,18 @@
 			wpa_s, wpa_s->bssid, NULL,
 			WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA);
 #endif /* CONFIG_TESTING_OPTIONS */
+	} else if (os_strncmp(buf, "TWT_SETUP ", 10) == 0) {
+		if (wpas_ctrl_iface_send_twt_setup(wpa_s, buf + 9))
+			reply_len = -1;
+	} else if (os_strcmp(buf, "TWT_SETUP") == 0) {
+		if (wpas_ctrl_iface_send_twt_setup(wpa_s, ""))
+			reply_len = -1;
+	} else if (os_strncmp(buf, "TWT_TEARDOWN ", 13) == 0) {
+		if (wpas_ctrl_iface_send_twt_teardown(wpa_s, buf + 12))
+			reply_len = -1;
+	} else if (os_strcmp(buf, "TWT_TEARDOWN") == 0) {
+		if (wpas_ctrl_iface_send_twt_teardown(wpa_s, ""))
+			reply_len = -1;
 	} else if (os_strncmp(buf, "VENDOR_ELEM_ADD ", 16) == 0) {
 		if (wpas_ctrl_vendor_elem_add(wpa_s, buf + 16) < 0)
 			reply_len = -1;
@@ -12186,6 +13370,27 @@
 	} else if (os_strncmp(buf, "MSCS ", 5) == 0) {
 		if (wpas_ctrl_iface_configure_mscs(wpa_s, buf + 5))
 			reply_len = -1;
+#ifdef CONFIG_PASN
+	} else if (os_strncmp(buf, "PASN_START ", 11) == 0) {
+		if (wpas_ctrl_iface_pasn_start(wpa_s, buf + 11) < 0)
+			reply_len = -1;
+	} else if (os_strcmp(buf, "PASN_STOP") == 0) {
+		wpas_pasn_auth_stop(wpa_s);
+	} else if (os_strcmp(buf, "PTKSA_CACHE_LIST") == 0) {
+		reply_len = ptksa_cache_list(wpa_s->ptksa, reply, reply_size);
+	} else if (os_strncmp(buf, "PASN_DEAUTH ", 12) == 0) {
+		if (wpas_ctrl_iface_pasn_deauthenticate(wpa_s, buf + 12) < 0)
+			reply_len = -1;
+#endif /* CONFIG_PASN */
+	} else if (os_strncmp(buf, "SCS ", 4) == 0) {
+		if (wpas_ctrl_iface_configure_scs(wpa_s, buf + 4))
+			reply_len = -1;
+	} else if (os_strncmp(buf, "DSCP_RESP ", 10) == 0) {
+		if (wpas_ctrl_iface_send_dscp_resp(wpa_s, buf + 10))
+			reply_len = -1;
+	} else if (os_strncmp(buf, "DSCP_QUERY ", 11) == 0) {
+		if (wpas_ctrl_iface_send_dscp_query(wpa_s, buf + 11))
+			reply_len = -1;
 	} else {
 		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
 		reply_len = 16;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ctrl_iface.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ctrl_iface.h
index 510668d..5489adb 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ctrl_iface.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ctrl_iface.h
@@ -11,6 +11,10 @@
 
 #ifdef CONFIG_CTRL_IFACE
 
+#if defined(WAPI_ANDROID)
+void wapiap_lib_deinitialize(char *ifname);
+void brcm_wapiap_initialize(void *ctx, int wapiap_tx_sock, struct i802_bss *bss);
+#endif 
 #ifndef CTRL_IFACE_MAX_LEN
 #define CTRL_IFACE_MAX_LEN 8192
 #endif /* CTRL_IFACE_MAX_LEN */
@@ -70,14 +74,17 @@
 
 /**
  * wpa_supplicant_ctrl_iface_deinit - Deinitialize control interface
+ * @wpa_s: Pointer to wpa_supplicant data
  * @priv: Pointer to private data from wpa_supplicant_ctrl_iface_init()
  *
  * Deinitialize the control interface that was initialized with
- * wpa_supplicant_ctrl_iface_init().
+ * wpa_supplicant_ctrl_iface_init() and any data related to the wpa_s instance.
+ * @priv may be %NULL if the control interface has not yet been initialized.
  *
  * Required to be implemented in each control interface backend.
  */
-void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv);
+void wpa_supplicant_ctrl_iface_deinit(struct wpa_supplicant *wpa_s,
+				      struct ctrl_iface_priv *priv);
 
 /**
  * wpa_supplicant_ctrl_iface_wait - Wait for ctrl_iface monitor
@@ -128,7 +135,8 @@
 }
 
 static inline void
-wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv)
+wpa_supplicant_ctrl_iface_deinit(struct wpa_supplicant *wpa_s,
+				 struct ctrl_iface_priv *priv)
 {
 }
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ctrl_iface_named_pipe.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ctrl_iface_named_pipe.c
index 79ff787..bddc041 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ctrl_iface_named_pipe.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ctrl_iface_named_pipe.c
@@ -462,8 +462,11 @@
 }
 
 
-void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv)
+void wpa_supplicant_ctrl_iface_deinit(struct wpa_supplicant *wpa_s,
+				      struct ctrl_iface_priv *priv)
 {
+	if (!priv)
+		return;
 	while (priv->ctrl_dst)
 		ctrl_close_pipe(priv->ctrl_dst);
 	if (priv->sec_attr_set)
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ctrl_iface_udp.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ctrl_iface_udp.c
index 1512080..1cbf7fa 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ctrl_iface_udp.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ctrl_iface_udp.c
@@ -490,8 +490,12 @@
 }
 
 
-void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv)
+void wpa_supplicant_ctrl_iface_deinit(struct wpa_supplicant *wpa_s,
+				      struct ctrl_iface_priv *priv)
 {
+	if (!priv)
+		return;
+
 	if (priv->sock > -1) {
 		eloop_unregister_read_sock(priv->sock);
 		if (priv->ctrl_dst) {
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ctrl_iface_unix.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ctrl_iface_unix.c
index 953fd2c..84d5454 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ctrl_iface_unix.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/ctrl_iface_unix.c
@@ -208,14 +208,6 @@
 				"ctrl_iface sendto failed: %d - %s",
 				_errno, strerror(_errno));
 			if (_errno == ENOBUFS || _errno == EAGAIN) {
-				/*
-				 * The socket send buffer could be full. This
-				 * may happen if client programs are not
-				 * receiving their pending messages. Close and
-				 * reopen the socket as a workaround to avoid
-				 * getting stuck being unable to send any new
-				 * responses.
-				 */
 				sock = wpas_ctrl_iface_reinit(wpa_s, priv);
 				if (sock < 0) {
 					wpa_dbg(wpa_s, MSG_DEBUG, "Failed to reinitialize ctrl_iface socket");
@@ -800,12 +792,52 @@
 }
 
 
-void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv)
+static void
+wpas_global_ctrl_iface_flush_queued_msg(struct wpa_global *global,
+					struct wpa_supplicant *wpa_s)
+{
+	struct ctrl_iface_global_priv *gpriv;
+	struct ctrl_iface_msg *msg, *prev_msg;
+	unsigned int count = 0;
+
+	if (!global || !global->ctrl_iface)
+		return;
+
+	gpriv = global->ctrl_iface;
+	dl_list_for_each_safe(msg, prev_msg, &gpriv->msg_queue,
+			      struct ctrl_iface_msg, list) {
+		if (msg->wpa_s == wpa_s) {
+			count++;
+			dl_list_del(&msg->list);
+			os_free(msg);
+		}
+	}
+
+	if (count) {
+		wpa_printf(MSG_DEBUG,
+			   "CTRL: Dropped %u pending message(s) for interface that is being removed",
+			count);
+	}
+}
+
+
+void wpa_supplicant_ctrl_iface_deinit(struct wpa_supplicant *wpa_s,
+				      struct ctrl_iface_priv *priv)
 {
 	struct wpa_ctrl_dst *dst, *prev;
 	struct ctrl_iface_msg *msg, *prev_msg;
 	struct ctrl_iface_global_priv *gpriv;
 
+	if (!priv) {
+		/* Control interface has not yet been initialized, so there is
+		 * nothing to deinitialize here. However, there might be a
+		 * pending message for this interface, so get rid of any such
+		 * entry before completing interface removal. */
+		wpas_global_ctrl_iface_flush_queued_msg(wpa_s->global, wpa_s);
+		eloop_cancel_timeout(wpas_ctrl_msg_queue_timeout, wpa_s, NULL);
+		return;
+	}
+
 	if (priv->sock > -1) {
 		char *fname;
 		char *buf, *dir = NULL;
@@ -877,6 +909,7 @@
 			}
 		}
 	}
+	wpas_global_ctrl_iface_flush_queued_msg(wpa_s->global, wpa_s);
 	eloop_cancel_timeout(wpas_ctrl_msg_queue_timeout, priv->wpa_s, NULL);
 	os_free(priv);
 }
@@ -967,13 +1000,6 @@
 		}
 
 		if (_errno == ENOBUFS || _errno == EAGAIN) {
-			/*
-			 * The socket send buffer could be full. This may happen
-			 * if client programs are not receiving their pending
-			 * messages. Close and reopen the socket as a workaround
-			 * to avoid getting stuck being unable to send any new
-			 * responses.
-			 */
 			if (priv)
 				sock = wpas_ctrl_iface_reinit(wpa_s, priv);
 			else if (gp)
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dbus/dbus_common.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dbus/dbus_common.c
index a727217..62f1a13 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dbus/dbus_common.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dbus/dbus_common.c
@@ -303,13 +303,6 @@
 	/* Tell dbus about our mainloop integration functions */
 	integrate_with_eloop(priv);
 
-	/*
-	 * Dispatch initial DBus messages that may have come in since the bus
-	 * name was claimed above. Happens when clients are quick to notice the
-	 * service.
-	 *
-	 * FIXME: is there a better solution to this problem?
-	 */
 	eloop_register_timeout(0, 50, dispatch_initial_dbus_messages,
 			       priv->con, NULL);
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dbus/dbus_new.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dbus/dbus_new.c
index 2c01943..9279ae4 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dbus/dbus_new.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dbus/dbus_new.c
@@ -937,6 +937,95 @@
 #endif /* CONFIG_MESH */
 
 
+#ifdef CONFIG_INTERWORKING
+
+void wpas_dbus_signal_interworking_ap_added(struct wpa_supplicant *wpa_s,
+					    struct wpa_bss *bss,
+					    struct wpa_cred *cred,
+					    const char *type,
+					    int excluded,
+					    int bh,
+					    int bss_load,
+					    int conn_capab)
+{
+	struct wpas_dbus_priv *iface;
+	DBusMessage *msg;
+	DBusMessageIter iter, dict_iter;
+	char bss_path[WPAS_DBUS_OBJECT_PATH_MAX], *bss_obj_path;
+	char cred_path[WPAS_DBUS_OBJECT_PATH_MAX], *cred_obj_path;
+
+	iface = wpa_s->global->dbus;
+
+	/* Do nothing if the control interface is not turned on */
+	if (!iface || !wpa_s->dbus_new_path)
+		return;
+
+	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
+				      WPAS_DBUS_NEW_IFACE_INTERFACE,
+				      "InterworkingAPAdded");
+	if (!msg)
+		return;
+
+	os_snprintf(bss_path, WPAS_DBUS_OBJECT_PATH_MAX,
+		    "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
+		    wpa_s->dbus_new_path, bss->id);
+	bss_obj_path = bss_path;
+
+	os_snprintf(cred_path, WPAS_DBUS_OBJECT_PATH_MAX,
+		    "%s/" WPAS_DBUS_NEW_CREDENTIALS_PART "/%u",
+		    wpa_s->dbus_new_path, cred->id);
+	cred_obj_path = cred_path;
+
+	dbus_message_iter_init_append(msg, &iter);
+	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
+					    &bss_obj_path) ||
+	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
+					    &cred_obj_path) ||
+	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
+	    !wpa_dbus_dict_append_string(&dict_iter, "type", type) ||
+	    !wpa_dbus_dict_append_int32(&dict_iter, "excluded", excluded) ||
+	    !wpa_dbus_dict_append_int32(&dict_iter, "priority",
+					cred->priority) ||
+	    !wpa_dbus_dict_append_int32(&dict_iter, "sp_priority",
+					cred->sp_priority) ||
+	    !wpa_dbus_dict_append_int32(&dict_iter, "below_min_backhaul", bh) ||
+	    !wpa_dbus_dict_append_int32(&dict_iter, "over_max_bss_load",
+					bss_load) ||
+	    !wpa_dbus_dict_append_int32(&dict_iter, "conn_capab_missing",
+					conn_capab) ||
+	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
+		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
+	else
+		dbus_connection_send(iface->con, msg, NULL);
+	dbus_message_unref(msg);
+}
+
+
+void wpas_dbus_signal_interworking_select_done(struct wpa_supplicant *wpa_s)
+{
+	struct wpas_dbus_priv *iface;
+	DBusMessage *msg;
+
+	iface = wpa_s->global->dbus;
+
+	/* Do nothing if the control interface is not turned on */
+	if (!iface || !wpa_s->dbus_new_path)
+		return;
+
+	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
+				      WPAS_DBUS_NEW_IFACE_INTERFACE,
+				      "InterworkingSelectDone");
+	if (!msg)
+		return;
+
+	dbus_connection_send(iface->con, msg, NULL);
+
+	dbus_message_unref(msg);
+}
+
+#endif /* CONFIG_INTERWORKING */
+
+
 void wpas_dbus_signal_certification(struct wpa_supplicant *wpa_s,
 				    int depth, const char *subject,
 				    const char *altsubject[],
@@ -3570,6 +3659,35 @@
 		  END_ARGS
 	  }
 	},
+#ifdef CONFIG_INTERWORKING
+	{ "AddCred", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  (WPADBusMethodHandler) wpas_dbus_handler_add_cred,
+	  {
+		  { "args", "a{sv}", ARG_IN },
+		  { "path", "o", ARG_OUT },
+		  END_ARGS
+	  }
+	},
+	{ "RemoveCred", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  (WPADBusMethodHandler) wpas_dbus_handler_remove_cred,
+	  {
+		  { "path", "o", ARG_IN },
+		  END_ARGS
+	  }
+	},
+	{ "RemoveAllCreds", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  (WPADBusMethodHandler) wpas_dbus_handler_remove_all_creds,
+	  {
+		  END_ARGS
+	  }
+	},
+	{ "InterworkingSelect", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  (WPADBusMethodHandler) wpas_dbus_handler_interworking_select,
+	  {
+		  END_ARGS
+	  }
+	},
+#endif /* CONFIG_INTERWORKING */
 	{ NULL, NULL, NULL, { END_ARGS } }
 };
 
@@ -4137,6 +4255,21 @@
 	  }
 	},
 #endif /* CONFIG_MESH */
+#ifdef CONFIG_INTERWORKING
+	{ "InterworkingAPAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  {
+		  { "bss", "o", ARG_OUT },
+		  { "cred", "o", ARG_OUT },
+		  { "properties", "a{sv}", ARG_OUT },
+		  END_ARGS
+	  }
+	},
+	{ "InterworkingSelectDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  {
+		  END_ARGS
+	  }
+	},
+#endif /* CONFIG_INTERWORKING */
 	{ NULL, NULL, { END_ARGS } }
 };
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dbus/dbus_new.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dbus/dbus_new.h
index 42db389..26bdcb5 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dbus/dbus_new.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dbus/dbus_new.h
@@ -16,6 +16,8 @@
 struct wpa_global;
 struct wpa_supplicant;
 struct wpa_ssid;
+struct wpa_cred;
+struct wpa_bss;
 struct wps_event_m2d;
 struct wps_event_fail;
 struct wps_credential;
@@ -96,6 +98,9 @@
 #define WPAS_DBUS_NEW_P2P_PEERS_PART	"Peers"
 #define	WPAS_DBUS_NEW_IFACE_P2P_PEER WPAS_DBUS_NEW_INTERFACE ".Peer"
 
+#define WPAS_DBUS_NEW_CREDENTIALS_PART "Credentials"
+#define WPAS_DBUS_NEW_IFACE_CREDENTIAL WPAS_DBUS_NEW_INTERFACE ".Credential"
+
 /* Top-level Errors */
 #define WPAS_DBUS_ERROR_UNKNOWN_ERROR \
 	WPAS_DBUS_NEW_INTERFACE ".UnknownError"
@@ -264,6 +269,13 @@
 					  const u8 *peer_addr);
 void wpas_dbus_signal_mesh_peer_disconnected(struct wpa_supplicant *wpa_s,
 					     const u8 *peer_addr, int reason);
+void wpas_dbus_signal_interworking_ap_added(struct wpa_supplicant *wpa_s,
+					    struct wpa_bss *bss,
+					    struct wpa_cred *cred,
+					    const char *type, int excluded,
+					    int bh, int bss_load,
+					    int conn_capab);
+void wpas_dbus_signal_interworking_select_done(struct wpa_supplicant *wpa_s);
 
 #else /* CONFIG_CTRL_IFACE_DBUS_NEW */
 
@@ -616,6 +628,21 @@
 {
 }
 
+static inline
+void wpas_dbus_signal_interworking_ap_added(struct wpa_supplicant *wpa_s,
+					    struct wpa_bss *bss,
+					    struct wpa_cred *cred,
+					    const char *type, int excluded,
+					    int bh, int bss_load,
+					    int conn_capab)
+{
+}
+
+static inline
+void wpas_dbus_signal_interworking_select_done(struct wpa_supplicant *wpa_s)
+{
+}
+
 #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
 
 #endif /* CTRL_IFACE_DBUS_H_NEW */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dbus/dbus_new_handlers.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dbus/dbus_new_handlers.c
index fa9a1a3..959a68b 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -26,6 +26,7 @@
 #include "../scan.h"
 #include "../autoscan.h"
 #include "../ap.h"
+#include "../interworking.h"
 #include "dbus_new_helpers.h"
 #include "dbus_new.h"
 #include "dbus_new_handlers.h"
@@ -138,7 +139,9 @@
 static const char * const dont_quote[] = {
 	"key_mgmt", "proto", "pairwise", "auth_alg", "group", "eap",
 	"bssid", "scan_freq", "freq_list", "scan_ssid", "bssid_hint",
-	"bssid_blacklist", "bssid_whitelist", "group_mgmt",
+	"bssid_ignore", "bssid_accept", /* deprecated aliases */
+	"bssid_blacklist", "bssid_whitelist",
+	"group_mgmt",
 	"ignore_broadcast_ssid",
 #ifdef CONFIG_MESH
 	"mesh_basic_rates",
@@ -146,6 +149,9 @@
 #ifdef CONFIG_P2P
 	"go_p2p_dev_addr", "p2p_client_list", "psk_list",
 #endif /* CONFIG_P2P */
+#ifdef CONFIG_INTERWORKING
+	"roaming_consortium", "required_roaming_consortium",
+#endif /* CONFIG_INTERWORKING */
 	NULL
 };
 
@@ -327,6 +333,110 @@
 
 
 /**
+ * set_cred_properties - Set the properties of a configured credential
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * @cred: wpa_cred structure for a configured credential
+ * @iter: DBus message iterator containing dictionary of network
+ * properties to set.
+ * @error: On failure, an error describing the failure
+ * Returns: TRUE if the request succeeds, FALSE if it failed
+ */
+static dbus_bool_t set_cred_properties(struct wpa_supplicant *wpa_s,
+				       struct wpa_cred *cred,
+				       DBusMessageIter *iter,
+				       DBusError *error)
+{
+	struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
+	DBusMessageIter	iter_dict;
+	char *value = NULL;
+
+	if (!wpa_dbus_dict_open_read(iter, &iter_dict, error))
+		return FALSE;
+
+	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
+		size_t size = 50;
+		int ret;
+
+		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
+			goto error;
+
+		value = NULL;
+		if (entry.type == DBUS_TYPE_ARRAY &&
+		    entry.array_type == DBUS_TYPE_BYTE) {
+			if (entry.array_len <= 0)
+				goto error;
+
+			size = entry.array_len * 2 + 1;
+			value = os_zalloc(size);
+			if (!value)
+				goto error;
+
+			ret = wpa_snprintf_hex(value, size,
+					       (u8 *) entry.bytearray_value,
+					       entry.array_len);
+			if (ret <= 0)
+				goto error;
+		} else if (entry.type == DBUS_TYPE_STRING) {
+			if (should_quote_opt(entry.key)) {
+				size = os_strlen(entry.str_value);
+
+				size += 3;
+				value = os_zalloc(size);
+				if (!value)
+					goto error;
+
+				ret = os_snprintf(value, size, "\"%s\"",
+						  entry.str_value);
+				if (os_snprintf_error(size, ret))
+					goto error;
+			} else {
+				value = os_strdup(entry.str_value);
+				if (!value)
+					goto error;
+			}
+		} else if (entry.type == DBUS_TYPE_UINT32) {
+			value = os_zalloc(size);
+			if (!value)
+				goto error;
+
+			ret = os_snprintf(value, size, "%u",
+					  entry.uint32_value);
+			if (os_snprintf_error(size, ret))
+				goto error;
+		} else if (entry.type == DBUS_TYPE_INT32) {
+			value = os_zalloc(size);
+			if (!value)
+				goto error;
+
+			ret = os_snprintf(value, size, "%d",
+					  entry.int32_value);
+			if (os_snprintf_error(size, ret))
+				goto error;
+		} else {
+			goto error;
+		}
+
+		ret = wpa_config_set_cred(cred, entry.key, value, 0);
+		if (ret < 0)
+			goto error;
+
+		os_free(value);
+		value = NULL;
+		wpa_dbus_dict_entry_clear(&entry);
+	}
+
+	return TRUE;
+
+error:
+	os_free(value);
+	wpa_dbus_dict_entry_clear(&entry);
+	dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
+			     "invalid message format");
+	return FALSE;
+}
+
+
+/**
  * wpas_dbus_simple_property_getter - Get basic type property
  * @iter: Message iter to use when appending arguments
  * @type: DBus type of property (must be basic type)
@@ -1011,7 +1121,7 @@
 	const struct wpa_dbus_property_desc *property_desc,
 	DBusMessageIter *iter, DBusError *error, void *user_data)
 {
-	const char *capabilities[12];
+	const char *capabilities[13];
 	size_t num_items = 0;
 	struct wpa_global *global = user_data;
 	struct wpa_supplicant *wpa_s;
@@ -1062,6 +1172,9 @@
 #ifdef CONFIG_OWE
 	capabilities[num_items++] = "owe";
 #endif /* CONFIG_OWE */
+#ifdef CONFIG_SUITEB192
+	capabilities[num_items++] = "suiteb192";
+#endif /* CONFIG_SUITEB192 */
 	if (ext_key_id_supported)
 		capabilities[num_items++] = "extended_key_id";
 
@@ -1511,6 +1624,187 @@
 
 
 /**
+ * wpas_dbus_new_iface_add_cred - Add a new credential
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: A dbus message containing the object path of the new credential
+ *
+ * Handler function for "AddCred" method call of a network interface.
+ */
+DBusMessage * wpas_dbus_handler_add_cred(DBusMessage *message,
+					 struct wpa_supplicant *wpa_s)
+{
+	DBusMessage *reply = NULL;
+	DBusMessageIter	iter;
+	struct wpa_cred *cred = NULL;
+	char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf;
+	DBusError error;
+
+	dbus_message_iter_init(message, &iter);
+
+	if (wpa_s->dbus_new_path)
+		cred = wpa_config_add_cred(wpa_s->conf);
+	if (!cred) {
+		wpa_printf(MSG_ERROR, "%s[dbus]: can't add new credential.",
+			   __func__);
+		reply = wpas_dbus_error_unknown_error(
+			message,
+			"wpa_supplicant could not add a credential on this interface.");
+		goto err;
+	}
+
+	dbus_error_init(&error);
+	if (!set_cred_properties(wpa_s, cred, &iter, &error)) {
+		wpa_printf(MSG_DEBUG,
+			   "%s[dbus]: control interface couldn't set credential properties",
+			   __func__);
+		reply = wpas_dbus_reply_new_from_error(message, &error,
+						       DBUS_ERROR_INVALID_ARGS,
+						       "Failed to add credential");
+		dbus_error_free(&error);
+		goto err;
+	}
+
+	/* Construct the object path for this network. */
+	os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
+		    "%s/" WPAS_DBUS_NEW_CREDENTIALS_PART "/%d",
+		    wpa_s->dbus_new_path, cred->id);
+
+	reply = dbus_message_new_method_return(message);
+	if (!reply) {
+		reply = wpas_dbus_error_no_memory(message);
+		goto err;
+	}
+	if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
+				      DBUS_TYPE_INVALID)) {
+		dbus_message_unref(reply);
+		reply = wpas_dbus_error_no_memory(message);
+		goto err;
+	}
+
+	return reply;
+
+err:
+	if (cred)
+		wpa_config_remove_cred(wpa_s->conf, cred->id);
+	return reply;
+}
+
+
+/**
+ * wpas_dbus_handler_remove_cred - Remove a configured credential
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: NULL on success or dbus error on failure
+ *
+ * Handler function for "RemoveCred" method call of a network interface.
+ */
+DBusMessage * wpas_dbus_handler_remove_cred(DBusMessage *message,
+					    struct wpa_supplicant *wpa_s)
+{
+	DBusMessage *reply = NULL;
+	const char *op;
+	char *iface, *cred_id;
+	int id;
+	struct wpa_cred *cred;
+
+	dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
+			      DBUS_TYPE_INVALID);
+
+	/* Extract the network ID and ensure the network is actually a child of
+	 * this interface */
+	iface = wpas_dbus_new_decompose_object_path(
+		op, WPAS_DBUS_NEW_CREDENTIALS_PART, &cred_id);
+	if (!iface || !cred_id || !wpa_s->dbus_new_path ||
+	    os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
+		reply = wpas_dbus_error_invalid_args(message, op);
+		goto out;
+	}
+
+	errno = 0;
+	id = strtoul(cred_id, NULL, 10);
+	if (errno != 0) {
+		reply = wpas_dbus_error_invalid_args(message, op);
+		goto out;
+	}
+
+	cred = wpa_config_get_cred(wpa_s->conf, id);
+	if (!cred) {
+		wpa_printf(MSG_ERROR, "%s[dbus]: could not find credential %s",
+			   __func__, op);
+		reply = wpas_dbus_error_invalid_args(
+			message, "could not find credential");
+		goto out;
+	}
+
+	if (wpas_remove_cred(wpa_s, cred) < 0) {
+		wpa_printf(MSG_ERROR,
+			   "%s[dbus]: error occurred when removing cred %d",
+			   __func__, id);
+		reply = wpas_dbus_error_unknown_error(
+			message,
+			"error removing the specified credential on its interface.");
+		goto out;
+	}
+
+out:
+	os_free(iface);
+	return reply;
+}
+
+
+/**
+ * wpas_dbus_handler_remove_all_creds - Remove all the configured credentials
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: NULL indicating success or DBus error message on failure
+ *
+ * Handler function for "RemoveAllCreds" method call of a network interface.
+ */
+DBusMessage * wpas_dbus_handler_remove_all_creds(DBusMessage *message,
+						 struct wpa_supplicant *wpa_s)
+{
+	int res;
+	DBusMessage *reply = NULL;
+
+	res = wpas_remove_all_creds(wpa_s);
+	if (res < 0) {
+		wpa_printf(MSG_ERROR,
+			   "%s[dbus]: failed to remove all credentials",
+			   __func__);
+		reply = wpas_dbus_error_unknown_error(
+			message, "failed to remove all credentials");
+	}
+
+	return reply;
+}
+
+
+#ifdef CONFIG_INTERWORKING
+DBusMessage *
+wpas_dbus_handler_interworking_select(DBusMessage *message,
+				      struct wpa_supplicant *wpa_s)
+{
+	int result;
+	DBusMessage *reply = NULL;
+
+	/* Automatic selection is disabled and no constraint on channels */
+	result = interworking_select(wpa_s, 0, NULL);
+	if (result < 0) {
+		wpa_printf(MSG_ERROR,
+			   "%s[dbus]: failed to start Interworking selection",
+			   __func__);
+		reply = wpas_dbus_error_scan_error(
+			message,
+			"error starting Interworking selection.");
+	}
+
+	return reply;
+}
+#endif /* CONFIG_INTERWORKING */
+
+
+/**
  * wpas_dbus_handler_signal_poll - Request immediate signal properties
  * @message: Pointer to incoming dbus message
  * @wpa_s: wpa_supplicant structure for a network interface
@@ -1697,7 +1991,8 @@
  * Returns: NULL
  *
  * Handler function for notifying system there will be a expected disconnect.
- * This will prevent wpa_supplicant from adding blacklists upon next disconnect..
+ * This will prevent wpa_supplicant from adding the BSSID to the ignore list
+ * upon next disconnect.
  */
 DBusMessage * wpas_dbus_handler_expect_disconnect(DBusMessage *message,
 						  struct wpa_global *global)
@@ -1973,6 +2268,7 @@
 	struct wpa_bss *bss;
 	struct wpa_ssid *ssid = wpa_s->current_ssid;
 	char *addr;
+	struct wpa_radio_work *already_connecting;
 
 	if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &addr,
 				   DBUS_TYPE_INVALID))
@@ -1996,9 +2292,18 @@
 			message, "Target BSS not found");
 	}
 
+	already_connecting = radio_work_pending(wpa_s, "sme-connect");
 	wpa_s->reassociate = 1;
 	wpa_supplicant_connect(wpa_s, bss, ssid);
 
+	/*
+	 * Indicate that an explicitly requested roam is in progress so scan
+	 * results that come in before the 'sme-connect' radio work gets
+	 * executed do not override the original connection attempt.
+	 */
+	if (!already_connecting && radio_work_pending(wpa_s, "sme-connect"))
+		wpa_s->roam_in_progress = true;
+
 	return NULL;
 #endif /* CONFIG_NO_SCAN_PROCESSING */
 }
@@ -2869,6 +3174,12 @@
 			goto nomem;
 #endif /* CONFIG_SAE */
 
+#ifdef CONFIG_OWE
+		if ((capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_OWE) &&
+		    !wpa_dbus_dict_string_array_add_element(&iter_array, "owe"))
+			goto nomem;
+#endif /* CONFIG_OWE */
+
 		if (!wpa_dbus_dict_end_string_array(&iter_dict,
 						    &iter_dict_entry,
 						    &iter_dict_val,
@@ -5073,8 +5384,8 @@
 		return FALSE;
 
 	return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
-						      res + 1, res->ie_len,
-						      error);
+						      wpa_bss_ie_ptr(res),
+						      res->ie_len, error);
 }
 
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dbus/dbus_new_handlers.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dbus/dbus_new_handlers.h
index c36383f..a421083 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dbus/dbus_new_handlers.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dbus/dbus_new_handlers.h
@@ -144,6 +144,19 @@
 DBusMessage * wpas_dbus_handler_eap_logon(DBusMessage *message,
 					  struct wpa_supplicant *wpa_s);
 
+DBusMessage * wpas_dbus_handler_add_cred(DBusMessage *message,
+					 struct wpa_supplicant *wpa_s);
+
+DBusMessage * wpas_dbus_handler_remove_cred(DBusMessage *message,
+					    struct wpa_supplicant *wpa_s);
+
+DBusMessage * wpas_dbus_handler_remove_all_creds(DBusMessage *message,
+						 struct wpa_supplicant *wpa_s);
+
+DBusMessage *
+wpas_dbus_handler_interworking_select(DBusMessage *message,
+				      struct wpa_supplicant *wpa_s);
+
 DECLARE_ACCESSOR(wpas_dbus_getter_capabilities);
 DECLARE_ACCESSOR(wpas_dbus_getter_state);
 DECLARE_ACCESSOR(wpas_dbus_getter_scanning);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
index 7a65673..de79178 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
@@ -175,7 +175,7 @@
 	}
 
 	if (wpas_p2p_find(wpa_s, timeout, type, num_req_dev_types,
-			  req_dev_types, NULL, 0, 0, NULL, freq))
+			  req_dev_types, NULL, 0, 0, NULL, freq, false))
 		reply = wpas_dbus_error_unknown_error(
 			message, "Could not start P2P find");
 
@@ -425,14 +425,15 @@
 			goto inv_args;
 
 		if (wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 0, 0, 0,
-						  0, 0, 0, 0, NULL, 0, 0)) {
+						  0, 0, 0, 0, NULL, 0, 0,
+						  false)) {
 			reply = wpas_dbus_error_unknown_error(
 				message,
 				"Failed to reinvoke a persistent group");
 			goto out;
 		}
 	} else if (wpas_p2p_group_add(wpa_s, persistent_group, freq, 0, 0, 0,
-				      0, 0, 0))
+				      0, 0, 0, false))
 		goto inv_args;
 
 out:
@@ -653,7 +654,7 @@
 	new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method,
 				   persistent_group, 0, join, authorize_only,
 				   go_intent, freq, 0, -1, 0, 0, 0, 0, 0, 0,
-				   NULL, 0);
+				   NULL, 0, false);
 
 	if (new_pin >= 0) {
 		char npin[9];
@@ -743,6 +744,7 @@
 	unsigned int group_id = 0;
 	int persistent = 0;
 	struct wpa_ssid *ssid;
+	const char *group_ifname;
 
 	if (!wpa_dbus_p2p_check_enabled(wpa_s, message, &reply, NULL))
 		return reply;
@@ -776,6 +778,8 @@
 	    !p2p_peer_known(wpa_s->global->p2p, peer_addr))
 		goto err;
 
+	/* Capture the interface name for the group first */
+	group_ifname = wpa_s->ifname;
 	wpa_s = wpa_s->global->p2p_init_wpa_s;
 
 	if (persistent) {
@@ -810,7 +814,7 @@
 			goto err;
 
 		if (wpas_p2p_invite(wpa_s, peer_addr, ssid, NULL, 0, 0, 0, 0, 0,
-				    0, 0, 0) < 0) {
+				    0, 0, 0, false) < 0) {
 			reply = wpas_dbus_error_unknown_error(
 				message,
 				"Failed to reinvoke a persistent group");
@@ -820,8 +824,8 @@
 		/*
 		 * No group ID means propose to a peer to join my active group
 		 */
-		if (wpas_p2p_invite_group(wpa_s, wpa_s->ifname,
-					  peer_addr, NULL)) {
+		if (wpas_p2p_invite_group(wpa_s, group_ifname,
+					  peer_addr, NULL, false)) {
 			reply = wpas_dbus_error_unknown_error(
 				message, "Failed to join to an active group");
 			goto out;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/defconfig b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/defconfig
index a0fe94e..aff423a 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/defconfig
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/defconfig
@@ -248,6 +248,9 @@
 # Simultaneous Authentication of Equals (SAE), WPA3-Personal
 CONFIG_SAE=y
 
+# Set SAE Auth status early
+CONFIG_WPA3_SAE_AUTH_EARLY_SET=y
+
 # Disable scan result processing (ap_scan=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
@@ -530,6 +533,8 @@
 #
 # External password backend for testing purposes (developer use)
 #CONFIG_EXT_PASSWORD_TEST=y
+# File-based backend to read passwords from an external file.
+#CONFIG_EXT_PASSWORD_FILE=y
 
 # Enable Fast Session Transfer (FST)
 #CONFIG_FST=y
@@ -601,8 +606,13 @@
 # Experimental implementation of draft-harkins-owe-07.txt
 #CONFIG_OWE=y
 
-# Device Provisioning Protocol (DPP)
+# Device Provisioning Protocol (DPP) (also known as Wi-Fi Easy Connect)
 CONFIG_DPP=y
+# DPP version 2 support
+CONFIG_DPP2=y
+# DPP version 3 support (experimental and still changing; do not enable for
+# production use)
+#CONFIG_DPP3=y
 
 # Wired equivalent privacy (WEP)
 # WEP is an obsolete cryptographic data confidentiality algorithm that is not
@@ -620,3 +630,9 @@
 # support for this by default, but that functionality is subject to be removed
 # in the future.
 #CONFIG_NO_TKIP=y
+
+# Pre-Association Security Negotiation (PASN)
+# Experimental implementation based on IEEE P802.11z/D2.6 and the protocol
+# design is still subject to change. As such, this should not yet be enabled in
+# production use.
+#CONFIG_PASN=y
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/defconfig_auto b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/defconfig_auto
index a119600..0199bde 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/defconfig_auto
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/defconfig_auto
@@ -248,6 +248,9 @@
 # Simultaneous Authentication of Equals (SAE), WPA3-Personal
 CONFIG_SAE=y
 
+# Set SAE Auth status early
+CONFIG_WPA3_SAE_AUTH_EARLY_SET=y
+
 # Host SAE via Vendor commands
 #CONFIG_WL_SAE=y
 
@@ -614,11 +617,11 @@
 CONFIG_BGSCAN_SIMPLE=y
 # Learn channels used by the network and try to avoid bgscans on other
 # channels (experimental)
-#CONFIG_BGSCAN_LEARN=y
+CONFIG_BGSCAN_LEARN=y
 
 # Opportunistic Wireless Encryption (OWE)
 # Experimental implementation of draft-harkins-owe-07.txt
-#CONFIG_OWE=y
+CONFIG_OWE=y
 
 # Device Provisioning Protocol (DPP)
 # This requires CONFIG_IEEE80211W=y to be enabled, too. (see
@@ -646,3 +649,6 @@
 
 # Enable all IFX/Cypress changes
 CONFIG_DRIVER_NL80211_IFX=y
+
+# Offload the TWT Session management to FW
+CONFIG_TWT_OFFLOAD_IFX=y
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/defconfig_auto_all b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/defconfig_auto_all
index 8811b45..7b5a7c6 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/defconfig_auto_all
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/defconfig_auto_all
@@ -596,6 +596,8 @@
 
 # Simultaneous Authentication of Equals (SAE), WPA3-Personal
 CONFIG_SAE=y
+
+# Set SAE Auth status early
 CONFIG_WPA3_SAE_AUTH_EARLY_SET=y
 
 # Host SAE via Vendor commands
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/defconfig_auto_wapi b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/defconfig_auto_wapi
index df04082..988d182 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/defconfig_auto_wapi
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/defconfig_auto_wapi
@@ -102,6 +102,9 @@
 # WPA3-Personal (SAE)
 CONFIG_SAE=y
 
+# Set SAE Auth status early
+CONFIG_WPA3_SAE_AUTH_EARLY_SET=y
+
 # Driver interface for Windows NDIS
 #CONFIG_DRIVER_NDIS=y
 #CFLAGS += -I/usr/include/w32api/ddk
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/defconfig_commercial b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/defconfig_commercial
index 15daf0a..bfed04e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/defconfig_commercial
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/defconfig_commercial
@@ -248,6 +248,9 @@
 # Simultaneous Authentication of Equals (SAE), WPA3-Personal
 CONFIG_SAE=y
 
+# Set SAE Auth status early
+CONFIG_WPA3_SAE_AUTH_EARLY_SET=y
+
 # Disable scan result processing (ap_scan=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
@@ -633,3 +636,4 @@
 # connect to this hostapd. These options allow, for example, to drop a
 # certain percentage of probe requests or auth/(re)assoc frames.
 CONFIG_TESTING_OPTIONS=y
+CONFIG_TWT_OFFLOAD_IFX=y
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/eapol_test.sgml b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/eapol_test.sgml
index e7705ab..b9b0a95 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/eapol_test.sgml
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/eapol_test.sgml
@@ -1,6 +1,10 @@
 <!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
 
 <refentry>
+  <refentryinfo>
+    <date>07 August 2019</date>
+  </refentryinfo>
+
   <refmeta>
     <refentrytitle>eapol_test</refentrytitle>
     <manvolnum>8</manvolnum>
@@ -194,7 +198,7 @@
   </refsect1>
   <refsect1>
     <title>Legal</title>
-    <para>wpa_supplicant is copyright (c) 2003-2019,
+    <para>wpa_supplicant is copyright (c) 2003-2022,
     Jouni Malinen <email>j@w1.fi</email> and
     contributors.
     All Rights Reserved.</para>
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_background.sgml b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_background.sgml
index f6a0ca8..b0592e2 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_background.sgml
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_background.sgml
@@ -1,6 +1,10 @@
 <!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
 
 <refentry>
+  <refentryinfo>
+    <date>07 August 2019</date>
+  </refentryinfo>
+
   <refmeta>
     <refentrytitle>wpa_background</refentrytitle>
     <manvolnum>8</manvolnum>
@@ -90,7 +94,7 @@
 
   <refsect1>
     <title>Legal</title>
-    <para>wpa_supplicant is copyright (c) 2003-2019,
+    <para>wpa_supplicant is copyright (c) 2003-2022,
     Jouni Malinen <email>j@w1.fi</email> and
     contributors.
     All Rights Reserved.</para>
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_cli.sgml b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_cli.sgml
index dc7fee4..b3d95ee 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_cli.sgml
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_cli.sgml
@@ -1,6 +1,10 @@
 <!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
 
 <refentry>
+  <refentryinfo>
+    <date>07 August 2019</date>
+  </refentryinfo>
+
   <refmeta>
     <refentrytitle>wpa_cli</refentrytitle>
     <manvolnum>8</manvolnum>
@@ -345,7 +349,7 @@
   </refsect1>
   <refsect1>
     <title>Legal</title>
-    <para>wpa_supplicant is copyright (c) 2003-2019,
+    <para>wpa_supplicant is copyright (c) 2003-2022,
     Jouni Malinen <email>j@w1.fi</email> and
     contributors.
     All Rights Reserved.</para>
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_gui.sgml b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_gui.sgml
index 31214e3..c391645 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_gui.sgml
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_gui.sgml
@@ -1,6 +1,10 @@
 <!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
 
 <refentry>
+  <refentryinfo>
+    <date>07 August 2019</date>
+  </refentryinfo>
+
   <refmeta>
     <refentrytitle>wpa_gui</refentrytitle>
     <manvolnum>8</manvolnum>
@@ -91,7 +95,7 @@
   </refsect1>
   <refsect1>
     <title>Legal</title>
-    <para>wpa_supplicant is copyright (c) 2003-2019,
+    <para>wpa_supplicant is copyright (c) 2003-2022,
     Jouni Malinen <email>j@w1.fi</email> and
     contributors.
     All Rights Reserved.</para>
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_passphrase.sgml b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_passphrase.sgml
index ed9baf1..5934e79 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_passphrase.sgml
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_passphrase.sgml
@@ -1,6 +1,10 @@
 <!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
 
 <refentry>
+  <refentryinfo>
+    <date>07 August 2019</date>
+  </refentryinfo>
+
   <refmeta>
     <refentrytitle>wpa_passphrase</refentrytitle>
     <manvolnum>8</manvolnum>
@@ -62,7 +66,7 @@
   </refsect1>
   <refsect1>
     <title>Legal</title>
-    <para>wpa_supplicant is copyright (c) 2003-2019,
+    <para>wpa_supplicant is copyright (c) 2003-2022,
     Jouni Malinen <email>j@w1.fi</email> and
     contributors.
     All Rights Reserved.</para>
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_priv.sgml b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_priv.sgml
index dd44565..4053eda 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_priv.sgml
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_priv.sgml
@@ -1,6 +1,10 @@
 <!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
 
 <refentry>
+  <refentryinfo>
+    <date>07 August 2019</date>
+  </refentryinfo>
+
   <refmeta>
     <refentrytitle>wpa_priv</refentrytitle>
     <manvolnum>8</manvolnum>
@@ -137,7 +141,7 @@
   </refsect1>
   <refsect1>
     <title>Legal</title>
-    <para>wpa_supplicant is copyright (c) 2003-2019,
+    <para>wpa_supplicant is copyright (c) 2003-2022,
     Jouni Malinen <email>j@w1.fi</email> and
     contributors.
     All Rights Reserved.</para>
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_supplicant.conf.sgml b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_supplicant.conf.sgml
index 462039d..8a0314e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_supplicant.conf.sgml
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_supplicant.conf.sgml
@@ -1,5 +1,9 @@
 <!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
 <refentry>
+  <refentryinfo>
+    <date>07 August 2019</date>
+  </refentryinfo>
+
   <refmeta>
     <refentrytitle>wpa_supplicant.conf</refentrytitle>
     <manvolnum>5</manvolnum>
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_supplicant.sgml b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
index aaff150..02012d1 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
@@ -1,6 +1,10 @@
 <!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
 
 <refentry>
+  <refentryinfo>
+    <date>07 August 2019</date>
+  </refentryinfo>
+
   <refmeta>
     <refentrytitle>wpa_supplicant</refentrytitle>
     <manvolnum>8</manvolnum>
@@ -42,7 +46,7 @@
     can be used to improve the network security, but even that has inherited
     security issues due to the use of WEP for encryption. Wi-Fi Protected
     Access and IEEE 802.11i amendment to the wireless LAN standard introduce
-    a much improvement mechanism for securing wireless networks. IEEE 802.11i
+    a much improved mechanism for securing wireless networks. IEEE 802.11i
     enabled networks that are using CCMP (encryption mechanism based on strong
     cryptographic algorithm AES) can finally be called secure used for
     applications which require efficient protection against unauthorized
@@ -749,7 +753,7 @@
   </refsect1>
   <refsect1>
     <title>Legal</title>
-    <para>wpa_supplicant is copyright (c) 2003-2019,
+    <para>wpa_supplicant is copyright (c) 2003-2022,
     Jouni Malinen <email>j@w1.fi</email> and
     contributors.
     All Rights Reserved.</para>
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dpp_supplicant.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dpp_supplicant.c
index 148cb65..a1a1375 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dpp_supplicant.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/dpp_supplicant.c
@@ -26,7 +26,9 @@
 #include "bss.h"
 #include "scan.h"
 #include "notify.h"
+#ifdef CONFIG_DPP
 #include "dpp_supplicant.h"
+#endif /* CONFIG_DPP */
 #ifdef CONFIG_CTRL_IFACE_HIDL
 #include "hidl.h"
 #endif
@@ -35,6 +37,7 @@
 static int wpas_dpp_listen_start(struct wpa_supplicant *wpa_s,
 				 unsigned int freq);
 static void wpas_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx);
+static void wpas_dpp_auth_conf_wait_timeout(void *eloop_ctx, void *timeout_ctx);
 static void wpas_dpp_auth_success(struct wpa_supplicant *wpa_s, int initiator);
 static void wpas_dpp_tx_status(struct wpa_supplicant *wpa_s,
 			       unsigned int freq, const u8 *dst,
@@ -476,6 +479,8 @@
 			   "DPP: Terminate authentication exchange due to a request to do so on TX status");
 		eloop_cancel_timeout(wpas_dpp_init_timeout, wpa_s, NULL);
 		eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
+		eloop_cancel_timeout(wpas_dpp_auth_conf_wait_timeout, wpa_s,
+				     NULL);
 		eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s,
 				     NULL);
 #ifdef CONFIG_DPP2
@@ -508,6 +513,17 @@
 		}
 	}
 
+	if (auth->waiting_auth_conf &&
+	    auth->auth_resp_status == DPP_STATUS_OK) {
+		/* Make sure we do not get stuck waiting for Auth Confirm
+		 * indefinitely after successfully transmitted Auth Response to
+		 * allow new authentication exchanges to be started. */
+		eloop_cancel_timeout(wpas_dpp_auth_conf_wait_timeout, wpa_s,
+				     NULL);
+		eloop_register_timeout(1, 0, wpas_dpp_auth_conf_wait_timeout,
+				       wpa_s, NULL);
+	}
+
 	if (!is_broadcast_ether_addr(dst) && auth->waiting_auth_resp &&
 	    result == OFFCHANNEL_SEND_ACTION_SUCCESS) {
 		/* Allow timeout handling to stop iteration if no response is
@@ -599,6 +615,23 @@
 }
 
 
+static void wpas_dpp_auth_conf_wait_timeout(void *eloop_ctx, void *timeout_ctx)
+{
+	struct wpa_supplicant *wpa_s = eloop_ctx;
+	struct dpp_authentication *auth = wpa_s->dpp_auth;
+
+	if (!auth || !auth->waiting_auth_conf)
+		return;
+
+	wpa_printf(MSG_DEBUG,
+		   "DPP: Terminate authentication exchange due to Auth Confirm timeout");
+	wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_FAIL "No Auth Confirm received");
+	offchannel_send_action_done(wpa_s);
+	dpp_auth_deinit(auth);
+	wpa_s->dpp_auth = NULL;
+}
+
+
 static void wpas_dpp_set_testing_options(struct wpa_supplicant *wpa_s,
 					 struct dpp_authentication *auth)
 {
@@ -687,7 +720,9 @@
 	freq = auth->freq[auth->freq_idx++];
 	auth->curr_freq = freq;
 
-	if (is_zero_ether_addr(auth->peer_bi->mac_addr))
+	if (!is_zero_ether_addr(auth->peer_mac_addr))
+		dst = auth->peer_mac_addr;
+	else if (is_zero_ether_addr(auth->peer_bi->mac_addr))
 		dst = broadcast;
 	else
 		dst = auth->peer_bi->mac_addr;
@@ -818,6 +853,8 @@
 	if (!tcp && wpa_s->dpp_auth) {
 		eloop_cancel_timeout(wpas_dpp_init_timeout, wpa_s, NULL);
 		eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
+		eloop_cancel_timeout(wpas_dpp_auth_conf_wait_timeout, wpa_s,
+				     NULL);
 		eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s,
 				     NULL);
 #ifdef CONFIG_DPP2
@@ -995,6 +1032,7 @@
 	wpa_drv_dpp_listen(wpa_s, false);
 	wpa_s->dpp_listen_freq = 0;
 	wpas_dpp_listen_work_done(wpa_s);
+	radio_remove_works(wpa_s, "dpp-listen", 0);
 }
 
 
@@ -1420,6 +1458,8 @@
 				      struct dpp_config_obj *conf)
 {
 	wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_RECEIVED);
+	wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONFOBJ_AKM "%s",
+		dpp_akm_str(conf->akm));
 	if (conf->ssid_len)
 		wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONFOBJ_SSID "%s",
 			wpa_ssid_txt(conf->ssid, conf->ssid_len));
@@ -1435,6 +1475,21 @@
 		wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONNECTOR "%s",
 			conf->connector);
 	}
+	if (conf->passphrase[0]) {
+		char hex[64 * 2 + 1];
+
+		wpa_snprintf_hex(hex, sizeof(hex),
+				 (const u8 *) conf->passphrase,
+				 os_strlen(conf->passphrase));
+		wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONFOBJ_PASS "%s",
+			hex);
+	} else if (conf->psk_set) {
+		char hex[PMK_LEN * 2 + 1];
+
+		wpa_snprintf_hex(hex, sizeof(hex), conf->psk, PMK_LEN);
+		wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONFOBJ_PSK "%s",
+			hex);
+	}
 	if (conf->c_sign_key) {
 		char *hex;
 		size_t hexlen;
@@ -1831,6 +1886,8 @@
 		return;
 	}
 
+	eloop_cancel_timeout(wpas_dpp_auth_conf_wait_timeout, wpa_s, NULL);
+
 	if (dpp_auth_conf_rx(auth, hdr, buf, len) < 0) {
 		wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
 #if !(defined(OREO) || defined(PIE))
@@ -1890,9 +1947,22 @@
 		   MAC2STR(src));
 
 	if (!auth || !auth->waiting_conf_result) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: No DPP Configuration waiting for result - drop");
-		return;
+		if (auth &&
+		    os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) == 0 &&
+		    gas_server_response_sent(wpa_s->gas_server,
+					     auth->gas_server_ctx)) {
+			/* This could happen if the TX status event gets delayed
+			 * long enough for the Enrollee to have time to send
+			 * the next frame before the TX status gets processed
+			 * locally. */
+			wpa_printf(MSG_DEBUG,
+				   "DPP: GAS response was sent but TX status not yet received - assume it was ACKed since the Enrollee sent the next frame in the sequence");
+			auth->waiting_conf_result = 1;
+		} else {
+			wpa_printf(MSG_DEBUG,
+				   "DPP: No DPP Configuration waiting for result - drop");
+			return;
+		}
 	}
 
 	if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) {
@@ -2047,8 +2117,9 @@
 
 	auth->neg_freq = freq;
 
-	if (!is_zero_ether_addr(peer_bi->mac_addr))
-		os_memcpy(auth->peer_mac_addr, peer_bi->mac_addr, ETH_ALEN);
+	/* The source address of the Presence Announcement frame overrides any
+	 * MAC address information from the bootstrapping information. */
+	os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
 
 	wpa_s->dpp_auth = auth;
 	if (wpas_dpp_auth_init_next(wpa_s) < 0) {
@@ -2420,6 +2491,16 @@
 			       &version_len);
 	if (version && version_len >= 1)
 		peer_version = version[0];
+#ifdef CONFIG_DPP3
+	if (intro.peer_version && intro.peer_version >= 2 &&
+	    peer_version != intro.peer_version) {
+		wpa_printf(MSG_INFO,
+			   "DPP: Protocol version mismatch (Connector: %d Attribute: %d",
+			   intro.peer_version, peer_version);
+		wpas_dpp_send_conn_status_result(wpa_s, DPP_STATUS_NO_MATCH);
+		goto fail;
+	}
+#endif /* CONFIG_DPP3 */
 	entry->dpp_pfs = peer_version >= 2;
 #endif /* CONFIG_DPP2 */
 	if (expiry) {
@@ -2526,7 +2607,9 @@
 	wpa_printf(MSG_DEBUG, "DPP: Retransmit PKEX Exchange Request (try %u)",
 		   pkex->exch_req_tries);
 	wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
-		MAC2STR(broadcast), pkex->freq, DPP_PA_PKEX_EXCHANGE_REQ);
+		MAC2STR(broadcast), pkex->freq,
+		pkex->v2 ? DPP_PA_PKEX_EXCHANGE_REQ :
+		DPP_PA_PKEX_V1_EXCHANGE_REQ);
 	offchannel_send_action(wpa_s, pkex->freq, broadcast,
 			       wpa_s->own_addr, broadcast,
 			       wpabuf_head(pkex->exchange_req),
@@ -2585,7 +2668,8 @@
 
 static void
 wpas_dpp_rx_pkex_exchange_req(struct wpa_supplicant *wpa_s, const u8 *src,
-			      const u8 *buf, size_t len, unsigned int freq)
+			      const u8 *buf, size_t len, unsigned int freq,
+			      bool v2)
 {
 	struct wpabuf *msg;
 	unsigned int wait_time;
@@ -2613,7 +2697,7 @@
 						   wpa_s->own_addr, src,
 						   wpa_s->dpp_pkex_identifier,
 						   wpa_s->dpp_pkex_code,
-						   buf, len);
+						   buf, len, v2);
 	if (!wpa_s->dpp_pkex) {
 		wpa_printf(MSG_DEBUG,
 			   "DPP: Failed to process the request - ignore it");
@@ -2836,8 +2920,17 @@
 	case DPP_PA_PEER_DISCOVERY_RESP:
 		wpas_dpp_rx_peer_disc_resp(wpa_s, src, buf, len);
 		break;
+#ifdef CONFIG_DPP3
 	case DPP_PA_PKEX_EXCHANGE_REQ:
-		wpas_dpp_rx_pkex_exchange_req(wpa_s, src, buf, len, freq);
+		/* This is for PKEXv2, but for now, process only with
+		 * CONFIG_DPP3 to avoid issues with a capability that has not
+		 * been tested with other implementations. */
+		wpas_dpp_rx_pkex_exchange_req(wpa_s, src, buf, len, freq, true);
+		break;
+#endif /* CONFIG_DPP3 */
+	case DPP_PA_PKEX_V1_EXCHANGE_REQ:
+		wpas_dpp_rx_pkex_exchange_req(wpa_s, src, buf, len, freq,
+					      false);
 		break;
 	case DPP_PA_PKEX_EXCHANGE_RESP:
 		wpas_dpp_rx_pkex_exchange_resp(wpa_s, src, buf, len, freq);
@@ -2945,6 +3038,7 @@
 #endif /* !(OREO || PIE) */
 	}
 	auth->conf_resp = resp;
+	auth->gas_server_ctx = resp_ctx;
 	return resp;
 }
 
@@ -2978,10 +3072,12 @@
 	wpa_printf(MSG_DEBUG, "DPP: Configuration exchange completed (ok=%d)",
 		   ok);
 	eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
+	eloop_cancel_timeout(wpas_dpp_auth_conf_wait_timeout, wpa_s, NULL);
 	eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s, NULL);
 #ifdef CONFIG_DPP2
 	if (ok && auth->peer_version >= 2 &&
-	    auth->conf_resp_status == DPP_STATUS_OK) {
+	    auth->conf_resp_status == DPP_STATUS_OK &&
+	    !auth->waiting_conf_result) {
 		wpa_printf(MSG_DEBUG, "DPP: Wait for Configuration Result");
 		auth->waiting_conf_result = 1;
 		auth->conf_resp = NULL;
@@ -3159,17 +3255,38 @@
 
 #ifdef CONFIG_TESTING_OPTIONS
 skip_connector:
+	if (dpp_test == DPP_TEST_NO_PROTOCOL_VERSION_PEER_DISC_REQ) {
+		wpa_printf(MSG_INFO, "DPP: TESTING - no Protocol Version");
+		goto skip_proto_ver;
+	}
 #endif /* CONFIG_TESTING_OPTIONS */
 
 #ifdef CONFIG_DPP2
 	if (DPP_VERSION > 1) {
+		u8 ver = DPP_VERSION;
+#ifdef CONFIG_DPP3
+		int conn_ver;
+
+		conn_ver = dpp_get_connector_version(ssid->dpp_connector);
+		if (conn_ver > 0 && ver != conn_ver) {
+			wpa_printf(MSG_DEBUG,
+				   "DPP: Use Connector version %d instead of current protocol version %d",
+				   conn_ver, ver);
+			ver = conn_ver;
+		}
+#endif /* CONFIG_DPP3 */
+
 		/* Protocol Version */
 		wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
 		wpabuf_put_le16(msg, 1);
-		wpabuf_put_u8(msg, DPP_VERSION);
+		wpabuf_put_u8(msg, ver);
 	}
 #endif /* CONFIG_DPP2 */
 
+#ifdef CONFIG_TESTING_OPTIONS
+skip_proto_ver:
+#endif /* CONFIG_TESTING_OPTIONS */
+
 	/* TODO: Timeout on AP response */
 	wait_time = wpa_s->max_remain_on_chan;
 	if (wait_time > 2000)
@@ -3237,15 +3354,16 @@
 	if (!wpa_s->dpp_pkex_code)
 		return -1;
 
-	if (os_strstr(cmd, " init=1")) {
+	if (os_strstr(cmd, " init=1") || os_strstr(cmd, " init=2")) {
 		struct dpp_pkex *pkex;
 		struct wpabuf *msg;
+		bool v2 = os_strstr(cmd, " init=2") != NULL;
 
 		wpa_printf(MSG_DEBUG, "DPP: Initiating PKEX");
 		dpp_pkex_free(wpa_s->dpp_pkex);
 		wpa_s->dpp_pkex = dpp_pkex_init(wpa_s, own_bi, wpa_s->own_addr,
 						wpa_s->dpp_pkex_identifier,
-						wpa_s->dpp_pkex_code);
+						wpa_s->dpp_pkex_code, v2);
 		pkex = wpa_s->dpp_pkex;
 		if (!pkex)
 			return -1;
@@ -3258,7 +3376,8 @@
 		wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
 			" freq=%u type=%d",
 			MAC2STR(broadcast), pkex->freq,
-			DPP_PA_PKEX_EXCHANGE_REQ);
+			v2 ? DPP_PA_PKEX_EXCHANGE_REQ :
+			DPP_PA_PKEX_V1_EXCHANGE_REQ);
 		offchannel_send_action(wpa_s, pkex->freq, broadcast,
 				       wpa_s->own_addr, broadcast,
 				       wpabuf_head(msg), wpabuf_len(msg),
@@ -3362,6 +3481,7 @@
 		return;
 	eloop_cancel_timeout(wpas_dpp_pkex_retry_timeout, wpa_s, NULL);
 	eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
+	eloop_cancel_timeout(wpas_dpp_auth_conf_wait_timeout, wpa_s, NULL);
 	eloop_cancel_timeout(wpas_dpp_init_timeout, wpa_s, NULL);
 	eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s, NULL);
 #ifdef CONFIG_DPP2
@@ -3512,7 +3632,7 @@
 	struct hostapd_hw_modes *mode;
 	int c;
 	struct wpa_bss *bss;
-	bool chan6;
+	bool chan6 = wpa_s->hw.modes == NULL;
 
 	if (!bi && !wpa_s->dpp_reconfig_ssid)
 		return;
@@ -3531,8 +3651,7 @@
 
 	/* Preferred chirping channels */
 	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
-			HOSTAPD_MODE_IEEE80211G, 0);
-	chan6 = mode == NULL;
+			HOSTAPD_MODE_IEEE80211G, false);
 	if (mode) {
 		for (c = 0; c < mode->num_channels; c++) {
 			struct hostapd_channel_data *chan = &mode->channels[c];
@@ -3548,7 +3667,7 @@
 		int_array_add_unique(&wpa_s->dpp_chirp_freqs, 2437);
 
 	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
-			HOSTAPD_MODE_IEEE80211A, 0);
+			HOSTAPD_MODE_IEEE80211A, false);
 	if (mode) {
 		int chan44 = 0, chan149 = 0;
 
@@ -3570,7 +3689,7 @@
 	}
 
 	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
-			HOSTAPD_MODE_IEEE80211AD, 0);
+			HOSTAPD_MODE_IEEE80211AD, false);
 	if (mode) {
 		for (c = 0; c < mode->num_channels; c++) {
 			struct hostapd_channel_data *chan = &mode->channels[c];
@@ -3609,6 +3728,17 @@
 	if (wpa_s->dpp_chirp_freq == 0) {
 		if (wpa_s->dpp_chirp_round % 4 == 0 &&
 		    !wpa_s->dpp_chirp_scan_done) {
+			if (wpas_scan_scheduled(wpa_s)) {
+				wpa_printf(MSG_DEBUG,
+					   "DPP: Deferring chirp scan because another scan is planned already");
+				if (eloop_register_timeout(1, 0,
+							   wpas_dpp_chirp_next,
+							   wpa_s, NULL) < 0) {
+					wpas_dpp_chirp_stop(wpa_s);
+					return;
+				}
+				return;
+			}
 			wpa_printf(MSG_DEBUG,
 				   "DPP: Update channel list for chirping");
 			wpa_s->scan_req = MANUAL_SCAN_REQ;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/driver_i.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/driver_i.h
index e60bada..2acc27f 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/driver_i.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/driver_i.h
@@ -957,11 +957,11 @@
 #endif /* CONFIG_MACSEC */
 
 static inline int wpa_drv_setband(struct wpa_supplicant *wpa_s,
-				  enum set_band band)
+				  u32 band_mask)
 {
 	if (!wpa_s->driver->set_band)
 		return -1;
-	return wpa_s->driver->set_band(wpa_s->drv_priv, band);
+	return wpa_s->driver->set_band(wpa_s->drv_priv, band_mask);
 }
 
 static inline int wpa_drv_get_pref_freq_list(struct wpa_supplicant *wpa_s,
@@ -1120,4 +1120,22 @@
 	return wpa_s->driver->dpp_listen(wpa_s->drv_priv, enable);
 }
 
+#ifdef CONFIG_TWT_OFFLOAD_IFX
+static inline int wpa_drv_setup_twt(struct wpa_supplicant *wpa_s,
+				    struct drv_setup_twt_params *params)
+{
+	if (!wpa_s->driver->setup_twt)
+		return -1;
+	return wpa_s->driver->setup_twt(wpa_s->drv_priv, params);
+}
+
+static inline int wpa_drv_teardown_twt(struct wpa_supplicant *wpa_s,
+				       struct drv_teardown_twt_params *params)
+{
+	if (!wpa_s->driver->teardown_twt)
+		return -1;
+	return wpa_s->driver->teardown_twt(wpa_s->drv_priv, params);
+}
+#endif /* CONFIG_TWT_OFFLOAD_IFX */
+
 #endif /* DRIVER_I_H */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/eapol_test.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/eapol_test.c
index 9f69736..e256ac5 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/eapol_test.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/eapol_test.c
@@ -674,10 +674,8 @@
 	os_free(e->radius_conf);
 	e->radius_conf = NULL;
 	scard_deinit(wpa_s->scard);
-	if (wpa_s->ctrl_iface) {
-		wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
-		wpa_s->ctrl_iface = NULL;
-	}
+	wpa_supplicant_ctrl_iface_deinit(wpa_s, wpa_s->ctrl_iface);
+	wpa_s->ctrl_iface = NULL;
 
 	ext_password_deinit(wpa_s->ext_pw);
 	wpa_s->ext_pw = NULL;
@@ -1025,6 +1023,7 @@
 		*pos++ = a[1];
 		*pos++ = a[2];
 		*pos++ = a[3];
+		as->addr.af = AF_INET;
 	}
 #else /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */
 	if (hostapd_parse_ip_addr(authsrv, &as->addr) < 0) {
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/eapol_test.py b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/eapol_test.py
index 734428d..88c83f3 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/eapol_test.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/eapol_test.py
@@ -72,7 +72,7 @@
                 break
         return None
 
-def run(ifname, count, no_fast_reauth, res):
+def run(ifname, count, no_fast_reauth, res, conf):
     et = eapol_test(ifname)
 
     et.request("AP_SCAN 0")
@@ -81,14 +81,20 @@
     else:
         et.request("SET fast_reauth 1")
     id = et.add_network()
-    et.set_network(id, "key_mgmt", "IEEE8021X")
-    et.set_network(id, "eapol_flags", "0")
-    et.set_network(id, "eap", "TLS")
-    et.set_network_quoted(id, "identity", "user")
-    et.set_network_quoted(id, "ca_cert", 'ca.pem')
-    et.set_network_quoted(id, "client_cert", 'client.pem')
-    et.set_network_quoted(id, "private_key", 'client.key')
-    et.set_network_quoted(id, "private_key_passwd", 'whatever')
+
+    if len(conf):
+        for item in conf:
+            et.set_network(id, item, conf[item])
+    else:
+        et.set_network(id, "key_mgmt", "IEEE8021X")
+        et.set_network(id, "eapol_flags", "0")
+        et.set_network(id, "eap", "TLS")
+        et.set_network_quoted(id, "identity", "user")
+        et.set_network_quoted(id, "ca_cert", 'ca.pem')
+        et.set_network_quoted(id, "client_cert", 'client.pem')
+        et.set_network_quoted(id, "private_key", 'client.key')
+        et.set_network_quoted(id, "private_key_passwd", 'whatever')
+
     et.set_network(id, "disabled", "0")
 
     fail = False
@@ -114,6 +120,7 @@
     parser.add_argument('--no-fast-reauth', action='store_true',
                         dest='no_fast_reauth',
                         help='disable TLS session resumption')
+    parser.add_argument('--conf', help='file of network conf items')
     args = parser.parse_args()
 
     num = int(args.num)
@@ -122,12 +129,22 @@
         global wpas_ctrl
         wpas_ctrl = args.ctrl
 
+    conf = {}
+    if args.conf:
+        f = open(args.conf, "r")
+        for line in f:
+            confitem = line.split("=")
+            if len(confitem) == 2:
+                conf[confitem[0].strip()] = confitem[1].strip()
+        f.close()
+
     t = {}
     res = {}
     for i in range(num):
         res[i] = Queue.Queue()
         t[i] = threading.Thread(target=run, args=(str(i), iter,
-                                                  args.no_fast_reauth, res[i]))
+                                                  args.no_fast_reauth, res[i],
+                                                  conf))
     for i in range(num):
         t[i].start()
     for i in range(num):
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/events.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/events.c
index 0738fd9..6b36e5e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/events.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/events.c
@@ -31,8 +31,9 @@
 #include "common/ieee802_11_common.h"
 #include "common/gas_server.h"
 #include "common/dpp.h"
+#include "common/ptksa_cache.h"
 #include "crypto/random.h"
-#include "blacklist.h"
+#include "bssid_ignore.h"
 #include "wpas_glue.h"
 #include "wps_supplicant.h"
 #include "ibss_rsn.h"
@@ -45,6 +46,9 @@
 #include "bss.h"
 #include "scan.h"
 #include "offchannel.h"
+#if defined(WAPI_ANDROID)
+#include "wapi/wapi_interface.h"
+#endif 
 #include "interworking.h"
 #include "mesh.h"
 #include "mesh_mpm.h"
@@ -363,9 +367,14 @@
 	struct wpa_ie_data ie;
 	int pmksa_set = -1;
 	size_t i;
+	struct rsn_pmksa_cache_entry *cur_pmksa;
 
-	/* Start with assumption of no PMKSA cache entry match */
-	pmksa_cache_clear_current(wpa_s->wpa);
+	/* Start with assumption of no PMKSA cache entry match for cases other
+	 * than SAE. In particular, this is needed to generate the PMKSA cache
+	 * entries for Suite B cases with driver-based roaming indication. */
+	cur_pmksa = pmksa_cache_get_current(wpa_s->wpa);
+	if (cur_pmksa && !wpa_key_mgmt_sae(cur_pmksa->akmp))
+		pmksa_cache_clear_current(wpa_s->wpa);
 
 	if (wpa_sm_parse_own_wpa_ie(wpa_s->wpa, &ie) < 0 ||
 	    ie.pmkid == NULL)
@@ -577,6 +586,10 @@
 	struct wpa_ie_data ie;
 	int proto_match = 0;
 	const u8 *rsn_ie, *wpa_ie;
+#if defined(WAPI_ANDROID)
+	const u8 *wapi_ie;
+	u8 wapi_ie_len;
+#endif 
 	int ret;
 #ifdef CONFIG_WEP
 	int wep_ok;
@@ -585,6 +598,41 @@
 	ret = wpas_wps_ssid_bss_match(wpa_s, ssid, bss);
 	if (ret >= 0)
 		return ret;
+#if defined(WAPI_ANDROID)
+	wapi_ie = wpa_bss_get_ie(bss, WLAN_EID_WAPI);
+	if(wapi_ie)
+		wpa_printf(MSG_DEBUG, "%s : get wapi_ie\n",__func__);
+	else
+		wpa_printf(MSG_DEBUG, "%s : wapi is null\n",__func__);
+	while ((ssid->proto & WPA_PROTO_WAPI) && wapi_ie)
+	{
+		proto_match++;
+
+		wapi_ie_len = wapi_ie ? wapi_ie[1] + 2: 0;
+		bss->wapi_ie_len = wapi_ie_len;
+		ssid->wapi_ie_len = wapi_ie_len;
+
+		wpa_printf(MSG_DEBUG, "ssid->wapi=%x, ssid->key_mgmt=%x "
+				      "bss->wapi_ie_len=%d \n"
+				,ssid->wapi, ssid->key_mgmt, (int)bss->wapi_ie_len);
+		wpa_printf(MSG_DEBUG, "wapi_ie:[%02x][%02x][%02x][%02x][%02x][%02x][%02x][%02x][%02x][%02x]\n",
+			   wapi_ie[0], wapi_ie[1], wapi_ie[2], wapi_ie[3], wapi_ie[4],
+			   wapi_ie[5], wapi_ie[6], wapi_ie[7], wapi_ie[8], wapi_ie[9] );
+
+		if ( ((ssid->wapi & 0x04) || (ssid->key_mgmt & WPA_KEY_MGMT_WAPI_PSK)) && (wapi_ie[9] == 2) ) {
+		/* 0x400 ---- 10000000000 */
+			wpa_printf(MSG_DEBUG, "WAPI PSK network is selected based on WAPI IE");
+			return 1;
+		}
+		/* 0x800 ---- 100000000000*/
+		if ( ((ssid->wapi & 0x08)  || (ssid->key_mgmt & WPA_KEY_MGMT_WAPI_CERT)) && (wapi_ie[9] == 1) ) {
+			wpa_printf(MSG_DEBUG, "WAPI CERT network is selected based on WAPI IE");
+			return 1;
+		}
+
+		break;
+	}
+#endif 
 
 #ifdef CONFIG_WEP
 	/* Allow TSN if local configuration accepts WEP use without WPA/WPA2 */
@@ -775,8 +823,13 @@
 	}
 #endif /* CONFIG_OWE */
 
+#if defined(WAPI_ANDROID)
+	if ((ssid->proto & (WPA_PROTO_WPA | WPA_PROTO_RSN | WPA_PROTO_WAPI)) &&
+	    wpa_key_mgmt_wpa(ssid->key_mgmt) && proto_match == 0) {
+#else
 	if ((ssid->proto & (WPA_PROTO_WPA | WPA_PROTO_RSN)) &&
 	    wpa_key_mgmt_wpa(ssid->key_mgmt) && proto_match == 0) {
+#endif 
 		if (debug_print)
 			wpa_dbg(wpa_s, MSG_DEBUG,
 				"   skip - no WPA/RSN proto match");
@@ -1109,7 +1162,7 @@
 
 static bool wpa_scan_res_ok(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
 			    const u8 *match_ssid, size_t match_ssid_len,
-			    struct wpa_bss *bss, int blacklist_count,
+			    struct wpa_bss *bss, int bssid_ignore_count,
 			    bool debug_print);
 
 
@@ -1125,14 +1178,11 @@
 	dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
 		int count;
 		const u8 *ie;
-		u8 rsnxe_capa = 0;
 
 		if (bss == orig_bss)
 			continue;
 		ie = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
-		if (ie && ie[1] >= 1)
-			rsnxe_capa = ie[2];
-		if (!(rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_PK)))
+		if (!(ieee802_11_rsnx_capab(ie, WLAN_RSNX_CAPAB_SAE_PK)))
 			continue;
 
 		/* TODO: Could be more thorough in checking what kind of
@@ -1141,7 +1191,7 @@
 		if (bss->est_throughput < 2000)
 			return false;
 
-		count = wpa_blacklist_is_blacklisted(wpa_s, bss->bssid);
+		count = wpa_bssid_ignore_is_listed(wpa_s, bss->bssid);
 		if (wpa_scan_res_ok(wpa_s, ssid, match_ssid, match_ssid_len,
 				    bss, count, 0))
 			return true;
@@ -1154,7 +1204,7 @@
 
 static bool wpa_scan_res_ok(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
 			    const u8 *match_ssid, size_t match_ssid_len,
-			    struct wpa_bss *bss, int blacklist_count,
+			    struct wpa_bss *bss, int bssid_ignore_count,
 			    bool debug_print)
 {
 	int res;
@@ -1202,10 +1252,10 @@
 	}
 
 #ifdef CONFIG_WPS
-	if ((ssid->key_mgmt & WPA_KEY_MGMT_WPS) && blacklist_count) {
+	if ((ssid->key_mgmt & WPA_KEY_MGMT_WPS) && bssid_ignore_count) {
 		if (debug_print)
 			wpa_dbg(wpa_s, MSG_DEBUG,
-				"   skip - blacklisted (WPS)");
+				"   skip - BSSID ignored (WPS)");
 		return false;
 	}
 
@@ -1240,23 +1290,23 @@
 		return false;
 	}
 
-	/* check blacklist */
-	if (ssid->num_bssid_blacklist &&
-	    addr_in_list(bss->bssid, ssid->bssid_blacklist,
-			 ssid->num_bssid_blacklist)) {
+	/* check the list of BSSIDs to ignore */
+	if (ssid->num_bssid_ignore &&
+	    addr_in_list(bss->bssid, ssid->bssid_ignore,
+			 ssid->num_bssid_ignore)) {
 		if (debug_print)
 			wpa_dbg(wpa_s, MSG_DEBUG,
-				"   skip - BSSID blacklisted");
+				"   skip - BSSID configured to be ignored");
 		return false;
 	}
 
-	/* if there is a whitelist, only accept those APs */
-	if (ssid->num_bssid_whitelist &&
-	    !addr_in_list(bss->bssid, ssid->bssid_whitelist,
-			  ssid->num_bssid_whitelist)) {
+	/* if there is a list of accepted BSSIDs, only accept those APs */
+	if (ssid->num_bssid_accept &&
+	    !addr_in_list(bss->bssid, ssid->bssid_accept,
+			  ssid->num_bssid_accept)) {
 		if (debug_print)
 			wpa_dbg(wpa_s, MSG_DEBUG,
-				"   skip - BSSID not in whitelist");
+				"   skip - BSSID not in list of accepted values");
 		return false;
 	}
 
@@ -1501,7 +1551,7 @@
 	int osen;
 	const u8 *match_ssid;
 	size_t match_ssid_len;
-	int blacklist_count;
+	int bssid_ignore_count;
 
 	ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
 	wpa_ie_len = ie ? ie[1] : 0;
@@ -1527,13 +1577,13 @@
 			osen ? " osen=1" : "");
 	}
 
-	blacklist_count = wpa_blacklist_is_blacklisted(wpa_s, bss->bssid);
-	if (blacklist_count) {
+	bssid_ignore_count = wpa_bssid_ignore_is_listed(wpa_s, bss->bssid);
+	if (bssid_ignore_count) {
 		int limit = 1;
 		if (wpa_supplicant_enabled_networks(wpa_s) == 1) {
 			/*
 			 * When only a single network is enabled, we can
-			 * trigger blacklisting on the first failure. This
+			 * trigger BSSID ignoring on the first failure. This
 			 * should not be done with multiple enabled networks to
 			 * avoid getting forced to move into a worse ESS on
 			 * single error if there are no other BSSes of the
@@ -1541,11 +1591,11 @@
 			 */
 			limit = 0;
 		}
-		if (blacklist_count > limit) {
+		if (bssid_ignore_count > limit) {
 			if (debug_print) {
 				wpa_dbg(wpa_s, MSG_DEBUG,
-					"   skip - blacklisted (count=%d limit=%d)",
-					blacklist_count, limit);
+					"   skip - BSSID ignored (count=%d limit=%d)",
+					bssid_ignore_count, limit);
 			}
 			return NULL;
 		}
@@ -1581,7 +1631,7 @@
 
 	for (ssid = group; ssid; ssid = only_first_ssid ? NULL : ssid->pnext) {
 		if (wpa_scan_res_ok(wpa_s, ssid, match_ssid, match_ssid_len,
-				    bss, blacklist_count, debug_print))
+				    bss, bssid_ignore_count, debug_print))
 			return ssid;
 	}
 
@@ -1624,6 +1674,123 @@
 		wpa_dbg(wpa_s, MSG_DEBUG, "Selecting BSS from priority group %d",
 			group->priority);
 
+#if defined(WAPI_ANDROID)
+	struct wpa_scan_res *selected = NULL;
+	wpa_printf(MSG_DEBUG, " * %s",__func__);
+	struct wpa_ssid *ssid;
+	const u8 *ssid_, *ie;
+	u8 ssid_len, wapi_ie_len;
+
+	struct wpa_bssid_ignore *e;
+	struct wpa_bss wpa_bss;
+	/* check scan_res */
+
+	if(wpa_s->wapi_scan_res) {
+	/* First, try to find WAPI-enabled AP */
+		wpa_printf(MSG_DEBUG, " * Try to find WAPI-enabled AP");
+		for (i = 0; i < wpa_s->wapi_scan_res->num && !selected; i++) {
+			struct wpa_scan_res *bss = wpa_s->wapi_scan_res->res[i];
+
+			/*
+				wpa_scan_res *bss -> use wpa_scan_get_ie func.
+			*/
+			ie = wpa_scan_get_ie(bss, WLAN_EID_SSID);
+			ssid_ = ie ? ie + 2 : (u8 *) "";
+			ssid_len = ie ? ie[1] : 0;
+
+			const u8 *wapi_ie = wpa_scan_get_ie(bss, WLAN_EID_WAPI);
+			wapi_ie_len = wapi_ie ? wapi_ie[1] + 2: 0;
+			wpa_printf(MSG_DEBUG, "%d: " MACSTR " ssid='%s' wapi_ie_len=%lu caps=0x%x",
+			   	i, MAC2STR(bss->bssid),
+			   	wpa_ssid_txt(ssid_, ssid_len),
+			   	(unsigned long) bss->wapi_ie_len, bss->caps);
+
+			e = wpa_bssid_ignore_get(wpa_s, bss->bssid);
+			if (e && e->count > 1) {
+				wpa_printf(MSG_DEBUG, "   skip - blacklisted");
+				continue;
+			}
+
+
+			if (wapi_ie_len == 0) {
+				wpa_printf(MSG_DEBUG, " * skip - no WAPI IE");
+				continue;
+			}
+			else {
+				wpa_printf(MSG_DEBUG, " * get Wapi via WAPI_IE, wapi_ie_len = %d wapi_ie_len = %d\n",(int)bss->wapi_ie_len, wapi_ie_len);
+			}
+
+			for (ssid = group; ssid; ssid = ssid->pnext) {
+				wpa_printf(MSG_DEBUG, " * Enter for loop\n");
+				if (ssid->disabled) {
+					wpa_printf(MSG_DEBUG, "   skip - disabled");
+					continue;
+				}
+
+#ifdef CONFIG_BRCM_AUTOMOTIVE
+                                if (ssid->bssid_set && ssid->ssid_len == 0 &&
+                                        os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0) {
+                                        wpa_printf(MSG_DEBUG, "   skip - "
+                                           "BSSID mismatch");
+                                        continue;
+                                }
+
+                                if ((ssid_len != ssid->ssid_len ||
+                                os_memcmp(ssid_, ssid->ssid, ssid_len) != 0)) {
+                                        wpa_printf(MSG_DEBUG, "   skip - "
+                                           "SSID mismatch");
+                                        continue;
+                                }
+#else
+				if (ssid_len != ssid->ssid_len ||
+			    	os_memcmp(ssid_, ssid->ssid, ssid_len) != 0) {
+					wpa_printf(MSG_DEBUG, "   skip - "
+					   "SSID mismatch");
+					continue;
+				}
+#endif /* CONFIG_BRCM_AUTOMOTIVE */
+				if (ssid->bssid_set &&
+			    	os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0) {
+					wpa_printf(MSG_DEBUG, "   skip - "
+					   "BSSID mismatch");
+					continue;
+				}
+				/* transfer to wpa_bss */
+				os_memset(&wpa_bss,0,sizeof(wpa_bss));
+				wpa_bss.flags = bss->flags;
+				wpa_bss.freq = bss->freq;
+				wpa_bss.beacon_int = bss->beacon_int;
+				wpa_bss.caps = bss->caps;
+				wpa_bss.qual = bss->qual;
+				wpa_bss.noise = bss->noise;
+				wpa_bss.level = bss->level;
+				wpa_bss.tsf = bss->tsf;
+				wpa_bss.ie_len = bss->ie_len;
+				wpa_bss.beacon_ie_len = bss->beacon_ie_len;
+				wpa_bss.wapi_ie_len = bss->wapi_ie_len;
+				os_memcpy(&wpa_bss.bssid,bss->bssid,ETH_ALEN);
+				int debug_print = 0;
+				if (wpa_supplicant_ssid_bss_match(wpa_s, ssid, &wpa_bss, debug_print)) {
+					selected = bss;
+					*selected_ssid = ssid;
+					wpa_printf(MSG_DEBUG, "   selected WAPI AP "
+					   MACSTR " ssid='%s'", MAC2STR(bss->bssid), wpa_ssid_txt(ssid_, ssid_len));
+					break;
+				}
+			}
+		}
+		if (selected) {
+			struct wpa_scan_res *bss = selected;
+			const u8 *ie, *ssid;
+			u8 ssid_len;
+			ie = wpa_scan_get_ie(bss, WLAN_EID_SSID);
+			ssid = ie ? ie + 2 : (u8 *) "";
+			ssid_len = ie ? ie[1] : 0;
+			wpa_printf(MSG_DEBUG, "   selected BSS " MACSTR " ssid='%s'", MAC2STR(bss->bssid), wpa_ssid_txt(ssid, ssid_len));
+			return wpa_bss_get(wpa_s, bss->bssid, ssid, ssid_len);
+		}
+	}
+#endif 
 	for (i = 0; i < wpa_s->last_scan_res_used; i++) {
 		struct wpa_bss *bss = wpa_s->last_scan_res[i];
 
@@ -1683,12 +1850,12 @@
 				break;
 		}
 
-		if (selected == NULL && wpa_s->blacklist &&
+		if (selected == NULL && wpa_s->bssid_ignore &&
 		    !wpa_s->countermeasures) {
-			wpa_dbg(wpa_s, MSG_DEBUG, "No APs found - clear "
-				"blacklist and try again");
-			wpa_blacklist_clear(wpa_s);
-			wpa_s->blacklist_cleared++;
+			wpa_dbg(wpa_s, MSG_DEBUG,
+				"No APs found - clear BSSID ignore list and try again");
+			wpa_bssid_ignore_clear(wpa_s);
+			wpa_s->bssid_ignore_cleared = true;
 		} else if (selected == NULL)
 			break;
 	}
@@ -1879,7 +2046,7 @@
 	const u8 *ies = wpa_bss_ie_ptr(bss);
 	size_t ie_len = bss->ie_len ? bss->ie_len : bss->beacon_ie_len;
 
-	return wpas_get_est_tpt(wpa_s, ies, ie_len, rate, snr);
+	return wpas_get_est_tpt(wpa_s, ies, ie_len, rate, snr, bss->freq);
 }
 
 
@@ -2115,25 +2282,49 @@
 			return -1;
 		if (data && data->scan_info.external_scan)
 			return -1;
-		wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get scan results - try "
-			"scanning again");
-		wpa_supplicant_req_new_scan(wpa_s, 1, 0);
+		if (wpa_s->scan_res_fail_handler) {
+			void (*handler)(struct wpa_supplicant *wpa_s);
+
+			handler = wpa_s->scan_res_fail_handler;
+			wpa_s->scan_res_fail_handler = NULL;
+			handler(wpa_s);
+		} else {
+			wpa_dbg(wpa_s, MSG_DEBUG,
+				"Failed to get scan results - try scanning again");
+			wpa_supplicant_req_new_scan(wpa_s, 1, 0);
+		}
+
 		ret = -1;
 		goto scan_work_done;
 	}
+#if defined(WAPI_ANDROID)
+	if (wpa_s->wapi_scan_res) {
+		wpa_scan_results_free(wpa_s->wapi_scan_res);
+	}
+	wpa_s->wapi_scan_res = wpa_supplicant_get_scan_results(wpa_s,
+                                                   data ? &data->scan_info :
+                                                   NULL, 1);
+#endif 
 
 #ifndef CONFIG_NO_RANDOM_POOL
 	num = scan_res->num;
 	if (num > 10)
 		num = 10;
 	for (i = 0; i < num; i++) {
+#if defined(WAPI_ANDROID)
+		u8 buf[6];
+#else
 		u8 buf[5];
+#endif 
 		struct wpa_scan_res *res = scan_res->res[i];
 		buf[0] = res->bssid[5];
 		buf[1] = res->qual & 0xff;
 		buf[2] = res->noise & 0xff;
 		buf[3] = res->level & 0xff;
 		buf[4] = res->tsf & 0xff;
+#if defined(WAPI_ANDROID)
+		buf[5] = res->wapi_ie_len & 0xff;
+#endif 
 		random_add_randomness(buf, sizeof(buf));
 	}
 #endif /* CONFIG_NO_RANDOM_POOL */
@@ -2189,7 +2380,7 @@
 	if (wnm_scan_process(wpa_s, 1) > 0)
 		goto scan_work_done;
 
-	if (sme_proc_obss_scan(wpa_s, scan_res) > 0)
+	if (sme_proc_obss_scan(wpa_s) > 0)
 		goto scan_work_done;
 
 	if (own_request && data &&
@@ -2463,7 +2654,7 @@
 
 	os_get_reltime(&now);
 	if (os_reltime_expired(&now, &wpa_s->last_scan,
-			       SCAN_RES_VALID_FOR_CONNECT)) {
+			       wpa_s->conf->scan_res_valid_for_connect)) {
 		wpa_printf(MSG_DEBUG, "Fast associate: Old scan results");
 		return -1;
 	}
@@ -2697,6 +2888,205 @@
 #endif /* CONFIG_FST */
 
 
+static int wpa_supplicant_use_own_rsne_params(struct wpa_supplicant *wpa_s,
+					      union wpa_event_data *data)
+{
+	int sel;
+	const u8 *p;
+	int l, len;
+	bool found = false;
+	struct wpa_ie_data ie;
+	struct wpa_ssid *ssid = wpa_s->current_ssid;
+	struct wpa_bss *bss = wpa_s->current_bss;
+	int pmf;
+
+	if (!ssid)
+		return 0;
+
+	p = data->assoc_info.req_ies;
+	l = data->assoc_info.req_ies_len;
+
+	while (p && l >= 2) {
+		len = p[1] + 2;
+		if (len > l) {
+			wpa_hexdump(MSG_DEBUG, "Truncated IE in assoc_info",
+				    p, l);
+			break;
+		}
+		if (((p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
+		      (os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0)) ||
+		     (p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 4 &&
+		      (os_memcmp(&p[2], "\x50\x6F\x9A\x12", 4) == 0)) ||
+		     (p[0] == WLAN_EID_RSN && p[1] >= 2))) {
+			found = true;
+			break;
+		}
+		l -= len;
+		p += len;
+	}
+
+	if (!found || wpa_parse_wpa_ie(p, len, &ie) < 0)
+		return 0;
+
+	wpa_hexdump(MSG_DEBUG,
+		    "WPA: Update cipher suite selection based on IEs in driver-generated WPA/RSNE in AssocReq",
+		    p, l);
+
+	/* Update proto from (Re)Association Request frame info */
+	wpa_s->wpa_proto = ie.proto;
+	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, wpa_s->wpa_proto);
+	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED,
+			 !!(wpa_s->wpa_proto &
+			    (WPA_PROTO_RSN | WPA_PROTO_OSEN)));
+
+	/* Update AKMP suite from (Re)Association Request frame info */
+	sel = ie.key_mgmt;
+	if (ssid->key_mgmt)
+		sel &= ssid->key_mgmt;
+
+	wpa_dbg(wpa_s, MSG_DEBUG,
+		"WPA: AP key_mgmt 0x%x network key_mgmt 0x%x; available key_mgmt 0x%x",
+		ie.key_mgmt, ssid->key_mgmt, sel);
+	if (ie.key_mgmt && !sel) {
+		wpa_supplicant_deauthenticate(
+			wpa_s, WLAN_REASON_AKMP_NOT_VALID);
+		return -1;
+	}
+
+	wpa_s->key_mgmt = ie.key_mgmt;
+	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
+	wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT %s and proto %d",
+		wpa_key_mgmt_txt(wpa_s->key_mgmt, wpa_s->wpa_proto),
+		wpa_s->wpa_proto);
+
+	/* Update pairwise cipher from (Re)Association Request frame info */
+	sel = ie.pairwise_cipher;
+	if (ssid->pairwise_cipher)
+		sel &= ssid->pairwise_cipher;
+
+	wpa_dbg(wpa_s, MSG_DEBUG,
+		"WPA: AP pairwise cipher 0x%x network pairwise cipher 0x%x; available pairwise cipher 0x%x",
+		ie.pairwise_cipher, ssid->pairwise_cipher, sel);
+	if (ie.pairwise_cipher && !sel) {
+		wpa_supplicant_deauthenticate(
+			wpa_s, WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID);
+		return -1;
+	}
+
+	wpa_s->pairwise_cipher = ie.pairwise_cipher;
+	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
+			 wpa_s->pairwise_cipher);
+	wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK %s",
+		wpa_cipher_txt(wpa_s->pairwise_cipher));
+
+	/* Update other parameters based on AP's WPA IE/RSNE, if available */
+	if (!bss) {
+		wpa_dbg(wpa_s, MSG_DEBUG,
+			"WPA: current_bss == NULL - skip AP IE check");
+		return 0;
+	}
+
+	/* Update GTK and IGTK from AP's RSNE */
+	found = false;
+
+	if (wpa_s->wpa_proto & (WPA_PROTO_RSN | WPA_PROTO_OSEN)) {
+		const u8 *bss_rsn;
+
+		bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+		if (bss_rsn) {
+			p = bss_rsn;
+			len = 2 + bss_rsn[1];
+			found = true;
+		}
+	} else if (wpa_s->wpa_proto & WPA_PROTO_WPA) {
+		const u8 *bss_wpa;
+
+		bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
+		if (bss_wpa) {
+			p = bss_wpa;
+			len = 2 + bss_wpa[1];
+			found = true;
+		}
+	}
+
+	if (!found || wpa_parse_wpa_ie(p, len, &ie) < 0)
+		return 0;
+
+	pmf = wpas_get_ssid_pmf(wpa_s, ssid);
+	if (!(ie.capabilities & WPA_CAPABILITY_MFPC) &&
+	    pmf == MGMT_FRAME_PROTECTION_REQUIRED) {
+		/* AP does not support MFP, local configuration requires it */
+		wpa_supplicant_deauthenticate(
+			wpa_s, WLAN_REASON_INVALID_RSN_IE_CAPAB);
+		return -1;
+	}
+	if ((ie.capabilities & WPA_CAPABILITY_MFPR) &&
+	    pmf == NO_MGMT_FRAME_PROTECTION) {
+		/* AP requires MFP, local configuration disables it */
+		wpa_supplicant_deauthenticate(
+			wpa_s, WLAN_REASON_INVALID_RSN_IE_CAPAB);
+		return -1;
+	}
+
+	/* Update PMF from local configuration now that MFP validation was done
+	 * above */
+	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP, pmf);
+
+	/* Update GTK from AP's RSNE */
+	sel = ie.group_cipher;
+	if (ssid->group_cipher)
+		sel &= ssid->group_cipher;
+
+	wpa_dbg(wpa_s, MSG_DEBUG,
+		"WPA: AP group cipher 0x%x network group cipher 0x%x; available group cipher 0x%x",
+		ie.group_cipher, ssid->group_cipher, sel);
+	if (ie.group_cipher && !sel) {
+		wpa_supplicant_deauthenticate(
+			wpa_s, WLAN_REASON_GROUP_CIPHER_NOT_VALID);
+		return -1;
+	}
+
+	wpa_s->group_cipher = ie.group_cipher;
+	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
+	wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK %s",
+		wpa_cipher_txt(wpa_s->group_cipher));
+
+	/* Update IGTK from AP RSN IE */
+	sel = ie.mgmt_group_cipher;
+	if (ssid->group_mgmt_cipher)
+		sel &= ssid->group_mgmt_cipher;
+
+	wpa_dbg(wpa_s, MSG_DEBUG,
+		"WPA: AP mgmt_group_cipher 0x%x network mgmt_group_cipher 0x%x; available mgmt_group_cipher 0x%x",
+		ie.mgmt_group_cipher, ssid->group_mgmt_cipher, sel);
+
+	if (pmf == NO_MGMT_FRAME_PROTECTION ||
+	    !(ie.capabilities & WPA_CAPABILITY_MFPC)) {
+		wpa_dbg(wpa_s, MSG_DEBUG,
+			"WPA: STA/AP is not MFP capable; AP RSNE caps 0x%x",
+			ie.capabilities);
+		ie.mgmt_group_cipher = 0;
+	}
+
+	if (ie.mgmt_group_cipher && !sel) {
+		wpa_supplicant_deauthenticate(
+			wpa_s, WLAN_REASON_CIPHER_SUITE_REJECTED);
+		return -1;
+	}
+
+	wpa_s->mgmt_group_cipher = ie.mgmt_group_cipher;
+	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
+			 wpa_s->mgmt_group_cipher);
+	if (wpa_s->mgmt_group_cipher)
+		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher %s",
+			wpa_cipher_txt(wpa_s->mgmt_group_cipher));
+	else
+		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher");
+
+	return 0;
+}
+
+
 static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
 					  union wpa_event_data *data)
 {
@@ -3071,6 +3461,9 @@
 
 	wpa_s->assoc_freq = data->assoc_info.freq;
 
+	wpas_handle_assoc_resp_qos_mgmt(wpa_s, data->assoc_info.resp_ies,
+					data->assoc_info.resp_ies_len);
+
 	return 0;
 }
 
@@ -3184,6 +3577,49 @@
 	eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
 	wpa_s->own_reconnect_req = 0;
 
+#if defined(WAPI_ANDROID)
+	MAC_ADDRESS bssid_s;
+	MAC_ADDRESS own_s;
+
+	ft_completed = 0;
+
+	if ( (wpa_s->current_ssid) && (wpa_s->current_ssid->wapi) ) {
+		wpa_printf(MSG_DEBUG,"[WAPI] %s: associated to a wapi network.\n", __FUNCTION__);
+		if (wpa_drv_get_bssid(wpa_s, bssid) >= 0 &&
+		    os_memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0) {
+			wpa_msg(wpa_s, MSG_DEBUG, "Associated to a new BSS: BSSID="
+				MACSTR, MAC2STR(bssid));
+			os_memcpy(wpa_s->bssid, bssid, ETH_ALEN);
+			os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
+		}
+
+		os_memset(&bssid_s, 0, sizeof(bssid_s));
+		os_memset(&own_s, 0, sizeof(own_s));
+
+		os_memcpy(bssid_s.v, bssid, sizeof(bssid_s.v));
+		os_memcpy(own_s.v, wpa_s->wapi_own_addr, sizeof(own_s.v));
+		wpa_hexdump(MSG_DEBUG,"bssid",bssid, sizeof(bssid));
+		wpa_hexdump(MSG_DEBUG,"own mac",wpa_s->wapi_own_addr, 6);
+
+		if(wpa_s->ap_wapi_ie_len) {
+			wpa_printf(MSG_DEBUG,"%s: ap_wapi_ie_len is Not Zero, wpa_s->ap_wapi_ie_len=%d\n", __FUNCTION__, wpa_s->ap_wapi_ie_len);
+			WAI_Msg_Input(CONN_ASSOC, &bssid_s, &own_s, wpa_s->ap_wapi_ie,
+				      wpa_s->ap_wapi_ie_len);
+		}
+		else {
+			wpa_printf(MSG_DEBUG,"%s: ap_wapi_ie_len is Zero \n", __FUNCTION__);
+			WAI_Msg_Input(CONN_ASSOC, &bssid_s, &own_s, NULL, 0);
+		}
+
+		wpa_supplicant_cancel_auth_timeout(wpa_s);
+		wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATED);
+#ifdef BRCM_SUPP
+		/* Update assoc frequency in case of wapi */
+		wpa_s->assoc_freq = data->assoc_info.freq;
+#endif /* BRCM_SUPP */
+		wpa_msg(wpa_s, MSG_INFO, "Associated with " MACSTR, MAC2STR(bssid));
+	} else {
+#endif 
 	ft_completed = wpa_ft_is_completed(wpa_s->wpa);
 #ifdef BRCM_OKC
 	/* BRCM OKC..
@@ -3286,6 +3722,10 @@
 		}
 	}
 
+	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
+	    data && wpa_supplicant_use_own_rsne_params(wpa_s, data) < 0)
+		return;
+
 	multi_ap_set_4addr_mode(wpa_s);
 
 	if (wpa_s->conf->ap_scan == 1 &&
@@ -3374,6 +3814,9 @@
 		/* Timeout for receiving the first EAPOL packet */
 		wpa_supplicant_req_auth_timeout(wpa_s, 10, 0);
 	}
+#if defined(WAPI_ANDROID)
+	}
+#endif 
 	wpa_supplicant_cancel_scan(wpa_s);
 
 	if (ft_completed) {
@@ -3541,6 +3984,12 @@
 			" reason=%d%s",
 			MAC2STR(bssid), reason_code,
 			locally_generated ? " locally_generated=1" : "");
+#ifdef CONFIG_TWT_OFFLOAD_IFX
+		if (locally_generated &&
+		    wpas_twt_offload_deinit_default_session(wpa_s))
+			wpa_msg(wpa_s, MSG_ERROR,
+				"Failed to cleanup all the TWT sessions including Default session");
+#endif
 	}
 }
 
@@ -3583,6 +4032,48 @@
 
 	authenticating = wpa_s->wpa_state == WPA_AUTHENTICATING;
 	os_memcpy(prev_pending_bssid, wpa_s->pending_bssid, ETH_ALEN);
+#if defined(WAPI_ANDROID)
+	MAC_ADDRESS bssid_s;
+	MAC_ADDRESS own_s;
+
+	wpa_printf(MSG_DEBUG, "%s: wpa_s->ap_wapi_ie_len=%d\twpa_s->assoc_wapi_ie_len =%d\n",
+		   __FUNCTION__, wpa_s->ap_wapi_ie_len, wpa_s->assoc_wapi_ie_len);
+	if ( (wpa_s->ap_wapi_ie_len > 0) && (wpa_s->assoc_wapi_ie_len > 0) ) { /* this is a WAPI network */
+		os_memset(&bssid_s, 0, sizeof(bssid_s));
+		os_memset(&own_s, 0, sizeof(own_s));
+
+		os_memcpy(bssid_s.v, wpa_s->bssid, sizeof(bssid_s.v));
+		os_memcpy(own_s.v, wpa_s->wapi_own_addr, sizeof(own_s.v));
+
+		WAI_Msg_Input(CONN_DISASSOC, &bssid_s, &own_s, NULL, 0);
+
+		if (wpa_s->wpa_state >= WPA_ASSOCIATED)
+			wpa_supplicant_req_scan(wpa_s, 0, 100000);
+
+		if (wpa_s->wpa_state >= WPA_AUTHENTICATING) {
+			wpas_connect_work_done(wpa_s);
+		}
+
+		bssid = wpa_s->bssid;
+		if (os_memcmp(bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0)
+			bssid = wpa_s->pending_bssid;
+		wpa_bssid_ignore_add(wpa_s, bssid);
+		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "- Disconnect event - "
+			"remove keys");
+
+		wpa_supplicant_mark_disassoc(wpa_s);
+
+		wpa_s->ap_wapi_ie_len = 0;
+		wpa_s->assoc_wapi_ie_len = 0;
+		os_memset(wpa_s->ap_wapi_ie, 0, sizeof(wpa_s->ap_wapi_ie));
+		os_memset(wpa_s->assoc_wapi_ie, 0, sizeof(wpa_s->assoc_wapi_ie));
+
+		if (wpa_s->wapi_conf != NULL) {
+			wapi_config_free(wpa_s->wapi_conf);
+			wpa_s->wapi_conf = NULL;
+		}
+	} else {
+#endif 
 
 	if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
 		/*
@@ -3665,6 +4156,8 @@
 	if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
 		wpas_connection_failed(wpa_s, bssid);
 	wpa_sm_notify_disassoc(wpa_s->wpa);
+	ptksa_cache_flush(wpa_s->ptksa, wpa_s->bssid, WPA_CIPHER_NONE);
+
 	if (locally_generated)
 		wpa_s->disconnect_reason = -reason_code;
 	else
@@ -3709,6 +4202,9 @@
 		 */
 		wpa_supplicant_req_scan(wpa_s, 0, 100000);
 	}
+#if defined(WAPI_ANDROID)
+    }
+#endif 
 }
 
 
@@ -3735,6 +4231,9 @@
 	struct os_reltime t;
 
 	wpa_msg(wpa_s, MSG_WARNING, "Michael MIC failure detected");
+#if defined(WAPI_ANDROID)
+	if (!wpa_s->current_ssid->wapi) {
+#endif 
 	pairwise = (data && data->michael_mic_failure.unicast);
 	os_get_reltime(&t);
 	if ((wpa_s->last_michael_mic_error.sec &&
@@ -3758,7 +4257,7 @@
 		/* initialize countermeasures */
 		wpa_s->countermeasures = 1;
 
-		wpa_blacklist_add(wpa_s, wpa_s->bssid);
+		wpa_bssid_ignore_add(wpa_s, wpa_s->bssid);
 
 		wpa_msg(wpa_s, MSG_WARNING, "TKIP countermeasures started");
 
@@ -3817,6 +4316,9 @@
 #endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
 	}
 	wpa_s->last_michael_mic_error = t;
+#if defined(WAPI_ANDROID)
+	}
+#endif 
 	wpa_s->mic_errors_seen++;
 }
 
@@ -3895,6 +4397,10 @@
 			break;
 		}
 #endif /* CONFIG_MATCH_IFACE */
+#if defined(WAPI_ANDROID)
+		l2_packet_deinit(wpa_s->l2_wapi);
+		wpa_s->l2_wapi = NULL;
+#endif 
 
 #ifdef CONFIG_TERMINATE_ONLASTIF
 		/* check if last interface */
@@ -4108,6 +4614,7 @@
 	if (!locally_generated)
 		wpa_s->own_disconnect_req = 0;
 
+	wpa_clear_keys(wpa_s, addr);
 	wpa_supplicant_event_disassoc(wpa_s, reason_code, locally_generated);
 
 	if (((reason_code == WLAN_REASON_IEEE_802_1X_AUTH_FAILED ||
@@ -4130,8 +4637,11 @@
 	}
 #endif /* CONFIG_P2P */
 
+/* Refer commit a64272329 SAE: Drop PMKSA cache after receiving
+ * specific deauth
+ */
 #if defined(WL_SAE) || defined(CONFIG_SAE)
-	if (reason_code == WLAN_REASON_PREV_AUTH_NOT_VALID) {
+	if (reason_code <= WLAN_REASON_PREV_AUTH_NOT_VALID) {
 		const u8 *bssid = wpa_s->bssid;
 
 		if (is_zero_ether_addr(bssid))
@@ -4364,7 +4874,7 @@
 
 #ifdef CONFIG_SME
 	if (category == WLAN_ACTION_SA_QUERY) {
-		sme_sa_query_rx(wpa_s, mgmt->sa, payload, plen);
+		sme_sa_query_rx(wpa_s, mgmt->da, mgmt->sa, payload, plen);
 		return;
 	}
 #endif /* CONFIG_SME */
@@ -4462,12 +4972,26 @@
 #endif /* CONFIG_DPP */
 
 	if (category == WLAN_ACTION_ROBUST_AV_STREAMING &&
+	    payload[0] == ROBUST_AV_SCS_RESP) {
+		wpas_handle_robust_av_scs_recv_action(wpa_s, mgmt->sa,
+						      payload + 1, plen - 1);
+		return;
+	}
+
+	if (category == WLAN_ACTION_ROBUST_AV_STREAMING &&
 	    payload[0] == ROBUST_AV_MSCS_RESP) {
 		wpas_handle_robust_av_recv_action(wpa_s, mgmt->sa,
 						  payload + 1, plen - 1);
 		return;
 	}
 
+	if (category == WLAN_ACTION_VENDOR_SPECIFIC_PROTECTED && plen > 4 &&
+	    WPA_GET_BE32(payload) == QM_ACTION_VENDOR_TYPE) {
+		wpas_handle_qos_mgmt_recv_action(wpa_s, mgmt->sa,
+						 payload + 4, plen - 4);
+		return;
+	}
+
 	wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
 			   category, payload, plen, freq);
 	if (wpa_s->ifmsh)
@@ -4604,6 +5128,8 @@
 
 	wpa_supplicant_event_port_authorized(wpa_s);
 
+	wpa_s->last_eapol_matches_bssid = 1;
+
 	wpa_sm_set_rx_replay_ctr(wpa_s->wpa, data->assoc_info.key_replay_ctr);
 	wpa_sm_set_ptk_kck_kek(wpa_s->wpa, data->assoc_info.ptk_kck,
 			       data->assoc_info.ptk_kck_len,
@@ -4823,6 +5349,7 @@
 #ifdef CONFIG_FILS
 	/* Update ERP next sequence number */
 	if (wpa_s->auth_alg == WPA_AUTH_ALG_FILS) {
+		fils_pmksa_cache_flush(wpa_s);
 		eapol_sm_update_erp_next_seq_num(
 			wpa_s->eapol,
 			data->assoc_reject.fils_erp_next_seq_num);
@@ -4945,6 +5472,11 @@
 			break;
 		}
 #endif /* CONFIG_TESTING_OPTIONS */
+		if (wpa_s->disconnected) {
+			wpa_printf(MSG_INFO,
+				   "Ignore unexpected EVENT_ASSOC in disconnected state");
+			break;
+		}
 		wpa_supplicant_event_assoc(wpa_s, data);
 		wpa_s->assoc_status_code = WLAN_STATUS_SUCCESS;
 		if (data &&
@@ -5005,7 +5537,7 @@
 			}
 		} else {
 			wpa_dbg(wpa_s, MSG_DEBUG, "External program started a scan");
-			wpa_s->radio->external_scan_running = 1;
+			wpa_s->radio->external_scan_req_interface = wpa_s;
 			wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_STARTED);
 		}
 		break;
@@ -5013,7 +5545,7 @@
 		if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
 			wpa_s->scan_res_handler = NULL;
 			wpa_s->own_scan_running = 0;
-			wpa_s->radio->external_scan_running = 0;
+			wpa_s->radio->external_scan_req_interface = NULL;
 			wpa_s->last_scan_req = NORMAL_SCAN_REQ;
 			break;
 		}
@@ -5033,7 +5565,7 @@
 		if (!(data && data->scan_info.external_scan))
 			wpa_s->own_scan_running = 0;
 		if (data && data->scan_info.nl_scan_event)
-			wpa_s->radio->external_scan_running = 0;
+			wpa_s->radio->external_scan_req_interface = NULL;
 		radio_work_check_next(wpa_s);
 		break;
 #endif /* CONFIG_NO_SCAN_PROCESSING */
@@ -5096,6 +5628,14 @@
 			" type=%d stype=%d",
 			MAC2STR(data->tx_status.dst),
 			data->tx_status.type, data->tx_status.stype);
+#ifdef CONFIG_PASN
+		if (data->tx_status.type == WLAN_FC_TYPE_MGMT &&
+		    data->tx_status.stype == WLAN_FC_STYPE_AUTH &&
+		    wpas_pasn_auth_tx_status(wpa_s, data->tx_status.data,
+					     data->tx_status.data_len,
+					     data->tx_status.ack) == 0)
+			break;
+#endif /* CONFIG_PASN */
 #ifdef CONFIG_AP
 		if (wpa_s->ap_iface == NULL) {
 #ifdef CONFIG_OFFCHANNEL
@@ -5191,6 +5731,12 @@
 
 		wpa_s->assoc_freq = data->ch_switch.freq;
 		wpa_s->current_ssid->frequency = data->ch_switch.freq;
+		if (wpa_s->current_bss &&
+		    wpa_s->current_bss->freq != data->ch_switch.freq) {
+			wpa_s->current_bss->freq = data->ch_switch.freq;
+			notify_bss_changes(wpa_s, WPA_BSS_FREQ_CHANGED_FLAG,
+					   wpa_s->current_bss);
+		}
 
 #ifdef CONFIG_SME
 		switch (data->ch_switch.ch_offset) {
@@ -5324,6 +5870,12 @@
 				mesh_mpm_mgmt_rx(wpa_s, &data->rx_mgmt);
 				break;
 			}
+#ifdef CONFIG_PASN
+			if (stype == WLAN_FC_STYPE_AUTH &&
+			    wpas_pasn_auth_rx(wpa_s, mgmt,
+					      data->rx_mgmt.frame_len) != -2)
+				break;
+#endif /* CONFIG_PASN */
 
 #ifdef CONFIG_SAE
 			if (stype == WLAN_FC_STYPE_AUTH &&
@@ -5431,13 +5983,21 @@
 		break;
 	case EVENT_INTERFACE_MAC_CHANGED:
 		wpa_supplicant_update_mac_addr(wpa_s);
+		wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
 		break;
 	case EVENT_INTERFACE_ENABLED:
 		wpa_dbg(wpa_s, MSG_DEBUG, "Interface was enabled");
 		if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
+			u8 addr[ETH_ALEN];
+
 			eloop_cancel_timeout(wpas_clear_disabled_interface,
 					     wpa_s, NULL);
+			os_memcpy(addr, wpa_s->own_addr, ETH_ALEN);
 			wpa_supplicant_update_mac_addr(wpa_s);
+			if (os_memcmp(addr, wpa_s->own_addr, ETH_ALEN) != 0)
+				wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
+			else
+				wpa_sm_pmksa_cache_reconfig(wpa_s->wpa);
 			wpa_supplicant_set_default_scan_ies(wpa_s);
 			if (wpa_s->p2p_mgmt) {
 				wpa_supplicant_set_state(wpa_s,
@@ -5510,13 +6070,13 @@
 			wpa_bss_flush(wpa_s);
 #endif /* ABOVE_10 */
 		os_reltime_age(&wpa_s->last_scan, &age);
-		if (age.sec >= SCAN_RES_VALID_FOR_CONNECT) {
-			clear_at.sec = SCAN_RES_VALID_FOR_CONNECT;
+		if (age.sec >= wpa_s->conf->scan_res_valid_for_connect) {
+			clear_at.sec = wpa_s->conf->scan_res_valid_for_connect;
 			clear_at.usec = 0;
 		} else {
 			struct os_reltime tmp;
 
-			tmp.sec = SCAN_RES_VALID_FOR_CONNECT;
+			tmp.sec = wpa_s->conf->scan_res_valid_for_connect;
 			tmp.usec = 0;
 			os_reltime_sub(&tmp, &age, &clear_at);
 		}
@@ -5673,7 +6233,11 @@
 		if (!wpa_s->current_bss || !wpa_s->current_ssid)
 			break;
 		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_BEACON_LOSS);
+#ifndef CONFIG_NO_ROAMING
 		bgscan_notify_beacon_loss(wpa_s);
+#else
+		wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_UNSPECIFIED);
+#endif /* CONFIG_NO_ROAMING */
 		break;
 	case EVENT_EXTERNAL_AUTH:
 #ifdef CONFIG_SAE
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/gas_query.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/gas_query.c
index e60a8c1..a6172d6 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/gas_query.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/gas_query.c
@@ -273,16 +273,6 @@
 }
 
 
-int pmf_in_use(struct wpa_supplicant *wpa_s, const u8 *addr)
-{
-	if (wpa_s->current_ssid == NULL ||
-	    wpa_s->wpa_state < WPA_4WAY_HANDSHAKE ||
-	    os_memcmp(addr, wpa_s->bssid, ETH_ALEN) != 0)
-		return 0;
-	return wpa_sm_pmf_enabled(wpa_s->wpa);
-}
-
-
 static int gas_query_tx(struct gas_query *gas, struct gas_query_pending *query,
 			struct wpabuf *req, unsigned int wait_time)
 {
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/gas_query.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/gas_query.h
index f9ce7b6..6ccecd4 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/gas_query.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/gas_query.h
@@ -19,7 +19,6 @@
 int gas_query_rx(struct gas_query *gas, const u8 *da, const u8 *sa,
 		 const u8 *bssid, u8 categ, const u8 *data, size_t len,
 		 int freq);
-int pmf_in_use(struct wpa_supplicant *wpa_s, const u8 *addr);
 
 /**
  * enum gas_query_result - GAS query result
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.0/hidl_manager.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.0/hidl_manager.cpp
index fba77ca..3a6d083 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.0/hidl_manager.cpp
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.0/hidl_manager.cpp
@@ -65,27 +65,6 @@
 	&on_hidl_died_fctor,
     std::vector<android::sp<CallbackType>> &callback_list)
 {
-#if 0   // TODO(b/31632518): HIDL object death notifications.
-	auto death_notifier = new CallbackObjectDeathNotifier<CallbackType>(
-	    callback, on_hidl_died_fctor);
-	// Use the |callback.get()| as cookie so that we don't need to
-	// store a reference to this |CallbackObjectDeathNotifier| instance
-	// to use in |unlinkToDeath| later.
-	// NOTE: This may cause an immediate callback if the object is already
-	// dead, so add it to the list before we register for callback!
-	if (android::hardware::IInterface::asBinder(callback)->linkToDeath(
-		death_notifier, callback.get()) != android::OK) {
-		wpa_printf(
-		    MSG_ERROR,
-		    "Error registering for death notification for "
-		    "supplicant callback object");
-		callback_list.erase(
-		    std::remove(
-			callback_list.begin(), callback_list.end(), callback),
-		    callback_list.end());
-		return 1;
-	}
-#endif  // TODO(b/31632518): HIDL object death notifications.
 	callback_list.push_back(callback);
 	return 0;
 }
@@ -173,19 +152,6 @@
 	auto iface_callback_map_iter = callbacks_map.find(ifname);
 	if (iface_callback_map_iter == callbacks_map.end())
 		return 1;
-#if 0   // TODO(b/31632518): HIDL object death notifications.
-	const auto &iface_callback_list = iface_callback_map_iter->second;
-	for (const auto &callback : iface_callback_list) {
-		if (android::hardware::IInterface::asBinder(callback)
-			->unlinkToDeath(nullptr, callback.get()) !=
-		    android::OK) {
-			wpa_printf(
-			    MSG_ERROR,
-			    "Error deregistering for death notification for "
-			    "iface callback object");
-		}
-	}
-#endif  // TODO(b/31632518): HIDL object death notifications.
 	callbacks_map.erase(iface_callback_map_iter);
 	return 0;
 }
@@ -199,20 +165,6 @@
 	auto network_callback_map_iter = callbacks_map.find(network_key);
 	if (network_callback_map_iter == callbacks_map.end())
 		return 1;
-#if 0   // TODO(b/31632518): HIDL object death notifications.
-	const auto &network_callback_list = network_callback_map_iter->second;
-	for (const auto &callback : network_callback_list) {
-		if (android::hardware::IInterface::asBinder(callback)
-			->unlinkToDeath(nullptr, callback.get()) !=
-		    android::OK) {
-			wpa_printf(
-			    MSG_ERROR,
-			    "Error deregistering for death "
-			    "notification for "
-			    "network callback object");
-		}
-	}
-#endif  // TODO(b/31632518): HIDL object death notifications.
 	callbacks_map.erase(network_callback_map_iter);
 	return 0;
 }
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.0/hidl_manager.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.0/hidl_manager.h
index 9d9527c..0a76487 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.0/hidl_manager.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.0/hidl_manager.h
@@ -251,39 +251,6 @@
 	    std::vector<android::sp<ISupplicantStaNetworkCallback>>>
 	    sta_network_callbacks_map_;
 
-#if 0  // TODO(b/31632518): HIDL object death notifications.
-	/**
-	 * Helper class used to deregister the callback object reference from
-	 * our callback list on the death of the hidl object.
-	 * This class stores a reference of the callback hidl object and a
-	 * function to be called to indicate the death of the hidl object.
-	 */
-	template <class CallbackType>
-	class CallbackObjectDeathNotifier
-	    : public android::hardware::IBinder::DeathRecipient
-	{
-	public:
-		CallbackObjectDeathNotifier(
-		    const android::sp<CallbackType> &callback,
-		    const std::function<void(const android::sp<CallbackType> &)>
-			&on_hidl_died)
-		    : callback_(callback), on_hidl_died_(on_hidl_died)
-		{
-		}
-		void binderDied(const android::wp<android::hardware::IBinder>
-				    & /* who */) override
-		{
-			on_hidl_died_(callback_);
-		}
-
-	private:
-		// The callback hidl object reference.
-		const android::sp<CallbackType> callback_;
-		// Callback function to be called when the hidl dies.
-		const std::function<void(const android::sp<CallbackType> &)>
-		    on_hidl_died_;
-	};
-#endif
 };
 
 // The hidl interface uses some values which are the same as internal ones to
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.0/p2p_iface.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.0/p2p_iface.cpp
index 212e5ce..0bab3e5 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.0/p2p_iface.cpp
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.0/p2p_iface.cpp
@@ -644,7 +644,8 @@
 	uint32_t search_delay = wpas_p2p_search_delay(wpa_s);
 	if (wpas_p2p_find(
 		wpa_s, timeout_in_sec, P2P_FIND_START_WITH_FULL, 0, nullptr,
-		nullptr, search_delay, 0, nullptr, 0)) {
+		nullptr, search_delay, 0, nullptr, 0,
+		is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 	}
 	return {SupplicantStatusCode::SUCCESS, ""};
@@ -704,7 +705,8 @@
 	int new_pin = wpas_p2p_connect(
 	    wpa_s, peer_address.data(), pin, wps_method,
 	    persistent, false, join_existing_group, false, go_intent_signed, 0, 0, -1,
-	    false, ht40, vht, CHANWIDTH_USE_HT, he, 0, nullptr, 0);
+	    false, ht40, vht, CHANWIDTH_USE_HT, he, 0, nullptr, 0,
+	    is_p2p_allow_6ghz(wpa_s->global->p2p));
 	if (new_pin < 0) {
 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
 	}
@@ -763,7 +765,8 @@
 	if (ssid == NULL) {
 		if (wpas_p2p_group_add(
 			wpa_s, persistent, 0, 0, ht40, vht,
-			CHANWIDTH_USE_HT, he, 0)) {
+			CHANWIDTH_USE_HT, he, 0,
+			is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 		} else {
 			return {SupplicantStatusCode::SUCCESS, ""};
@@ -771,7 +774,8 @@
 	} else if (ssid->disabled == 2) {
 		if (wpas_p2p_group_add_persistent(
 			wpa_s, ssid, 0, 0, 0, 0, ht40, vht,
-			CHANWIDTH_USE_HT, he, 0, NULL, 0, 0)) {
+			CHANWIDTH_USE_HT, he, 0, NULL, 0, 0,
+			is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 			return {SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN,
 				""};
 		} else {
@@ -815,7 +819,8 @@
 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
 	if (wpas_p2p_invite_group(
 		wpa_s, group_ifname.c_str(), peer_address.data(),
-		go_device_address.data())) {
+		go_device_address.data(),
+		is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 	}
 	return {SupplicantStatusCode::SUCCESS, ""};
@@ -836,7 +841,8 @@
 	}
 	if (wpas_p2p_invite(
 		wpa_s, peer_address.data(), ssid, NULL, 0, 0, ht40, vht,
-		CHANWIDTH_USE_HT, 0, he, 0)) {
+		CHANWIDTH_USE_HT, 0, he, 0,
+		is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 	}
 	return {SupplicantStatusCode::SUCCESS, ""};
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.1/hidl.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.1/hidl.cpp
index 95194af..67c6aa6 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.1/hidl.cpp
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.1/hidl.cpp
@@ -642,4 +642,3 @@
 
 	hidl_manager->notifyEapError(wpa_s, error_code);
 }
-
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.1/hidl_manager.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.1/hidl_manager.cpp
index ca614d2..90cba57 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.1/hidl_manager.cpp
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.1/hidl_manager.cpp
@@ -65,27 +65,6 @@
 	&on_hidl_died_fctor,
     std::vector<android::sp<CallbackType>> &callback_list)
 {
-#if 0   // TODO(b/31632518): HIDL object death notifications.
-	auto death_notifier = new CallbackObjectDeathNotifier<CallbackType>(
-	    callback, on_hidl_died_fctor);
-	// Use the |callback.get()| as cookie so that we don't need to
-	// store a reference to this |CallbackObjectDeathNotifier| instance
-	// to use in |unlinkToDeath| later.
-	// NOTE: This may cause an immediate callback if the object is already
-	// dead, so add it to the list before we register for callback!
-	if (android::hardware::IInterface::asBinder(callback)->linkToDeath(
-		death_notifier, callback.get()) != android::OK) {
-		wpa_printf(
-		    MSG_ERROR,
-		    "Error registering for death notification for "
-		    "supplicant callback object");
-		callback_list.erase(
-		    std::remove(
-			callback_list.begin(), callback_list.end(), callback),
-		    callback_list.end());
-		return 1;
-	}
-#endif  // TODO(b/31632518): HIDL object death notifications.
 	callback_list.push_back(callback);
 	return 0;
 }
@@ -173,19 +152,6 @@
 	auto iface_callback_map_iter = callbacks_map.find(ifname);
 	if (iface_callback_map_iter == callbacks_map.end())
 		return 1;
-#if 0   // TODO(b/31632518): HIDL object death notifications.
-	const auto &iface_callback_list = iface_callback_map_iter->second;
-	for (const auto &callback : iface_callback_list) {
-		if (android::hardware::IInterface::asBinder(callback)
-			->unlinkToDeath(nullptr, callback.get()) !=
-		    android::OK) {
-			wpa_printf(
-			    MSG_ERROR,
-			    "Error deregistering for death notification for "
-			    "iface callback object");
-		}
-	}
-#endif  // TODO(b/31632518): HIDL object death notifications.
 	callbacks_map.erase(iface_callback_map_iter);
 	return 0;
 }
@@ -199,20 +165,6 @@
 	auto network_callback_map_iter = callbacks_map.find(network_key);
 	if (network_callback_map_iter == callbacks_map.end())
 		return 1;
-#if 0   // TODO(b/31632518): HIDL object death notifications.
-	const auto &network_callback_list = network_callback_map_iter->second;
-	for (const auto &callback : network_callback_list) {
-		if (android::hardware::IInterface::asBinder(callback)
-			->unlinkToDeath(nullptr, callback.get()) !=
-		    android::OK) {
-			wpa_printf(
-			    MSG_ERROR,
-			    "Error deregistering for death "
-			    "notification for "
-			    "network callback object");
-		}
-	}
-#endif  // TODO(b/31632518): HIDL object death notifications.
 	callbacks_map.erase(network_callback_map_iter);
 	return 0;
 }
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.1/hidl_manager.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.1/hidl_manager.h
index 4f100aa..5a106dd 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.1/hidl_manager.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.1/hidl_manager.h
@@ -260,39 +260,6 @@
 	    std::vector<android::sp<ISupplicantStaNetworkCallback>>>
 	    sta_network_callbacks_map_;
 
-#if 0  // TODO(b/31632518): HIDL object death notifications.
-	/**
-	 * Helper class used to deregister the callback object reference from
-	 * our callback list on the death of the hidl object.
-	 * This class stores a reference of the callback hidl object and a
-	 * function to be called to indicate the death of the hidl object.
-	 */
-	template <class CallbackType>
-	class CallbackObjectDeathNotifier
-	    : public android::hardware::IBinder::DeathRecipient
-	{
-	public:
-		CallbackObjectDeathNotifier(
-		    const android::sp<CallbackType> &callback,
-		    const std::function<void(const android::sp<CallbackType> &)>
-			&on_hidl_died)
-		    : callback_(callback), on_hidl_died_(on_hidl_died)
-		{
-		}
-		void binderDied(const android::wp<android::hardware::IBinder>
-				    & /* who */) override
-		{
-			on_hidl_died_(callback_);
-		}
-
-	private:
-		// The callback hidl object reference.
-		const android::sp<CallbackType> callback_;
-		// Callback function to be called when the hidl dies.
-		const std::function<void(const android::sp<CallbackType> &)>
-		    on_hidl_died_;
-	};
-#endif
 };
 
 // The hidl interface uses some values which are the same as internal ones to
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.1/p2p_iface.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.1/p2p_iface.cpp
index 3d7697f..23ce6b5 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.1/p2p_iface.cpp
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.1/p2p_iface.cpp
@@ -644,7 +644,8 @@
 	uint32_t search_delay = wpas_p2p_search_delay(wpa_s);
 	if (wpas_p2p_find(
 		wpa_s, timeout_in_sec, P2P_FIND_START_WITH_FULL, 0, nullptr,
-		nullptr, search_delay, 0, nullptr, 0)) {
+		nullptr, search_delay, 0, nullptr, 0,
+		is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 	}
 	return {SupplicantStatusCode::SUCCESS, ""};
@@ -704,7 +705,8 @@
 	int new_pin = wpas_p2p_connect(
 	    wpa_s, peer_address.data(), pin, wps_method,
 	    persistent, false, join_existing_group, false, go_intent_signed, 0, 0, -1,
-	    false, ht40, vht,CHANWIDTH_USE_HT, he, 0, nullptr, 0);
+	    false, ht40, vht,CHANWIDTH_USE_HT, he, 0, nullptr, 0,
+	    is_p2p_allow_6ghz(wpa_s->global->p2p));
 	if (new_pin < 0) {
 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
 	}
@@ -763,7 +765,8 @@
 	if (ssid == NULL) {
 		if (wpas_p2p_group_add(
 			wpa_s, persistent, 0, 0, ht40, vht,
-			CHANWIDTH_USE_HT, he, 0)) {
+			CHANWIDTH_USE_HT, he, 0,
+			is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 		} else {
 			return {SupplicantStatusCode::SUCCESS, ""};
@@ -771,7 +774,8 @@
 	} else if (ssid->disabled == 2) {
 		if (wpas_p2p_group_add_persistent(
 			wpa_s, ssid, 0, 0, 0, 0, ht40, vht,
-			CHANWIDTH_USE_HT, he, 0, NULL, 0, 0)) {
+			CHANWIDTH_USE_HT, he, 0, NULL, 0, 0,
+			is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 			return {SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN,
 				""};
 		} else {
@@ -815,7 +819,8 @@
 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
 	if (wpas_p2p_invite_group(
 		wpa_s, group_ifname.c_str(), peer_address.data(),
-		go_device_address.data())) {
+		go_device_address.data(),
+		is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 	}
 	return {SupplicantStatusCode::SUCCESS, ""};
@@ -836,7 +841,8 @@
 	}
 	if (wpas_p2p_invite(
 		wpa_s, peer_address.data(), ssid, NULL, 0, 0, ht40, vht,
-		CHANWIDTH_USE_HT, 0, he, 0)) {
+		CHANWIDTH_USE_HT, 0, he, 0,
+		is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 	}
 	return {SupplicantStatusCode::SUCCESS, ""};
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.2/hidl_manager.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.2/hidl_manager.cpp
index b69fe04..a4f5b1d 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.2/hidl_manager.cpp
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.2/hidl_manager.cpp
@@ -67,27 +67,6 @@
 	&on_hidl_died_fctor,
     std::vector<android::sp<CallbackType>> &callback_list)
 {
-#if 0   // TODO(b/31632518): HIDL object death notifications.
-	auto death_notifier = new CallbackObjectDeathNotifier<CallbackType>(
-	    callback, on_hidl_died_fctor);
-	// Use the |callback.get()| as cookie so that we don't need to
-	// store a reference to this |CallbackObjectDeathNotifier| instance
-	// to use in |unlinkToDeath| later.
-	// NOTE: This may cause an immediate callback if the object is already
-	// dead, so add it to the list before we register for callback!
-	if (android::hardware::IInterface::asBinder(callback)->linkToDeath(
-		death_notifier, callback.get()) != android::OK) {
-		wpa_printf(
-		    MSG_ERROR,
-		    "Error registering for death notification for "
-		    "supplicant callback object");
-		callback_list.erase(
-		    std::remove(
-			callback_list.begin(), callback_list.end(), callback),
-		    callback_list.end());
-		return 1;
-	}
-#endif  // TODO(b/31632518): HIDL object death notifications.
 	callback_list.push_back(callback);
 	return 0;
 }
@@ -175,19 +154,6 @@
 	auto iface_callback_map_iter = callbacks_map.find(ifname);
 	if (iface_callback_map_iter == callbacks_map.end())
 		return 1;
-#if 0   // TODO(b/31632518): HIDL object death notifications.
-	const auto &iface_callback_list = iface_callback_map_iter->second;
-	for (const auto &callback : iface_callback_list) {
-		if (android::hardware::IInterface::asBinder(callback)
-			->unlinkToDeath(nullptr, callback.get()) !=
-		    android::OK) {
-			wpa_printf(
-			    MSG_ERROR,
-			    "Error deregistering for death notification for "
-			    "iface callback object");
-		}
-	}
-#endif  // TODO(b/31632518): HIDL object death notifications.
 	callbacks_map.erase(iface_callback_map_iter);
 	return 0;
 }
@@ -201,20 +167,6 @@
 	auto network_callback_map_iter = callbacks_map.find(network_key);
 	if (network_callback_map_iter == callbacks_map.end())
 		return 1;
-#if 0   // TODO(b/31632518): HIDL object death notifications.
-	const auto &network_callback_list = network_callback_map_iter->second;
-	for (const auto &callback : network_callback_list) {
-		if (android::hardware::IInterface::asBinder(callback)
-			->unlinkToDeath(nullptr, callback.get()) !=
-		    android::OK) {
-			wpa_printf(
-			    MSG_ERROR,
-			    "Error deregistering for death "
-			    "notification for "
-			    "network callback object");
-		}
-	}
-#endif  // TODO(b/31632518): HIDL object death notifications.
 	callbacks_map.erase(network_callback_map_iter);
 	return 0;
 }
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.2/hidl_manager.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.2/hidl_manager.h
index 910e2bf..2637c0d 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.2/hidl_manager.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.2/hidl_manager.h
@@ -271,39 +271,6 @@
 	    std::vector<android::sp<ISupplicantStaNetworkCallback>>>
 	    sta_network_callbacks_map_;
 
-#if 0  // TODO(b/31632518): HIDL object death notifications.
-	/**
-	 * Helper class used to deregister the callback object reference from
-	 * our callback list on the death of the hidl object.
-	 * This class stores a reference of the callback hidl object and a
-	 * function to be called to indicate the death of the hidl object.
-	 */
-	template <class CallbackType>
-	class CallbackObjectDeathNotifier
-	    : public android::hardware::IBinder::DeathRecipient
-	{
-	public:
-		CallbackObjectDeathNotifier(
-		    const android::sp<CallbackType> &callback,
-		    const std::function<void(const android::sp<CallbackType> &)>
-			&on_hidl_died)
-		    : callback_(callback), on_hidl_died_(on_hidl_died)
-		{
-		}
-		void binderDied(const android::wp<android::hardware::IBinder>
-				    & /* who */) override
-		{
-			on_hidl_died_(callback_);
-		}
-
-	private:
-		// The callback hidl object reference.
-		const android::sp<CallbackType> callback_;
-		// Callback function to be called when the hidl dies.
-		const std::function<void(const android::sp<CallbackType> &)>
-		    on_hidl_died_;
-	};
-#endif
 };
 
 // The hidl interface uses some values which are the same as internal ones to
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.2/p2p_iface.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.2/p2p_iface.cpp
index 46b3a8f..5d70055 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.2/p2p_iface.cpp
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.2/p2p_iface.cpp
@@ -344,7 +344,8 @@
 
 	if (wpas_p2p_group_add_persistent(
 		wpa_s, wpa_network, 0, 0, 0, 0, ht40, vht,
-		CHANWIDTH_USE_HT, he, 0, NULL, 0, 1)) {
+		CHANWIDTH_USE_HT, he, 0, NULL, 0, 1,
+		is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 		ret = -1;
 	}
 
@@ -997,7 +998,8 @@
 	uint32_t search_delay = wpas_p2p_search_delay(wpa_s);
 	if (wpas_p2p_find(
 		wpa_s, timeout_in_sec, P2P_FIND_START_WITH_FULL, 0, nullptr,
-		nullptr, search_delay, 0, nullptr, 0)) {
+		nullptr, search_delay, 0, nullptr, 0,
+		is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 	}
 	return {SupplicantStatusCode::SUCCESS, ""};
@@ -1063,7 +1065,8 @@
 	int new_pin = wpas_p2p_connect(
 	    wpa_s, peer_address.data(), pin, wps_method, persistent, false,
 	    join_existing_group, false, go_intent_signed, 0, 0, -1, false, ht40,
-	    vht, CHANWIDTH_USE_HT, he, 0, nullptr, 0);
+	    vht, CHANWIDTH_USE_HT, he, 0, nullptr, 0,
+	    is_p2p_allow_6ghz(wpa_s->global->p2p));
 	if (new_pin < 0) {
 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
 	}
@@ -1127,7 +1130,8 @@
 	if (ssid == NULL) {
 		if (wpas_p2p_group_add(
 			wpa_s, persistent, 0, 0, ht40, vht,
-			CHANWIDTH_USE_HT, he, 0)) {
+			CHANWIDTH_USE_HT, he, 0,
+			is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 		} else {
 			return {SupplicantStatusCode::SUCCESS, ""};
@@ -1135,7 +1139,8 @@
 	} else if (ssid->disabled == 2) {
 		if (wpas_p2p_group_add_persistent(
 			wpa_s, ssid, 0, 0, 0, 0, ht40, vht,
-			CHANWIDTH_USE_HT, he, 0, NULL, 0, 0)) {
+			CHANWIDTH_USE_HT, he, 0, NULL, 0, 0,
+			is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 			return {SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN,
 				""};
 		} else {
@@ -1179,7 +1184,8 @@
 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
 	if (wpas_p2p_invite_group(
 		wpa_s, group_ifname.c_str(), peer_address.data(),
-		go_device_address.data())) {
+		go_device_address.data(),
+		is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 	}
 	return {SupplicantStatusCode::SUCCESS, ""};
@@ -1200,7 +1206,9 @@
 	}
 	if (wpas_p2p_invite(
 		wpa_s, peer_address.data(), ssid, NULL, 0, 0, ht40, vht,
-		CHANWIDTH_USE_HT, 0, he, 0)) {
+		CHANWIDTH_USE_HT, 0, he, 0,
+		is_p2p_allow_6ghz(wpa_s->global->p2p)
+		)) {
 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 	}
 	return {SupplicantStatusCode::SUCCESS, ""};
@@ -1657,7 +1665,8 @@
 
 		if (wpas_p2p_group_add(
 		    wpa_s, persistent, freq, 0, ht40, vht,
-		    CHANWIDTH_USE_HT, he, 0)) {
+		    CHANWIDTH_USE_HT, he, 0,
+		    is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 		}
 		return {SupplicantStatusCode::SUCCESS, ""};
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.2/sta_iface.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.2/sta_iface.cpp
index 76ad3f9..d66001a 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.2/sta_iface.cpp
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.2/sta_iface.cpp
@@ -81,7 +81,7 @@
 	char driver_cmd_reply_buf[4096] = {};
 	if (wpa_drv_driver_cmd(
 		wpa_s, cmd_vec.data(), driver_cmd_reply_buf,
-		sizeof(driver_cmd_reply_buf))<0) {
+		sizeof(driver_cmd_reply_buf)) < 0) {
 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 	}
 	return {SupplicantStatusCode::SUCCESS, ""};
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/hidl.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/hidl.cpp
index 0ba494c..5a090fe 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/hidl.cpp
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/hidl.cpp
@@ -9,9 +9,6 @@
 
 #include <hwbinder/IPCThreadState.h>
 
-#if defined(CONFIG_DRIVER_NL80211_IFX) && defined(WAPI)
-#undef WAPI
-#endif /* CONFIG_DRIVER_NL80211_IFX && WAPI */
 
 #include <hidl/HidlTransportSupport.h>
 #include "hidl_manager.h"
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/hidl_manager.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/hidl_manager.cpp
index 088ae25..d13335f 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/hidl_manager.cpp
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/hidl_manager.cpp
@@ -11,9 +11,6 @@
 #include <iostream>
 #include <regex>
 
-#if defined(CONFIG_DRIVER_NL80211_IFX) && defined(WAPI)
-#undef WAPI
-#endif /* CONFIG_DRIVER_NL80211_IFX && WAPI */
 
 #include "hidl_manager.h"
 #include "misc_utils.h"
@@ -71,27 +68,6 @@
 	&on_hidl_died_fctor,
     std::vector<android::sp<CallbackType>> &callback_list)
 {
-#if 0   // TODO(b/31632518): HIDL object death notifications.
-	auto death_notifier = new CallbackObjectDeathNotifier<CallbackType>(
-	    callback, on_hidl_died_fctor);
-	// Use the |callback.get()| as cookie so that we don't need to
-	// store a reference to this |CallbackObjectDeathNotifier| instance
-	// to use in |unlinkToDeath| later.
-	// NOTE: This may cause an immediate callback if the object is already
-	// dead, so add it to the list before we register for callback!
-	if (android::hardware::IInterface::asBinder(callback)->linkToDeath(
-		death_notifier, callback.get()) != android::OK) {
-		wpa_printf(
-		    MSG_ERROR,
-		    "Error registering for death notification for "
-		    "supplicant callback object");
-		callback_list.erase(
-		    std::remove(
-			callback_list.begin(), callback_list.end(), callback),
-		    callback_list.end());
-		return 1;
-	}
-#endif  // TODO(b/31632518): HIDL object death notifications.
 	callback_list.push_back(callback);
 	return 0;
 }
@@ -179,19 +155,6 @@
 	auto iface_callback_map_iter = callbacks_map.find(ifname);
 	if (iface_callback_map_iter == callbacks_map.end())
 		return 1;
-#if 0   // TODO(b/31632518): HIDL object death notifications.
-	const auto &iface_callback_list = iface_callback_map_iter->second;
-	for (const auto &callback : iface_callback_list) {
-		if (android::hardware::IInterface::asBinder(callback)
-			->unlinkToDeath(nullptr, callback.get()) !=
-		    android::OK) {
-			wpa_printf(
-			    MSG_ERROR,
-			    "Error deregistering for death notification for "
-			    "iface callback object");
-		}
-	}
-#endif  // TODO(b/31632518): HIDL object death notifications.
 	callbacks_map.erase(iface_callback_map_iter);
 	return 0;
 }
@@ -205,20 +168,6 @@
 	auto network_callback_map_iter = callbacks_map.find(network_key);
 	if (network_callback_map_iter == callbacks_map.end())
 		return 1;
-#if 0   // TODO(b/31632518): HIDL object death notifications.
-	const auto &network_callback_list = network_callback_map_iter->second;
-	for (const auto &callback : network_callback_list) {
-		if (android::hardware::IInterface::asBinder(callback)
-			->unlinkToDeath(nullptr, callback.get()) !=
-		    android::OK) {
-			wpa_printf(
-			    MSG_ERROR,
-			    "Error deregistering for death "
-			    "notification for "
-			    "network callback object");
-		}
-	}
-#endif  // TODO(b/31632518): HIDL object death notifications.
 	callbacks_map.erase(network_callback_map_iter);
 	return 0;
 }
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/hidl_manager.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/hidl_manager.h
index e49e28d..d93898f 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/hidl_manager.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/hidl_manager.h
@@ -292,39 +292,6 @@
 	    std::vector<android::sp<ISupplicantStaNetworkCallback>>>
 	    sta_network_callbacks_map_;
 
-#if 0  // TODO(b/31632518): HIDL object death notifications.
-	/**
-	 * Helper class used to deregister the callback object reference from
-	 * our callback list on the death of the hidl object.
-	 * This class stores a reference of the callback hidl object and a
-	 * function to be called to indicate the death of the hidl object.
-	 */
-	template <class CallbackType>
-	class CallbackObjectDeathNotifier
-	    : public android::hardware::IBinder::DeathRecipient
-	{
-	public:
-		CallbackObjectDeathNotifier(
-		    const android::sp<CallbackType> &callback,
-		    const std::function<void(const android::sp<CallbackType> &)>
-			&on_hidl_died)
-		    : callback_(callback), on_hidl_died_(on_hidl_died)
-		{
-		}
-		void binderDied(const android::wp<android::hardware::IBinder>
-				    & /* who */) override
-		{
-			on_hidl_died_(callback_);
-		}
-
-	private:
-		// The callback hidl object reference.
-		const android::sp<CallbackType> callback_;
-		// Callback function to be called when the hidl dies.
-		const std::function<void(const android::sp<CallbackType> &)>
-		    on_hidl_died_;
-	};
-#endif
 };
 
 // The hidl interface uses some values which are the same as internal ones to
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/iface_config_utils.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/iface_config_utils.cpp
index 4e67dc0..5be96c3 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/iface_config_utils.cpp
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/iface_config_utils.cpp
@@ -9,9 +9,6 @@
  * See README for more details.
  */
 
-#if defined(CONFIG_DRIVER_NL80211_IFX) && defined(WAPI)
-#undef WAPI
-#endif /* CONFIG_DRIVER_NL80211_IFX && WAPI */
 
 #include "hidl_manager.h"
 #include "hidl_return_util.h"
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/p2p_iface.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/p2p_iface.cpp
index ed0368b..0e2b73b 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/p2p_iface.cpp
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/p2p_iface.cpp
@@ -8,9 +8,6 @@
  * See README for more details.
  */
 
-#if defined(CONFIG_DRIVER_NL80211_IFX) && defined(WAPI)
-#undef WAPI
-#endif /* CONFIG_DRIVER_NL80211_IFX && WAPI */
 
 #include "hidl_manager.h"
 #include "hidl_return_util.h"
@@ -363,7 +360,8 @@
 
 	if (wpas_p2p_group_add_persistent(
 		wpa_s, wpa_network, 0, 0, 0, 0, ht40, vht,
-		CHANWIDTH_USE_HT, he, 0, NULL, 0, 0)) {
+		CHANWIDTH_USE_HT, he, 0, NULL, 0, 0,
+		is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 		ret = -1;
 	}
 
@@ -1024,7 +1022,8 @@
 	uint32_t search_delay = wpas_p2p_search_delay(wpa_s);
 	if (wpas_p2p_find(
 		wpa_s, timeout_in_sec, P2P_FIND_START_WITH_FULL, 0, nullptr,
-		nullptr, search_delay, 0, nullptr, 0)) {
+		nullptr, search_delay, 0, nullptr, 0,
+		is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 	}
 	return {SupplicantStatusCode::SUCCESS, ""};
@@ -1090,7 +1089,8 @@
 	int new_pin = wpas_p2p_connect(
 	    wpa_s, peer_address.data(), pin, wps_method, persistent, false,
 	    join_existing_group, false, go_intent_signed, 0, 0, -1, false, ht40,
-	    vht, CHANWIDTH_USE_HT, he, 0, nullptr, 0);
+	    vht, CHANWIDTH_USE_HT, he, 0, nullptr, 0,
+	    is_p2p_allow_6ghz(wpa_s->global->p2p));
 	if (new_pin < 0) {
 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
 	}
@@ -1154,7 +1154,8 @@
 	if (ssid == NULL) {
 		if (wpas_p2p_group_add(
 			wpa_s, persistent, 0, 0, ht40, vht,
-			CHANWIDTH_USE_HT, he, 0)) {
+			CHANWIDTH_USE_HT, he, 0,
+			is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 		} else {
 			return {SupplicantStatusCode::SUCCESS, ""};
@@ -1162,7 +1163,8 @@
 	} else if (ssid->disabled == 2) {
 		if (wpas_p2p_group_add_persistent(
 			wpa_s, ssid, 0, 0, 0, 0, ht40, vht,
-			CHANWIDTH_USE_HT, he, 0, NULL, 0, 0)) {
+			CHANWIDTH_USE_HT, he, 0, NULL, 0, 0,
+			is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 			return {SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN,
 				""};
 		} else {
@@ -1206,7 +1208,8 @@
 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
 	if (wpas_p2p_invite_group(
 		wpa_s, group_ifname.c_str(), peer_address.data(),
-		go_device_address.data())) {
+		go_device_address.data(),
+		is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 	}
 	return {SupplicantStatusCode::SUCCESS, ""};
@@ -1227,7 +1230,8 @@
 	}
 	if (wpas_p2p_invite(
 		wpa_s, peer_address.data(), ssid, NULL, 0, 0, ht40, vht,
-		CHANWIDTH_USE_HT, 0, he, 0)) {
+		CHANWIDTH_USE_HT, 0, he, 0,
+		is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 	}
 	return {SupplicantStatusCode::SUCCESS, ""};
@@ -1684,7 +1688,8 @@
 
 		if (wpas_p2p_group_add(
 		    wpa_s, persistent, freq, 0, ht40, vht,
-		    CHANWIDTH_USE_HT, he, 0)) {
+		    CHANWIDTH_USE_HT, he, 0,
+		    is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 		}
 		return {SupplicantStatusCode::SUCCESS, ""};
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/p2p_network.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/p2p_network.cpp
index ade66b1..b91fb2f 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/p2p_network.cpp
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/p2p_network.cpp
@@ -7,9 +7,6 @@
  * See README for more details.
  */
 
-#if defined(CONFIG_DRIVER_NL80211_IFX) && defined(WAPI)
-#undef WAPI
-#endif /* CONFIG_DRIVER_NL80211_IFX && WAPI */
 
 #include "hidl_manager.h"
 #include "hidl_return_util.h"
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/sta_iface.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/sta_iface.cpp
index 9ae7b95..705263e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/sta_iface.cpp
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/sta_iface.cpp
@@ -7,9 +7,6 @@
  * See README for more details.
  */
 
-#if defined(CONFIG_DRIVER_NL80211_IFX) && defined(WAPI)
-#undef WAPI
-#endif /* CONFIG_DRIVER_NL80211_IFX && WAPI */
 
 #include "hidl_manager.h"
 #include "hidl_return_util.h"
@@ -95,7 +92,7 @@
 	char driver_cmd_reply_buf[4096] = {};
 	if (wpa_drv_driver_cmd(
 		wpa_s, cmd_vec.data(), driver_cmd_reply_buf,
-		sizeof(driver_cmd_reply_buf))) {
+		sizeof(driver_cmd_reply_buf)) < 0) {
 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 	}
 	return {SupplicantStatusCode::SUCCESS, ""};
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/sta_network.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/sta_network.cpp
index daf423e..7a1aebb 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/sta_network.cpp
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/sta_network.cpp
@@ -7,9 +7,6 @@
  * See README for more details.
  */
 
-#if defined(CONFIG_DRIVER_NL80211_IFX) && defined(WAPI)
-#undef WAPI
-#endif /* CONFIG_DRIVER_NL80211_IFX && WAPI */
 
 #include "hidl_manager.h"
 #include "hidl_return_util.h"
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/supplicant.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/supplicant.cpp
index 60ed418..e969cfd 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/supplicant.cpp
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.3/supplicant.cpp
@@ -7,9 +7,6 @@
  * See README for more details.
  */
 
-#if defined(CONFIG_DRIVER_NL80211_IFX) && defined(WAPI)
-#undef WAPI
-#endif /* CONFIG_DRIVER_NL80211_IFX && WAPI */
 
 #include "hidl_manager.h"
 #include "hidl_return_util.h"
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/hidl.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/hidl.cpp
index 2038e83..bd0354c 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/hidl.cpp
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/hidl.cpp
@@ -9,9 +9,6 @@
 
 #include <hwbinder/IPCThreadState.h>
 
-#if defined(CONFIG_DRIVER_NL80211_IFX) && defined(WAPI)
-#undef WAPI
-#endif /* CONFIG_DRIVER_NL80211_IFX && WAPI */
 
 #include <hidl/HidlTransportSupport.h>
 #include "hidl_manager.h"
@@ -849,6 +846,7 @@
 }
 
 
+#ifdef CONFIG_DPP
 void wpas_hidl_notify_dpp_conn_status(struct wpa_supplicant *wpa_s, enum dpp_status_error status,
 		const char *ssid, const char *channel_list, unsigned short band_list[], int size)
 {
@@ -870,6 +868,7 @@
 		break;
 	}
 }
+#endif /* CONFIG_DPP */
 
 void wpas_hidl_notify_pmk_cache_added(
     struct wpa_supplicant *wpa_s,
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/hidl.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/hidl.h
index 0974048..0a3cce1 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/hidl.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/hidl.h
@@ -103,6 +103,7 @@
 	    const u8 *p2p_dev_addr);
 	void wpas_hidl_notify_eap_error(
 	    struct wpa_supplicant *wpa_s, int error_code);
+#ifdef CONFIG_DPP
 	void wpas_hidl_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
 		    struct wpa_ssid *ssid);
 	void wpas_hidl_notify_dpp_config_sent(struct wpa_supplicant *wpa_s);
@@ -121,6 +122,7 @@
 	void wpas_hidl_notify_dpp_conn_status(struct wpa_supplicant *wpa_s,
 	    enum dpp_status_error status, const char *ssid,
 	    const char *channel_list, unsigned short band_list[], int size);
+#endif /* CONFIG_DPP */
 	void wpas_hidl_notify_pmk_cache_added(
 	    struct wpa_supplicant *wpas, struct rsn_pmksa_cache_entry *pmksa_entry);
 	void wpas_hidl_notify_bss_tm_status(struct wpa_supplicant *wpa_s);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/hidl_manager.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/hidl_manager.cpp
index 8eeb79a..de71c34 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/hidl_manager.cpp
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/hidl_manager.cpp
@@ -11,9 +11,6 @@
 #include <iostream>
 #include <regex>
 
-#if defined(CONFIG_DRIVER_NL80211_IFX) && defined(WAPI)
-#undef WAPI
-#endif /* CONFIG_DRIVER_NL80211_IFX && WAPI */
 
 #include "hidl_manager.h"
 #include "misc_utils.h"
@@ -465,7 +462,7 @@
 	if (isP2pIface(wpa_s)) {
 		wpa_printf(
                             MSG_ERROR,
-                            "Priyanka register p2p interface");
+                            "register p2p interface");
 		if (addHidlObjectToMap<P2pIface>(
 			wpa_s->ifname,
 			new P2pIface(wpa_s->global, wpa_s->ifname),
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/iface_config_utils.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/iface_config_utils.cpp
index 3b20d29..c2bbfee 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/iface_config_utils.cpp
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/iface_config_utils.cpp
@@ -9,9 +9,6 @@
  * See README for more details.
  */
 
-#if defined(CONFIG_DRIVER_NL80211_IFX) && defined(WAPI)
-#undef WAPI
-#endif /* CONFIG_DRIVER_NL80211_IFX && WAPI */
 
 #include "hidl_manager.h"
 #include "hidl_return_util.h"
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/p2p_iface.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/p2p_iface.cpp
index d6bd990..60916f0 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/p2p_iface.cpp
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/p2p_iface.cpp
@@ -8,9 +8,6 @@
  * See README for more details.
  */
 
-#if defined(CONFIG_DRIVER_NL80211_IFX) && defined(WAPI)
-#undef WAPI
-#endif /* CONFIG_DRIVER_NL80211_IFX && WAPI */
 
 #include "hidl_manager.h"
 #include "hidl_return_util.h"
@@ -413,7 +410,8 @@
 
 	if (wpas_p2p_group_add_persistent(
 		wpa_s, wpa_network, 0, 0, 0, 0, ht40, vht,
-		CHANWIDTH_USE_HT, he, 0, NULL, 0, 0)) {
+		CHANWIDTH_USE_HT, he, 0, NULL, 0, 0,
+		is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 		ret = -1;
 	}
 
@@ -1105,7 +1103,8 @@
 	uint32_t search_delay = wpas_p2p_search_delay(wpa_s);
 	if (wpas_p2p_find(
 		wpa_s, timeout_in_sec, P2P_FIND_START_WITH_FULL, 0, nullptr,
-		nullptr, search_delay, 0, nullptr, 0)) {
+		nullptr, search_delay, 0, nullptr, 0,
+		is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 	}
 	return {SupplicantStatusCode::SUCCESS, ""};
@@ -1172,7 +1171,8 @@
 	int new_pin = wpas_p2p_connect(
 	    wpa_s, peer_address.data(), pin, wps_method, persistent, auto_join,
 	    join_existing_group, false, go_intent_signed, 0, 0, -1, false, ht40,
-	    vht, CHANWIDTH_USE_HT, he, 0, nullptr, 0);
+	    vht, CHANWIDTH_USE_HT, he, 0, nullptr, 0,
+	    is_p2p_allow_6ghz(wpa_s->global->p2p));
 	if (new_pin < 0) {
 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
 	}
@@ -1236,7 +1236,8 @@
 	if (ssid == NULL) {
 		if (wpas_p2p_group_add(
 			wpa_s, persistent, 0, 0, ht40, vht,
-			CHANWIDTH_USE_HT, he, 0)) {
+			CHANWIDTH_USE_HT, he, 0,
+			is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 		} else {
 			return {SupplicantStatusCode::SUCCESS, ""};
@@ -1244,7 +1245,8 @@
 	} else if (ssid->disabled == 2) {
 		if (wpas_p2p_group_add_persistent(
 			wpa_s, ssid, 0, 0, 0, 0, ht40, vht,
-			CHANWIDTH_USE_HT, he, 0, NULL, 0, 0)) {
+			CHANWIDTH_USE_HT, he, 0, NULL, 0, 0,
+			is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 			return {SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN,
 				""};
 		} else {
@@ -1289,7 +1291,8 @@
 	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
 	if (wpas_p2p_invite_group(
 		wpa_s, group_ifname.c_str(), peer_address.data(),
-		go_device_address.data())) {
+		go_device_address.data(),
+		is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 	}
 	return {SupplicantStatusCode::SUCCESS, ""};
@@ -1310,7 +1313,8 @@
 	}
 	if (wpas_p2p_invite(
 		wpa_s, peer_address.data(), ssid, NULL, 0, 0, ht40, vht,
-		CHANWIDTH_USE_HT, 0, he, 0)) {
+		CHANWIDTH_USE_HT, 0, he, 0,
+		is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 	}
 	return {SupplicantStatusCode::SUCCESS, ""};
@@ -1767,7 +1771,7 @@
 
 		if (wpas_p2p_group_add(
 		    wpa_s, persistent, freq, 0, ht40, vht,
-		    CHANWIDTH_USE_HT, he, 0)) {
+		    CHANWIDTH_USE_HT, he, 0, is_p2p_allow_6ghz(wpa_s->global->p2p))) {
 			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 		}
 		return {SupplicantStatusCode::SUCCESS, ""};
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/p2p_network.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/p2p_network.cpp
index f1e3b53..083db4a 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/p2p_network.cpp
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/p2p_network.cpp
@@ -7,9 +7,6 @@
  * See README for more details.
  */
 
-#if defined(CONFIG_DRIVER_NL80211_IFX) && defined(WAPI)
-#undef WAPI
-#endif /* CONFIG_DRIVER_NL80211_IFX && WAPI */
 
 #include "hidl_manager.h"
 #include "hidl_return_util.h"
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/sta_iface.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/sta_iface.cpp
index 84b57bd..41ebc26 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/sta_iface.cpp
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/sta_iface.cpp
@@ -7,9 +7,6 @@
  * See README for more details.
  */
 
-#if defined(CONFIG_DRIVER_NL80211_IFX) && defined(WAPI)
-#undef WAPI
-#endif /* CONFIG_DRIVER_NL80211_IFX && WAPI */
 
 #include "hidl_manager.h"
 #include "hidl_return_util.h"
@@ -24,8 +21,10 @@
 #include "interworking.h"
 #include "hs20_supplicant.h"
 #include "wps_supplicant.h"
+#ifdef CONFIG_DPP
 #include "dpp.h"
 #include "dpp_supplicant.h"
+#endif /* CONFIG_DPP */
 #include "rsn_supp/wpa.h"
 #include "rsn_supp/pmksa_cache.h"
 }
@@ -96,7 +95,7 @@
 	char driver_cmd_reply_buf[4096] = {};
 	if (wpa_drv_driver_cmd(
 		wpa_s, cmd_vec.data(), driver_cmd_reply_buf,
-		sizeof(driver_cmd_reply_buf))) {
+		sizeof(driver_cmd_reply_buf)) < 0) {
 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
 	}
 	return {SupplicantStatusCode::SUCCESS, ""};
@@ -1617,7 +1616,7 @@
 	}
 	return {{V1_4::SupplicantStatusCode::FAILURE_UNKNOWN, ""}, bootstrap_info};
 #else
-	return {{V1_4::SupplicantStatusCode::FAILURE_UNSUPPORTED, ""}, bootstrap_info};
+	return {{V1_4::SupplicantStatusCode::FAILURE_UNSUPPORTED, ""}, {}};
 #endif
 }
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/sta_network.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/sta_network.cpp
index 9847342..7d8ca07 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/sta_network.cpp
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/sta_network.cpp
@@ -7,9 +7,6 @@
  * See README for more details.
  */
 
-#if defined(CONFIG_DRIVER_NL80211_IFX) && defined(WAPI)
-#undef WAPI
-#endif /* CONFIG_DRIVER_NL80211_IFX && WAPI */
 
 #include "hidl_manager.h"
 #include "hidl_return_util.h"
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/supplicant.cpp b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/supplicant.cpp
index 2fbff53..ea135c9 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/supplicant.cpp
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hidl/1.4/supplicant.cpp
@@ -7,9 +7,6 @@
  * See README for more details.
  */
 
-#if defined(CONFIG_DRIVER_NL80211_IFX) && defined(WAPI)
-#undef WAPI
-#endif /* CONFIG_DRIVER_NL80211_IFX && WAPI */
 
 #include "hidl_manager.h"
 #include "hidl_return_util.h"
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hs20_supplicant.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hs20_supplicant.c
index aa0ce7d..4d08a11 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hs20_supplicant.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/hs20_supplicant.c
@@ -25,7 +25,7 @@
 #include "notify.h"
 #endif /* ABOVE_8_1 */
 #include "bss.h"
-#include "blacklist.h"
+#include "bssid_ignore.h"
 #include "gas_query.h"
 #include "interworking.h"
 #include "hs20_supplicant.h"
@@ -1351,8 +1351,8 @@
 	wpas_notify_hs20_rx_deauth_imminent_notice(wpa_s, code, reauth_delay, url);
 #endif /* ABOVE_8_1 */
 	if (code == HS20_DEAUTH_REASON_CODE_BSS) {
-		wpa_printf(MSG_DEBUG, "HS 2.0: Add BSS to blacklist");
-		wpa_blacklist_add(wpa_s, wpa_s->bssid);
+		wpa_printf(MSG_DEBUG, "HS 2.0: Add BSS to ignore list");
+		wpa_bssid_ignore_add(wpa_s, wpa_s->bssid);
 		/* TODO: For now, disable full ESS since some drivers may not
 		 * support disabling per BSS. */
 		if (wpa_s->current_ssid) {
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/interworking.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/interworking.c
index f68af5f..e3b6293 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/interworking.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/interworking.c
@@ -702,12 +702,14 @@
 	    ((cred->password == NULL ||
 	      cred->password[0] == '\0') &&
 	     (cred->private_key == NULL ||
-	      cred->private_key[0] == '\0'))) {
+	      cred->private_key[0] == '\0') &&
+	     (!cred->key_id || cred->key_id[0] == '\0'))) {
 		wpa_msg(wpa_s, MSG_DEBUG,
-			"nai-realm-find-eap: incomplete cred info: username: %s  password: %s private_key: %s",
+			"nai-realm-find-eap: incomplete cred info: username: %s  password: %s private_key: %s key_id: %s",
 			cred->username ? cred->username : "NULL",
 			cred->password ? cred->password : "NULL",
-			cred->private_key ? cred->private_key : "NULL");
+			cred->private_key ? cred->private_key : "NULL",
+			cred->key_id ? cred->key_id : "NULL");
 		return NULL;
 	}
 
@@ -716,7 +718,8 @@
 		if (cred->password && cred->password[0] &&
 		    nai_realm_cred_username(wpa_s, eap))
 			return eap;
-		if (cred->private_key && cred->private_key[0] &&
+		if (((cred->private_key && cred->private_key[0]) ||
+		     (cred->key_id && cred->key_id[0])) &&
 		    nai_realm_cred_cert(wpa_s, eap))
 			return eap;
 	}
@@ -1539,6 +1542,24 @@
 				  cred->private_key_passwd) < 0)
 		return -1;
 
+	if (cred->ca_cert_id && cred->ca_cert_id[0] &&
+	    wpa_config_set_quoted(ssid, "ca_cert_id", cred->ca_cert_id) < 0)
+		return -1;
+
+	if (cred->cert_id && cred->cert_id[0] &&
+	    wpa_config_set_quoted(ssid, "cert_id", cred->cert_id) < 0)
+		return -1;
+
+	if (cred->key_id && cred->key_id[0] &&
+	    wpa_config_set_quoted(ssid, "key_id", cred->key_id) < 0)
+		return -1;
+
+	if (cred->engine_id && cred->engine_id[0] &&
+	    wpa_config_set_quoted(ssid, "engine_id", cred->engine_id) < 0)
+		return -1;
+
+	ssid->eap.cert.engine = cred->engine;
+
 	if (cred->phase1) {
 		os_free(ssid->eap.phase1);
 		ssid->eap.phase1 = os_strdup(cred->phase1);
@@ -2481,13 +2502,9 @@
 		bh = cred_below_min_backhaul(wpa_s, cred, bss);
 		bss_load = cred_over_max_bss_load(wpa_s, cred, bss);
 		conn_capab = cred_conn_capab_missing(wpa_s, cred, bss);
-		wpa_msg(wpa_s, MSG_INFO, "%s" MACSTR " type=%s%s%s%s id=%d priority=%d sp_priority=%d",
-			excluded ? INTERWORKING_BLACKLISTED : INTERWORKING_AP,
-			MAC2STR(bss->bssid), type,
-			bh ? " below_min_backhaul=1" : "",
-			bss_load ? " over_max_bss_load=1" : "",
-			conn_capab ? " conn_capab_missing=1" : "",
-			cred->id, cred->priority, cred->sp_priority);
+		wpas_notify_interworking_ap_added(wpa_s, bss, cred, excluded,
+						  type, bh, bss_load,
+						  conn_capab);
 		if (excluded)
 			continue;
 		if (wpa_s->auto_select ||
@@ -2578,6 +2595,8 @@
 			wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
 	}
 
+	wpas_notify_interworking_select_done(wpa_s);
+
 	if (selected) {
 		wpa_printf(MSG_DEBUG, "Interworking: Selected " MACSTR,
 			   MAC2STR(selected->bssid));
@@ -2793,6 +2812,7 @@
 			wpa_printf(MSG_WARNING,
 				   "ANQP: Cannot send MBO query to unknown BSS "
 				   MACSTR, MAC2STR(dst));
+			wpabuf_free(extra_buf);
 			return -1;
 		}
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/main.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/main.c
index 3bd07a3..5006671 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/main.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/main.c
@@ -130,11 +130,6 @@
 #ifdef __linux__
 	static int fd[3] = { -1, -1, -1 };
 	int i;
-	/* When started from pcmcia-cs scripts, wpa_supplicant might start with
-	 * fd 0, 1, and 2 closed. This will cause some issues because many
-	 * places in wpa_supplicant are still printing out to stdout. As a
-	 * workaround, make sure that fd's 0, 1, and 2 are not used for other
-	 * sockets. */
 	if (start) {
 		for (i = 0; i < 3; i++) {
 			fd[i] = open("/dev/null", O_RDWR);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/mesh.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/mesh.c
index 558d87a..b9e71b9 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/mesh.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/mesh.c
@@ -13,6 +13,7 @@
 #include "utils/uuid.h"
 #include "common/ieee802_11_defs.h"
 #include "common/wpa_ctrl.h"
+#include "common/hw_features_common.h"
 #include "ap/sta_info.h"
 #include "ap/hostapd.h"
 #include "ap/ieee802_11.h"
@@ -27,22 +28,30 @@
 #include "mesh.h"
 
 
-static void wpa_supplicant_mesh_deinit(struct wpa_supplicant *wpa_s)
+static void wpa_supplicant_mesh_deinit(struct wpa_supplicant *wpa_s,
+				       bool also_clear_hostapd)
 {
-	wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh);
-	wpa_s->ifmsh = NULL;
-	wpa_s->current_ssid = NULL;
+	wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh,
+					 also_clear_hostapd);
+
+	if (also_clear_hostapd) {
+		wpa_s->ifmsh = NULL;
+		wpa_s->current_ssid = NULL;
+		os_free(wpa_s->mesh_params);
+		wpa_s->mesh_params = NULL;
+	}
+
 	os_free(wpa_s->mesh_rsn);
 	wpa_s->mesh_rsn = NULL;
-	os_free(wpa_s->mesh_params);
-	wpa_s->mesh_params = NULL;
-	/* TODO: leave mesh (stop beacon). This will happen on link down
-	 * anyway, so it's not urgent */
+
+	if (!also_clear_hostapd)
+		wpa_supplicant_leave_mesh(wpa_s, false);
 }
 
 
 void wpa_supplicant_mesh_iface_deinit(struct wpa_supplicant *wpa_s,
-				      struct hostapd_iface *ifmsh)
+				      struct hostapd_iface *ifmsh,
+				      bool also_clear_hostapd)
 {
 	if (!ifmsh)
 		return;
@@ -63,8 +72,10 @@
 	}
 
 	/* take care of shared data */
-	hostapd_interface_deinit(ifmsh);
-	hostapd_interface_free(ifmsh);
+	if (also_clear_hostapd) {
+		hostapd_interface_deinit(ifmsh);
+		hostapd_interface_free(ifmsh);
+	}
 }
 
 
@@ -129,6 +140,7 @@
 	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;
+	conf->mesh_fwding = ssid->mesh_fwding;
 	conf->dot11MeshMaxRetries = ssid->dot11MeshMaxRetries;
 	conf->dot11MeshRetryTimeout = ssid->dot11MeshRetryTimeout;
 	conf->dot11MeshConfirmTimeout = ssid->dot11MeshConfirmTimeout;
@@ -194,6 +206,40 @@
 }
 
 
+static int wpas_mesh_update_freq_params(struct wpa_supplicant *wpa_s)
+{
+	struct wpa_driver_mesh_join_params *params = wpa_s->mesh_params;
+	struct hostapd_iface *ifmsh = wpa_s->ifmsh;
+	struct he_capabilities *he_capab = NULL;
+
+	if (ifmsh->current_mode)
+		he_capab = &ifmsh->current_mode->he_capab[IEEE80211_MODE_MESH];
+
+	if (hostapd_set_freq_params(
+		    &params->freq,
+		    ifmsh->conf->hw_mode,
+		    ifmsh->freq,
+		    ifmsh->conf->channel,
+		    ifmsh->conf->enable_edmg,
+		    ifmsh->conf->edmg_channel,
+		    ifmsh->conf->ieee80211n,
+		    ifmsh->conf->ieee80211ac,
+		    ifmsh->conf->ieee80211ax,
+		    ifmsh->conf->secondary_channel,
+		    hostapd_get_oper_chwidth(ifmsh->conf),
+		    hostapd_get_oper_centr_freq_seg0_idx(ifmsh->conf),
+		    hostapd_get_oper_centr_freq_seg1_idx(ifmsh->conf),
+		    ifmsh->conf->vht_capab,
+		    he_capab)) {
+		wpa_printf(MSG_ERROR, "Error updating mesh frequency params");
+		wpa_supplicant_mesh_deinit(wpa_s, true);
+		return -1;
+	}
+
+	return 0;
+}
+
+
 static int wpas_mesh_complete(struct wpa_supplicant *wpa_s)
 {
 	struct hostapd_iface *ifmsh = wpa_s->ifmsh;
@@ -207,12 +253,22 @@
 		return -1;
 	}
 
+	/*
+	 * Update channel configuration if the channel has changed since the
+	 * initial setting, i.e., due to DFS radar detection during CAC.
+	 */
+	if (ifmsh->freq > 0 && ifmsh->freq != params->freq.freq) {
+		wpa_s->assoc_freq = ifmsh->freq;
+		ssid->frequency = ifmsh->freq;
+		if (wpas_mesh_update_freq_params(wpa_s) < 0)
+			return -1;
+	}
+
 	if (ifmsh->mconf->security != MESH_CONF_SEC_NONE &&
 	    wpas_mesh_init_rsn(wpa_s)) {
 		wpa_printf(MSG_ERROR,
 			   "mesh: RSN initialization failed - deinit mesh");
-		wpa_supplicant_mesh_deinit(wpa_s);
-		wpa_drv_leave_mesh(wpa_s);
+		wpa_supplicant_mesh_deinit(wpa_s, false);
 		return -1;
 	}
 
@@ -237,13 +293,90 @@
 	/* hostapd sets the interface down until we associate */
 	wpa_drv_set_operstate(wpa_s, 1);
 
-	if (!ret)
+	if (!ret) {
 		wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
 
+		wpa_msg(wpa_s, MSG_INFO, MESH_GROUP_STARTED "ssid=\"%s\" id=%d",
+			wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
+			ssid->id);
+		wpas_notify_mesh_group_started(wpa_s, ssid);
+	}
+
 	return ret;
 }
 
 
+static void wpas_mesh_complete_cb(void *arg)
+{
+	struct wpa_supplicant *wpa_s = arg;
+
+	wpas_mesh_complete(wpa_s);
+}
+
+
+static int wpa_supplicant_mesh_enable_iface_cb(struct hostapd_iface *ifmsh)
+{
+	struct wpa_supplicant *wpa_s = ifmsh->owner;
+	struct hostapd_data *bss;
+
+	ifmsh->mconf = mesh_config_create(wpa_s, wpa_s->current_ssid);
+
+	bss = ifmsh->bss[0];
+	bss->msg_ctx = wpa_s;
+	os_memcpy(bss->own_addr, wpa_s->own_addr, ETH_ALEN);
+	bss->driver = wpa_s->driver;
+	bss->drv_priv = wpa_s->drv_priv;
+	bss->iface = ifmsh;
+	bss->mesh_sta_free_cb = mesh_mpm_free_sta;
+	bss->setup_complete_cb = wpas_mesh_complete_cb;
+	bss->setup_complete_cb_ctx = wpa_s;
+
+	bss->conf->start_disabled = 1;
+	bss->conf->mesh = MESH_ENABLED;
+	bss->conf->ap_max_inactivity = wpa_s->conf->mesh_max_inactivity;
+
+	if (wpa_drv_init_mesh(wpa_s)) {
+		wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh in driver");
+		return -1;
+	}
+
+	if (hostapd_setup_interface(ifmsh)) {
+		wpa_printf(MSG_ERROR,
+			   "Failed to initialize hostapd interface for mesh");
+		return -1;
+	}
+
+	return 0;
+}
+
+
+static int wpa_supplicant_mesh_disable_iface_cb(struct hostapd_iface *ifmsh)
+{
+	struct wpa_supplicant *wpa_s = ifmsh->owner;
+	size_t j;
+
+	wpa_supplicant_mesh_deinit(wpa_s, false);
+
+#ifdef NEED_AP_MLME
+	for (j = 0; j < ifmsh->num_bss; j++)
+		hostapd_cleanup_cs_params(ifmsh->bss[j]);
+#endif /* NEED_AP_MLME */
+
+	/* Same as hostapd_interface_deinit() without deinitializing control
+	 * interface */
+	for (j = 0; j < ifmsh->num_bss; j++) {
+		struct hostapd_data *hapd = ifmsh->bss[j];
+
+		hostapd_bss_deinit_no_free(hapd);
+		hostapd_free_hapd_data(hapd);
+	}
+
+	hostapd_cleanup_iface_partial(ifmsh);
+
+	return 0;
+}
+
+
 static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
 				    struct wpa_ssid *ssid,
 				    struct hostapd_freq_params *freq)
@@ -267,9 +400,12 @@
 	if (!ifmsh)
 		return -ENOMEM;
 
+	ifmsh->owner = wpa_s;
 	ifmsh->drv_flags = wpa_s->drv_flags;
 	ifmsh->drv_flags2 = wpa_s->drv_flags2;
 	ifmsh->num_bss = 1;
+	ifmsh->enable_iface_cb = wpa_supplicant_mesh_enable_iface_cb;
+	ifmsh->disable_iface_cb = wpa_supplicant_mesh_disable_iface_cb;
 	ifmsh->bss = os_calloc(wpa_s->ifmsh->num_bss,
 			       sizeof(struct hostapd_data *));
 	if (!ifmsh->bss)
@@ -285,11 +421,14 @@
 	bss->drv_priv = wpa_s->drv_priv;
 	bss->iface = ifmsh;
 	bss->mesh_sta_free_cb = mesh_mpm_free_sta;
+	bss->setup_complete_cb = wpas_mesh_complete_cb;
+	bss->setup_complete_cb_ctx = wpa_s;
 	frequency = ssid->frequency;
 	if (frequency != freq->freq &&
 	    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;
@@ -299,10 +438,42 @@
 	if (!conf)
 		goto out_free;
 
+	if (is_6ghz_freq(freq->freq)) {
+		/*
+		 * IEEE Std 802.11ax-2021, 12.12.2:
+		 * The STA shall use management frame protection (MFPR=1) when
+		 * using RSN.
+		 */
+		ssid->ieee80211w = MGMT_FRAME_PROTECTION_REQUIRED;
+
+		/* Set mandatory op_class parameter for setting up BSS */
+		switch (freq->bandwidth) {
+		case 20:
+			if (freq->freq == 5935)
+				conf->op_class = 136;
+			else
+				conf->op_class = 131;
+			break;
+		case 40:
+			conf->op_class = 132;
+			break;
+		case 80:
+			conf->op_class = 133;
+			break;
+		case 160:
+			conf->op_class = 134;
+			break;
+		default:
+			conf->op_class = 131;
+			break;
+		}
+	}
+
 	bss->conf = *conf->bss;
 	bss->conf->start_disabled = 1;
 	bss->conf->mesh = MESH_ENABLED;
 	bss->conf->ap_max_inactivity = wpa_s->conf->mesh_max_inactivity;
+	bss->conf->mesh_fwding = wpa_s->conf->mesh_fwding;
 
 	if (ieee80211_is_dfs(ssid->frequency, wpa_s->hw.modes,
 			     wpa_s->hw.num_modes) && wpa_s->conf->country[0]) {
@@ -311,6 +482,7 @@
 		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 = true;
 	}
 
 	bss->iconf = conf;
@@ -335,13 +507,6 @@
 	}
 
 	if (ssid->mesh_basic_rates == NULL) {
-		/*
-		 * XXX: Hack! This is so an MPM which correctly sets the ERP
-		 * mandatory rates as BSSBasicRateSet doesn't reject us. We
-		 * could add a new hw_mode HOSTAPD_MODE_IEEE80211G_ERP, but
-		 * this is way easier. This also makes our BSSBasicRateSet
-		 * advertised in beacons match the one in peering frames, sigh.
-		 */
 		if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G) {
 			conf->basic_rates = os_memdup(basic_rates_erp,
 						      sizeof(basic_rates_erp));
@@ -401,7 +566,7 @@
 
 	return 0;
 out_free:
-	wpa_supplicant_mesh_deinit(wpa_s);
+	wpa_supplicant_mesh_deinit(wpa_s, true);
 	return -ENOMEM;
 }
 
@@ -449,7 +614,7 @@
 		goto out;
 	}
 
-	wpa_supplicant_mesh_deinit(wpa_s);
+	wpa_supplicant_mesh_deinit(wpa_s, true);
 
 	wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
 	wpa_s->group_cipher = WPA_CIPHER_NONE;
@@ -516,29 +681,33 @@
 	}
 	params->conf.peer_link_timeout = wpa_s->conf->mesh_max_inactivity;
 
+	/* Always explicitely set forwarding to on or off for now */
+	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");
-		wpa_drv_leave_mesh(wpa_s);
+		wpa_supplicant_leave_mesh(wpa_s, true);
 		ret = -1;
 		goto out;
 	}
 
-	ret = wpas_mesh_complete(wpa_s);
 out:
 	return ret;
 }
 
 
-int wpa_supplicant_leave_mesh(struct wpa_supplicant *wpa_s)
+int wpa_supplicant_leave_mesh(struct wpa_supplicant *wpa_s, bool need_deinit)
 {
 	int ret = 0;
 
 	wpa_msg(wpa_s, MSG_INFO, "leaving mesh");
 
 	/* Need to send peering close messages first */
-	wpa_supplicant_mesh_deinit(wpa_s);
+	if (need_deinit)
+		wpa_supplicant_mesh_deinit(wpa_s, true);
 
 	ret = wpa_drv_leave_mesh(wpa_s);
 	if (ret)
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/mesh.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/mesh.h
index 7317083..a429e5e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/mesh.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/mesh.h
@@ -11,9 +11,11 @@
 
 int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s,
 			     struct wpa_ssid *ssid);
-int wpa_supplicant_leave_mesh(struct wpa_supplicant *wpa_s);
+int wpa_supplicant_leave_mesh(struct wpa_supplicant *wpa_s,
+			      bool need_deinit);
 void wpa_supplicant_mesh_iface_deinit(struct wpa_supplicant *wpa_s,
-				      struct hostapd_iface *ifmsh);
+				      struct hostapd_iface *ifmsh,
+				      bool also_clear_hostapd);
 int wpas_mesh_scan_result_text(const u8 *ies, size_t ies_len, char *buf,
 			       char *end);
 int wpas_mesh_add_interface(struct wpa_supplicant *wpa_s, char *ifname,
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/mesh_mpm.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/mesh_mpm.c
index b6a5e88..2eb9a7e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/mesh_mpm.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/mesh_mpm.c
@@ -251,6 +251,9 @@
 			   HE_MAX_MCS_CAPAB_SIZE +
 			   HE_MAX_PPET_CAPAB_SIZE;
 		buf_len += 3 + sizeof(struct ieee80211_he_operation);
+		if (is_6ghz_op_class(bss->iconf->op_class))
+			buf_len += sizeof(struct ieee80211_he_6ghz_oper_info) +
+				3 + sizeof(struct ieee80211_he_6ghz_band_cap);
 	}
 #endif /* CONFIG_IEEE80211AX */
 	if (type != PLINK_CLOSE)
@@ -303,9 +306,10 @@
 		info = (bss->num_plinks > 63 ? 63 : bss->num_plinks) << 1;
 		/* TODO: Add Connected to Mesh Gate/AS subfields */
 		wpabuf_put_u8(buf, info);
-		/* always forwarding & accepting plinks for now */
+		/* Set forwarding based on configuration and always accept
+		 * plinks for now */
 		wpabuf_put_u8(buf, MESH_CAP_ACCEPT_ADDITIONAL_PEER |
-			      MESH_CAP_FORWARDING);
+			      (conf->mesh_fwding ? MESH_CAP_FORWARDING : 0));
 	} else {	/* Peer closing frame */
 		/* IE: Mesh ID */
 		wpabuf_put_u8(buf, WLAN_EID_MESH_ID);
@@ -375,11 +379,14 @@
 				HE_MAX_PHY_CAPAB_SIZE +
 				HE_MAX_MCS_CAPAB_SIZE +
 				HE_MAX_PPET_CAPAB_SIZE +
-				3 + sizeof(struct ieee80211_he_operation)];
+				3 + sizeof(struct ieee80211_he_operation) +
+				sizeof(struct ieee80211_he_6ghz_oper_info) +
+				3 + sizeof(struct ieee80211_he_6ghz_band_cap)];
 
 		pos = hostapd_eid_he_capab(bss, he_capa_oper,
 					   IEEE80211_MODE_MESH);
 		pos = hostapd_eid_he_operation(bss, pos);
+		pos = hostapd_eid_he_6ghz_band_cap(bss, pos);
 		wpabuf_put_data(buf, he_capa_oper, pos - he_capa_oper);
 	}
 #endif /* CONFIG_IEEE80211AX */
@@ -749,6 +756,7 @@
 #ifdef CONFIG_IEEE80211AX
 	copy_sta_he_capab(data, sta, IEEE80211_MODE_MESH,
 			  elems->he_capabilities, elems->he_capabilities_len);
+	copy_sta_he_6ghz_capab(data, sta, elems->he_6ghz_band_cap);
 #endif /* CONFIG_IEEE80211AX */
 
 	if (hostapd_get_aid(data, sta) < 0) {
@@ -770,6 +778,7 @@
 	params.vht_capabilities = sta->vht_capabilities;
 	params.he_capab = sta->he_capab;
 	params.he_capab_len = sta->he_capab_len;
+	params.he_6ghz_capab = sta->he_6ghz_capab;
 	params.flags |= WPA_STA_WMM;
 	params.flags_mask |= WPA_STA_AUTHENTICATED;
 	if (conf->security == MESH_CONF_SEC_NONE) {
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/mesh_rsn.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/mesh_rsn.c
index 834c7a1..65daa77 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/mesh_rsn.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/mesh_rsn.c
@@ -344,7 +344,6 @@
 	}
 	return sae_prepare_commit(wpa_s->own_addr, sta->addr,
 				  (u8 *) password, os_strlen(password),
-				  ssid->sae_password_id,
 				  sta->sae);
 }
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/nmake.mak b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/nmake.mak
index 80e0ac8..617df03 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/nmake.mak
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/nmake.mak
@@ -114,7 +114,7 @@
 	$(OBJDIR)\driver_ndis_.obj \
 	$(OBJDIR)\scan_helpers.obj \
 	$(OBJDIR)\events.obj \
-	$(OBJDIR)\blacklist.obj \
+	$(OBJDIR)\bssid_ignore.obj \
 	$(OBJDIR)\scan.obj \
 	$(OBJDIR)\wpas_glue.obj \
 	$(OBJDIR)\eap_register.obj \
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/notify.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/notify.c
index bfd8ce2..e6ef0c8 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/notify.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/notify.c
@@ -19,18 +19,22 @@
 #include "rsn_supp/wpa.h"
 #include "fst/fst.h"
 #include "crypto/tls.h"
+#include "bss.h"
 #include "driver_i.h"
 #include "scan.h"
 #include "p2p_supplicant.h"
 #include "sme.h"
 #include "notify.h"
+#ifdef CONFIG_CTRL_IFACE_AIDL
+#include "aidl.h"
+#endif
 #if defined(CONFIG_HIDL) && defined(CONFIG_ANDROIDQ)
 #include "hidl/1.2/hidl.h"
-#elif defined(ABOVE_8_1) && defined(PIE)
+#elif defined(CONFIG_HIDL) && defined(ABOVE_8_1) && defined(PIE)
 #include "hidl/1.1/hidl.h"
-#elif defined(CONFIG_ANDROID11)
+#elif defined(CONFIG_HIDL) && defined(CONFIG_ANDROID11)
 #include "hidl/1.3/hidl.h"
-#elif defined(CONFIG_ANDROID12)
+#elif defined(CONFIG_HIDL) && defined(CONFIG_ANDROID12)
 #include "hidl/1.4/hidl.h"
 #else
 #ifdef CONFIG_CTRL_IFACE_HIDL
@@ -114,6 +118,11 @@
 	if (!global->hidl)
 		return -1;
 #endif /* CONFIG_CTRL_IFACE_HIDL */
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	global->aidl = wpas_aidl_init(global);
+	if (!global->aidl)
+		return -1;
+#endif
 
 	return 0;
 }
@@ -130,6 +139,10 @@
 	if (global->hidl)
 		wpas_hidl_deinit(global->hidl);
 #endif /* CONFIG_CTRL_IFACE_HIDL */
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	if (global->aidl)
+		wpas_aidl_deinit(global->aidl);
+#endif
 }
 
 
@@ -155,6 +168,11 @@
 	if (wpas_hidl_register_interface(wpa_s))
 		return -1;
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	/* AIDL interface wants to keep track of the P2P mgmt iface. */
+	if (wpas_aidl_register_interface(wpa_s))
+		return -1;
+#endif
 
 	return 0;
 }
@@ -179,6 +197,9 @@
 	/* HIDL interface wants to keep track of the P2P mgmt iface. */
 	wpas_hidl_unregister_interface(wpa_s);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	wpas_aidl_unregister_interface(wpa_s);
+#endif
 }
 
 
@@ -222,6 +243,9 @@
 #ifdef CONFIG_CTRL_IFACE_HIDL
 	wpas_hidl_notify_state_changed(wpa_s);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	wpas_aidl_notify_state_changed(wpa_s);
+#endif
 }
 
 
@@ -234,6 +258,9 @@
 #ifdef CONFIG_CTRL_IFACE_HIDL
 	wpas_hidl_notify_disconnect_reason(wpa_s);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_disconnect_reason(wpa_s);
+#endif
 }
 
 
@@ -264,6 +291,9 @@
 #endif /* CONFIG_ANDROID12 */
 			);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	wpas_aidl_notify_assoc_reject(wpa_s, bssid, timed_out, assoc_resp_ie, assoc_resp_ie_len);
+#endif
 }
 #ifdef ABOVE_8_1
 /* android commit:38e96765 wpa_supplicant(hidl):
@@ -276,6 +306,10 @@
 #ifdef CONFIG_CTRL_IFACE_HIDL
 	wpas_hidl_notify_auth_timeout(wpa_s);
 #endif /* CONFIG_CTRL_IFACE_HIDL */
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_auth_timeout(wpa_s);
+#endif /* CONFIG_CTRL_IFACE_AIDL */
+
 }
 #endif /* ABOVE_8_1 */
 
@@ -313,6 +347,11 @@
 		return;
 
 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSS_TM_STATUS);
+#ifdef CONFIG_WNM
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	wpas_aidl_notify_bss_tm_status(wpa_s);
+#endif
+#endif
 }
 
 
@@ -343,6 +382,9 @@
 #ifdef CONFIG_CTRL_IFACE_HIDL
 	wpas_hidl_notify_bssid_changed(wpa_s);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_bssid_changed(wpa_s);
+#endif
 }
 
 
@@ -387,6 +429,9 @@
 #ifdef CONFIG_CTRL_IFACE_HIDL
 	wpas_hidl_notify_network_request(wpa_s, ssid, rtype, default_txt);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_network_request(wpa_s, ssid, rtype, default_txt);
+#endif
 }
 
 
@@ -456,6 +501,11 @@
 					fail->config_error,
 					fail->error_indication);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_wps_event_fail(wpa_s, fail->peer_macaddr,
+                                        fail->config_error,
+                                        fail->error_indication);
+#endif
 #endif /* CONFIG_WPS */
 }
 
@@ -470,6 +520,9 @@
 #ifdef CONFIG_CTRL_IFACE_HIDL
 	wpas_hidl_notify_wps_event_success(wpa_s);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_wps_event_success(wpa_s);
+#endif
 #endif /* CONFIG_WPS */
 }
 
@@ -483,6 +536,9 @@
 #ifdef CONFIG_CTRL_IFACE_HIDL
 	wpas_hidl_notify_wps_event_pbc_overlap(wpa_s);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_wps_event_pbc_overlap(wpa_s);
+#endif
 #endif /* CONFIG_WPS */
 }
 
@@ -503,10 +559,16 @@
 	/* android commit:57ffbcfc wpa_supplicant: HIDL implementation (1/2) */
 	{
 		wpas_dbus_register_network(wpa_s, ssid);
+		wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_NETWORK_ADDED "%d",
+			     ssid->id);
 		/* android commit:57ffbcfc wpa_supplicant: HIDL implementation (1/2) */
 #ifdef CONFIG_CTRL_IFACE_HIDL
 		wpas_hidl_register_network(wpa_s, ssid);
 #endif /* CONFIG_CTRL_IFACE_HIDL */
+#ifdef CONFIG_CTRL_IFACE_AIDL
+                wpas_aidl_register_network(wpa_s, ssid);
+#endif /* CONFIG_CTRL_IFACE_AIDL */
+
 	}
 }
 
@@ -519,6 +581,9 @@
 #ifdef CONFIG_CTRL_IFACE_HIDL
 	wpas_hidl_register_network(wpa_s, ssid);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_register_network(wpa_s, ssid);
+#endif
 #endif /* CONFIG_P2P */
 }
 
@@ -531,6 +596,9 @@
 #ifdef CONFIG_CTRL_IFACE_HIDL
 	wpas_hidl_unregister_network(wpa_s, ssid);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_unregister_network(wpa_s, ssid);
+#endif
 #endif /* CONFIG_P2P */
 }
 
@@ -547,15 +615,25 @@
 	/* android commit:57ffbcfc wpa_supplicant: HIDL implementation (1/2) */
 	{
 		wpas_dbus_unregister_network(wpa_s, ssid->id);
+		wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_NETWORK_REMOVED "%d",
+			     ssid->id);
 		/* android commit:57ffbcfc wpa_supplicant: HIDL implementation (1/2) */
 #ifdef CONFIG_CTRL_IFACE_HIDL
 		wpas_hidl_unregister_network(wpa_s, ssid);
 #endif /* CONFIG_CTRL_IFACE_HIDL */
+#ifdef CONFIG_CTRL_IFACE_AIDL
+                wpas_aidl_unregister_network(wpa_s, ssid);
+#endif /* CONFIG_CTRL_IFACE_AIDL */
 	}
 	if (network_is_persistent_group(ssid))
 		wpas_notify_persistent_group_removed(wpa_s, ssid);
 
 	wpas_p2p_network_removed(wpa_s, ssid);
+
+#ifdef CONFIG_PASN
+	if (wpa_s->pasn.ssid == ssid)
+		wpa_s->pasn.ssid = NULL;
+#endif /* CONFIG_PASN */
 }
 
 
@@ -767,6 +845,9 @@
 	 * Implementation of P2p callbacks */
 	wpas_hidl_notify_p2p_find_stopped(wpa_s);
 #endif /* CONFIG_CTRL_IFACE_HIDL */
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_p2p_find_stopped(wpa_s);
+#endif /* CONFIG_CTRL_IFACE_HIDL */
 }
 
 
@@ -802,6 +883,14 @@
 #endif /* CONFIG_ANDROID12 */
 					  );
 #endif /* CONFIG_CTRL_IFACE_HIDL */
+
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	wpas_aidl_notify_p2p_device_found(wpa_s, addr, info,
+					  peer_wfd_device_info,
+					  peer_wfd_device_info_len,
+					  peer_wfd_r2_device_info,
+					  peer_wfd_r2_device_info_len);
+#endif /* CONFIG_CTRL_IFACE_AIDL */
 }
 
 
@@ -817,6 +906,9 @@
 	 * Implementation of P2p callbacks */
 	wpas_hidl_notify_p2p_device_lost(wpa_s, dev_addr);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_p2p_device_lost(wpa_s, dev_addr);
+#endif
 }
 
 
@@ -832,6 +924,9 @@
 	 * Implementation of P2p callbacks */
 	wpas_hidl_notify_p2p_group_removed(wpa_s, ssid, role);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_p2p_group_removed(wpa_s, ssid, role);
+#endif
 }
 
 
@@ -844,6 +939,9 @@
 	 * Implementation of P2p callbacks */
 	wpas_hidl_notify_p2p_go_neg_req(wpa_s, src, dev_passwd_id, go_intent);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_p2p_go_neg_req(wpa_s, src, dev_passwd_id, go_intent);
+#endif
 }
 
 
@@ -856,6 +954,9 @@
 	 * Implementation of P2p callbacks */
 	wpas_hidl_notify_p2p_go_neg_completed(wpa_s, res);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_p2p_go_neg_completed(wpa_s, res);
+#endif
 }
 
 
@@ -868,6 +969,9 @@
 	 * Implementation of P2p callbacks */
 	wpas_hidl_notify_p2p_invitation_result(wpa_s, status, bssid);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_p2p_invitation_result(wpa_s, status, bssid);
+#endif
 }
 
 
@@ -893,6 +997,10 @@
 	wpas_hidl_notify_p2p_sd_response(wpa_s, sa, update_indic,
 					 tlvs, tlvs_len);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_p2p_sd_response(wpa_s, sa, update_indic,
+                                         tlvs, tlvs_len);
+#endif
 }
 
 
@@ -925,6 +1033,11 @@
 						 status, config_methods,
 						 generated_pin);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_p2p_provision_discovery(wpa_s, dev_addr, request,
+                                                 status, config_methods,
+                                                 generated_pin);
+#endif
 }
 
 
@@ -941,6 +1054,9 @@
 	 * Implementation of P2p callbacks */
 	wpas_hidl_notify_p2p_group_started(wpa_s, ssid, persistent, client);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_p2p_group_started(wpa_s, ssid, persistent, client);
+#endif
 }
 
 
@@ -954,6 +1070,9 @@
 	 * Implementation of P2p callbacks */
 	wpas_hidl_notify_p2p_group_formation_failure(wpa_s, reason);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_p2p_group_formation_failure(wpa_s, reason);
+#endif
 }
 
 
@@ -977,6 +1096,10 @@
 	wpas_hidl_notify_p2p_invitation_received(wpa_s, sa, go_dev_addr, bssid,
 						 id, op_freq);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_p2p_invitation_received(wpa_s, sa, go_dev_addr, bssid,
+                                                 id, op_freq);
+#endif
 }
 
 #endif /* CONFIG_P2P */
@@ -1007,6 +1130,11 @@
 	 * Implementation of P2p callbacks */
 	wpas_hidl_notify_ap_sta_authorized(wpa_s, sta, p2p_dev_addr);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        /* android commit:fd2fd660 wpa_supplicant(hidl):
+         * Implementation of P2p callbacks */
+        wpas_aidl_notify_ap_sta_authorized(wpa_s, sta, p2p_dev_addr);
+#endif
 }
 
 
@@ -1031,6 +1159,9 @@
 	 * Implementation of P2p callbacks */
 	wpas_hidl_notify_ap_sta_deauthorized(wpa_s, sta, p2p_dev_addr);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_ap_sta_deauthorized(wpa_s, sta, p2p_dev_addr);
+#endif
 	/* Unregister the station */
 	wpas_dbus_unregister_sta(wpa_s, sta);
 }
@@ -1079,6 +1210,12 @@
 		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_ALT
 			"depth=%d %s", cert->depth, cert->altsubject[i]);
 
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	wpas_aidl_notify_ceritification(wpa_s, cert->depth, cert->subject,
+				       cert->altsubject, cert->num_altsubject,
+				       cert_hash, cert->cert);
+#endif
+
 	/* notify the new DBus API */
 	wpas_dbus_signal_certification(wpa_s, cert->depth, cert->subject,
 				       cert->altsubject, cert->num_altsubject,
@@ -1112,6 +1249,9 @@
 #ifdef VTS_1_0
 	wpas_hidl_notify_eap_error(wpa_s, error_code);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	wpas_aidl_notify_eap_error(wpa_s, error_code);
+#endif
 }
 
 
@@ -1164,6 +1304,9 @@
 #ifdef CONFIG_CTRL_IFACE_HIDL
 	wpas_hidl_notify_anqp_query_done(wpa_s, bssid, result, anqp);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_anqp_query_done(wpa_s, bssid, result, anqp);
+#endif
 #endif /* CONFIG_INTERWORKING */
 }
 
@@ -1179,6 +1322,10 @@
 	wpas_hidl_notify_hs20_icon_query_done(wpa_s, bssid, file_name, image,
 					      image_length);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_hs20_icon_query_done(wpa_s, bssid, file_name, image,
+                                              image_length);
+#endif
 #endif /* CONFIG_HS20 */
 }
 
@@ -1193,6 +1340,9 @@
 #ifdef CONFIG_CTRL_IFACE_HIDL
 	wpas_hidl_notify_hs20_rx_subscription_remediation(wpa_s, url, osu_method);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_hs20_rx_subscription_remediation(wpa_s, url, osu_method);
+#endif
 #endif /* CONFIG_HS20 */
 }
 
@@ -1208,9 +1358,27 @@
 	wpas_hidl_notify_hs20_rx_deauth_imminent_notice(wpa_s, code, reauth_delay,
 							url);
 #endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_hs20_rx_deauth_imminent_notice(wpa_s, code, reauth_delay,
+                                                        url);
+#endif
 #endif /* CONFIG_HS20 */
 }
 #endif /* ABOVE_8_1 */
+
+
+#ifdef CONFIG_CTRL_IFACE_AIDL
+void wpas_notify_hs20_rx_terms_and_conditions_acceptance(
+		struct wpa_supplicant *wpa_s, const char *url) {
+#ifdef CONFIG_HS20
+	if (!wpa_s || !url)
+		return;
+
+	wpas_aidl_notify_hs20_rx_terms_and_conditions_acceptance(wpa_s, url);
+#endif /* CONFIG_HS20 */
+}
+#endif /*CONFIG_CTRL_IFACE_AIDL*/
+
 #ifdef CONFIG_MESH
 
 void wpas_notify_mesh_group_started(struct wpa_supplicant *wpa_s,
@@ -1255,6 +1423,35 @@
 }
 
 #endif /* CONFIG_MESH */
+
+#ifdef CONFIG_INTERWORKING
+
+void wpas_notify_interworking_ap_added(struct wpa_supplicant *wpa_s,
+				       struct wpa_bss *bss,
+				       struct wpa_cred *cred, int excluded,
+				       const char *type, int bh, int bss_load,
+				       int conn_capab)
+{
+	wpa_msg(wpa_s, MSG_INFO, "%s" MACSTR " type=%s%s%s%s id=%d priority=%d sp_priority=%d",
+		excluded ? INTERWORKING_EXCLUDED : INTERWORKING_AP,
+		MAC2STR(bss->bssid), type,
+		bh ? " below_min_backhaul=1" : "",
+		bss_load ? " over_max_bss_load=1" : "",
+		conn_capab ? " conn_capab_missing=1" : "",
+		cred->id, cred->priority, cred->sp_priority);
+
+	wpas_dbus_signal_interworking_ap_added(wpa_s, bss, cred, type, excluded,
+					       bh, bss_load, conn_capab);
+}
+
+
+void wpas_notify_interworking_select_done(struct wpa_supplicant *wpa_s)
+{
+	wpas_dbus_signal_interworking_select_done(wpa_s);
+}
+
+#endif /* CONFIG_INTERWORKING */
+
 #if !(defined(OREO) || defined(PIE))
 /* android commit:59532857 [DPP] Added support for DPP in hidl */
 /*
@@ -1266,22 +1463,31 @@
 void wpas_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
 	    struct wpa_ssid *ssid)
 {
-#if defined(CONFIG_DPP) && defined(CONFIG_CTRL_IFACE_HIDL)
+#if defined(CONFIG_DPP)
 	if (!wpa_s)
 		return;
 
+#ifdef CONFIG_CTRL_IFACE_HIDL
 	wpas_hidl_notify_dpp_config_received(wpa_s, ssid);
-#endif /* CONFIG_DPP && CONFIG_CTRL_IFACE_HIDL */
+#endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_dpp_config_received(wpa_s, ssid);
+#endif
+#endif /* CONFIG_DPP */
 }
 
 void wpas_notify_dpp_config_sent(struct wpa_supplicant *wpa_s)
 {
-#if defined(CONFIG_DPP) && defined(CONFIG_CTRL_IFACE_HIDL)
+#if defined(CONFIG_DPP)
 	if (!wpa_s)
 		return;
-
+#ifdef CONFIG_CTRL_IFACE_HIDL
 	wpas_hidl_notify_dpp_config_sent(wpa_s);
-#endif /* CONFIG_DPP && CONFIG_CTRL_IFACE_HIDL */
+#endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_dpp_config_sent(wpa_s);
+#endif
+#endif /* CONFIG_DPP */
 }
 
 /* DPP Progress notifications */
@@ -1290,9 +1496,13 @@
 #if defined(CONFIG_DPP) && defined(CONFIG_CTRL_IFACE_HIDL)
 	if (!wpa_s)
 		return;
-
+#ifdef CONFIG_CTRL_IFACE_HIDL
 	wpas_hidl_notify_dpp_auth_success(wpa_s);
-#endif /* CONFIG_DPP && CONFIG_CTRL_IFACE_HIDL */
+#endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	wpas_aidl_notify_dpp_auth_success(wpa_s);
+#endif
+#endif /* CONFIG_DPP */
 }
 
 void wpas_notify_dpp_resp_pending(struct wpa_supplicant *wpa_s)
@@ -1300,85 +1510,124 @@
 #if defined(CONFIG_DPP) && defined(CONFIG_CTRL_IFACE_HIDL)
 	if (!wpa_s)
 		return;
-
+#ifdef CONFIG_CTRL_IFACE_HIDL
 	wpas_hidl_notify_dpp_resp_pending(wpa_s);
-#endif /* CONFIG_DPP && CONFIG_CTRL_IFACE_HIDL */
+#endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	wpas_aidl_notify_dpp_resp_pending(wpa_s);
+#endif
+#endif /* CONFIG_DPP */
 }
 
 /* DPP Failure notifications */
+
 void wpas_notify_dpp_not_compatible(struct wpa_supplicant *wpa_s)
 {
-#if defined(CONFIG_DPP) && defined(CONFIG_CTRL_IFACE_HIDL)
+#if defined(CONFIG_DPP)
 	if (!wpa_s)
 		return;
-
+#ifdef CONFIG_CTRL_IFACE_HIDL
 	wpas_hidl_notify_dpp_not_compatible(wpa_s);
-#endif /* CONFIG_DPP && CONFIG_CTRL_IFACE_HIDL */
+#endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	wpas_aidl_notify_dpp_not_compatible(wpa_s);
+#endif
+#endif /* CONFIG_DPP */
 }
 
 void wpas_notify_dpp_missing_auth(struct wpa_supplicant *wpa_s)
 {
-#if defined(CONFIG_DPP) && defined(CONFIG_CTRL_IFACE_HIDL)
+#if defined(CONFIG_DPP)
 	if (!wpa_s)
 		return;
-
+#ifdef CONFIG_CTRL_IFACE_HIDL
 	wpas_hidl_notify_dpp_missing_auth(wpa_s);
-#endif /* CONFIG_DPP && CONFIG_CTRL_IFACE_HIDL */
+#endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	wpas_aidl_notify_dpp_missing_auth(wpa_s);
+#endif
+#endif /* CONFIG_DPP */
 }
 
 void wpas_notify_dpp_configuration_failure(struct wpa_supplicant *wpa_s)
 {
-#if defined(CONFIG_DPP) && defined(CONFIG_CTRL_IFACE_HIDL)
+#if defined(CONFIG_DPP)
 	if (!wpa_s)
 		return;
-
+#ifdef CONFIG_CTRL_IFACE_HIDL
 	wpas_hidl_notify_dpp_configuration_failure(wpa_s);
-#endif /* CONFIG_DPP && CONFIG_CTRL_IFACE_HIDL */
+#endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	wpas_aidl_notify_dpp_configuration_failure(wpa_s);
+#endif
+#endif /* CONFIG_DPP */
 }
 
 void wpas_notify_dpp_timeout(struct wpa_supplicant *wpa_s)
 {
-#if defined(CONFIG_DPP) && defined(CONFIG_CTRL_IFACE_HIDL)
+#if defined(CONFIG_DPP)
 	if (!wpa_s)
 		return;
-
+#ifdef CONFIG_CTRL_IFACE_HIDL
 	wpas_hidl_notify_dpp_timeout(wpa_s);
-#endif /* CONFIG_DPP && CONFIG_CTRL_IFACE_HIDL */
+#endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	wpas_aidl_notify_dpp_timeout(wpa_s);
+#endif
+#endif /* CONFIG_DPP */
 }
 
 void wpas_notify_dpp_auth_failure(struct wpa_supplicant *wpa_s)
 {
-#if defined(CONFIG_DPP) && defined(CONFIG_CTRL_IFACE_HIDL)
+#if defined(CONFIG_DPP)
 	if (!wpa_s)
 		return;
-
+#ifdef CONFIG_CTRL_IFACE_HIDL
 	wpas_hidl_notify_dpp_auth_failure(wpa_s);
-#endif /* CONFIG_DPP && CONFIG_CTRL_IFACE_HIDL */
+#endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	wpas_aidl_notify_dpp_auth_failure(wpa_s);
+#endif
+#endif /* CONFIG_DPP */
 }
 
 void wpas_notify_dpp_failure(struct wpa_supplicant *wpa_s)
 {
-#if defined(CONFIG_DPP) && defined(CONFIG_CTRL_IFACE_HIDL)
+#if defined(CONFIG_DPP)
 	if (!wpa_s)
 		return;
-
+#ifdef CONFIG_CTRL_IFACE_HIDL
 	wpas_hidl_notify_dpp_fail(wpa_s);
-#endif /* CONFIG_DPP && CONFIG_CTRL_IFACE_HIDL */
+#endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	wpas_aidl_notify_dpp_fail(wpa_s);
+#endif
+#endif /* CONFIG_DPP */
 }
 
 /* android commit:0676811b [DPP R2] Added support for DPP R2 events */
 void wpas_notify_dpp_config_sent_wait_response(struct wpa_supplicant *wpa_s)
 {
-#if defined(CONFIG_DPP2) && defined(CONFIG_CTRL_IFACE_HIDL)
+#if defined(CONFIG_DPP2)
+#ifdef CONFIG_CTRL_IFACE_HIDL
 	wpas_hidl_notify_dpp_config_sent_wait_response(wpa_s);
-#endif /* CONFIG_DPP2 && CONFIG_CTRL_IFACE_HIDL */
+#endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	wpas_aidl_notify_dpp_config_sent_wait_response(wpa_s);
+#endif
+#endif /* CONFIG_DPP2 */
 }
 
 void wpas_notify_dpp_config_accepted(struct wpa_supplicant *wpa_s)
 {
-#if defined(CONFIG_DPP2) && defined(CONFIG_CTRL_IFACE_HIDL)
+#if defined(CONFIG_DPP2)
+#ifdef CONFIG_CTRL_IFACE_HIDL
 	wpas_hidl_notify_dpp_config_accepted(wpa_s);
-#endif /* CONFIG_DPP2 && CONFIG_CTRL_IFACE_HIDL */
+#endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	wpas_aidl_notify_dpp_config_accepted(wpa_s);
+#endif
+#endif /* CONFIG_DPP2 */
 }
 
 #ifdef CONFIG_DPP
@@ -1386,17 +1635,27 @@
 		enum dpp_status_error status, const char *ssid,
 		const char *channel_list, unsigned short band_list[], int size)
 {
-#if defined(CONFIG_DPP2) && defined(CONFIG_CTRL_IFACE_HIDL)
+#if defined(CONFIG_DPP2)
+#ifdef CONFIG_CTRL_IFACE_HIDL
 	wpas_hidl_notify_dpp_conn_status(wpa_s, status, ssid, channel_list, band_list, size);
-#endif /* CONFIG_DPP2 && CONFIG_CTRL_IFACE_HIDL */
+#endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	wpas_aidl_notify_dpp_conn_status(wpa_s, status, ssid, channel_list, band_list, size);
+#endif
+#endif /* CONFIG_DPP2 */
 }
 #endif /* CONFIG_DPP */
 
 void wpas_notify_dpp_config_rejected(struct wpa_supplicant *wpa_s)
 {
-#if defined(CONFIG_DPP2) && defined(CONFIG_CTRL_IFACE_HIDL)
+#if defined(CONFIG_DPP2)
+#ifdef CONFIG_CTRL_IFACE_HIDL
 	wpas_hidl_notify_dpp_config_rejected(wpa_s);
-#endif /* CONFIG_DPP2 && CONFIG_CTRL_IFACE_HIDL */
+#endif
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	wpas_aidl_notify_dpp_config_rejected(wpa_s);
+#endif
+#endif /* CONFIG_DPP2 */
 }
 #endif /* !(OREO || PIE) */
 
@@ -1405,11 +1664,80 @@
 void wpas_notify_pmk_cache_added(struct wpa_supplicant *wpa_s,
 				 struct rsn_pmksa_cache_entry *entry)
 {
+	if (!wpa_s)
+		return;
 #ifdef CONFIG_CTRL_IFACE_HIDL
+	wpas_hidl_notify_pmk_cache_added(wpa_s, entry);
+#endif /* CONFIG_CTRL_IFACE_HIDL */
+#ifdef CONFIG_CTRL_IFACE_AIDL
+        wpas_aidl_notify_pmk_cache_added(wpa_s, entry);
+#endif /* CONFIG_CTRL_IFACE_AIDL */
+}
+#endif /* CONFIG_ANDROID11 */
+
+
+#ifdef CONFIG_CTRL_IFACE_AIDL
+void wpas_notify_transition_disable(struct wpa_supplicant *wpa_s,
+                                    struct wpa_ssid *ssid,
+                                    u8 bitmap)
+{
+        if (!wpa_s)
+                return;
+
+        if (!ssid)
+                return;
+
+        wpas_aidl_notify_transition_disable(wpa_s, ssid, bitmap);
+}
+
+void wpas_notify_network_not_found(struct wpa_supplicant *wpa_s)
+{
+        if (!wpa_s)
+                return;
+
+        wpas_aidl_notify_network_not_found(wpa_s);
+}
+
+void wpas_notify_eap_method_selected(struct wpa_supplicant *wpa_s,
+			const char* reason_string)
+{
+	wpas_aidl_notify_eap_method_selected(wpa_s, reason_string);
+}
+
+void wpas_notify_ssid_temp_disabled(struct wpa_supplicant *wpa_s,
+			const char *reason_string)
+{
+	wpas_aidl_notify_ssid_temp_disabled(wpa_s, reason_string);
+}
+
+void wpas_notify_open_ssl_failure(struct wpa_supplicant *wpa_s,
+			const char *reason_string)
+{
+	wpas_aidl_notify_open_ssl_failure(wpa_s, reason_string);
+}
+
+void wpas_notify_qos_policy_reset(struct wpa_supplicant *wpa_s)
+{
 	if (!wpa_s)
 		return;
 
-	wpas_hidl_notify_pmk_cache_added(wpa_s, entry);
-#endif /* CONFIG_CTRL_IFACE_HIDL */
+	wpas_aidl_notify_qos_policy_reset(wpa_s);
 }
-#endif /* CONFIG_ANDROID11 */
+
+void wpas_notify_qos_policy_request(struct wpa_supplicant *wpa_s,
+	struct dscp_policy_data *policies, int num_policies)
+{
+	if (!wpa_s || !policies)
+		return;
+
+	wpas_aidl_notify_qos_policy_request(wpa_s, policies, num_policies);
+}
+
+void wpas_notify_frequency_changed(struct wpa_supplicant *wpa_s, int frequency)
+{
+	if (!wpa_s)
+		return;
+
+	wpas_aidl_notify_frequency_changed(wpa_s, frequency);
+}
+#endif /* CONFIG_CTRL_IFACE_AIDL */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/notify.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/notify.h
index 386f643..1a051e0 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/notify.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/notify.h
@@ -26,6 +26,7 @@
 struct wps_event_m2d;
 struct wps_event_fail;
 struct tls_cert_data;
+struct wpa_cred;
 
 int wpas_notify_supplicant_initialized(struct wpa_global *global);
 void wpas_notify_supplicant_deinitialized(struct wpa_global *global);
@@ -185,6 +186,13 @@
 				     const u8 *peer_addr);
 void wpas_notify_mesh_peer_disconnected(struct wpa_supplicant *wpa_s,
 					const u8 *peer_addr, u16 reason_code);
+void wpas_notify_interworking_ap_added(struct wpa_supplicant *wpa_s,
+				       struct wpa_bss *bss,
+				       struct wpa_cred *cred, int excluded,
+				       const char *type, int bh, int bss_load,
+				       int conn_capab);
+void wpas_notify_interworking_select_done(struct wpa_supplicant *wpa_s);
+
 #ifdef ABOVE_8_1
 /* android commit:04a9d747 Add notifications for ANQP/HS20 events */
 void wpas_notify_anqp_query_done(struct wpa_supplicant *wpa_s, const u8* bssid,
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/op_classes.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/op_classes.c
index b4c0c8a..bd53c5c 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/op_classes.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/op_classes.c
@@ -22,10 +22,10 @@
 				       unsigned int *flags)
 {
 	int i;
-	int is_6ghz = op_class >= 131 && op_class <= 136;
+	bool is_6ghz = op_class >= 131 && op_class <= 136;
 
 	for (i = 0; i < mode->num_channels; i++) {
-		int chan_is_6ghz;
+		bool chan_is_6ghz;
 
 		chan_is_6ghz = mode->channels[i].freq >= 5935 &&
 			mode->channels[i].freq <= 7115;
@@ -77,7 +77,7 @@
 	unsigned int no_ir = 0;
 	const u8 *center_channels;
 	size_t num_chan;
-	const u8 center_channels_5ghz[] = { 42, 58, 106, 122, 138, 155 };
+	const u8 center_channels_5ghz[] = { 42, 58, 106, 122, 138, 155, 171 };
 	const u8 center_channels_6ghz[] = { 7, 23, 39, 55, 71, 87, 103, 119,
 					    135, 151, 167, 183, 199, 215 };
 
@@ -150,7 +150,7 @@
 	unsigned int no_ir = 0;
 	const u8 *center_channels;
 	size_t num_chan;
-	const u8 center_channels_5ghz[] = { 50, 114 };
+	const u8 center_channels_5ghz[] = { 50, 114, 163 };
 	const u8 center_channels_6ghz[] = { 15, 47, 79, 111, 143, 175, 207 };
 
 	if (is_6ghz_op_class(op_class)) {
@@ -207,11 +207,15 @@
 		if (!(flag & HOSTAPD_CHAN_HT40MINUS))
 			return NOT_ALLOWED;
 		res2 = allow_channel(mode, op_class, channel - 4, NULL);
-	} else if (bw == BW40PLUS ||
-		   (bw == BW40 && !(((channel - 1) / 4) % 2))) {
+	} else if (bw == BW40PLUS) {
 		if (!(flag & HOSTAPD_CHAN_HT40PLUS))
 			return NOT_ALLOWED;
 		res2 = allow_channel(mode, op_class, channel + 4, NULL);
+	} else if (is_6ghz_op_class(op_class) && bw == BW40) {
+		if (get_6ghz_sec_channel(channel) < 0)
+			res2 = allow_channel(mode, op_class, channel - 4, NULL);
+		else
+			res2 = allow_channel(mode, op_class, channel + 4, NULL);
 	} else if (bw == BW80) {
 		/*
 		 * channel is a center channel and as such, not necessarily a
@@ -320,7 +324,7 @@
 #endif /* CONFIG_VHT_OVERRIDES */
 
 	if (op_class->op_class == 128) {
-		u8 channels[] = { 42, 58, 106, 122, 138, 155 };
+		u8 channels[] = { 42, 58, 106, 122, 138, 155, 171 };
 
 		for (i = 0; i < ARRAY_SIZE(channels); i++) {
 			if (verify_channel(mode, op_class->op_class,
@@ -337,6 +341,8 @@
 		return verify_channel(mode, op_class->op_class, 50,
 				      op_class->bw) != NOT_ALLOWED ||
 			verify_channel(mode, op_class->op_class, 114,
+				       op_class->bw) != NOT_ALLOWED ||
+			verify_channel(mode, op_class->op_class, 163,
 				       op_class->bw) != NOT_ALLOWED;
 	}
 
@@ -354,6 +360,10 @@
 		    verify_channel(mode, op_class->op_class, 122,
 				   op_class->bw) != NOT_ALLOWED ||
 		    verify_channel(mode, op_class->op_class, 138,
+				   op_class->bw) != NOT_ALLOWED ||
+		    verify_channel(mode, op_class->op_class, 155,
+				   op_class->bw) != NOT_ALLOWED ||
+		    verify_channel(mode, op_class->op_class, 171,
 				   op_class->bw) != NOT_ALLOWED)
 			found++;
 		if (verify_channel(mode, op_class->op_class, 106,
@@ -361,7 +371,14 @@
 		    verify_channel(mode, op_class->op_class, 138,
 				   op_class->bw) != NOT_ALLOWED)
 			found++;
-		if (verify_channel(mode, op_class->op_class, 155,
+		if (verify_channel(mode, op_class->op_class, 122,
+				   op_class->bw) != NOT_ALLOWED &&
+		    verify_channel(mode, op_class->op_class, 155,
+				   op_class->bw) != NOT_ALLOWED)
+			found++;
+		if (verify_channel(mode, op_class->op_class, 138,
+				   op_class->bw) != NOT_ALLOWED &&
+		    verify_channel(mode, op_class->op_class, 171,
 				   op_class->bw) != NOT_ALLOWED)
 			found++;
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/p2p_supplicant.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/p2p_supplicant.c
index b28308b..65c2789 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/p2p_supplicant.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/p2p_supplicant.c
@@ -172,6 +172,17 @@
                                    const struct p2p_channels *channels);
 #endif /* CONFIG_BRCM_BT_WIFI_HO */
 
+static int wpas_get_6ghz_he_chwidth_capab(struct hostapd_hw_modes *mode)
+{
+	int he_capab = 0;
+
+	if (mode)
+		he_capab = mode->he_capab[WPAS_MODE_INFRA].phy_cap[
+			HE_PHYCAP_CHANNEL_WIDTH_SET_IDX];
+	return he_capab;
+}
+
+
 /*
  * Get the number of concurrent channels that the HW can operate, but that are
  * currently not in use by any of the wpa_supplicant interfaces.
@@ -250,6 +261,22 @@
 }
 
 
+static void wpas_p2p_scan_res_handled(struct wpa_supplicant *wpa_s)
+{
+	unsigned int delay = wpas_p2p_search_delay(wpa_s);
+
+	/* In case of concurrent P2P and external scans, delay P2P search. */
+	if (external_scan_running(wpa_s->radio)) {
+		delay = wpa_s->conf->p2p_search_delay;
+		wpa_printf(MSG_DEBUG,
+			   "P2P: Delay next P2P search by %d ms to let externally triggered scan complete",
+			   delay);
+	}
+
+	p2p_scan_res_handled(wpa_s->global->p2p, delay);
+}
+
+
 static void wpas_p2p_scan_res_handler(struct wpa_supplicant *wpa_s,
 				      struct wpa_scan_results *scan_res)
 {
@@ -295,42 +322,25 @@
 			break;
 	}
 
-	p2p_scan_res_handled(wpa_s->global->p2p);
+	wpas_p2p_scan_res_handled(wpa_s);
 }
 
 
-static int wpas_p2p_add_scan_freq_list(struct wpa_supplicant *wpa_s,
-				       enum hostapd_hw_mode band,
-				       struct wpa_driver_scan_params *params)
+static void wpas_p2p_scan_res_fail_handler(struct wpa_supplicant *wpa_s)
 {
-	struct hostapd_hw_modes *mode;
-	int num_chans = 0;
-	int *freqs, i;
+	if (wpa_s->p2p_scan_work) {
+		struct wpa_radio_work *work = wpa_s->p2p_scan_work;
 
-	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, band, 0);
-	if (!mode)
-		return -1;
-
-	if (params->freqs) {
-		while (params->freqs[num_chans])
-			num_chans++;
+		wpa_s->p2p_scan_work = NULL;
+		radio_work_done(work);
 	}
 
-	freqs = os_realloc(params->freqs,
-			   (num_chans + mode->num_channels + 1) * sizeof(int));
-	if (!freqs)
-		return -1;
+	if (wpa_s->global->p2p_disabled || !wpa_s->global->p2p)
+		return;
 
-	params->freqs = freqs;
-
-	for (i = 0; i < mode->num_channels; i++) {
-		if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED)
-			continue;
-		params->freqs[num_chans++] = mode->channels[i].freq;
-	}
-	params->freqs[num_chans] = 0;
-
-	return 0;
+	wpa_dbg(wpa_s, MSG_DEBUG,
+		"P2P: Failed to get scan results - try to continue");
+	wpas_p2p_scan_res_handled(wpa_s);
 }
 
 
@@ -356,13 +366,13 @@
 		params->only_new_results = 1;
 	}
 
-	if (wpa_s->conf->p2p_6ghz_disable && !params->freqs) {
+	if (!params->p2p_include_6ghz && !params->freqs) {
 		wpa_printf(MSG_DEBUG,
-			   "P2P: 6 GHz disabled - update the scan frequency list");
-		wpas_p2p_add_scan_freq_list(wpa_s, HOSTAPD_MODE_IEEE80211G,
-					    params);
-		wpas_p2p_add_scan_freq_list(wpa_s, HOSTAPD_MODE_IEEE80211A,
-					    params);
+			   "P2P: Exclude 6 GHz channels - update the scan frequency list");
+		wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211G, params,
+					0);
+		wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211A, params,
+					0);
 	}
 	ret = wpa_drv_scan(wpa_s, params);
 	if (ret == 0)
@@ -378,6 +388,7 @@
 	p2p_notify_scan_trigger_status(wpa_s->global->p2p, ret);
 	os_get_reltime(&wpa_s->scan_trigger_time);
 	wpa_s->scan_res_handler = wpas_p2p_scan_res_handler;
+	wpa_s->scan_res_fail_handler = wpas_p2p_scan_res_fail_handler;
 	wpa_s->own_scan_requested = 1;
 	wpa_s->clear_driver_scan_cache = 0;
 	wpa_s->p2p_scan_work = work;
@@ -403,11 +414,13 @@
 #if defined(CONFIG_BRCM_RSDB)
 static int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int *freq,
 			 unsigned int num_req_dev_types,
-			 const u8 *req_dev_types, const u8 *dev_id, u16 pw_id)
+			 const u8 *req_dev_types, const u8 *dev_id, u16 pw_id,
+			 bool include_6ghz)
 #else
 static int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
 			 unsigned int num_req_dev_types,
-			 const u8 *req_dev_types, const u8 *dev_id, u16 pw_id)
+			 const u8 *req_dev_types, const u8 *dev_id, u16 pw_id,
+			 bool include_6ghz)
 #endif /* CONFIG_DRIVER_NL80211_IFX && CONFIG_BRCM_RSDB */
 {
 	struct wpa_supplicant *wpa_s = ctx;
@@ -446,7 +459,8 @@
 					num_req_dev_types, req_dev_types);
 	if (wps_ie == NULL)
 		goto fail;
-
+	if (!wpa_s->conf->p2p_6ghz_disable)
+		params->p2p_include_6ghz = include_6ghz;
 	switch (type) {
 	case P2P_SCAN_SOCIAL:
 		params->freqs = os_calloc(ARRAY_SIZE(social_channels_freq) + 1,
@@ -1062,6 +1076,7 @@
 	wpa_s->p2p_group_common_freqs = NULL;
 	wpa_s->p2p_group_common_freqs_num = 0;
 	wpa_s->p2p_go_do_acs = 0;
+	wpa_s->p2p_go_allow_dfs = 0;
 
 	wpa_s->waiting_presence_resp = 0;
 
@@ -1998,7 +2013,7 @@
 		return -1;
 
 	hwmode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
-			  HOSTAPD_MODE_IEEE80211AD, 0);
+			  HOSTAPD_MODE_IEEE80211AD, false);
 	if (!hwmode) {
 		wpa_printf(MSG_ERROR,
 			   "Unsupported AP mode: HOSTAPD_MODE_IEEE80211AD");
@@ -2105,6 +2120,16 @@
 	}
 	ssid->auth_alg = WPA_AUTH_ALG_OPEN;
 	ssid->key_mgmt = WPA_KEY_MGMT_PSK;
+	if (is_6ghz_freq(ssid->frequency) &&
+	    is_p2p_6ghz_capable(wpa_s->global->p2p)) {
+		ssid->auth_alg |= WPA_AUTH_ALG_SAE;
+		ssid->key_mgmt = WPA_KEY_MGMT_SAE;
+		ssid->ieee80211w = MGMT_FRAME_PROTECTION_REQUIRED;
+		ssid->sae_pwe = 1;
+		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use SAE auth_alg and key_mgmt");
+	} else {
+		p2p_set_6ghz_dev_capab(wpa_s->global->p2p, false);
+	}
 	ssid->proto = WPA_PROTO_RSN;
 	ssid->pairwise_cipher = WPA_CIPHER_CCMP;
 	ssid->group_cipher = WPA_CIPHER_CCMP;
@@ -2189,6 +2214,8 @@
 	d->disassoc_low_ack = s->disassoc_low_ack;
 	d->disable_scan_offload = s->disable_scan_offload;
 	d->passive_scan = s->passive_scan;
+	d->pmf = s->pmf;
+	d->p2p_6ghz_disable = s->p2p_6ghz_disable;
 #ifdef CONFIG_BRCM_RSN_CNTRS
 	d->replay_cntrs = s->replay_cntrs;
 #endif /* CONFIG_BRCM_RSN_CNTRS */
@@ -3497,7 +3524,7 @@
 				wpa_s->conf->p2p_go_he,
 				wpa_s->conf->p2p_go_edmg, NULL,
 				go ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0,
-				1);
+				1, is_p2p_allow_6ghz(wpa_s->global->p2p));
 		} else if (bssid) {
 			wpa_s->user_initiated_pd = 0;
 			wpa_msg_global(wpa_s, MSG_INFO,
@@ -3726,7 +3753,8 @@
 				      channels,
 				      ssid->mode == WPAS_MODE_P2P_GO ?
 				      P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE :
-				      0, 1);
+				      0, 1,
+				      is_p2p_allow_6ghz(wpa_s->global->p2p));
 }
 
 
@@ -3808,27 +3836,27 @@
 }
 
 
-static int has_channel(struct wpa_global *global,
-		       struct hostapd_hw_modes *mode, u8 chan, int *flags)
+static enum chan_allowed has_channel(struct wpa_global *global,
+				     struct hostapd_hw_modes *mode, u8 op_class,
+				     u8 chan, int *flags)
 {
 	int i;
 	unsigned int freq;
 
-	freq = (mode->mode == HOSTAPD_MODE_IEEE80211A ? 5000 : 2407) +
-		chan * 5;
+	freq = ieee80211_chan_to_freq(NULL, op_class, chan);
 	if (wpas_p2p_disallowed_freq(global, freq))
 		return NOT_ALLOWED;
 
 	for (i = 0; i < mode->num_channels; i++) {
-		if (mode->channels[i].chan == chan) {
+		if ((unsigned int) mode->channels[i].freq == freq) {
 			if (flags)
 				*flags = mode->channels[i].flag;
-			if (mode->channels[i].flag &
-			    (HOSTAPD_CHAN_DISABLED |
-			     HOSTAPD_CHAN_RADAR))
+			if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED)
 				return NOT_ALLOWED;
 			if (mode->channels[i].flag & HOSTAPD_CHAN_NO_IR)
 				return NO_IR;
+			if (mode->channels[i].flag & HOSTAPD_CHAN_RADAR)
+				return RADAR;
 			return ALLOWED;
 		}
 	}
@@ -3839,15 +3867,15 @@
 
 static int wpas_p2p_get_center_80mhz(struct wpa_supplicant *wpa_s,
 				     struct hostapd_hw_modes *mode,
-				     u8 channel)
+				     u8 channel, const u8 *center_channels,
+				     size_t num_chan)
 {
-	u8 center_channels[] = { 42, 58, 106, 122, 138, 155 };
 	size_t i;
 
 	if (mode->mode != HOSTAPD_MODE_IEEE80211A)
 		return 0;
 
-	for (i = 0; i < ARRAY_SIZE(center_channels); i++)
+	for (i = 0; i < num_chan; i++)
 		/*
 		 * In 80 MHz, the bandwidth "spans" 12 channels (e.g., 36-48),
 		 * so the center channel is 6 channels away from the start/end.
@@ -3860,38 +3888,64 @@
 }
 
 
+static const u8 center_channels_5ghz_80mhz[] = { 42, 58, 106, 122, 138,
+						 155, 171 };
+static const u8 center_channels_6ghz_80mhz[] = { 7, 23, 39, 55, 71, 87, 103,
+						 119, 135, 151, 167, 183, 199,
+						 215 };
+
 static enum chan_allowed wpas_p2p_verify_80mhz(struct wpa_supplicant *wpa_s,
 					       struct hostapd_hw_modes *mode,
-					       u8 channel, u8 bw)
+					       u8 op_class, u8 channel, u8 bw)
 {
 	u8 center_chan;
 	int i, flags;
 	enum chan_allowed res, ret = ALLOWED;
+	const u8 *chans;
+	size_t num_chans;
+	bool is_6ghz = is_6ghz_op_class(op_class);
 
-	center_chan = wpas_p2p_get_center_80mhz(wpa_s, mode, channel);
+	if (is_6ghz) {
+		chans = center_channels_6ghz_80mhz;
+		num_chans = ARRAY_SIZE(center_channels_6ghz_80mhz);
+	} else {
+		chans = center_channels_5ghz_80mhz;
+		num_chans = ARRAY_SIZE(center_channels_5ghz_80mhz);
+	}
+	center_chan = wpas_p2p_get_center_80mhz(wpa_s, mode, channel,
+						chans, num_chans);
 	if (!center_chan)
 		return NOT_ALLOWED;
-	if (center_chan >= 58 && center_chan <= 138)
+	if (!wpa_s->p2p_go_allow_dfs &&
+	    !is_6ghz && center_chan >= 58 && center_chan <= 138)
 		return NOT_ALLOWED; /* Do not allow DFS channels for P2P */
 
 	/* check all the channels are available */
 	for (i = 0; i < 4; i++) {
 		int adj_chan = center_chan - 6 + i * 4;
 
-		res = has_channel(wpa_s->global, mode, adj_chan, &flags);
+		res = has_channel(wpa_s->global, mode, op_class, adj_chan,
+				  &flags);
 		if (res == NOT_ALLOWED)
 			return NOT_ALLOWED;
+		if (res == RADAR)
+			ret = RADAR;
 		if (res == NO_IR)
 			ret = NO_IR;
-
-		if (i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_70))
+		if (!is_6ghz) {
+			if (i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_70))
+				return NOT_ALLOWED;
+			if (i == 1 && !(flags & HOSTAPD_CHAN_VHT_30_50))
+				return NOT_ALLOWED;
+			if (i == 2 && !(flags & HOSTAPD_CHAN_VHT_50_30))
+				return NOT_ALLOWED;
+			if (i == 3 && !(flags & HOSTAPD_CHAN_VHT_70_10))
+				return NOT_ALLOWED;
+		} else if (is_6ghz &&
+			   (!(wpas_get_6ghz_he_chwidth_capab(mode) &
+			      HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G))) {
 			return NOT_ALLOWED;
-		if (i == 1 && !(flags & HOSTAPD_CHAN_VHT_30_50))
-			return NOT_ALLOWED;
-		if (i == 2 && !(flags & HOSTAPD_CHAN_VHT_50_30))
-			return NOT_ALLOWED;
-		if (i == 3 && !(flags & HOSTAPD_CHAN_VHT_70_10))
-			return NOT_ALLOWED;
+		}
 	}
 
 	return ret;
@@ -3900,15 +3954,15 @@
 
 static int wpas_p2p_get_center_160mhz(struct wpa_supplicant *wpa_s,
 				     struct hostapd_hw_modes *mode,
-				     u8 channel)
+				     u8 channel, const u8 *center_channels,
+				     size_t num_chan)
 {
-	u8 center_channels[] = { 50, 114 };
 	unsigned int i;
 
 	if (mode->mode != HOSTAPD_MODE_IEEE80211A)
 		return 0;
 
-	for (i = 0; i < ARRAY_SIZE(center_channels); i++)
+	for (i = 0; i < num_chan; i++)
 		/*
 		 * In 160 MHz, the bandwidth "spans" 28 channels (e.g., 36-64),
 		 * so the center channel is 14 channels away from the start/end.
@@ -3921,15 +3975,29 @@
 }
 
 
+static const u8 center_channels_5ghz_160mhz[] = { 50, 114, 163 };
+static const u8 center_channels_6ghz_160mhz[] = { 15, 47, 79, 111, 143, 175,
+						  207 };
+
 static enum chan_allowed wpas_p2p_verify_160mhz(struct wpa_supplicant *wpa_s,
 					       struct hostapd_hw_modes *mode,
-					       u8 channel, u8 bw)
+					       u8 op_class, u8 channel, u8 bw)
 {
 	u8 center_chan;
 	int i, flags;
 	enum chan_allowed res, ret = ALLOWED;
+	const u8 *chans;
+	size_t num_chans;
 
-	center_chan = wpas_p2p_get_center_160mhz(wpa_s, mode, channel);
+	if (is_6ghz_op_class(op_class)) {
+		chans = center_channels_6ghz_160mhz;
+		num_chans = ARRAY_SIZE(center_channels_6ghz_160mhz);
+	} else {
+		chans = center_channels_5ghz_160mhz;
+		num_chans = ARRAY_SIZE(center_channels_5ghz_160mhz);
+	}
+	center_chan = wpas_p2p_get_center_160mhz(wpa_s, mode, channel,
+						 chans, num_chans);
 	if (!center_chan)
 		return NOT_ALLOWED;
 	/* VHT 160 MHz uses DFS channels in most countries. */
@@ -3938,29 +4006,38 @@
 	for (i = 0; i < 8; i++) {
 		int adj_chan = center_chan - 14 + i * 4;
 
-		res = has_channel(wpa_s->global, mode, adj_chan, &flags);
+		res = has_channel(wpa_s->global, mode, op_class, adj_chan,
+				  &flags);
 		if (res == NOT_ALLOWED)
 			return NOT_ALLOWED;
 
+		if (res == RADAR)
+			ret = RADAR;
 		if (res == NO_IR)
 			ret = NO_IR;
 
-		if (i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_150))
+		if (!is_6ghz_op_class(op_class)) {
+			if (i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_150))
+				return NOT_ALLOWED;
+			if (i == 1 && !(flags & HOSTAPD_CHAN_VHT_30_130))
+				return NOT_ALLOWED;
+			if (i == 2 && !(flags & HOSTAPD_CHAN_VHT_50_110))
+				return NOT_ALLOWED;
+			if (i == 3 && !(flags & HOSTAPD_CHAN_VHT_70_90))
+				return NOT_ALLOWED;
+			if (i == 4 && !(flags & HOSTAPD_CHAN_VHT_90_70))
+				return NOT_ALLOWED;
+			if (i == 5 && !(flags & HOSTAPD_CHAN_VHT_110_50))
+				return NOT_ALLOWED;
+			if (i == 6 && !(flags & HOSTAPD_CHAN_VHT_130_30))
+				return NOT_ALLOWED;
+			if (i == 7 && !(flags & HOSTAPD_CHAN_VHT_150_10))
+				return NOT_ALLOWED;
+		} else if (is_6ghz_op_class(op_class) &&
+			   (!(wpas_get_6ghz_he_chwidth_capab(mode) &
+			      HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G))) {
 			return NOT_ALLOWED;
-		if (i == 1 && !(flags & HOSTAPD_CHAN_VHT_30_130))
-			return NOT_ALLOWED;
-		if (i == 2 && !(flags & HOSTAPD_CHAN_VHT_50_110))
-			return NOT_ALLOWED;
-		if (i == 3 && !(flags & HOSTAPD_CHAN_VHT_70_90))
-			return NOT_ALLOWED;
-		if (i == 4 && !(flags & HOSTAPD_CHAN_VHT_90_70))
-			return NOT_ALLOWED;
-		if (i == 5 && !(flags & HOSTAPD_CHAN_VHT_110_50))
-			return NOT_ALLOWED;
-		if (i == 6 && !(flags & HOSTAPD_CHAN_VHT_130_30))
-			return NOT_ALLOWED;
-		if (i == 7 && !(flags & HOSTAPD_CHAN_VHT_150_10))
-			return NOT_ALLOWED;
+		}
 	}
 
 	return ret;
@@ -3983,24 +4060,37 @@
 
 static enum chan_allowed wpas_p2p_verify_channel(struct wpa_supplicant *wpa_s,
 						 struct hostapd_hw_modes *mode,
-						 u8 channel, u8 bw)
+						 u8 op_class, u8 channel, u8 bw)
 {
 	int flag = 0;
 	enum chan_allowed res, res2;
 
-	res2 = res = has_channel(wpa_s->global, mode, channel, &flag);
+	res2 = res = has_channel(wpa_s->global, mode, op_class, channel, &flag);
 	if (bw == BW40MINUS) {
 		if (!(flag & HOSTAPD_CHAN_HT40MINUS))
 			return NOT_ALLOWED;
-		res2 = has_channel(wpa_s->global, mode, channel - 4, NULL);
+		res2 = has_channel(wpa_s->global, mode, op_class, channel - 4,
+				   NULL);
 	} else if (bw == BW40PLUS) {
 		if (!(flag & HOSTAPD_CHAN_HT40PLUS))
 			return NOT_ALLOWED;
-		res2 = has_channel(wpa_s->global, mode, channel + 4, NULL);
+		res2 = has_channel(wpa_s->global, mode, op_class, channel + 4,
+				   NULL);
+	} else if (is_6ghz_op_class(op_class) && bw == BW40) {
+		if (mode->mode != HOSTAPD_MODE_IEEE80211A)
+			return NOT_ALLOWED;
+		if (get_6ghz_sec_channel(channel) < 0)
+			res2 = has_channel(wpa_s->global, mode, op_class,
+					   channel - 4, NULL);
+		else
+			res2 = has_channel(wpa_s->global, mode, op_class,
+					   channel + 4, NULL);
 	} else if (bw == BW80) {
-		res2 = wpas_p2p_verify_80mhz(wpa_s, mode, channel, bw);
+		res2 = wpas_p2p_verify_80mhz(wpa_s, mode, op_class, channel,
+					     bw);
 	} else if (bw == BW160) {
-		res2 = wpas_p2p_verify_160mhz(wpa_s, mode, channel, bw);
+		res2 = wpas_p2p_verify_160mhz(wpa_s, mode, op_class, channel,
+					      bw);
 	} else if (bw == BW4320 || bw == BW6480 || bw == BW8640) {
 		return wpas_p2p_verify_edmg(wpa_s, mode, channel);
 	}
@@ -4009,6 +4099,8 @@
 		return NOT_ALLOWED;
 	if (res == NO_IR || res2 == NO_IR)
 		return NO_IR;
+	if (res == RADAR || res2 == RADAR)
+		return RADAR;
 	return res;
 }
 
@@ -4032,7 +4124,7 @@
 
 	for (op = 0; global_op_class[op].op_class; op++) {
 		const struct oper_class_map *o = &global_op_class[op];
-		u8 ch;
+		unsigned int ch;
 		struct p2p_reg_class *reg = NULL, *cli_reg = NULL;
 
 		if (o->p2p == NO_P2P_SUPP ||
@@ -4050,11 +4142,12 @@
 
 			/* Check for non-continuous jump in channel index
 			 * incrementation */
-			if ((o->op_class == 128 || o->op_class == 130) &&
+			if ((o->op_class >= 128 && o->op_class <= 130) &&
 			    ch < 149 && ch + o->inc > 149)
 				ch = 149;
 
-			res = wpas_p2p_verify_channel(wpa_s, mode, ch, o->bw);
+			res = wpas_p2p_verify_channel(wpa_s, mode, o->op_class,
+						      ch, o->bw);
 			if (res == ALLOWED) {
 				if (reg == NULL) {
 					if (cla == P2P_MAX_REG_CLASSES)
@@ -4104,29 +4197,50 @@
 }
 
 
-int wpas_p2p_get_ht40_mode(struct wpa_supplicant *wpa_s,
-			   struct hostapd_hw_modes *mode, u8 channel)
+int wpas_p2p_get_sec_channel_offset_40mhz(struct wpa_supplicant *wpa_s,
+					  struct hostapd_hw_modes *mode,
+					  u8 channel)
 {
 	int op;
 	enum chan_allowed ret;
 
 	for (op = 0; global_op_class[op].op_class; op++) {
 		const struct oper_class_map *o = &global_op_class[op];
-		u8 ch;
+		u16 ch;
+		int chan = channel;
 
-		if (o->p2p == NO_P2P_SUPP ||
+		/* Allow DFS channels marked as NO_P2P_SUPP to be used with
+		 * driver offloaded DFS. */
+		if ((o->p2p == NO_P2P_SUPP &&
+		     (!is_dfs_global_op_class(o->op_class) ||
+		      !wpa_s->p2p_go_allow_dfs)) ||
 		    (is_6ghz_op_class(o->op_class) &&
 		     wpa_s->conf->p2p_6ghz_disable))
 			continue;
 
+		if (is_6ghz_op_class(o->op_class) && o->bw == BW40 &&
+		    get_6ghz_sec_channel(channel) < 0)
+			chan = channel - 4;
+
 		for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
 			if (o->mode != HOSTAPD_MODE_IEEE80211A ||
-			    (o->bw != BW40PLUS && o->bw != BW40MINUS) ||
-			    ch != channel)
+			    (o->bw != BW40PLUS && o->bw != BW40MINUS &&
+			     o->bw != BW40) ||
+			    ch != chan)
 				continue;
-			ret = wpas_p2p_verify_channel(wpa_s, mode, ch, o->bw);
-			if (ret == ALLOWED)
+			ret = wpas_p2p_verify_channel(wpa_s, mode, o->op_class,
+						      ch, o->bw);
+			if (ret == ALLOWED) {
+				if (is_6ghz_op_class(o->op_class) &&
+				    o->bw == BW40)
+					return get_6ghz_sec_channel(channel);
 				return (o->bw == BW40MINUS) ? -1 : 1;
+			}
+			if (ret == RADAR && wpa_s->p2p_go_allow_dfs) {
+				/* Allow RADAR channels used for driver
+				 * offloaded DFS */
+				return (o->bw == BW40MINUS) ? -1 : 1;
+			}
 		}
 	}
 	return 0;
@@ -4134,21 +4248,49 @@
 
 
 int wpas_p2p_get_vht80_center(struct wpa_supplicant *wpa_s,
-			      struct hostapd_hw_modes *mode, u8 channel)
+			      struct hostapd_hw_modes *mode, u8 channel,
+			      u8 op_class)
 {
-	if (!wpas_p2p_verify_channel(wpa_s, mode, channel, BW80))
+	const u8 *chans;
+	size_t num_chans;
+	enum chan_allowed ret;
+
+	ret = wpas_p2p_verify_channel(wpa_s, mode, op_class, channel, BW80);
+	if (!(ret == ALLOWED || (ret == RADAR && wpa_s->p2p_go_allow_dfs)))
 		return 0;
 
-	return wpas_p2p_get_center_80mhz(wpa_s, mode, channel);
+	if (is_6ghz_op_class(op_class)) {
+		chans = center_channels_6ghz_80mhz;
+		num_chans = ARRAY_SIZE(center_channels_6ghz_80mhz);
+	} else {
+		chans = center_channels_5ghz_80mhz;
+		num_chans = ARRAY_SIZE(center_channels_5ghz_80mhz);
+	}
+	return wpas_p2p_get_center_80mhz(wpa_s, mode, channel,
+					 chans, num_chans);
 }
 
 
 int wpas_p2p_get_vht160_center(struct wpa_supplicant *wpa_s,
-			       struct hostapd_hw_modes *mode, u8 channel)
+			       struct hostapd_hw_modes *mode, u8 channel,
+			       u8 op_class)
 {
-	if (!wpas_p2p_verify_channel(wpa_s, mode, channel, BW160))
+	const u8 *chans;
+	size_t num_chans;
+	enum chan_allowed ret;
+
+	ret = wpas_p2p_verify_channel(wpa_s, mode, op_class, channel, BW160);
+	if (!(ret == ALLOWED || (ret == RADAR && wpa_s->p2p_go_allow_dfs)))
 		return 0;
-	return wpas_p2p_get_center_160mhz(wpa_s, mode, channel);
+	if (is_6ghz_op_class(op_class)) {
+		chans = center_channels_6ghz_160mhz;
+		num_chans = ARRAY_SIZE(center_channels_6ghz_160mhz);
+	} else {
+		chans = center_channels_5ghz_160mhz;
+		num_chans = ARRAY_SIZE(center_channels_5ghz_160mhz);
+	}
+	return wpas_p2p_get_center_160mhz(wpa_s, mode, channel,
+					  chans, num_chans);
 }
 
 
@@ -4243,6 +4385,7 @@
 	char ifname[100];
 	char force_name[100];
 	int ret;
+	const u8 *if_addr = NULL;
 
 	ret = os_snprintf(ifname, sizeof(ifname), P2P_MGMT_DEVICE_PREFIX "%s",
 			  wpa_s->ifname);
@@ -4254,7 +4397,12 @@
 	ifname[IFNAMSIZ - 1] = '\0';
 	force_name[0] = '\0';
 	wpa_s->pending_interface_type = WPA_IF_P2P_DEVICE;
-	ret = wpa_drv_if_add(wpa_s, WPA_IF_P2P_DEVICE, ifname, NULL, NULL,
+
+	if (wpa_s->conf->p2p_device_random_mac_addr == 2 &&
+	    !is_zero_ether_addr(wpa_s->conf->p2p_device_persistent_mac_addr))
+		if_addr = wpa_s->conf->p2p_device_persistent_mac_addr;
+
+	ret = wpa_drv_if_add(wpa_s, WPA_IF_P2P_DEVICE, ifname, if_addr, NULL,
 			     force_name, wpa_s->pending_interface_addr, NULL);
 	if (ret < 0) {
 		wpa_printf(MSG_DEBUG, "P2P: Failed to create P2P Device interface");
@@ -4682,10 +4830,10 @@
 					persistent_go->mode ==
 					WPAS_MODE_P2P_GO ?
 					P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE :
-					0, 0);
+					0, 0, false);
 			} else if (response_done) {
 				wpas_p2p_group_add(wpa_s, 1, freq,
-						   0, 0, 0, 0, 0, 0);
+						   0, 0, 0, 0, 0, 0, false);
 			}
 
 			if (passwd_id == DEV_PW_P2PS_DEFAULT) {
@@ -4804,9 +4952,11 @@
 			wpa_s, persistent_go, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 			NULL,
 			persistent_go->mode == WPAS_MODE_P2P_GO ?
-			P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0, 0);
+			P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0, 0,
+			is_p2p_allow_6ghz(wpa_s->global->p2p));
 	} else {
-		wpas_p2p_group_add(wpa_s, 1, freq, 0, 0, 0, 0, 0, 0);
+		wpas_p2p_group_add(wpa_s, 1, freq, 0, 0, 0, 0, 0, 0,
+				   is_p2p_allow_6ghz(wpa_s->global->p2p));
 	}
 
 	return 1;
@@ -4831,6 +4981,16 @@
 	if (wpa_s->conf->p2p_device_random_mac_addr == 0)
 		return 0;
 
+	if (wpa_s->conf->p2p_device_random_mac_addr == 2) {
+		if (is_zero_ether_addr(
+			    wpa_s->conf->p2p_device_persistent_mac_addr) &&
+		    !is_zero_ether_addr(wpa_s->own_addr)) {
+			os_memcpy(wpa_s->conf->p2p_device_persistent_mac_addr,
+				  wpa_s->own_addr, ETH_ALEN);
+		}
+		return 0;
+	}
+
 #ifdef ABOVE_10
 	if (wpa_s->conf->ssid == NULL) {
 #else /* ABOVE_10 */
@@ -5408,7 +5568,8 @@
 					 wpa_s->p2p_go_max_oper_chwidth,
 					 wpa_s->p2p_go_he,
 					 wpa_s->p2p_go_edmg,
-					 NULL, 0);
+					 NULL, 0,
+					 is_p2p_allow_6ghz(wpa_s->global->p2p));
 			return;
 		}
 
@@ -5606,13 +5767,14 @@
 	if (freq > 0) {
 		freqs[0] = freq;
 		params.freqs = freqs;
-	} else if (wpa_s->conf->p2p_6ghz_disable) {
+	} else if (wpa_s->conf->p2p_6ghz_disable ||
+		   !is_p2p_allow_6ghz(wpa_s->global->p2p)) {
 		wpa_printf(MSG_DEBUG,
 			   "P2P: 6 GHz disabled - update the scan frequency list");
-		wpas_p2p_add_scan_freq_list(wpa_s, HOSTAPD_MODE_IEEE80211G,
-					    &params);
-		wpas_p2p_add_scan_freq_list(wpa_s, HOSTAPD_MODE_IEEE80211A,
-					    &params);
+		wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211G, &params,
+					0);
+		wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211A, &params,
+					0);
 	}
 
 	ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
@@ -5643,7 +5805,7 @@
 	 * the new scan results become available.
 	 */
 	ret = wpa_drv_scan(wpa_s, &params);
-	if (wpa_s->conf->p2p_6ghz_disable && params.freqs != freqs)
+	if (params.freqs != freqs)
 		os_free(params.freqs);
 	if (!ret) {
 		os_get_reltime(&wpa_s->scan_trigger_time);
@@ -5873,6 +6035,10 @@
 		res = wpa_drv_get_pref_freq_list(wpa_s, iface_type,
 						 &max_pref_freq,
 						 pref_freq_list);
+		if (!is_p2p_allow_6ghz(wpa_s->global->p2p))
+			max_pref_freq = p2p_remove_6ghz_channels(pref_freq_list,
+								 max_pref_freq);
+
 		if (!res && max_pref_freq > 0) {
 			*num_pref_freq = max_pref_freq;
 			i = 0;
@@ -5932,13 +6098,48 @@
 }
 
 
+static bool is_p2p_6ghz_supported(struct wpa_supplicant *wpa_s,
+				  const u8 *peer_addr)
+{
+	if (wpa_s->conf->p2p_6ghz_disable ||
+	    !get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
+		      HOSTAPD_MODE_IEEE80211A, true))
+		return false;
+
+	if (!p2p_wfd_enabled(wpa_s->global->p2p))
+		return false;
+	if (peer_addr && !p2p_peer_wfd_enabled(wpa_s->global->p2p, peer_addr))
+		return false;
+
+	return true;
+}
+
+
+static int wpas_p2p_check_6ghz(struct wpa_supplicant *wpa_s,
+			       const u8 *peer_addr, bool allow_6ghz, int freq)
+{
+	if (allow_6ghz && is_p2p_6ghz_supported(wpa_s, peer_addr)) {
+		wpa_printf(MSG_DEBUG,
+			   "P2P: Allow connection on 6 GHz channels");
+		p2p_set_6ghz_dev_capab(wpa_s->global->p2p, true);
+	} else {
+		if (is_6ghz_freq(freq))
+			return -2;
+		p2p_set_6ghz_dev_capab(wpa_s->global->p2p, false);
+	}
+
+	return 0;
+}
+
+
 int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
 		     const char *pin, enum p2p_wps_method wps_method,
 		     int persistent_group, int auto_join, int join, int auth,
 		     int go_intent, int freq, unsigned int vht_center_freq2,
 		     int persistent_id, int pd, int ht40, int vht,
 		     unsigned int vht_chwidth, int he, int edmg,
-		     const u8 *group_ssid, size_t group_ssid_len)
+		     const u8 *group_ssid, size_t group_ssid_len,
+		     bool allow_6ghz)
 {
 	int force_freq = 0, pref_freq = 0;
 	int ret = 0, res;
@@ -5957,7 +6158,7 @@
 			return -1;
 	}
 
-	if (is_6ghz_freq(freq) && wpa_s->conf->p2p_6ghz_disable)
+	if (wpas_p2p_check_6ghz(wpa_s, peer_addr, allow_6ghz, freq))
 		return -2;
 
 	os_free(wpa_s->global->add_psk);
@@ -6235,6 +6436,9 @@
 
 		res = wpa_drv_get_pref_freq_list(wpa_s, WPA_IF_P2P_GO,
 						 &size, pref_freq_list);
+		if (!is_p2p_allow_6ghz(wpa_s->global->p2p))
+			size = p2p_remove_6ghz_channels(pref_freq_list, size);
+
 		if (!res && size > 0) {
 			i = 0;
 			while (i < size &&
@@ -6290,10 +6494,32 @@
 			wpa_printf(MSG_DEBUG, "P2P: Use best 5 GHz band "
 				   "channel: %d MHz", freq);
 		} else {
+			const int freqs[] = {
+				/* operating class 115 */
+				5180, 5200, 5220, 5240,
+				/* operating class 124 */
+				5745, 5765, 5785, 5805,
+			};
+			unsigned int i, num_freqs = ARRAY_SIZE(freqs);
+
 			if (os_get_random((u8 *) &r, sizeof(r)) < 0)
 				return -1;
-			freq = 5180 + (r % 4) * 20;
-			if (!p2p_supported_freq_go(wpa_s->global->p2p, freq)) {
+
+			/*
+			 * Most of the 5 GHz channels require DFS. Only
+			 * operating classes 115 and 124 are available possibly
+			 * without that requirement. Check these for
+			 * availability starting from a randomly picked
+			 * position.
+			 */
+			for (i = 0; i < num_freqs; i++, r++) {
+				freq = freqs[r % num_freqs];
+				if (p2p_supported_freq_go(wpa_s->global->p2p,
+							  freq))
+					break;
+			}
+
+			if (i >= num_freqs) {
 				wpa_printf(MSG_DEBUG, "P2P: Could not select "
 					   "5 GHz channel for P2P group");
 				return -1;
@@ -6347,34 +6573,26 @@
 	/* try all channels in operating class 115 */
 	for (i = 0; i < 4; i++) {
 		params->freq = 5180 + i * 20;
-		if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
-		    freq_included(wpa_s, channels, params->freq) &&
-		    p2p_supported_freq(wpa_s->global->p2p, params->freq))
+		if (wpas_p2p_supported_freq_go(wpa_s, channels, params->freq))
 			goto out;
 	}
 
 	/* try all channels in operating class 124 */
 	for (i = 0; i < 4; i++) {
 		params->freq = 5745 + i * 20;
-		if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
-		    freq_included(wpa_s, channels, params->freq) &&
-		    p2p_supported_freq(wpa_s->global->p2p, params->freq))
+		if (wpas_p2p_supported_freq_go(wpa_s, channels, params->freq))
 			goto out;
 	}
 
 	/* try social channel class 180 channel 2 */
 	params->freq = 58320 + 1 * 2160;
-	if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
-	    freq_included(wpa_s, channels, params->freq) &&
-	    p2p_supported_freq(wpa_s->global->p2p, params->freq))
+	if (wpas_p2p_supported_freq_go(wpa_s, channels, params->freq))
 		goto out;
 
 	/* try all channels in reg. class 180 */
 	for (i = 0; i < 4; i++) {
 		params->freq = 58320 + i * 2160;
-		if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
-		    freq_included(wpa_s, channels, params->freq) &&
-		    p2p_supported_freq(wpa_s->global->p2p, params->freq))
+		if (wpas_p2p_supported_freq_go(wpa_s, channels, params->freq))
 			goto out;
 	}
 
@@ -6640,14 +6858,16 @@
 			enum hostapd_hw_mode mode;
 			struct hostapd_hw_modes *hwmode;
 			u8 chan;
+			u8 op_class;
 
 			cand = wpa_s->p2p_group_common_freqs[i];
+			op_class = is_6ghz_freq(cand) ? 133 : 128;
 			mode = ieee80211_freq_to_chan(cand, &chan);
 			hwmode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
 					  mode, is_6ghz_freq(cand));
 			if (!hwmode ||
-			    wpas_p2p_verify_channel(wpa_s, hwmode, chan,
-						    BW80) != ALLOWED)
+			    wpas_p2p_verify_channel(wpa_s, hwmode, op_class,
+						    chan, BW80) != ALLOWED)
 				continue;
 			if (wpas_p2p_supported_freq_go(wpa_s, channels, cand)) {
 				params->freq = cand;
@@ -6666,20 +6886,44 @@
 		for (i = 0; i < wpa_s->p2p_group_common_freqs_num; i++) {
 			enum hostapd_hw_mode mode;
 			struct hostapd_hw_modes *hwmode;
-			u8 chan;
+			u8 chan, op_class;
+			bool is_6ghz, supported = false;
 
+			is_6ghz = is_6ghz_freq(cand);
 			cand = wpa_s->p2p_group_common_freqs[i];
 			mode = ieee80211_freq_to_chan(cand, &chan);
 			hwmode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
-					  mode, is_6ghz_freq(cand));
+					  mode, is_6ghz);
 			if (!wpas_same_band(wpa_s->current_ssid->frequency,
 					    cand) ||
-			    !hwmode ||
-			    (wpas_p2p_verify_channel(wpa_s, hwmode, chan,
-						     BW40MINUS) != ALLOWED &&
-			     wpas_p2p_verify_channel(wpa_s, hwmode, chan,
-						     BW40PLUS) != ALLOWED))
+			    !hwmode)
 				continue;
+			if (is_6ghz &&
+			    wpas_p2p_verify_channel(wpa_s, hwmode, 132, chan,
+						    BW40) == ALLOWED)
+				supported = true;
+
+			if (!is_6ghz &&
+			    ieee80211_freq_to_channel_ext(
+				    cand, -1, CHANWIDTH_USE_HT, &op_class,
+				    &chan) != NUM_HOSTAPD_MODES &&
+			    wpas_p2p_verify_channel(
+				    wpa_s, hwmode, op_class, chan,
+				    BW40MINUS) == ALLOWED)
+				supported = true;
+
+			if (!supported && !is_6ghz &&
+			    ieee80211_freq_to_channel_ext(
+				    cand, 1, CHANWIDTH_USE_HT, &op_class,
+				    &chan) != NUM_HOSTAPD_MODES &&
+			    wpas_p2p_verify_channel(
+				    wpa_s, hwmode, op_class, chan,
+				    BW40PLUS) == ALLOWED)
+				supported = true;
+
+			if (!supported)
+				continue;
+
 			if (wpas_p2p_supported_freq_go(wpa_s, channels, cand)) {
 				params->freq = cand;
 				wpa_printf(MSG_DEBUG,
@@ -6783,6 +7027,11 @@
 		wpa_s->p2p_go_do_acs = 0;
 	}
 
+	if (go && wpa_s->p2p_go_allow_dfs) {
+		group_wpa_s->p2p_go_allow_dfs = wpa_s->p2p_go_allow_dfs;
+		wpa_s->p2p_go_allow_dfs = 0;
+	}
+
 	wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use separate group interface %s",
 		group_wpa_s->ifname);
 	group_wpa_s->p2p_first_connection_timeout = 0;
@@ -6800,6 +7049,7 @@
  * @vht:  Start GO with VHT support
  * @vht_chwidth: channel bandwidth for GO operating with VHT support
  * @edmg: Start GO with EDMG support
+ * @allow_6ghz: Allow P2P group creation on a 6 GHz channel
  * Returns: 0 on success, -1 on failure
  *
  * This function creates a new P2P group with the local end as the Group Owner,
@@ -6807,12 +7057,15 @@
  */
 int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
 		       int freq, int vht_center_freq2, int ht40, int vht,
-		       int max_oper_chwidth, int he, int edmg)
+		       int max_oper_chwidth, int he, int edmg,
+		       bool allow_6ghz)
 {
 	struct p2p_go_neg_results params;
 
 	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
 		return -1;
+	if (wpas_p2p_check_6ghz(wpa_s, NULL, allow_6ghz, freq))
+		return -1;
 
 	os_free(wpa_s->global->add_psk);
 	wpa_s->global->add_psk = NULL;
@@ -6916,7 +7169,8 @@
 				  int vht, int max_oper_chwidth, int he,
 				  int edmg,
 				  const struct p2p_channels *channels,
-				  int connection_timeout, int force_scan)
+				  int connection_timeout, int force_scan,
+				  bool allow_6ghz)
 {
 	struct p2p_go_neg_results params;
 	int go = 0, freq;
@@ -7308,7 +7562,8 @@
 		  enum p2p_discovery_type type,
 		  unsigned int num_req_dev_types, const u8 *req_dev_types,
 		  const u8 *dev_id, unsigned int search_delay,
-		  u8 seek_cnt, const char **seek_string, int freq)
+		  u8 seek_cnt, const char **seek_string, int freq,
+		  bool include_6ghz)
 {
 	wpas_p2p_clear_pending_action_tx(wpa_s);
 	wpa_s->global->p2p_long_listen = 0;
@@ -7327,7 +7582,8 @@
 
 	return p2p_find(wpa_s->global->p2p, timeout, type,
 			num_req_dev_types, req_dev_types, dev_id,
-			search_delay, seek_cnt, seek_string, freq);
+			search_delay, seek_cnt, seek_string, freq,
+			include_6ghz);
 }
 
 
@@ -7349,7 +7605,7 @@
 	 * Indicate that results have been processed so that the P2P module can
 	 * continue pending tasks.
 	 */
-	p2p_scan_res_handled(wpa_s->global->p2p);
+	wpas_p2p_scan_res_handled(wpa_s);
 }
 
 
@@ -7543,7 +7799,7 @@
 int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
 		    struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq,
 		    int vht_center_freq2, int ht40, int vht, int max_chwidth,
-		    int pref_freq, int he, int edmg)
+		    int pref_freq, int he, int edmg, bool allow_6ghz)
 {
 	enum p2p_invite_role role;
 	u8 *bssid = NULL;
@@ -7552,6 +7808,9 @@
 	int no_pref_freq_given = pref_freq == 0;
 	unsigned int pref_freq_list[P2P_MAX_PREF_CHANNELS], size;
 
+	if (wpas_p2p_check_6ghz(wpa_s, NULL, allow_6ghz, freq))
+		return -1;
+
 	wpa_s->global->p2p_invite_group = NULL;
 	if (peer_addr)
 		os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN);
@@ -7626,7 +7885,8 @@
 
 /* Invite to join an active group */
 int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname,
-			  const u8 *peer_addr, const u8 *go_dev_addr)
+			  const u8 *peer_addr, const u8 *go_dev_addr,
+			  bool allow_6ghz)
 {
 	struct wpa_global *global = wpa_s->global;
 	enum p2p_invite_role role;
@@ -7689,6 +7949,8 @@
 
 	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
 		return -1;
+	if (wpas_p2p_check_6ghz(wpa_s, peer_addr, allow_6ghz, freq))
+		return -1;
 
 	size = P2P_MAX_PREF_CHANNELS;
 	res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,
@@ -8607,7 +8869,7 @@
 			 wpa_s->p2p_go_max_oper_chwidth,
 			 wpa_s->p2p_go_he,
 			 wpa_s->p2p_go_edmg,
-			 NULL, 0);
+			 NULL, 0, is_p2p_allow_6ghz(wpa_s->global->p2p));
 	return ret;
 }
 
@@ -9145,7 +9407,7 @@
 				-1, 0, 1, 1, wpa_s->p2p_go_max_oper_chwidth,
 				wpa_s->p2p_go_he, wpa_s->p2p_go_edmg,
 				params->go_ssid_len ? params->go_ssid : NULL,
-				params->go_ssid_len);
+				params->go_ssid_len, false);
 }
 
 
@@ -9224,7 +9486,7 @@
 				forced_freq, wpa_s->p2p_go_vht_center_freq2,
 				-1, 0, 1, 1, wpa_s->p2p_go_max_oper_chwidth,
 				wpa_s->p2p_go_he, wpa_s->p2p_go_edmg,
-				NULL, 0);
+				NULL, 0, false);
 }
 
 
@@ -9241,7 +9503,7 @@
 			       forced_freq, wpa_s->p2p_go_vht_center_freq2,
 			       -1, 0, 1, 1, wpa_s->p2p_go_max_oper_chwidth,
 			       wpa_s->p2p_go_he, wpa_s->p2p_go_edmg,
-			       NULL, 0);
+			       NULL, 0, false);
 	if (res)
 		return res;
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/p2p_supplicant.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/p2p_supplicant.h
index be878ef..43fd316 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/p2p_supplicant.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/p2p_supplicant.h
@@ -38,7 +38,8 @@
 		     int go_intent, int freq, unsigned int vht_center_freq2,
 		     int persistent_id, int pd, int ht40, int vht,
 		     unsigned int vht_chwidth, int he, int edmg,
-		     const u8 *group_ssid, size_t group_ssid_len);
+		     const u8 *group_ssid, size_t group_ssid_len,
+		     bool allow_6ghz);
 int wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s,
                                           int freq, struct wpa_ssid *ssid);
 #ifdef CONFIG_BRCM_BT_WIFI_HO
@@ -69,14 +70,15 @@
 #endif /* CONFIG_BRCM_BT_WIFI_HO */
 int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
 		       int freq, int vht_center_freq2, int ht40, int vht,
-		       int max_oper_chwidth, int he, int edmg);
+		       int max_oper_chwidth, int he, int edmg, bool allow_6ghz);
 int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
 				  struct wpa_ssid *ssid, int addr_allocated,
 				  int force_freq, int neg_freq,
 				  int vht_center_freq2, int ht40, int vht,
 				  int max_oper_chwidth, int he, int edmg,
 				  const struct p2p_channels *channels,
-				  int connection_timeout, int force_scan);
+				  int connection_timeout, int force_scan,
+				  bool allow_6ghz);
 struct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s,
 				       struct wpa_ssid *ssid);
 enum wpas_p2p_prov_disc_use {
@@ -99,7 +101,8 @@
 		  enum p2p_discovery_type type,
 		  unsigned int num_req_dev_types, const u8 *req_dev_types,
 		  const u8 *dev_id, unsigned int search_delay,
-		  u8 seek_cnt, const char **seek_string, int freq);
+		  u8 seek_cnt, const char **seek_string, int freq,
+		  bool include_6ghz);
 void wpas_p2p_stop_find(struct wpa_supplicant *wpa_s);
 int wpas_p2p_listen(struct wpa_supplicant *wpa_s, unsigned int timeout);
 int wpas_p2p_listen_start(struct wpa_supplicant *wpa_s, unsigned int timeout);
@@ -143,9 +146,10 @@
 int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
 		    struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq,
 		    int vht_center_freq2, int ht40, int vht, int max_chwidth,
-		    int pref_freq, int he, int edmg);
+		    int pref_freq, int he, int edmg, bool allow_6ghz);
 int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname,
-			  const u8 *peer_addr, const u8 *go_dev_addr);
+			  const u8 *peer_addr, const u8 *go_dev_addr,
+			  bool allow_6ghz);
 int wpas_p2p_presence_req(struct wpa_supplicant *wpa_s, u32 duration1,
 			  u32 interval1, u32 duration2, u32 interval2);
 int wpas_p2p_ext_listen(struct wpa_supplicant *wpa_s, unsigned int period,
@@ -168,12 +172,15 @@
 void wpas_p2p_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
 				       const u8 *addr);
 int wpas_p2p_scan_no_go_seen(struct wpa_supplicant *wpa_s);
-int wpas_p2p_get_ht40_mode(struct wpa_supplicant *wpa_s,
-			   struct hostapd_hw_modes *mode, u8 channel);
+int wpas_p2p_get_sec_channel_offset_40mhz(struct wpa_supplicant *wpa_s,
+					  struct hostapd_hw_modes *mode,
+					  u8 channel);
 int wpas_p2p_get_vht80_center(struct wpa_supplicant *wpa_s,
-			      struct hostapd_hw_modes *mode, u8 channel);
+			      struct hostapd_hw_modes *mode, u8 channel,
+			      u8 op_class);
 int wpas_p2p_get_vht160_center(struct wpa_supplicant *wpa_s,
-			       struct hostapd_hw_modes *mode, u8 channel);
+			       struct hostapd_hw_modes *mode, u8 channel,
+			       u8 op_class);
 unsigned int wpas_p2p_search_delay(struct wpa_supplicant *wpa_s);
 void wpas_p2p_new_psk_cb(struct wpa_supplicant *wpa_s, const u8 *mac_addr,
 			 const u8 *p2p_dev_addr,
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/p2p_supplicant_sd.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/p2p_supplicant_sd.c
index f8675e6..b400cba 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/p2p_supplicant_sd.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/p2p_supplicant_sd.c
@@ -826,7 +826,7 @@
 		size_t buf_len;
 		u8 svc_len;
 
-		/* Sanity check fixed length+svc_str */
+		/* Validity check fixed length+svc_str */
 		if (6 >= tlv_end - pos)
 			break;
 		svc_len = pos[6];
@@ -854,7 +854,7 @@
 		buf_len = WPA_GET_LE16(pos);
 		pos += sizeof(u16);
 
-		/* Sanity check buffer length */
+		/* Validity check buffer length */
 		if (buf_len > (unsigned int) (tlv_end - pos))
 			break;
 
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/pasn_supplicant.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/pasn_supplicant.c
new file mode 100755
index 0000000..baf4c26
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/pasn_supplicant.c
@@ -0,0 +1,1710 @@
+/*
+ * wpa_supplicant - PASN processing
+ *
+ * Copyright (C) 2019 Intel Corporation
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "includes.h"
+
+#include "common/ieee802_11_defs.h"
+#include "common/ieee802_11_common.h"
+#include "common/dragonfly.h"
+#include "common/ptksa_cache.h"
+#include "utils/eloop.h"
+#include "drivers/driver.h"
+#include "crypto/crypto.h"
+#include "crypto/random.h"
+#include "eap_common/eap_defs.h"
+#include "rsn_supp/wpa.h"
+#include "rsn_supp/pmksa_cache.h"
+#include "wpa_supplicant_i.h"
+#include "driver_i.h"
+#include "bss.h"
+#include "config.h"
+
+static const int dot11RSNAConfigPMKLifetime = 43200;
+
+struct wpa_pasn_auth_work {
+	u8 bssid[ETH_ALEN];
+	int akmp;
+	int cipher;
+	u16 group;
+	int network_id;
+	struct wpabuf *comeback;
+};
+
+
+static void wpas_pasn_free_auth_work(struct wpa_pasn_auth_work *awork)
+{
+	wpabuf_free(awork->comeback);
+	awork->comeback = NULL;
+	os_free(awork);
+}
+
+
+static void wpas_pasn_auth_work_timeout(void *eloop_ctx, void *timeout_ctx)
+{
+	struct wpa_supplicant *wpa_s = eloop_ctx;
+
+	wpa_printf(MSG_DEBUG, "PASN: Auth work timeout - stopping auth");
+
+	wpas_pasn_auth_stop(wpa_s);
+}
+
+
+static void wpas_pasn_cancel_auth_work(struct wpa_supplicant *wpa_s)
+{
+	wpa_printf(MSG_DEBUG, "PASN: Cancel pasn-start-auth work");
+
+	/* Remove pending/started work */
+	radio_remove_works(wpa_s, "pasn-start-auth", 0);
+}
+
+
+static void wpas_pasn_auth_status(struct wpa_supplicant *wpa_s, const u8 *bssid,
+				  int akmp, int cipher, u8 status,
+				  struct wpabuf *comeback,
+				  u16 comeback_after)
+{
+	if (comeback) {
+		size_t comeback_len = wpabuf_len(comeback);
+		size_t buflen = comeback_len * 2 + 1;
+		char *comeback_txt = os_malloc(buflen);
+
+		if (comeback_txt) {
+			wpa_snprintf_hex(comeback_txt, buflen,
+					 wpabuf_head(comeback), comeback_len);
+
+			wpa_msg(wpa_s, MSG_INFO, PASN_AUTH_STATUS MACSTR
+				" akmp=%s, status=%u comeback_after=%u comeback=%s",
+				MAC2STR(bssid),
+				wpa_key_mgmt_txt(akmp, WPA_PROTO_RSN),
+				status, comeback_after, comeback_txt);
+
+			os_free(comeback_txt);
+			return;
+		}
+	}
+
+	wpa_msg(wpa_s, MSG_INFO,
+		PASN_AUTH_STATUS MACSTR " akmp=%s, status=%u",
+		MAC2STR(bssid), wpa_key_mgmt_txt(akmp, WPA_PROTO_RSN),
+		status);
+}
+
+
+#ifdef CONFIG_SAE
+
+static struct wpabuf * wpas_pasn_wd_sae_commit(struct wpa_supplicant *wpa_s)
+{
+	struct wpas_pasn *pasn = &wpa_s->pasn;
+	struct wpabuf *buf = NULL;
+	int ret;
+
+	ret = sae_set_group(&pasn->sae, pasn->group);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed to set SAE group");
+		return NULL;
+	}
+
+	ret = sae_prepare_commit_pt(&pasn->sae, pasn->ssid->pt,
+				    wpa_s->own_addr, pasn->bssid,
+				    NULL, NULL);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed to prepare SAE commit");
+		return NULL;
+	}
+
+	/* Need to add the entire Authentication frame body */
+	buf = wpabuf_alloc(6 + SAE_COMMIT_MAX_LEN);
+	if (!buf) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed to allocate SAE buffer");
+		return NULL;
+	}
+
+	wpabuf_put_le16(buf, WLAN_AUTH_SAE);
+	wpabuf_put_le16(buf, 1);
+	wpabuf_put_le16(buf, WLAN_STATUS_SAE_HASH_TO_ELEMENT);
+
+	sae_write_commit(&pasn->sae, buf, NULL, 0);
+	pasn->sae.state = SAE_COMMITTED;
+
+	return buf;
+}
+
+
+static int wpas_pasn_wd_sae_rx(struct wpa_supplicant *wpa_s, struct wpabuf *wd)
+{
+	struct wpas_pasn *pasn = &wpa_s->pasn;
+	const u8 *data;
+	size_t buf_len;
+	u16 len, res, alg, seq, status;
+	int groups[] = { pasn->group, 0 };
+	int ret;
+
+	if (!wd)
+		return -1;
+
+	data = wpabuf_head_u8(wd);
+	buf_len = wpabuf_len(wd);
+
+	/* first handle the commit message */
+	if (buf_len < 2) {
+		wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short (commit)");
+		return -1;
+	}
+
+	len = WPA_GET_LE16(data);
+	if (len < 6 || buf_len - 2 < len) {
+		wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short for commit");
+		return -1;
+	}
+
+	buf_len -= 2;
+	data += 2;
+
+	alg = WPA_GET_LE16(data);
+	seq = WPA_GET_LE16(data + 2);
+	status = WPA_GET_LE16(data + 4);
+
+	wpa_printf(MSG_DEBUG, "PASN: SAE: commit: alg=%u, seq=%u, status=%u",
+		   alg, seq, status);
+
+	if (alg != WLAN_AUTH_SAE || seq != 1 ||
+	    status != WLAN_STATUS_SAE_HASH_TO_ELEMENT) {
+		wpa_printf(MSG_DEBUG, "PASN: SAE: dropping peer commit");
+		return -1;
+	}
+
+	res = sae_parse_commit(&pasn->sae, data + 6, len - 6, NULL, 0, groups,
+			       1);
+	if (res != WLAN_STATUS_SUCCESS) {
+		wpa_printf(MSG_DEBUG, "PASN: SAE failed parsing commit");
+		return -1;
+	}
+
+	/* Process the commit message and derive the PMK */
+	ret = sae_process_commit(&pasn->sae);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "SAE: Failed to process peer commit");
+		return -1;
+	}
+
+	buf_len -= len;
+	data += len;
+
+	/* Handle the confirm message */
+	if (buf_len < 2) {
+		wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short (confirm)");
+		return -1;
+	}
+
+	len = WPA_GET_LE16(data);
+	if (len < 6 || buf_len - 2 < len) {
+		wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short for confirm");
+		return -1;
+	}
+
+	buf_len -= 2;
+	data += 2;
+
+	alg = WPA_GET_LE16(data);
+	seq = WPA_GET_LE16(data + 2);
+	status = WPA_GET_LE16(data + 4);
+
+	wpa_printf(MSG_DEBUG, "PASN: SAE confirm: alg=%u, seq=%u, status=%u",
+		   alg, seq, status);
+
+	if (alg != WLAN_AUTH_SAE || seq != 2 || status != WLAN_STATUS_SUCCESS) {
+		wpa_printf(MSG_DEBUG, "PASN: Dropping peer SAE confirm");
+		return -1;
+	}
+
+	res = sae_check_confirm(&pasn->sae, data + 6, len - 6);
+	if (res != WLAN_STATUS_SUCCESS) {
+		wpa_printf(MSG_DEBUG, "PASN: SAE failed checking confirm");
+		return -1;
+	}
+
+	wpa_printf(MSG_DEBUG, "PASN: SAE completed successfully");
+	pasn->sae.state = SAE_ACCEPTED;
+
+	return 0;
+}
+
+
+static struct wpabuf * wpas_pasn_wd_sae_confirm(struct wpa_supplicant *wpa_s)
+{
+	struct wpas_pasn *pasn = &wpa_s->pasn;
+	struct wpabuf *buf = NULL;
+
+	/* Need to add the entire authentication frame body */
+	buf = wpabuf_alloc(6 + SAE_CONFIRM_MAX_LEN);
+	if (!buf) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed to allocate SAE buffer");
+		return NULL;
+	}
+
+	wpabuf_put_le16(buf, WLAN_AUTH_SAE);
+	wpabuf_put_le16(buf, 2);
+	wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
+
+	sae_write_confirm(&pasn->sae, buf);
+	pasn->sae.state = SAE_CONFIRMED;
+
+	return buf;
+}
+
+
+static int wpas_pasn_sae_setup_pt(struct wpa_supplicant *wpa_s,
+				  struct wpa_ssid *ssid, int group)
+{
+	const char *password = ssid->sae_password;
+	int groups[2] = { group, 0 };
+
+	if (!password)
+		password = ssid->passphrase;
+
+	if (!password) {
+		wpa_printf(MSG_DEBUG, "PASN: SAE without a password");
+		return -1;
+	}
+
+	if (ssid->pt)
+		return 0; /* PT already derived */
+
+	ssid->pt = sae_derive_pt(groups, ssid->ssid, ssid->ssid_len,
+				 (const u8 *) password, os_strlen(password),
+				 ssid->sae_password_id);
+
+	return ssid->pt ? 0 : -1;
+}
+
+#endif /* CONFIG_SAE */
+
+
+#ifdef CONFIG_FILS
+
+static struct wpabuf * wpas_pasn_fils_build_auth(struct wpa_supplicant *wpa_s)
+{
+	struct wpas_pasn *pasn = &wpa_s->pasn;
+	struct wpabuf *buf = NULL;
+	struct wpabuf *erp_msg;
+	int ret;
+
+	erp_msg = eapol_sm_build_erp_reauth_start(wpa_s->eapol);
+	if (!erp_msg) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: FILS: ERP EAP-Initiate/Re-auth unavailable");
+		return NULL;
+	}
+
+	if (random_get_bytes(pasn->fils.nonce, FILS_NONCE_LEN) < 0 ||
+	    random_get_bytes(pasn->fils.session, FILS_SESSION_LEN) < 0)
+		goto fail;
+
+	wpa_hexdump(MSG_DEBUG, "PASN: FILS: Nonce", pasn->fils.nonce,
+		    FILS_NONCE_LEN);
+
+	wpa_hexdump(MSG_DEBUG, "PASN: FILS: Session", pasn->fils.session,
+		    FILS_SESSION_LEN);
+
+	buf = wpabuf_alloc(1500);
+	if (!buf)
+		goto fail;
+
+	/* Add the authentication algorithm */
+	wpabuf_put_le16(buf, WLAN_AUTH_FILS_SK);
+
+	/* Authentication Transaction seq# */
+	wpabuf_put_le16(buf, 1);
+
+	/* Status Code */
+	wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
+
+	/* Own RSNE */
+	wpa_pasn_add_rsne(buf, NULL, pasn->akmp, pasn->cipher);
+
+	/* FILS Nonce */
+	wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
+	wpabuf_put_u8(buf, 1 + FILS_NONCE_LEN);
+	wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_NONCE);
+	wpabuf_put_data(buf, pasn->fils.nonce, FILS_NONCE_LEN);
+
+	/* FILS Session */
+	wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
+	wpabuf_put_u8(buf, 1 + FILS_SESSION_LEN);
+	wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_SESSION);
+	wpabuf_put_data(buf, pasn->fils.session, FILS_SESSION_LEN);
+
+	/* Wrapped Data (ERP) */
+	wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
+	wpabuf_put_u8(buf, 1 + wpabuf_len(erp_msg));
+	wpabuf_put_u8(buf, WLAN_EID_EXT_WRAPPED_DATA);
+	wpabuf_put_buf(buf, erp_msg);
+
+	/*
+	 * Calculate pending PMKID here so that we do not need to maintain a
+	 * copy of the EAP-Initiate/Reauth message.
+	 */
+	ret = fils_pmkid_erp(pasn->akmp, wpabuf_head(erp_msg),
+			     wpabuf_len(erp_msg),
+			     pasn->fils.erp_pmkid);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: FILS: Failed to get ERP PMKID");
+		goto fail;
+	}
+
+	wpabuf_free(erp_msg);
+	erp_msg = NULL;
+
+	wpa_hexdump_buf(MSG_DEBUG, "PASN: FILS: Authentication frame", buf);
+	return buf;
+fail:
+	wpabuf_free(erp_msg);
+	wpabuf_free(buf);
+	return NULL;
+}
+
+
+static void wpas_pasn_initiate_eapol(struct wpa_supplicant *wpa_s)
+{
+	struct wpas_pasn *pasn = &wpa_s->pasn;
+	struct eapol_config eapol_conf;
+	struct wpa_ssid *ssid = pasn->ssid;
+
+	wpa_printf(MSG_DEBUG, "PASN: FILS: Initiating EAPOL");
+
+	eapol_sm_notify_eap_success(wpa_s->eapol, false);
+	eapol_sm_notify_eap_fail(wpa_s->eapol, false);
+	eapol_sm_notify_portControl(wpa_s->eapol, Auto);
+
+	os_memset(&eapol_conf, 0, sizeof(eapol_conf));
+	eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
+	eapol_conf.workaround = ssid->eap_workaround;
+
+	eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
+}
+
+
+static struct wpabuf * wpas_pasn_wd_fils_auth(struct wpa_supplicant *wpa_s)
+{
+	struct wpas_pasn *pasn = &wpa_s->pasn;
+	struct wpa_bss *bss;
+	const u8 *indic;
+	u16 fils_info;
+
+	wpa_printf(MSG_DEBUG, "PASN: FILS: wrapped data - completed=%u",
+		   pasn->fils.completed);
+
+	/* Nothing to add as we are done */
+	if (pasn->fils.completed)
+		return NULL;
+
+	if (!pasn->ssid) {
+		wpa_printf(MSG_DEBUG, "PASN: FILS: No network block");
+		return NULL;
+	}
+
+	bss = wpa_bss_get_bssid(wpa_s, pasn->bssid);
+	if (!bss) {
+		wpa_printf(MSG_DEBUG, "PASN: FILS: BSS not found");
+		return NULL;
+	}
+
+	indic = wpa_bss_get_ie(bss, WLAN_EID_FILS_INDICATION);
+	if (!indic || indic[1] < 2) {
+		wpa_printf(MSG_DEBUG, "PASN: Missing FILS Indication IE");
+		return NULL;
+	}
+
+	fils_info = WPA_GET_LE16(indic + 2);
+	if (!(fils_info & BIT(9))) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: FILS auth without PFS not supported");
+		return NULL;
+	}
+
+	wpas_pasn_initiate_eapol(wpa_s);
+
+	return wpas_pasn_fils_build_auth(wpa_s);
+}
+
+
+static int wpas_pasn_wd_fils_rx(struct wpa_supplicant *wpa_s, struct wpabuf *wd)
+{
+	struct wpas_pasn *pasn = &wpa_s->pasn;
+	struct ieee802_11_elems elems;
+	struct wpa_ie_data rsne_data;
+	u8 rmsk[ERP_MAX_KEY_LEN];
+	size_t rmsk_len;
+	u8 anonce[FILS_NONCE_LEN];
+	const u8 *data;
+	size_t buf_len;
+	struct wpabuf *fils_wd = NULL;
+	u16 alg, seq, status;
+	int ret;
+
+	if (!wd)
+		return -1;
+
+	data = wpabuf_head(wd);
+	buf_len = wpabuf_len(wd);
+
+	wpa_hexdump(MSG_DEBUG, "PASN: FILS: Authentication frame len=%zu",
+		    data, buf_len);
+
+	/* first handle the header */
+	if (buf_len < 6) {
+		wpa_printf(MSG_DEBUG, "PASN: FILS: Buffer too short");
+		return -1;
+	}
+
+	alg = WPA_GET_LE16(data);
+	seq = WPA_GET_LE16(data + 2);
+	status = WPA_GET_LE16(data + 4);
+
+	wpa_printf(MSG_DEBUG, "PASN: FILS: commit: alg=%u, seq=%u, status=%u",
+		   alg, seq, status);
+
+	if (alg != WLAN_AUTH_FILS_SK || seq != 2 ||
+	    status != WLAN_STATUS_SUCCESS) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: FILS: Dropping peer authentication");
+		return -1;
+	}
+
+	data += 6;
+	buf_len -= 6;
+
+	if (ieee802_11_parse_elems(data, buf_len, &elems, 1) == ParseFailed) {
+		wpa_printf(MSG_DEBUG, "PASN: FILS: Could not parse elements");
+		return -1;
+	}
+
+	if (!elems.rsn_ie || !elems.fils_nonce || !elems.fils_nonce ||
+	    !elems.wrapped_data) {
+		wpa_printf(MSG_DEBUG, "PASN: FILS: Missing IEs");
+		return -1;
+	}
+
+	ret = wpa_parse_wpa_ie(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
+			       &rsne_data);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: FILS: Failed parsing RNSE");
+		return -1;
+	}
+
+	ret = wpa_pasn_validate_rsne(&rsne_data);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: FILS: Failed validating RSNE");
+		return -1;
+	}
+
+	if (rsne_data.num_pmkid) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: FILS: Not expecting PMKID in RSNE");
+		return -1;
+	}
+
+	wpa_hexdump(MSG_DEBUG, "PASN: FILS: ANonce", elems.fils_nonce,
+		    FILS_NONCE_LEN);
+	os_memcpy(anonce, elems.fils_nonce, FILS_NONCE_LEN);
+
+	wpa_hexdump(MSG_DEBUG, "PASN: FILS: FILS Session", elems.fils_session,
+		    FILS_SESSION_LEN);
+
+	if (os_memcmp(pasn->fils.session, elems.fils_session,
+		      FILS_SESSION_LEN)) {
+		wpa_printf(MSG_DEBUG, "PASN: FILS: Session mismatch");
+		return -1;
+	}
+
+	fils_wd = ieee802_11_defrag(&elems, WLAN_EID_EXTENSION,
+				    WLAN_EID_EXT_WRAPPED_DATA);
+
+	if (!fils_wd) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: FILS: Failed getting wrapped data");
+		return -1;
+	}
+
+	eapol_sm_process_erp_finish(wpa_s->eapol, wpabuf_head(fils_wd),
+				    wpabuf_len(fils_wd));
+
+	wpabuf_free(fils_wd);
+	fils_wd = NULL;
+
+	if (eapol_sm_failed(wpa_s->eapol)) {
+		wpa_printf(MSG_DEBUG, "PASN: FILS: ERP finish failed");
+		return -1;
+	}
+
+	rmsk_len = ERP_MAX_KEY_LEN;
+	ret = eapol_sm_get_key(wpa_s->eapol, rmsk, rmsk_len);
+
+	if (ret == PMK_LEN) {
+		rmsk_len = PMK_LEN;
+		ret = eapol_sm_get_key(wpa_s->eapol, rmsk, rmsk_len);
+	}
+
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: FILS: Failed getting RMSK");
+		return -1;
+	}
+
+	ret = fils_rmsk_to_pmk(pasn->akmp, rmsk, rmsk_len,
+			       pasn->fils.nonce, anonce, NULL, 0,
+			       pasn->pmk, &pasn->pmk_len);
+
+	forced_memzero(rmsk, sizeof(rmsk));
+
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: FILS: Failed to derive PMK");
+		return -1;
+	}
+
+	wpa_hexdump(MSG_DEBUG, "PASN: FILS: PMKID", pasn->fils.erp_pmkid,
+		    PMKID_LEN);
+
+	wpa_printf(MSG_DEBUG, "PASN: FILS: ERP processing succeeded");
+
+	wpa_pasn_pmksa_cache_add(wpa_s->wpa, pasn->pmk,
+				 pasn->pmk_len, pasn->fils.erp_pmkid,
+				 pasn->bssid, pasn->akmp);
+
+	pasn->fils.completed = true;
+	return 0;
+}
+
+#endif /* CONFIG_FILS */
+
+
+static struct wpabuf * wpas_pasn_get_wrapped_data(struct wpa_supplicant *wpa_s)
+{
+	struct wpas_pasn *pasn = &wpa_s->pasn;
+
+	if (pasn->using_pmksa)
+		return NULL;
+
+	switch (pasn->akmp) {
+	case WPA_KEY_MGMT_PASN:
+		/* no wrapped data */
+		return NULL;
+	case WPA_KEY_MGMT_SAE:
+#ifdef CONFIG_SAE
+		if (pasn->trans_seq == 0)
+			return wpas_pasn_wd_sae_commit(wpa_s);
+		if (pasn->trans_seq == 2)
+			return wpas_pasn_wd_sae_confirm(wpa_s);
+#endif /* CONFIG_SAE */
+		wpa_printf(MSG_ERROR,
+			   "PASN: SAE: Cannot derive wrapped data");
+		return NULL;
+	case WPA_KEY_MGMT_FILS_SHA256:
+	case WPA_KEY_MGMT_FILS_SHA384:
+#ifdef CONFIG_FILS
+		return wpas_pasn_wd_fils_auth(wpa_s);
+#endif /* CONFIG_FILS */
+	case WPA_KEY_MGMT_FT_PSK:
+	case WPA_KEY_MGMT_FT_IEEE8021X:
+	case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
+		/*
+		 * Wrapped data with these AKMs is optional and is only needed
+		 * for further validation of FT security parameters. For now do
+		 * not use them.
+		 */
+		return NULL;
+	default:
+		wpa_printf(MSG_ERROR,
+			   "PASN: TODO: Wrapped data for akmp=0x%x",
+			   pasn->akmp);
+		return NULL;
+	}
+}
+
+
+static u8 wpas_pasn_get_wrapped_data_format(struct wpas_pasn *pasn)
+{
+	if (pasn->using_pmksa)
+		return WPA_PASN_WRAPPED_DATA_NO;
+
+	/* Note: Valid AKMP is expected to already be validated */
+	switch (pasn->akmp) {
+	case WPA_KEY_MGMT_SAE:
+		return WPA_PASN_WRAPPED_DATA_SAE;
+	case WPA_KEY_MGMT_FILS_SHA256:
+	case WPA_KEY_MGMT_FILS_SHA384:
+		return WPA_PASN_WRAPPED_DATA_FILS_SK;
+	case WPA_KEY_MGMT_FT_PSK:
+	case WPA_KEY_MGMT_FT_IEEE8021X:
+	case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
+		/*
+		 * Wrapped data with these AKMs is optional and is only needed
+		 * for further validation of FT security parameters. For now do
+		 * not use them.
+		 */
+		return WPA_PASN_WRAPPED_DATA_NO;
+	case WPA_KEY_MGMT_PASN:
+	default:
+		return WPA_PASN_WRAPPED_DATA_NO;
+	}
+}
+
+
+static struct wpabuf * wpas_pasn_build_auth_1(struct wpa_supplicant *wpa_s,
+					      const struct wpabuf *comeback)
+{
+	struct wpas_pasn *pasn = &wpa_s->pasn;
+	struct wpabuf *buf, *pubkey = NULL, *wrapped_data_buf = NULL;
+	const u8 *pmkid;
+	u8 wrapped_data;
+	int ret;
+	u16 capab;
+
+	wpa_printf(MSG_DEBUG, "PASN: Building frame 1");
+
+	if (pasn->trans_seq)
+		return NULL;
+
+	buf = wpabuf_alloc(1500);
+	if (!buf)
+		goto fail;
+
+	/* Get public key */
+	pubkey = crypto_ecdh_get_pubkey(pasn->ecdh, 0);
+	pubkey = wpabuf_zeropad(pubkey, crypto_ecdh_prime_len(pasn->ecdh));
+	if (!pubkey) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed to get pubkey");
+		goto fail;
+	}
+
+	wrapped_data = wpas_pasn_get_wrapped_data_format(pasn);
+
+	wpa_pasn_build_auth_header(buf, pasn->bssid,
+				   wpa_s->own_addr, pasn->bssid,
+				   pasn->trans_seq + 1, WLAN_STATUS_SUCCESS);
+
+	pmkid = NULL;
+	if (wpa_key_mgmt_ft(pasn->akmp)) {
+		ret = wpa_pasn_ft_derive_pmk_r1(wpa_s->wpa, pasn->akmp,
+						pasn->bssid,
+						pasn->pmk_r1,
+						&pasn->pmk_r1_len,
+						pasn->pmk_r1_name);
+		if (ret) {
+			wpa_printf(MSG_DEBUG,
+				   "PASN: FT: Failed to derive keys");
+			goto fail;
+		}
+
+		pmkid = pasn->pmk_r1_name;
+	} else if (wrapped_data != WPA_PASN_WRAPPED_DATA_NO) {
+		struct rsn_pmksa_cache_entry *pmksa;
+
+		pmksa = wpa_sm_pmksa_cache_get(wpa_s->wpa, pasn->bssid,
+					       NULL, NULL, pasn->akmp);
+		if (pmksa)
+			pmkid = pmksa->pmkid;
+
+		/*
+		 * Note: Even when PMKSA is available, also add wrapped data as
+		 * it is possible that the PMKID is no longer valid at the AP.
+		 */
+		wrapped_data_buf = wpas_pasn_get_wrapped_data(wpa_s);
+	}
+
+	if (wpa_pasn_add_rsne(buf, pmkid, pasn->akmp, pasn->cipher) < 0)
+		goto fail;
+
+	if (!wrapped_data_buf)
+		wrapped_data = WPA_PASN_WRAPPED_DATA_NO;
+
+	wpa_pasn_add_parameter_ie(buf, pasn->group, wrapped_data,
+				  pubkey, true, comeback, -1);
+
+	if (wpa_pasn_add_wrapped_data(buf, wrapped_data_buf) < 0)
+		goto fail;
+
+	/* Add own RNSXE */
+	capab = 0;
+	capab |= BIT(WLAN_RSNX_CAPAB_SAE_H2E);
+	if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF)
+		capab |= BIT(WLAN_RSNX_CAPAB_SECURE_LTF);
+	if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_RTT)
+		capab |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT);
+	if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_PROT_RANGE_NEG)
+		capab |= BIT(WLAN_RSNX_CAPAB_PROT_RANGE_NEG);
+	wpa_pasn_add_rsnxe(buf, capab);
+
+	ret = pasn_auth_frame_hash(pasn->akmp, pasn->cipher,
+				   wpabuf_head_u8(buf) + IEEE80211_HDRLEN,
+				   wpabuf_len(buf) - IEEE80211_HDRLEN,
+				   pasn->hash);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed to compute hash");
+		goto fail;
+	}
+
+	pasn->trans_seq++;
+
+	wpabuf_free(wrapped_data_buf);
+	wpabuf_free(pubkey);
+
+	wpa_printf(MSG_DEBUG, "PASN: Frame 1: Success");
+	return buf;
+fail:
+	pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+	wpabuf_free(wrapped_data_buf);
+	wpabuf_free(pubkey);
+	wpabuf_free(buf);
+	return NULL;
+}
+
+
+static struct wpabuf * wpas_pasn_build_auth_3(struct wpa_supplicant *wpa_s)
+{
+	struct wpas_pasn *pasn = &wpa_s->pasn;
+	struct wpabuf *buf, *wrapped_data_buf = NULL;
+	u8 mic[WPA_PASN_MAX_MIC_LEN];
+	u8 mic_len, data_len;
+	const u8 *data;
+	u8 *ptr;
+	u8 wrapped_data;
+	int ret;
+
+	wpa_printf(MSG_DEBUG, "PASN: Building frame 3");
+
+	if (pasn->trans_seq != 2)
+		return NULL;
+
+	buf = wpabuf_alloc(1500);
+	if (!buf)
+		goto fail;
+
+	wrapped_data = wpas_pasn_get_wrapped_data_format(pasn);
+
+	wpa_pasn_build_auth_header(buf, pasn->bssid,
+				   wpa_s->own_addr, pasn->bssid,
+				   pasn->trans_seq + 1, WLAN_STATUS_SUCCESS);
+
+	wrapped_data_buf = wpas_pasn_get_wrapped_data(wpa_s);
+
+	if (!wrapped_data_buf)
+		wrapped_data = WPA_PASN_WRAPPED_DATA_NO;
+
+	wpa_pasn_add_parameter_ie(buf, pasn->group, wrapped_data,
+				  NULL, false, NULL, -1);
+
+	if (wpa_pasn_add_wrapped_data(buf, wrapped_data_buf) < 0)
+		goto fail;
+	wpabuf_free(wrapped_data_buf);
+	wrapped_data_buf = NULL;
+
+	/* Add the MIC */
+	mic_len = pasn_mic_len(pasn->akmp, pasn->cipher);
+	wpabuf_put_u8(buf, WLAN_EID_MIC);
+	wpabuf_put_u8(buf, mic_len);
+	ptr = wpabuf_put(buf, mic_len);
+
+	os_memset(ptr, 0, mic_len);
+
+	data = wpabuf_head_u8(buf) + IEEE80211_HDRLEN;
+	data_len = wpabuf_len(buf) - IEEE80211_HDRLEN;
+
+	ret = pasn_mic(pasn->ptk.kck, pasn->akmp, pasn->cipher,
+		       wpa_s->own_addr, pasn->bssid,
+		       pasn->hash, mic_len * 2, data, data_len, mic);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: frame 3: Failed MIC calculation");
+		goto fail;
+	}
+
+#ifdef CONFIG_TESTING_OPTIONS
+	if (wpa_s->conf->pasn_corrupt_mic) {
+		wpa_printf(MSG_DEBUG, "PASN: frame 3: Corrupt MIC");
+		mic[0] = ~mic[0];
+	}
+#endif /* CONFIG_TESTING_OPTIONS */
+
+	os_memcpy(ptr, mic, mic_len);
+
+	pasn->trans_seq++;
+
+	wpa_printf(MSG_DEBUG, "PASN: frame 3: Success");
+	return buf;
+fail:
+	pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+	wpabuf_free(wrapped_data_buf);
+	wpabuf_free(buf);
+	return NULL;
+}
+
+
+static void wpas_pasn_reset(struct wpa_supplicant *wpa_s)
+{
+	struct wpas_pasn *pasn = &wpa_s->pasn;
+
+	wpa_printf(MSG_DEBUG, "PASN: Reset");
+
+	crypto_ecdh_deinit(pasn->ecdh);
+	pasn->ecdh = NULL;
+
+	wpas_pasn_cancel_auth_work(wpa_s);
+	wpa_s->pasn_auth_work = NULL;
+
+	eloop_cancel_timeout(wpas_pasn_auth_work_timeout, wpa_s, NULL);
+
+	pasn->akmp = 0;
+	pasn->cipher = 0;
+	pasn->group = 0;
+	pasn->trans_seq = 0;
+	pasn->pmk_len = 0;
+	pasn->using_pmksa = false;
+
+	forced_memzero(pasn->pmk, sizeof(pasn->pmk));
+	forced_memzero(&pasn->ptk, sizeof(pasn->ptk));
+	forced_memzero(&pasn->hash, sizeof(pasn->hash));
+
+	wpabuf_free(pasn->beacon_rsne_rsnxe);
+	pasn->beacon_rsne_rsnxe = NULL;
+
+	wpabuf_free(pasn->comeback);
+	pasn->comeback = NULL;
+	pasn->comeback_after = 0;
+
+#ifdef CONFIG_SAE
+	sae_clear_data(&pasn->sae);
+#endif /* CONFIG_SAE */
+
+#ifdef CONFIG_FILS
+	os_memset(&pasn->fils, 0, sizeof(pasn->fils));
+#endif /* CONFIG_FILS*/
+
+#ifdef CONFIG_IEEE80211R
+	forced_memzero(pasn->pmk_r1, sizeof(pasn->pmk_r1));
+	pasn->pmk_r1_len = 0;
+	os_memset(pasn->pmk_r1_name, 0, sizeof(pasn->pmk_r1_name));
+#endif /* CONFIG_IEEE80211R */
+	pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+}
+
+
+static int wpas_pasn_set_pmk(struct wpa_supplicant *wpa_s,
+			     struct wpa_ie_data *rsn_data,
+			     struct wpa_pasn_params_data *pasn_data,
+			     struct wpabuf *wrapped_data)
+{
+	static const u8 pasn_default_pmk[] = {'P', 'M', 'K', 'z'};
+	struct wpas_pasn *pasn = &wpa_s->pasn;
+
+	os_memset(pasn->pmk, 0, sizeof(pasn->pmk));
+	pasn->pmk_len = 0;
+
+	if (pasn->akmp == WPA_KEY_MGMT_PASN) {
+		wpa_printf(MSG_DEBUG, "PASN: Using default PMK");
+
+		pasn->pmk_len = WPA_PASN_PMK_LEN;
+		os_memcpy(pasn->pmk, pasn_default_pmk,
+			  sizeof(pasn_default_pmk));
+		return 0;
+	}
+
+	if (wpa_key_mgmt_ft(pasn->akmp)) {
+#ifdef CONFIG_IEEE80211R
+		wpa_printf(MSG_DEBUG, "PASN: FT: Using PMK-R1");
+		pasn->pmk_len = pasn->pmk_r1_len;
+		os_memcpy(pasn->pmk, pasn->pmk_r1, pasn->pmk_r1_len);
+		pasn->using_pmksa = true;
+		return 0;
+#else /* CONFIG_IEEE80211R */
+		wpa_printf(MSG_DEBUG, "PASN: FT: Not supported");
+		return -1;
+#endif /* CONFIG_IEEE80211R */
+	}
+
+	if (rsn_data->num_pmkid) {
+		struct rsn_pmksa_cache_entry *pmksa;
+
+		pmksa = wpa_sm_pmksa_cache_get(wpa_s->wpa, pasn->bssid,
+					       rsn_data->pmkid, NULL,
+					       pasn->akmp);
+		if (pmksa) {
+			wpa_printf(MSG_DEBUG, "PASN: Using PMKSA");
+
+			pasn->pmk_len = pmksa->pmk_len;
+			os_memcpy(pasn->pmk, pmksa->pmk, pmksa->pmk_len);
+			pasn->using_pmksa = true;
+
+			return 0;
+		}
+	}
+
+#ifdef CONFIG_SAE
+	if (pasn->akmp == WPA_KEY_MGMT_SAE) {
+		int ret;
+
+		ret = wpas_pasn_wd_sae_rx(wpa_s, wrapped_data);
+		if (ret) {
+			wpa_printf(MSG_DEBUG,
+				   "PASN: Failed processing SAE wrapped data");
+			pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+			return -1;
+		}
+
+		wpa_printf(MSG_DEBUG, "PASN: Success deriving PMK with SAE");
+		pasn->pmk_len = PMK_LEN;
+		os_memcpy(pasn->pmk, pasn->sae.pmk, PMK_LEN);
+
+		wpa_pasn_pmksa_cache_add(wpa_s->wpa, pasn->pmk,
+					 pasn->pmk_len, pasn->sae.pmkid,
+					 pasn->bssid, pasn->akmp);
+		return 0;
+	}
+#endif /* CONFIG_SAE */
+
+#ifdef CONFIG_FILS
+	if (pasn->akmp == WPA_KEY_MGMT_FILS_SHA256 ||
+	    pasn->akmp == WPA_KEY_MGMT_FILS_SHA384) {
+		int ret;
+
+		ret = wpas_pasn_wd_fils_rx(wpa_s, wrapped_data);
+		if (ret) {
+			wpa_printf(MSG_DEBUG,
+				   "PASN: Failed processing FILS wrapped data");
+			pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+			return -1;
+		}
+
+		return 0;
+	}
+#endif	/* CONFIG_FILS */
+
+	/* TODO: Derive PMK based on wrapped data */
+	wpa_printf(MSG_DEBUG, "PASN: Missing implementation to derive PMK");
+	pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+	return -1;
+}
+
+
+static int wpas_pasn_start(struct wpa_supplicant *wpa_s, const u8 *bssid,
+			   int akmp, int cipher, u16 group, int freq,
+			   const u8 *beacon_rsne, u8 beacon_rsne_len,
+			   const u8 *beacon_rsnxe, u8 beacon_rsnxe_len,
+			   int network_id, struct wpabuf *comeback)
+{
+	struct wpas_pasn *pasn = &wpa_s->pasn;
+	struct wpa_ssid *ssid = NULL;
+	struct wpabuf *frame;
+	int ret;
+
+	/* TODO: Currently support only ECC groups */
+	if (!dragonfly_suitable_group(group, 1)) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: Reject unsuitable group %u", group);
+		return -1;
+	}
+
+	ssid = wpa_config_get_network(wpa_s->conf, network_id);
+
+	switch (akmp) {
+	case WPA_KEY_MGMT_PASN:
+		break;
+#ifdef CONFIG_SAE
+	case WPA_KEY_MGMT_SAE:
+		if (!ssid) {
+			wpa_printf(MSG_DEBUG,
+				   "PASN: No network profile found for SAE");
+			return -1;
+		}
+
+		if (!ieee802_11_rsnx_capab(beacon_rsnxe,
+					   WLAN_RSNX_CAPAB_SAE_H2E)) {
+			wpa_printf(MSG_DEBUG,
+				   "PASN: AP does not support SAE H2E");
+			return -1;
+		}
+
+		if (wpas_pasn_sae_setup_pt(wpa_s, ssid, group) < 0) {
+			wpa_printf(MSG_DEBUG,
+				   "PASN: Failed to derive PT");
+			return -1;
+		}
+
+		pasn->sae.state = SAE_NOTHING;
+		pasn->sae.send_confirm = 0;
+		pasn->ssid = ssid;
+		break;
+#endif /* CONFIG_SAE */
+#ifdef CONFIG_FILS
+	case WPA_KEY_MGMT_FILS_SHA256:
+	case WPA_KEY_MGMT_FILS_SHA384:
+		pasn->ssid = ssid;
+		break;
+#endif /* CONFIG_FILS */
+#ifdef CONFIG_IEEE80211R
+	case WPA_KEY_MGMT_FT_PSK:
+	case WPA_KEY_MGMT_FT_IEEE8021X:
+	case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
+		break;
+#endif /* CONFIG_IEEE80211R */
+	default:
+		wpa_printf(MSG_ERROR, "PASN: Unsupported AKMP=0x%x", akmp);
+		return -1;
+	}
+
+	pasn->ecdh = crypto_ecdh_init(group);
+	if (!pasn->ecdh) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed to init ECDH");
+		goto fail;
+	}
+
+	pasn->beacon_rsne_rsnxe = wpabuf_alloc(beacon_rsne_len +
+					       beacon_rsnxe_len);
+	if (!pasn->beacon_rsne_rsnxe) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed storing beacon RSNE/RSNXE");
+		goto fail;
+	}
+
+	wpabuf_put_data(pasn->beacon_rsne_rsnxe, beacon_rsne, beacon_rsne_len);
+	if (beacon_rsnxe && beacon_rsnxe_len)
+		wpabuf_put_data(pasn->beacon_rsne_rsnxe, beacon_rsnxe,
+				beacon_rsnxe_len);
+
+	pasn->akmp = akmp;
+	pasn->cipher = cipher;
+	pasn->group = group;
+	pasn->freq = freq;
+
+	if (wpa_s->conf->force_kdk_derivation ||
+	    (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF &&
+	     ieee802_11_rsnx_capab(beacon_rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
+		pasn->kdk_len = WPA_KDK_MAX_LEN;
+	else
+		pasn->kdk_len = 0;
+	wpa_printf(MSG_DEBUG, "PASN: kdk_len=%zu", pasn->kdk_len);
+
+	os_memcpy(pasn->bssid, bssid, ETH_ALEN);
+
+	wpa_printf(MSG_DEBUG,
+		   "PASN: Init: " MACSTR " akmp=0x%x, cipher=0x%x, group=%u",
+		   MAC2STR(pasn->bssid), pasn->akmp, pasn->cipher,
+		   pasn->group);
+
+	frame = wpas_pasn_build_auth_1(wpa_s, comeback);
+	if (!frame) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed building 1st auth frame");
+		goto fail;
+	}
+
+	ret = wpa_drv_send_mlme(wpa_s, wpabuf_head(frame), wpabuf_len(frame), 0,
+				pasn->freq, 1000);
+
+	wpabuf_free(frame);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed sending 1st auth frame");
+		goto fail;
+	}
+
+	eloop_register_timeout(2, 0, wpas_pasn_auth_work_timeout, wpa_s, NULL);
+	return 0;
+
+fail:
+	return -1;
+}
+
+
+static struct wpa_bss * wpas_pasn_allowed(struct wpa_supplicant *wpa_s,
+					  const u8 *bssid, int akmp, int cipher)
+{
+	struct wpa_bss *bss;
+	const u8 *rsne;
+	struct wpa_ie_data rsne_data;
+	int ret;
+
+	if (os_memcmp(wpa_s->bssid, bssid, ETH_ALEN) == 0) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: Not doing authentication with current BSS");
+		return NULL;
+	}
+
+	bss = wpa_bss_get_bssid(wpa_s, bssid);
+	if (!bss) {
+		wpa_printf(MSG_DEBUG, "PASN: BSS not found");
+		return NULL;
+	}
+
+	rsne = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+	if (!rsne) {
+		wpa_printf(MSG_DEBUG, "PASN: BSS without RSNE");
+		return NULL;
+	}
+
+	ret = wpa_parse_wpa_ie(rsne, *(rsne + 1) + 2, &rsne_data);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed parsing RSNE data");
+		return NULL;
+	}
+
+	if (!(rsne_data.key_mgmt & akmp) ||
+	    !(rsne_data.pairwise_cipher & cipher)) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: AP does not support requested AKMP or cipher");
+		return NULL;
+	}
+
+	return bss;
+}
+
+
+static void wpas_pasn_auth_start_cb(struct wpa_radio_work *work, int deinit)
+{
+	struct wpa_supplicant *wpa_s = work->wpa_s;
+	struct wpa_pasn_auth_work *awork = work->ctx;
+	struct wpa_bss *bss;
+	const u8 *rsne, *rsnxe;
+	int ret;
+
+	wpa_printf(MSG_DEBUG, "PASN: auth_start_cb: deinit=%d", deinit);
+
+	if (deinit) {
+		if (work->started) {
+			eloop_cancel_timeout(wpas_pasn_auth_work_timeout,
+					     wpa_s, NULL);
+			wpa_s->pasn_auth_work = NULL;
+		}
+
+		wpas_pasn_free_auth_work(awork);
+		return;
+	}
+
+	/*
+	 * It is possible that by the time the callback is called, the PASN
+	 * authentication is not allowed, e.g., a connection with the AP was
+	 * established.
+	 */
+	bss = wpas_pasn_allowed(wpa_s, awork->bssid, awork->akmp,
+				awork->cipher);
+	if (!bss) {
+		wpa_printf(MSG_DEBUG, "PASN: auth_start_cb: Not allowed");
+		goto fail;
+	}
+
+	rsne = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+	if (!rsne) {
+		wpa_printf(MSG_DEBUG, "PASN: BSS without RSNE");
+		goto fail;
+	}
+
+	rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
+
+	ret = wpas_pasn_start(wpa_s, awork->bssid, awork->akmp, awork->cipher,
+			      awork->group, bss->freq, rsne, *(rsne + 1) + 2,
+			      rsnxe, rsnxe ? *(rsnxe + 1) + 2 : 0,
+			      awork->network_id, awork->comeback);
+	if (ret) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: Failed to start PASN authentication");
+		goto fail;
+	}
+
+	/* comeback token is no longer needed at this stage */
+	wpabuf_free(awork->comeback);
+	awork->comeback = NULL;
+
+	wpa_s->pasn_auth_work = work;
+	return;
+fail:
+	wpas_pasn_free_auth_work(awork);
+	work->ctx = NULL;
+	radio_work_done(work);
+}
+
+
+int wpas_pasn_auth_start(struct wpa_supplicant *wpa_s, const u8 *bssid,
+			 int akmp, int cipher, u16 group, int network_id,
+			 const u8 *comeback, size_t comeback_len)
+{
+	struct wpa_pasn_auth_work *awork;
+	struct wpa_bss *bss;
+
+	wpa_printf(MSG_DEBUG, "PASN: Start: " MACSTR " akmp=0x%x, cipher=0x%x",
+		   MAC2STR(bssid), akmp, cipher);
+
+	/*
+	 * TODO: Consider modifying the offchannel logic to handle additional
+	 * Management frames other then Action frames. For now allow PASN only
+	 * with drivers that support off-channel TX.
+	 */
+	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX)) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: Driver does not support offchannel TX");
+		return -1;
+	}
+
+	if (radio_work_pending(wpa_s, "pasn-start-auth")) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: send_auth: Work is already pending");
+		return -1;
+	}
+
+	if (wpa_s->pasn_auth_work) {
+		wpa_printf(MSG_DEBUG, "PASN: send_auth: Already in progress");
+		return -1;
+	}
+
+	bss = wpas_pasn_allowed(wpa_s, bssid, akmp, cipher);
+	if (!bss)
+		return -1;
+
+	wpas_pasn_reset(wpa_s);
+
+	awork = os_zalloc(sizeof(*awork));
+	if (!awork)
+		return -1;
+
+	os_memcpy(awork->bssid, bssid, ETH_ALEN);
+	awork->akmp = akmp;
+	awork->cipher = cipher;
+	awork->group = group;
+	awork->network_id = network_id;
+
+	if (comeback && comeback_len) {
+		awork->comeback = wpabuf_alloc_copy(comeback, comeback_len);
+		if (!awork->comeback) {
+			wpas_pasn_free_auth_work(awork);
+			return -1;
+		}
+	}
+
+	if (radio_add_work(wpa_s, bss->freq, "pasn-start-auth", 1,
+			   wpas_pasn_auth_start_cb, awork) < 0) {
+		wpas_pasn_free_auth_work(awork);
+		return -1;
+	}
+
+	wpa_printf(MSG_DEBUG, "PASN: Auth work successfully added");
+	return 0;
+}
+
+
+void wpas_pasn_auth_stop(struct wpa_supplicant *wpa_s)
+{
+	struct wpas_pasn *pasn = &wpa_s->pasn;
+
+	if (!wpa_s->pasn.ecdh)
+		return;
+
+	wpa_printf(MSG_DEBUG, "PASN: Stopping authentication");
+
+	wpas_pasn_auth_status(wpa_s, pasn->bssid, pasn->akmp, pasn->cipher,
+			      pasn->status, pasn->comeback,
+			      pasn->comeback_after);
+
+	wpas_pasn_reset(wpa_s);
+}
+
+
+static int wpas_pasn_immediate_retry(struct wpa_supplicant *wpa_s,
+				     struct wpas_pasn *pasn,
+				     struct wpa_pasn_params_data *params)
+{
+	int akmp = pasn->akmp;
+	int cipher = pasn->cipher;
+	u16 group = pasn->group;
+	u8 bssid[ETH_ALEN];
+	int network_id = pasn->ssid ? pasn->ssid->id : 0;
+
+	wpa_printf(MSG_DEBUG, "PASN: Immediate retry");
+	os_memcpy(bssid, pasn->bssid, ETH_ALEN);
+	wpas_pasn_reset(wpa_s);
+
+	return wpas_pasn_auth_start(wpa_s, bssid, akmp, cipher, group,
+				    network_id,
+				    params->comeback, params->comeback_len);
+}
+
+
+int wpas_pasn_auth_rx(struct wpa_supplicant *wpa_s,
+		      const struct ieee80211_mgmt *mgmt, size_t len)
+{
+	struct wpas_pasn *pasn = &wpa_s->pasn;
+	struct ieee802_11_elems elems;
+	struct wpa_ie_data rsn_data;
+	struct wpa_pasn_params_data pasn_params;
+	struct wpabuf *wrapped_data = NULL, *secret = NULL, *frame = NULL;
+	u8 mic[WPA_PASN_MAX_MIC_LEN], out_mic[WPA_PASN_MAX_MIC_LEN];
+	u8 mic_len;
+	u16 status;
+	int ret, inc_y;
+	u16 fc = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
+			      (WLAN_FC_STYPE_AUTH << 4));
+
+	if (!wpa_s->pasn_auth_work || !mgmt ||
+	    len < offsetof(struct ieee80211_mgmt, u.auth.variable))
+		return -2;
+
+	/* Not an Authentication frame; do nothing */
+	if ((mgmt->frame_control & fc) != fc)
+		return -2;
+
+	/* Not our frame; do nothing */
+	if (os_memcmp(mgmt->da, wpa_s->own_addr, ETH_ALEN) != 0 ||
+	    os_memcmp(mgmt->sa, pasn->bssid, ETH_ALEN) != 0 ||
+	    os_memcmp(mgmt->bssid, pasn->bssid, ETH_ALEN) != 0)
+		return -2;
+
+	/* Not PASN; do nothing */
+	if (mgmt->u.auth.auth_alg != host_to_le16(WLAN_AUTH_PASN))
+		return -2;
+
+	if (mgmt->u.auth.auth_transaction !=
+	    host_to_le16(pasn->trans_seq + 1)) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: RX: Invalid transaction sequence: (%u != %u)",
+			   le_to_host16(mgmt->u.auth.auth_transaction),
+			   pasn->trans_seq + 1);
+		return -1;
+	}
+
+	status = le_to_host16(mgmt->u.auth.status_code);
+
+	if (status != WLAN_STATUS_SUCCESS &&
+	    status != WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: Authentication rejected - status=%u", status);
+		pasn->status = status;
+		wpas_pasn_auth_stop(wpa_s);
+		return -1;
+	}
+
+	if (ieee802_11_parse_elems(mgmt->u.auth.variable,
+				   len - offsetof(struct ieee80211_mgmt,
+						  u.auth.variable),
+				   &elems, 0) == ParseFailed) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: Failed parsing Authentication frame");
+		goto fail;
+	}
+
+	/* Check that the MIC IE exists. Save it and zero out the memory */
+	mic_len = pasn_mic_len(pasn->akmp, pasn->cipher);
+	if (status == WLAN_STATUS_SUCCESS) {
+		if (!elems.mic || elems.mic_len != mic_len) {
+			wpa_printf(MSG_DEBUG,
+				   "PASN: Invalid MIC. Expecting len=%u",
+				   mic_len);
+			goto fail;
+		} else {
+			os_memcpy(mic, elems.mic, mic_len);
+			/* TODO: Clean this up.. Should not be modifying the
+			 * received message buffer. */
+			os_memset((u8 *) elems.mic, 0, mic_len);
+		}
+	}
+
+	if (!elems.pasn_params || !elems.pasn_params_len) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: Missing PASN Parameters IE");
+		goto fail;
+	}
+
+	ret = wpa_pasn_parse_parameter_ie(elems.pasn_params - 3,
+					  elems.pasn_params_len + 3,
+					  true, &pasn_params);
+	if (ret) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: Failed validation PASN of Parameters IE");
+		goto fail;
+	}
+
+	if (status == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: Authentication temporarily rejected");
+
+		if (pasn_params.comeback && pasn_params.comeback_len) {
+			wpa_printf(MSG_DEBUG,
+				   "PASN: Comeback token available. After=%u",
+				   pasn_params.after);
+
+			if (!pasn_params.after)
+				return wpas_pasn_immediate_retry(wpa_s, pasn,
+								 &pasn_params);
+
+			pasn->comeback = wpabuf_alloc_copy(
+				pasn_params.comeback, pasn_params.comeback_len);
+			if (pasn->comeback)
+				pasn->comeback_after = pasn_params.after;
+		}
+
+		pasn->status = status;
+		goto fail;
+	}
+
+	ret = wpa_parse_wpa_ie(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
+			       &rsn_data);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed parsing RNSE");
+		goto fail;
+	}
+
+	ret = wpa_pasn_validate_rsne(&rsn_data);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed validating RSNE");
+		goto fail;
+	}
+
+	if (pasn->akmp != rsn_data.key_mgmt ||
+	    pasn->cipher != rsn_data.pairwise_cipher) {
+		wpa_printf(MSG_DEBUG, "PASN: Mismatch in AKMP/cipher");
+		goto fail;
+	}
+
+	if (pasn->group != pasn_params.group) {
+		wpa_printf(MSG_DEBUG, "PASN: Mismatch in group");
+		goto fail;
+	}
+
+	if (!pasn_params.pubkey || !pasn_params.pubkey_len) {
+		wpa_printf(MSG_DEBUG, "PASN: Invalid public key");
+		goto fail;
+	}
+
+	if (pasn_params.pubkey[0] == WPA_PASN_PUBKEY_UNCOMPRESSED) {
+		inc_y = 1;
+	} else if (pasn_params.pubkey[0] == WPA_PASN_PUBKEY_COMPRESSED_0 ||
+		   pasn_params.pubkey[0] == WPA_PASN_PUBKEY_COMPRESSED_1) {
+		inc_y = 0;
+	} else {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: Invalid first octet in pubkey=0x%x",
+			   pasn_params.pubkey[0]);
+		goto fail;
+	}
+
+	secret = crypto_ecdh_set_peerkey(pasn->ecdh, inc_y,
+					 pasn_params.pubkey + 1,
+					 pasn_params.pubkey_len - 1);
+
+	if (!secret) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed to derive shared secret");
+		goto fail;
+	}
+
+	if (pasn_params.wrapped_data_format != WPA_PASN_WRAPPED_DATA_NO) {
+		wrapped_data = ieee802_11_defrag(&elems,
+						 WLAN_EID_EXTENSION,
+						 WLAN_EID_EXT_WRAPPED_DATA);
+
+		if (!wrapped_data) {
+			wpa_printf(MSG_DEBUG, "PASN: Missing wrapped data");
+			goto fail;
+		}
+	}
+
+	ret = wpas_pasn_set_pmk(wpa_s, &rsn_data, &pasn_params, wrapped_data);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed to set PMK");
+		goto fail;
+	}
+
+	ret = pasn_pmk_to_ptk(pasn->pmk, pasn->pmk_len,
+			      wpa_s->own_addr, pasn->bssid,
+			      wpabuf_head(secret), wpabuf_len(secret),
+			      &pasn->ptk, pasn->akmp, pasn->cipher,
+			      pasn->kdk_len);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed to derive PTK");
+		goto fail;
+	}
+
+	wpabuf_free(wrapped_data);
+	wrapped_data = NULL;
+	wpabuf_free(secret);
+	secret = NULL;
+
+	/* Verify the MIC */
+	ret = pasn_mic(pasn->ptk.kck, pasn->akmp, pasn->cipher,
+		       pasn->bssid, wpa_s->own_addr,
+		       wpabuf_head(pasn->beacon_rsne_rsnxe),
+		       wpabuf_len(pasn->beacon_rsne_rsnxe),
+		       (u8 *) &mgmt->u.auth,
+		       len - offsetof(struct ieee80211_mgmt, u.auth),
+		       out_mic);
+
+	wpa_hexdump_key(MSG_DEBUG, "PASN: Frame MIC", mic, mic_len);
+	if (ret || os_memcmp(mic, out_mic, mic_len) != 0) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed MIC verification");
+		goto fail;
+	}
+
+	pasn->trans_seq++;
+
+	wpa_printf(MSG_DEBUG, "PASN: Success verifying Authentication frame");
+
+	frame = wpas_pasn_build_auth_3(wpa_s);
+	if (!frame) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed building 3rd auth frame");
+		goto fail;
+	}
+
+	ret = wpa_drv_send_mlme(wpa_s, wpabuf_head(frame), wpabuf_len(frame), 0,
+				pasn->freq, 100);
+	wpabuf_free(frame);
+	if (ret) {
+		wpa_printf(MSG_DEBUG, "PASN: Failed sending 3st auth frame");
+		goto fail;
+	}
+
+	wpa_printf(MSG_DEBUG, "PASN: Success sending last frame. Store PTK");
+
+	ptksa_cache_add(wpa_s->ptksa, pasn->bssid, pasn->cipher,
+			dot11RSNAConfigPMKLifetime, &pasn->ptk);
+
+	forced_memzero(&pasn->ptk, sizeof(pasn->ptk));
+
+	pasn->status = WLAN_STATUS_SUCCESS;
+	return 0;
+fail:
+	wpa_printf(MSG_DEBUG, "PASN: Failed RX processing - terminating");
+	wpabuf_free(wrapped_data);
+	wpabuf_free(secret);
+
+	/*
+	 * TODO: In case of an error the standard allows to silently drop
+	 * the frame and terminate the authentication exchange. However, better
+	 * reply to the AP with an error status.
+	 */
+	if (status == WLAN_STATUS_SUCCESS)
+		pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+	else
+		pasn->status = status;
+
+	wpas_pasn_auth_stop(wpa_s);
+	return -1;
+}
+
+
+int wpas_pasn_auth_tx_status(struct wpa_supplicant *wpa_s,
+			     const u8 *data, size_t data_len, u8 acked)
+
+{
+	struct wpas_pasn *pasn = &wpa_s->pasn;
+	const struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) data;
+	u16 fc = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
+			      (WLAN_FC_STYPE_AUTH << 4));
+
+	wpa_printf(MSG_DEBUG, "PASN: auth_tx_status: acked=%u", acked);
+
+	if (!wpa_s->pasn_auth_work) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: auth_tx_status: no work in progress");
+		return -1;
+	}
+
+	if (!mgmt ||
+	    data_len < offsetof(struct ieee80211_mgmt, u.auth.variable))
+		return -1;
+
+	/* Not an authentication frame; do nothing */
+	if ((mgmt->frame_control & fc) != fc)
+		return -1;
+
+	/* Not our frame; do nothing */
+	if (os_memcmp(mgmt->da, pasn->bssid, ETH_ALEN) ||
+	    os_memcmp(mgmt->sa, wpa_s->own_addr, ETH_ALEN) ||
+	    os_memcmp(mgmt->bssid, pasn->bssid, ETH_ALEN))
+		return -1;
+
+	/* Not PASN; do nothing */
+	if (mgmt->u.auth.auth_alg !=  host_to_le16(WLAN_AUTH_PASN))
+		return -1;
+
+	if (mgmt->u.auth.auth_transaction != host_to_le16(pasn->trans_seq)) {
+		wpa_printf(MSG_ERROR,
+			   "PASN: Invalid transaction sequence: (%u != %u)",
+			   pasn->trans_seq,
+			   le_to_host16(mgmt->u.auth.auth_transaction));
+		return 0;
+	}
+
+	wpa_printf(MSG_ERROR,
+		   "PASN: auth with trans_seq=%u, acked=%u", pasn->trans_seq,
+		   acked);
+
+	/*
+	 * Even if the frame was not acked, do not treat this is an error, and
+	 * try to complete the flow, relying on the PASN timeout callback to
+	 * clean up.
+	 */
+	if (pasn->trans_seq == 3) {
+		wpa_printf(MSG_DEBUG, "PASN: auth complete with: " MACSTR,
+			   MAC2STR(pasn->bssid));
+		/*
+		 * Either frame was not ACKed or it was ACKed but the trans_seq
+		 * != 1, i.e., not expecting an RX frame, so we are done.
+		 */
+		wpas_pasn_auth_stop(wpa_s);
+	}
+
+	return 0;
+}
+
+
+int wpas_pasn_deauthenticate(struct wpa_supplicant *wpa_s, const u8 *bssid)
+{
+	struct wpa_bss *bss;
+	struct wpabuf *buf;
+	struct ieee80211_mgmt *deauth;
+	int ret;
+
+	if (os_memcmp(wpa_s->bssid, bssid, ETH_ALEN) == 0) {
+		wpa_printf(MSG_DEBUG,
+			   "PASN: Cannot deauthenticate from current BSS");
+		return -1;
+	}
+
+	wpa_printf(MSG_DEBUG, "PASN: deauth: Flushing all PTKSA entries for "
+		   MACSTR, MAC2STR(bssid));
+	ptksa_cache_flush(wpa_s->ptksa, bssid, WPA_CIPHER_NONE);
+
+	bss = wpa_bss_get_bssid(wpa_s, bssid);
+	if (!bss) {
+		wpa_printf(MSG_DEBUG, "PASN: deauth: BSS not found");
+		return -1;
+	}
+
+	buf = wpabuf_alloc(64);
+	if (!buf) {
+		wpa_printf(MSG_DEBUG, "PASN: deauth: Failed wpabuf allocate");
+		return -1;
+	}
+
+	deauth = wpabuf_put(buf, offsetof(struct ieee80211_mgmt,
+					  u.deauth.variable));
+
+	deauth->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
+					     (WLAN_FC_STYPE_DEAUTH << 4));
+
+	os_memcpy(deauth->da, bssid, ETH_ALEN);
+	os_memcpy(deauth->sa, wpa_s->own_addr, ETH_ALEN);
+	os_memcpy(deauth->bssid, bssid, ETH_ALEN);
+	deauth->u.deauth.reason_code =
+		host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
+
+	/*
+	 * Since we do not expect any response from the AP, implement the
+	 * Deauthentication frame transmission using direct call to the driver
+	 * without a radio work.
+	 */
+	ret = wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1,
+				bss->freq, 0);
+
+	wpabuf_free(buf);
+	wpa_printf(MSG_DEBUG, "PASN: deauth: send_mlme ret=%d", ret);
+
+	return ret;
+}
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/preauth_test.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/preauth_test.c
index de49948..31b5532 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/preauth_test.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/preauth_test.c
@@ -193,10 +193,8 @@
 	pmksa_candidate_free(wpa_s->wpa);
 	wpa_sm_deinit(wpa_s->wpa);
 	scard_deinit(wpa_s->scard);
-	if (wpa_s->ctrl_iface) {
-		wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
-		wpa_s->ctrl_iface = NULL;
-	}
+	wpa_supplicant_ctrl_iface_deinit(wpa_s, wpa_s->ctrl_iface);
+	wpa_s->ctrl_iface = NULL;
 	wpa_config_free(wpa_s->conf);
 }
 
@@ -222,7 +220,7 @@
 }
 
 
-static struct wpa_driver_ops dummy_driver;
+static struct wpa_driver_ops stub_driver;
 
 
 static void wpa_init_conf(struct wpa_supplicant *wpa_s, const char *ifname)
@@ -230,8 +228,8 @@
 	struct l2_packet_data *l2;
 	struct wpa_sm_ctx *ctx;
 
-	os_memset(&dummy_driver, 0, sizeof(dummy_driver));
-	wpa_s->driver = &dummy_driver;
+	os_memset(&stub_driver, 0, sizeof(stub_driver));
+	wpa_s->driver = &stub_driver;
 
 	ctx = os_zalloc(sizeof(*ctx));
 	assert(ctx != NULL);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/robust_av.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/robust_av.c
index 1280f5d..6587116 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/robust_av.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/robust_av.c
@@ -8,6 +8,7 @@
 
 #include "utils/includes.h"
 #include "utils/common.h"
+#include "utils/eloop.h"
 #include "common/wpa_ctrl.h"
 #include "common/ieee802_11_common.h"
 #include "wpa_supplicant_i.h"
@@ -15,6 +16,10 @@
 #include "bss.h"
 
 
+#define SCS_RESP_TIMEOUT 1
+#define DSCP_REQ_TIMEOUT 5
+
+
 void wpas_populate_mscs_descriptor_ie(struct robust_av_data *robust_av,
 				      struct wpabuf *buf)
 {
@@ -45,21 +50,136 @@
 }
 
 
+static int wpas_populate_type4_classifier(struct type4_params *type4_param,
+					  struct wpabuf *buf)
+{
+	/* classifier parameters */
+	wpabuf_put_u8(buf, type4_param->classifier_mask);
+	if (type4_param->ip_version == IPV4) {
+		wpabuf_put_u8(buf, IPV4); /* IP version */
+		wpabuf_put_data(buf, &type4_param->ip_params.v4.src_ip.s_addr,
+				4);
+		wpabuf_put_data(buf, &type4_param->ip_params.v4.dst_ip.s_addr,
+				4);
+		wpabuf_put_be16(buf, type4_param->ip_params.v4.src_port);
+		wpabuf_put_be16(buf, type4_param->ip_params.v4.dst_port);
+		wpabuf_put_u8(buf, type4_param->ip_params.v4.dscp);
+		wpabuf_put_u8(buf, type4_param->ip_params.v4.protocol);
+		wpabuf_put_u8(buf, 0); /* Reserved octet */
+	} else {
+		wpabuf_put_u8(buf, IPV6);
+		wpabuf_put_data(buf, &type4_param->ip_params.v6.src_ip.s6_addr,
+				16);
+		wpabuf_put_data(buf, &type4_param->ip_params.v6.dst_ip.s6_addr,
+				16);
+		wpabuf_put_be16(buf, type4_param->ip_params.v6.src_port);
+		wpabuf_put_be16(buf, type4_param->ip_params.v6.dst_port);
+		wpabuf_put_u8(buf, type4_param->ip_params.v6.dscp);
+		wpabuf_put_u8(buf, type4_param->ip_params.v6.next_header);
+		wpabuf_put_data(buf, type4_param->ip_params.v6.flow_label, 3);
+	}
+
+	return 0;
+}
+
+
+static int wpas_populate_type10_classifier(struct type10_params *type10_param,
+					   struct wpabuf *buf)
+{
+	/* classifier parameters */
+	wpabuf_put_u8(buf, type10_param->prot_instance);
+	wpabuf_put_u8(buf, type10_param->prot_number);
+	wpabuf_put_data(buf, type10_param->filter_value,
+			type10_param->filter_len);
+	wpabuf_put_data(buf, type10_param->filter_mask,
+			type10_param->filter_len);
+	return 0;
+}
+
+
+static int wpas_populate_scs_descriptor_ie(struct scs_desc_elem *desc_elem,
+					   struct wpabuf *buf)
+{
+	u8 *len, *len1;
+	struct tclas_element *tclas_elem;
+	unsigned int i;
+
+	/* SCS Descriptor element */
+	wpabuf_put_u8(buf, WLAN_EID_SCS_DESCRIPTOR);
+	len = wpabuf_put(buf, 1);
+	wpabuf_put_u8(buf, desc_elem->scs_id);
+	wpabuf_put_u8(buf, desc_elem->request_type);
+	if (desc_elem->request_type == SCS_REQ_REMOVE)
+		goto end;
+
+	if (desc_elem->intra_access_priority || desc_elem->scs_up_avail) {
+		wpabuf_put_u8(buf, WLAN_EID_INTRA_ACCESS_CATEGORY_PRIORITY);
+		wpabuf_put_u8(buf, 1);
+		wpabuf_put_u8(buf, desc_elem->intra_access_priority);
+	}
+
+	tclas_elem = desc_elem->tclas_elems;
+
+	if (!tclas_elem)
+		return -1;
+
+	for (i = 0; i < desc_elem->num_tclas_elem; i++, tclas_elem++) {
+		int ret;
+
+		/* TCLAS element */
+		wpabuf_put_u8(buf, WLAN_EID_TCLAS);
+		len1 = wpabuf_put(buf, 1);
+		wpabuf_put_u8(buf, 255); /* User Priority: not compared */
+		/* Frame Classifier */
+		wpabuf_put_u8(buf, tclas_elem->classifier_type);
+		/* Frame classifier parameters */
+		switch (tclas_elem->classifier_type) {
+		case 4:
+			ret = wpas_populate_type4_classifier(
+				&tclas_elem->frame_classifier.type4_param,
+				buf);
+			break;
+		case 10:
+			ret = wpas_populate_type10_classifier(
+				&tclas_elem->frame_classifier.type10_param,
+				buf);
+			break;
+		default:
+			return -1;
+		}
+
+		if (ret == -1) {
+			wpa_printf(MSG_ERROR,
+				   "Failed to populate frame classifier");
+			return -1;
+		}
+
+		*len1 = (u8 *) wpabuf_put(buf, 0) - len1 - 1;
+	}
+
+	if (desc_elem->num_tclas_elem > 1) {
+		/* TCLAS Processing element */
+		wpabuf_put_u8(buf, WLAN_EID_TCLAS_PROCESSING);
+		wpabuf_put_u8(buf, 1);
+		wpabuf_put_u8(buf, desc_elem->tclas_processing);
+	}
+
+end:
+	*len = (u8 *) wpabuf_put(buf, 0) - len - 1;
+	return 0;
+}
+
+
 int wpas_send_mscs_req(struct wpa_supplicant *wpa_s)
 {
 	struct wpabuf *buf;
-	const u8 *ext_capab = NULL;
 	size_t buf_len;
 	int ret;
 
 	if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid)
 		return 0;
 
-	if (wpa_s->current_bss)
-		ext_capab = wpa_bss_get_ie(wpa_s->current_bss,
-					   WLAN_EID_EXT_CAPAB);
-
-	if (!ext_capab || ext_capab[1] < 11 || !(ext_capab[12] & 0x20)) {
+	if (!wpa_bss_ext_capab(wpa_s->current_bss, WLAN_EXT_CAPAB_MSCS)) {
 		wpa_dbg(wpa_s, MSG_INFO,
 			"AP does not support MSCS - could not send MSCS Req");
 		return -1;
@@ -106,6 +226,277 @@
 }
 
 
+static size_t tclas_elem_len(const struct tclas_element *elem)
+{
+	size_t buf_len = 0;
+
+	buf_len += 2 +	/* TCLAS element header */
+		1 +	/* User Priority */
+		1 ;	/* Classifier Type */
+
+	if (elem->classifier_type == 4) {
+		enum ip_version ip_ver;
+
+		buf_len += 1 +	/* Classifier mask */
+			1 +	/* IP version */
+			1 +	/* user priority */
+			2 +	/* src_port */
+			2 +	/* dst_port */
+			1 ;	/* dscp */
+		ip_ver = elem->frame_classifier.type4_param.ip_version;
+		if (ip_ver == IPV4) {
+			buf_len += 4 +  /* src_ip */
+				4 +	/* dst_ip */
+				1 +	/* protocol */
+				1 ;  /* Reserved */
+		} else if (ip_ver == IPV6) {
+			buf_len += 16 +  /* src_ip */
+				16 +  /* dst_ip */
+				1  +  /* next_header */
+				3  ;  /* flow_label */
+		} else {
+			wpa_printf(MSG_ERROR, "%s: Incorrect IP version %d",
+				   __func__, ip_ver);
+			return 0;
+		}
+	} else if (elem->classifier_type == 10) {
+		buf_len += 1 +	/* protocol instance */
+			1 +	/* protocol number */
+			2 * elem->frame_classifier.type10_param.filter_len;
+	} else {
+		wpa_printf(MSG_ERROR, "%s: Incorrect classifier type %u",
+			   __func__, elem->classifier_type);
+		return 0;
+	}
+
+	return buf_len;
+}
+
+
+static struct wpabuf * allocate_scs_buf(struct scs_desc_elem *desc_elem,
+					unsigned int num_scs_desc)
+{
+	struct wpabuf *buf;
+	size_t buf_len = 0;
+	unsigned int i, j;
+
+	buf_len = 3; /* Action frame header */
+
+	for (i = 0; i < num_scs_desc; i++, desc_elem++) {
+		struct tclas_element *tclas_elem;
+
+		buf_len += 2 +	/* SCS descriptor IE header */
+			   1 +	/* SCSID */
+			   1 ;	/* Request type */
+
+		if (desc_elem->request_type == SCS_REQ_REMOVE)
+			continue;
+
+		if (desc_elem->intra_access_priority || desc_elem->scs_up_avail)
+			buf_len += 3;
+
+		tclas_elem = desc_elem->tclas_elems;
+		if (!tclas_elem) {
+			wpa_printf(MSG_ERROR, "%s: TCLAS element null",
+				   __func__);
+			return NULL;
+		}
+
+		for (j = 0; j < desc_elem->num_tclas_elem; j++, tclas_elem++) {
+			size_t elen;
+
+			elen = tclas_elem_len(tclas_elem);
+			if (elen == 0)
+				return NULL;
+			buf_len += elen;
+		}
+
+		if (desc_elem->num_tclas_elem > 1) {
+			buf_len += 1 +	/* TCLAS Processing eid */
+				   1 +	/* length */
+				   1 ;	/* processing */
+		}
+	}
+
+	buf = wpabuf_alloc(buf_len);
+	if (!buf) {
+		wpa_printf(MSG_ERROR, "Failed to allocate SCS req");
+		return NULL;
+	}
+
+	return buf;
+}
+
+
+static void scs_request_timer(void *eloop_ctx, void *timeout_ctx)
+{
+	struct wpa_supplicant *wpa_s = eloop_ctx;
+	struct active_scs_elem *scs_desc, *prev;
+
+	if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid)
+		return;
+
+	/* Once timeout is over, remove all SCS descriptors with no response */
+	dl_list_for_each_safe(scs_desc, prev, &wpa_s->active_scs_ids,
+			      struct active_scs_elem, list) {
+		u8 bssid[ETH_ALEN] = { 0 };
+		const u8 *src;
+
+		if (scs_desc->status == SCS_DESC_SUCCESS)
+			continue;
+
+		if (wpa_s->current_bss)
+			src = wpa_s->current_bss->bssid;
+		else
+			src = bssid;
+
+		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCS_RESULT "bssid=" MACSTR
+			" SCSID=%u status_code=timedout", MAC2STR(src),
+			scs_desc->scs_id);
+
+		dl_list_del(&scs_desc->list);
+		wpa_printf(MSG_INFO, "%s: SCSID %d removed after timeout",
+			   __func__, scs_desc->scs_id);
+		os_free(scs_desc);
+	}
+
+	eloop_cancel_timeout(scs_request_timer, wpa_s, NULL);
+	wpa_s->ongoing_scs_req = false;
+}
+
+
+int wpas_send_scs_req(struct wpa_supplicant *wpa_s)
+{
+	struct wpabuf *buf = NULL;
+	struct scs_desc_elem *desc_elem = NULL;
+	int ret = -1;
+	unsigned int i;
+
+	if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid)
+		return -1;
+
+	if (!wpa_bss_ext_capab(wpa_s->current_bss, WLAN_EXT_CAPAB_SCS)) {
+		wpa_dbg(wpa_s, MSG_INFO,
+			"AP does not support SCS - could not send SCS Request");
+		return -1;
+	}
+
+	desc_elem = wpa_s->scs_robust_av_req.scs_desc_elems;
+	if (!desc_elem)
+		return -1;
+
+	buf = allocate_scs_buf(desc_elem,
+			       wpa_s->scs_robust_av_req.num_scs_desc);
+	if (!buf)
+		return -1;
+
+	wpabuf_put_u8(buf, WLAN_ACTION_ROBUST_AV_STREAMING);
+	wpabuf_put_u8(buf, ROBUST_AV_SCS_REQ);
+	wpa_s->scs_dialog_token++;
+	if (wpa_s->scs_dialog_token == 0)
+		wpa_s->scs_dialog_token++;
+	wpabuf_put_u8(buf, wpa_s->scs_dialog_token);
+
+	for (i = 0; i < wpa_s->scs_robust_av_req.num_scs_desc;
+	     i++, desc_elem++) {
+		/* SCS Descriptor element */
+		if (wpas_populate_scs_descriptor_ie(desc_elem, buf) < 0)
+			goto end;
+	}
+
+	wpa_hexdump_buf(MSG_DEBUG, "SCS Request", buf);
+	ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
+				  wpa_s->own_addr, wpa_s->bssid,
+				  wpabuf_head(buf), wpabuf_len(buf), 0);
+	if (ret < 0) {
+		wpa_dbg(wpa_s, MSG_ERROR, "SCS: Failed to send SCS Request");
+		wpa_s->scs_dialog_token--;
+		goto end;
+	}
+
+	desc_elem = wpa_s->scs_robust_av_req.scs_desc_elems;
+	for (i = 0; i < wpa_s->scs_robust_av_req.num_scs_desc;
+	     i++, desc_elem++) {
+		struct active_scs_elem *active_scs_elem;
+
+		if (desc_elem->request_type != SCS_REQ_ADD)
+			continue;
+
+		active_scs_elem = os_malloc(sizeof(struct active_scs_elem));
+		if (!active_scs_elem)
+			break;
+		active_scs_elem->scs_id = desc_elem->scs_id;
+		active_scs_elem->status = SCS_DESC_SENT;
+		dl_list_add(&wpa_s->active_scs_ids, &active_scs_elem->list);
+	}
+
+	/*
+	 * Register a timeout after which this request will be removed from
+	 * the cache.
+	 */
+	eloop_register_timeout(SCS_RESP_TIMEOUT, 0, scs_request_timer, wpa_s,
+			       NULL);
+	wpa_s->ongoing_scs_req = true;
+
+end:
+	wpabuf_free(buf);
+	free_up_scs_desc(&wpa_s->scs_robust_av_req);
+
+	return ret;
+}
+
+
+void free_up_tclas_elem(struct scs_desc_elem *elem)
+{
+	struct tclas_element *tclas_elems = elem->tclas_elems;
+	unsigned int num_tclas_elem = elem->num_tclas_elem;
+	struct tclas_element *tclas_data;
+	unsigned int j;
+
+	elem->tclas_elems = NULL;
+	elem->num_tclas_elem = 0;
+
+	if (!tclas_elems)
+		return;
+
+	tclas_data = tclas_elems;
+	for (j = 0; j < num_tclas_elem; j++, tclas_data++) {
+		if (tclas_data->classifier_type != 10)
+			continue;
+
+		os_free(tclas_data->frame_classifier.type10_param.filter_value);
+		os_free(tclas_data->frame_classifier.type10_param.filter_mask);
+	}
+
+	os_free(tclas_elems);
+}
+
+
+void free_up_scs_desc(struct scs_robust_av_data *data)
+{
+	struct scs_desc_elem *desc_elems = data->scs_desc_elems;
+	unsigned int num_scs_desc = data->num_scs_desc;
+	struct scs_desc_elem *desc_data;
+	unsigned int i;
+
+	data->scs_desc_elems = NULL;
+	data->num_scs_desc = 0;
+
+	if (!desc_elems)
+		return;
+
+	desc_data = desc_elems;
+	for (i = 0; i < num_scs_desc; i++, desc_data++) {
+		if (desc_data->request_type == SCS_REQ_REMOVE ||
+		    !desc_data->tclas_elems)
+			continue;
+
+		free_up_tclas_elem(desc_data);
+	}
+	os_free(desc_elems);
+}
+
+
 void wpas_handle_robust_av_recv_action(struct wpa_supplicant *wpa_s,
 				       const u8 *src, const u8 *buf, size_t len)
 {
@@ -123,7 +514,7 @@
 		return;
 	}
 
-	status_code = *buf;
+	status_code = WPA_GET_LE16(buf);
 	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_MSCS_RESULT "bssid=" MACSTR
 		" status_code=%u", MAC2STR(src), status_code);
 	wpa_s->mscs_setup_done = status_code == WLAN_STATUS_SUCCESS;
@@ -158,3 +549,939 @@
 		" status_code=%u", MAC2STR(bssid), status);
 	wpa_s->mscs_setup_done = status == WLAN_STATUS_SUCCESS;
 }
+
+
+static void wpas_wait_for_dscp_req_timer(void *eloop_ctx, void *timeout_ctx)
+{
+	struct wpa_supplicant *wpa_s = eloop_ctx;
+
+	/* Once timeout is over, reset wait flag and allow sending DSCP query */
+	wpa_printf(MSG_DEBUG,
+		   "QM: Wait time over for sending DSCP request - allow DSCP query");
+	wpa_s->wait_for_dscp_req = 0;
+	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "request_wait end");
+}
+
+
+void wpas_handle_assoc_resp_qos_mgmt(struct wpa_supplicant *wpa_s,
+				     const u8 *ies, size_t ies_len)
+{
+	const u8 *wfa_capa;
+
+	wpa_s->connection_dscp = 0;
+	if (wpa_s->wait_for_dscp_req)
+		eloop_cancel_timeout(wpas_wait_for_dscp_req_timer, wpa_s, NULL);
+
+	if (!ies || ies_len == 0 || !wpa_s->enable_dscp_policy_capa)
+		return;
+
+	wfa_capa = get_vendor_ie(ies, ies_len, WFA_CAPA_IE_VENDOR_TYPE);
+	if (!wfa_capa || wfa_capa[1] < 6 || wfa_capa[6] < 1 ||
+	    !(wfa_capa[7] & WFA_CAPA_QM_DSCP_POLICY))
+		return; /* AP does not enable QM DSCP Policy */
+
+	wpa_s->connection_dscp = 1;
+	wpa_s->wait_for_dscp_req = !!(wfa_capa[7] &
+				      WFA_CAPA_QM_UNSOLIC_DSCP);
+	if (!wpa_s->wait_for_dscp_req)
+		return;
+
+	/* Register a timeout after which dscp query can be sent to AP. */
+	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "request_wait start");
+	eloop_register_timeout(DSCP_REQ_TIMEOUT, 0,
+			       wpas_wait_for_dscp_req_timer, wpa_s, NULL);
+}
+
+
+void wpas_handle_robust_av_scs_recv_action(struct wpa_supplicant *wpa_s,
+					   const u8 *src, const u8 *buf,
+					   size_t len)
+{
+	u8 dialog_token;
+	unsigned int i, count;
+	struct active_scs_elem *scs_desc, *prev;
+
+	if (len < 2)
+		return;
+	if (!wpa_s->ongoing_scs_req) {
+		wpa_printf(MSG_INFO,
+			   "SCS: Drop received response due to no ongoing request");
+		return;
+	}
+
+	dialog_token = *buf++;
+	len--;
+	if (dialog_token != wpa_s->scs_dialog_token) {
+		wpa_printf(MSG_INFO,
+			   "SCS: Drop received frame due to dialog token mismatch: received:%u expected:%u",
+			   dialog_token, wpa_s->scs_dialog_token);
+		return;
+	}
+
+	/* This Count field does not exist in the IEEE Std 802.11-2020
+	 * definition of the SCS Response frame. However, it was accepted to
+	 * be added into REVme per REVme/D0.0 CC35 CID 49 (edits in document
+	 * 11-21-0688-07). */
+	count = *buf++;
+	len--;
+	if (count == 0 || count * 3 > len) {
+		wpa_printf(MSG_INFO,
+			   "SCS: Drop received frame due to invalid count: %u (remaining %zu octets)",
+			   count, len);
+		return;
+	}
+
+	for (i = 0; i < count; i++) {
+		u8 id;
+		u16 status;
+		bool scs_desc_found = false;
+
+		id = *buf++;
+		status = WPA_GET_LE16(buf);
+		buf += 2;
+		len -= 3;
+
+		dl_list_for_each(scs_desc, &wpa_s->active_scs_ids,
+				 struct active_scs_elem, list) {
+			if (id == scs_desc->scs_id) {
+				scs_desc_found = true;
+				break;
+			}
+		}
+
+		if (!scs_desc_found) {
+			wpa_printf(MSG_INFO, "SCS: SCS ID invalid %u", id);
+			continue;
+		}
+
+		if (status != WLAN_STATUS_SUCCESS) {
+			dl_list_del(&scs_desc->list);
+			os_free(scs_desc);
+		} else if (status == WLAN_STATUS_SUCCESS) {
+			scs_desc->status = SCS_DESC_SUCCESS;
+		}
+
+		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCS_RESULT "bssid=" MACSTR
+			" SCSID=%u status_code=%u", MAC2STR(src), id, status);
+	}
+
+	eloop_cancel_timeout(scs_request_timer, wpa_s, NULL);
+	wpa_s->ongoing_scs_req = false;
+
+	dl_list_for_each_safe(scs_desc, prev, &wpa_s->active_scs_ids,
+			      struct active_scs_elem, list) {
+		if (scs_desc->status != SCS_DESC_SUCCESS) {
+			wpa_msg(wpa_s, MSG_INFO,
+				WPA_EVENT_SCS_RESULT "bssid=" MACSTR
+				" SCSID=%u status_code=response_not_received",
+				MAC2STR(src), scs_desc->scs_id);
+			dl_list_del(&scs_desc->list);
+			os_free(scs_desc);
+		}
+	}
+}
+
+
+static void wpas_clear_active_scs_ids(struct wpa_supplicant *wpa_s)
+{
+	struct active_scs_elem *scs_elem;
+
+	while ((scs_elem = dl_list_first(&wpa_s->active_scs_ids,
+					 struct active_scs_elem, list))) {
+		dl_list_del(&scs_elem->list);
+		os_free(scs_elem);
+	}
+}
+
+
+void wpas_scs_deinit(struct wpa_supplicant *wpa_s)
+{
+	free_up_scs_desc(&wpa_s->scs_robust_av_req);
+	wpa_s->scs_dialog_token = 0;
+	wpas_clear_active_scs_ids(wpa_s);
+	eloop_cancel_timeout(scs_request_timer, wpa_s, NULL);
+	wpa_s->ongoing_scs_req = false;
+}
+
+
+static int write_ipv4_info(char *pos, int total_len,
+			   const struct ipv4_params *v4)
+{
+	int res, rem_len;
+	char addr[INET_ADDRSTRLEN];
+
+	rem_len = total_len;
+
+	if (v4->param_mask & BIT(1)) {
+		if (!inet_ntop(AF_INET, &v4->src_ip, addr, INET_ADDRSTRLEN)) {
+			wpa_printf(MSG_ERROR,
+				   "QM: Failed to set IPv4 source address");
+			return -1;
+		}
+
+		res = os_snprintf(pos, rem_len, " src_ip=%s", addr);
+		if (os_snprintf_error(rem_len, res))
+			return -1;
+
+		pos += res;
+		rem_len -= res;
+	}
+
+	if (v4->param_mask & BIT(2)) {
+		if (!inet_ntop(AF_INET, &v4->dst_ip, addr, INET_ADDRSTRLEN)) {
+			wpa_printf(MSG_ERROR,
+				   "QM: Failed to set IPv4 destination address");
+			return -1;
+		}
+
+		res = os_snprintf(pos, rem_len, " dst_ip=%s", addr);
+		if (os_snprintf_error(rem_len, res))
+			return -1;
+
+		pos += res;
+		rem_len -= res;
+	}
+
+	if (v4->param_mask & BIT(3)) {
+		res = os_snprintf(pos, rem_len, " src_port=%d", v4->src_port);
+		if (os_snprintf_error(rem_len, res))
+			return -1;
+
+		pos += res;
+		rem_len -= res;
+	}
+
+	if (v4->param_mask & BIT(4)) {
+		res = os_snprintf(pos, rem_len, " dst_port=%d", v4->dst_port);
+		if (os_snprintf_error(rem_len, res))
+			return -1;
+
+		pos += res;
+		rem_len -= res;
+	}
+
+	if (v4->param_mask & BIT(6)) {
+		res = os_snprintf(pos, rem_len, " protocol=%d", v4->protocol);
+		if (os_snprintf_error(rem_len, res))
+			return -1;
+
+		pos += res;
+		rem_len -= res;
+	}
+
+	return total_len - rem_len;
+}
+
+
+static int write_ipv6_info(char *pos, int total_len,
+			   const struct ipv6_params *v6)
+{
+	int res, rem_len;
+	char addr[INET6_ADDRSTRLEN];
+
+	rem_len = total_len;
+
+	if (v6->param_mask & BIT(1)) {
+		if (!inet_ntop(AF_INET6, &v6->src_ip, addr, INET6_ADDRSTRLEN)) {
+			wpa_printf(MSG_ERROR,
+				   "QM: Failed to set IPv6 source addr");
+			return -1;
+		}
+
+		res = os_snprintf(pos, rem_len, " src_ip=%s", addr);
+		if (os_snprintf_error(rem_len, res))
+			return -1;
+
+		pos += res;
+		rem_len -= res;
+	}
+
+	if (v6->param_mask & BIT(2)) {
+		if (!inet_ntop(AF_INET6, &v6->dst_ip, addr, INET6_ADDRSTRLEN)) {
+			wpa_printf(MSG_ERROR,
+				   "QM: Failed to set IPv6 destination addr");
+			return -1;
+		}
+
+		res = os_snprintf(pos, rem_len, " dst_ip=%s", addr);
+		if (os_snprintf_error(rem_len, res))
+			return -1;
+
+		pos += res;
+		rem_len -= res;
+	}
+
+	if (v6->param_mask & BIT(3)) {
+		res = os_snprintf(pos, rem_len, " src_port=%d", v6->src_port);
+		if (os_snprintf_error(rem_len, res))
+			return -1;
+
+		pos += res;
+		rem_len -= res;
+	}
+
+	if (v6->param_mask & BIT(4)) {
+		res = os_snprintf(pos, rem_len, " dst_port=%d", v6->dst_port);
+		if (os_snprintf_error(rem_len, res))
+			return -1;
+
+		pos += res;
+		rem_len -= res;
+	}
+
+	if (v6->param_mask & BIT(6)) {
+		res = os_snprintf(pos, rem_len, " protocol=%d",
+				  v6->next_header);
+		if (os_snprintf_error(rem_len, res))
+			return -1;
+
+		pos += res;
+		rem_len -= res;
+	}
+
+	return total_len - rem_len;
+}
+
+#ifndef CONFIG_AIDL
+struct dscp_policy_data {
+	u8 policy_id;
+	u8 req_type;
+	u8 dscp;
+	bool dscp_info;
+	const u8 *frame_classifier;
+	u8 frame_classifier_len;
+	struct type4_params type4_param;
+	const u8 *domain_name;
+	u8 domain_name_len;
+	u16 start_port;
+	u16 end_port;
+	bool port_range_info;
+};
+#endif
+
+static int set_frame_classifier_type4_ipv4(struct dscp_policy_data *policy)
+{
+	u8 classifier_mask;
+	const u8 *frame_classifier = policy->frame_classifier;
+	struct type4_params *type4_param = &policy->type4_param;
+
+	if (policy->frame_classifier_len < 18) {
+		wpa_printf(MSG_ERROR,
+			   "QM: Received IPv4 frame classifier with insufficient length %d",
+			   policy->frame_classifier_len);
+		return -1;
+	}
+
+	classifier_mask = frame_classifier[1];
+
+	/* Classifier Mask - bit 1 = Source IP Address */
+	if (classifier_mask & BIT(1)) {
+		type4_param->ip_params.v4.param_mask |= BIT(1);
+		os_memcpy(&type4_param->ip_params.v4.src_ip,
+			  &frame_classifier[3], 4);
+	}
+
+	/* Classifier Mask - bit 2 = Destination IP Address */
+	if (classifier_mask & BIT(2)) {
+		if (policy->domain_name) {
+			wpa_printf(MSG_ERROR,
+				   "QM: IPv4: Both domain name and destination IP address not expected");
+			return -1;
+		}
+
+		type4_param->ip_params.v4.param_mask |= BIT(2);
+		os_memcpy(&type4_param->ip_params.v4.dst_ip,
+			  &frame_classifier[7], 4);
+	}
+
+	/* Classifier Mask - bit 3 = Source Port */
+	if (classifier_mask & BIT(3)) {
+		type4_param->ip_params.v4.param_mask |= BIT(3);
+		type4_param->ip_params.v4.src_port =
+			WPA_GET_BE16(&frame_classifier[11]);
+	}
+
+	/* Classifier Mask - bit 4 = Destination Port */
+	if (classifier_mask & BIT(4)) {
+		if (policy->port_range_info) {
+			wpa_printf(MSG_ERROR,
+				   "QM: IPv4: Both port range and destination port not expected");
+			return -1;
+		}
+
+		type4_param->ip_params.v4.param_mask |= BIT(4);
+		type4_param->ip_params.v4.dst_port =
+			WPA_GET_BE16(&frame_classifier[13]);
+	}
+
+	/* Classifier Mask - bit 5 = DSCP (ignored) */
+
+	/* Classifier Mask - bit 6 = Protocol */
+	if (classifier_mask & BIT(6)) {
+		type4_param->ip_params.v4.param_mask |= BIT(6);
+		type4_param->ip_params.v4.protocol = frame_classifier[16];
+	}
+
+	return 0;
+}
+
+
+static int set_frame_classifier_type4_ipv6(struct dscp_policy_data *policy)
+{
+	u8 classifier_mask;
+	const u8 *frame_classifier = policy->frame_classifier;
+	struct type4_params *type4_param = &policy->type4_param;
+
+	if (policy->frame_classifier_len < 44) {
+		wpa_printf(MSG_ERROR,
+			   "QM: Received IPv6 frame classifier with insufficient length %d",
+			   policy->frame_classifier_len);
+		return -1;
+	}
+
+	classifier_mask = frame_classifier[1];
+
+	/* Classifier Mask - bit 1 = Source IP Address */
+	if (classifier_mask & BIT(1)) {
+		type4_param->ip_params.v6.param_mask |= BIT(1);
+		os_memcpy(&type4_param->ip_params.v6.src_ip,
+			  &frame_classifier[3], 16);
+	}
+
+	/* Classifier Mask - bit 2 = Destination IP Address */
+	if (classifier_mask & BIT(2)) {
+		if (policy->domain_name) {
+			wpa_printf(MSG_ERROR,
+				   "QM: IPv6: Both domain name and destination IP address not expected");
+			return -1;
+		}
+		type4_param->ip_params.v6.param_mask |= BIT(2);
+		os_memcpy(&type4_param->ip_params.v6.dst_ip,
+			  &frame_classifier[19], 16);
+	}
+
+	/* Classifier Mask - bit 3 = Source Port */
+	if (classifier_mask & BIT(3)) {
+		type4_param->ip_params.v6.param_mask |= BIT(3);
+		type4_param->ip_params.v6.src_port =
+				WPA_GET_BE16(&frame_classifier[35]);
+	}
+
+	/* Classifier Mask - bit 4 = Destination Port */
+	if (classifier_mask & BIT(4)) {
+		if (policy->port_range_info) {
+			wpa_printf(MSG_ERROR,
+				   "IPv6: Both port range and destination port not expected");
+			return -1;
+		}
+
+		type4_param->ip_params.v6.param_mask |= BIT(4);
+		type4_param->ip_params.v6.dst_port =
+				WPA_GET_BE16(&frame_classifier[37]);
+	}
+
+	/* Classifier Mask - bit 5 = DSCP (ignored) */
+
+	/* Classifier Mask - bit 6 = Next Header */
+	if (classifier_mask & BIT(6)) {
+		type4_param->ip_params.v6.param_mask |= BIT(6);
+		type4_param->ip_params.v6.next_header = frame_classifier[40];
+	}
+
+	return 0;
+}
+
+
+static int wpas_set_frame_classifier_params(struct dscp_policy_data *policy)
+{
+	const u8 *frame_classifier = policy->frame_classifier;
+	u8 frame_classifier_len = policy->frame_classifier_len;
+
+	if (frame_classifier_len < 3) {
+		wpa_printf(MSG_ERROR,
+			   "QM: Received frame classifier with insufficient length %d",
+			   frame_classifier_len);
+		return -1;
+	}
+
+	/* Only allowed Classifier Type: IP and higher layer parameters (4) */
+	if (frame_classifier[0] != 4) {
+		wpa_printf(MSG_ERROR,
+			   "QM: Received frame classifier with invalid classifier type %d",
+			   frame_classifier[0]);
+		return -1;
+	}
+
+	/* Classifier Mask - bit 0 = Version */
+	if (!(frame_classifier[1] & BIT(0))) {
+		wpa_printf(MSG_ERROR,
+			   "QM: Received frame classifier without IP version");
+		return -1;
+	}
+
+	/* Version (4 or 6) */
+	if (frame_classifier[2] == 4) {
+		if (set_frame_classifier_type4_ipv4(policy)) {
+			wpa_printf(MSG_ERROR,
+				   "QM: Failed to set IPv4 parameters");
+			return -1;
+		}
+
+		policy->type4_param.ip_version = IPV4;
+	} else if (frame_classifier[2] == 6) {
+		if (set_frame_classifier_type4_ipv6(policy)) {
+			wpa_printf(MSG_ERROR,
+				   "QM: Failed to set IPv6 parameters");
+			return -1;
+		}
+
+		policy->type4_param.ip_version = IPV6;
+	} else {
+		wpa_printf(MSG_ERROR,
+			   "QM: Received unknown IP version %d",
+			   frame_classifier[2]);
+		return -1;
+	}
+
+	return 0;
+}
+
+
+static bool dscp_valid_domain_name(const char *str)
+{
+	if (!str[0])
+		return false;
+
+	while (*str) {
+		if (is_ctrl_char(*str) || *str == ' ' || *str == '=')
+			return false;
+		str++;
+	}
+
+	return true;
+}
+
+
+static void wpas_add_dscp_policy(struct wpa_supplicant *wpa_s,
+				 struct dscp_policy_data *policy)
+{
+	int ip_ver = 0, res;
+	char policy_str[1000], *pos;
+	int len;
+
+	if (!policy->frame_classifier && !policy->domain_name &&
+	    !policy->port_range_info) {
+		wpa_printf(MSG_ERROR,
+			   "QM: Invalid DSCP policy - no attributes present");
+		goto fail;
+	}
+
+	policy_str[0] = '\0';
+	pos = policy_str;
+	len = sizeof(policy_str);
+
+	if (policy->frame_classifier) {
+		struct type4_params *type4 = &policy->type4_param;
+
+		if (wpas_set_frame_classifier_params(policy)) {
+			wpa_printf(MSG_ERROR,
+				   "QM: Failed to set frame classifier parameters");
+			goto fail;
+		}
+
+		if (type4->ip_version == IPV4)
+			res = write_ipv4_info(pos, len, &type4->ip_params.v4);
+		else
+			res = write_ipv6_info(pos, len, &type4->ip_params.v6);
+
+		if (res <= 0) {
+			wpa_printf(MSG_ERROR,
+				   "QM: Failed to write IP parameters");
+			goto fail;
+		}
+
+		ip_ver = type4->ip_version;
+
+		pos += res;
+		len -= res;
+	}
+
+	if (policy->port_range_info) {
+		res = os_snprintf(pos, len, " start_port=%u end_port=%u",
+				  policy->start_port, policy->end_port);
+		if (os_snprintf_error(len, res)) {
+			wpa_printf(MSG_ERROR,
+				   "QM: Failed to write port range attributes for policy id = %d",
+				   policy->policy_id);
+			goto fail;
+		}
+
+		pos += res;
+		len -= res;
+	}
+
+	if (policy->domain_name) {
+		char domain_name_str[250];
+
+		if (policy->domain_name_len >= sizeof(domain_name_str)) {
+			wpa_printf(MSG_ERROR,
+				   "QM: Domain name length higher than max expected");
+			goto fail;
+		}
+		os_memcpy(domain_name_str, policy->domain_name,
+			  policy->domain_name_len);
+		domain_name_str[policy->domain_name_len] = '\0';
+		if (!dscp_valid_domain_name(domain_name_str)) {
+			wpa_printf(MSG_ERROR, "QM: Invalid domain name string");
+			goto fail;
+		}
+		res = os_snprintf(pos, len, " domain_name=%s", domain_name_str);
+		if (os_snprintf_error(len, res)) {
+			wpa_printf(MSG_ERROR,
+				   "QM: Failed to write domain name attribute for policy id = %d",
+				   policy->policy_id);
+			goto fail;
+		}
+	}
+
+	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY
+		"add policy_id=%u dscp=%u ip_version=%d%s",
+		policy->policy_id, policy->dscp, ip_ver, policy_str);
+	return;
+fail:
+	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "reject policy_id=%u",
+		policy->policy_id);
+}
+
+
+void wpas_dscp_deinit(struct wpa_supplicant *wpa_s)
+{
+	wpa_printf(MSG_DEBUG, "QM: Clear all active DSCP policies");
+	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "clear_all");
+	wpa_s->dscp_req_dialog_token = 0;
+	wpa_s->dscp_query_dialog_token = 0;
+	wpa_s->connection_dscp = 0;
+	if (wpa_s->wait_for_dscp_req) {
+		wpa_s->wait_for_dscp_req = 0;
+		eloop_cancel_timeout(wpas_wait_for_dscp_req_timer, wpa_s, NULL);
+	}
+}
+
+
+static void wpas_fill_dscp_policy(struct dscp_policy_data *policy, u8 attr_id,
+				  u8 attr_len, const u8 *attr_data)
+{
+	switch (attr_id) {
+	case QM_ATTR_PORT_RANGE:
+		if (attr_len < 4) {
+			wpa_printf(MSG_ERROR,
+				   "QM: Received Port Range attribute with insufficient length %d",
+				    attr_len);
+			break;
+		}
+		policy->start_port = WPA_GET_BE16(attr_data);
+		policy->end_port = WPA_GET_BE16(attr_data + 2);
+		policy->port_range_info = true;
+		break;
+	case QM_ATTR_DSCP_POLICY:
+		if (attr_len < 3) {
+			wpa_printf(MSG_ERROR,
+				   "QM: Received DSCP Policy attribute with insufficient length %d",
+				   attr_len);
+			return;
+		}
+		policy->policy_id = attr_data[0];
+		policy->req_type = attr_data[1];
+		policy->dscp = attr_data[2];
+		policy->dscp_info = true;
+		break;
+	case QM_ATTR_TCLAS:
+		if (attr_len < 1) {
+			wpa_printf(MSG_ERROR,
+				   "QM: Received TCLAS attribute with insufficient length %d",
+				   attr_len);
+			return;
+		}
+		policy->frame_classifier = attr_data;
+		policy->frame_classifier_len = attr_len;
+		break;
+	case QM_ATTR_DOMAIN_NAME:
+		if (attr_len < 1) {
+			wpa_printf(MSG_ERROR,
+				   "QM: Received domain name attribute with insufficient length %d",
+				   attr_len);
+			return;
+		}
+		policy->domain_name = attr_data;
+		policy->domain_name_len = attr_len;
+		break;
+	default:
+		wpa_printf(MSG_ERROR, "QM: Received invalid QoS attribute %d",
+			   attr_id);
+		break;
+	}
+}
+
+
+void wpas_handle_qos_mgmt_recv_action(struct wpa_supplicant *wpa_s,
+				      const u8 *src,
+				      const u8 *buf, size_t len)
+{
+	int rem_len;
+	const u8 *qos_ie, *attr;
+	int more, reset;
+
+	if (!wpa_s->enable_dscp_policy_capa) {
+		wpa_printf(MSG_ERROR,
+			   "QM: Ignore DSCP Policy frame since the capability is not enabled");
+		return;
+	}
+
+	if (!pmf_in_use(wpa_s, src)) {
+		wpa_printf(MSG_ERROR,
+			   "QM: Ignore DSCP Policy frame since PMF is not in use");
+		return;
+	}
+
+	if (!wpa_s->connection_dscp) {
+		 wpa_printf(MSG_DEBUG,
+			    "QM: DSCP Policy capability not enabled for the current association - ignore QoS Management Action frames");
+		return;
+	}
+
+	if (len < 1)
+		return;
+
+	/* Handle only DSCP Policy Request frame */
+	if (buf[0] != QM_DSCP_POLICY_REQ) {
+		wpa_printf(MSG_ERROR, "QM: Received unexpected QoS action frame %d",
+			   buf[0]);
+		return;
+	}
+
+	if (len < 3) {
+		wpa_printf(MSG_ERROR,
+			   "Received QoS Management DSCP Policy Request frame with invalid length %zu",
+			   len);
+		return;
+	}
+
+	/* Clear wait_for_dscp_req on receiving first DSCP request from AP */
+	if (wpa_s->wait_for_dscp_req) {
+		wpa_s->wait_for_dscp_req = 0;
+		eloop_cancel_timeout(wpas_wait_for_dscp_req_timer, wpa_s, NULL);
+	}
+
+	wpa_s->dscp_req_dialog_token = buf[1];
+	more = buf[2] & DSCP_POLICY_CTRL_MORE;
+	reset = buf[2] & DSCP_POLICY_CTRL_RESET;
+
+	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "request_start%s%s",
+		reset ? " clear_all" : "", more ? " more" : "");
+
+	qos_ie = buf + 3;
+	rem_len = len - 3;
+	while (rem_len > 2) {
+		struct dscp_policy_data policy;
+		int rem_attrs_len, ie_len;
+
+		ie_len = 2 + qos_ie[1];
+		if (rem_len < ie_len)
+			break;
+
+		if (rem_len < 6 || qos_ie[0] != WLAN_EID_VENDOR_SPECIFIC ||
+		    qos_ie[1] < 4 ||
+		    WPA_GET_BE32(&qos_ie[2]) != QM_IE_VENDOR_TYPE) {
+			rem_len -= ie_len;
+			qos_ie += ie_len;
+			continue;
+		}
+
+		os_memset(&policy, 0, sizeof(struct dscp_policy_data));
+		attr = qos_ie + 6;
+		rem_attrs_len = qos_ie[1] - 4;
+
+		while (rem_attrs_len > 2 && rem_attrs_len >= 2 + attr[1]) {
+			wpas_fill_dscp_policy(&policy, attr[0], attr[1],
+					      &attr[2]);
+			rem_attrs_len -= 2 + attr[1];
+			attr += 2 + attr[1];
+		}
+
+		rem_len -= ie_len;
+		qos_ie += ie_len;
+
+		if (!policy.dscp_info) {
+			wpa_printf(MSG_ERROR,
+				   "QM: Received QoS IE without DSCP Policy attribute");
+			continue;
+		}
+
+		if (policy.req_type == DSCP_POLICY_REQ_ADD)
+			wpas_add_dscp_policy(wpa_s, &policy);
+		else if (policy.req_type == DSCP_POLICY_REQ_REMOVE)
+			wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY
+				"remove policy_id=%u", policy.policy_id);
+		else
+			wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY
+				"reject policy_id=%u", policy.policy_id);
+	}
+
+	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "request_end");
+}
+
+
+int wpas_send_dscp_response(struct wpa_supplicant *wpa_s,
+			    struct dscp_resp_data *resp_data)
+{
+	struct wpabuf *buf = NULL;
+	size_t buf_len;
+	int ret = -1, i;
+	u8 resp_control = 0;
+
+	if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid) {
+		wpa_printf(MSG_ERROR,
+			   "QM: Failed to send DSCP response - not connected to AP");
+		return -1;
+	}
+
+	if (resp_data->solicited && !wpa_s->dscp_req_dialog_token) {
+		wpa_printf(MSG_ERROR, "QM: No ongoing DSCP request");
+		return -1;
+	}
+
+	if (!wpa_s->connection_dscp) {
+		wpa_printf(MSG_ERROR,
+			   "QM: Failed to send DSCP response - DSCP capability not enabled for the current association");
+		return -1;
+
+	}
+
+	buf_len = 1 +	/* Category */
+		  3 +	/* OUI */
+		  1 +	/* OUI Type */
+		  1 +	/* OUI Subtype */
+		  1 +	/* Dialog Token */
+		  1 +	/* Response Control */
+		  1 +	/* Count */
+		  2 * resp_data->num_policies;  /* Status list */
+	buf = wpabuf_alloc(buf_len);
+	if (!buf) {
+		wpa_printf(MSG_ERROR,
+			   "QM: Failed to allocate DSCP policy response");
+		return -1;
+	}
+
+	wpabuf_put_u8(buf, WLAN_ACTION_VENDOR_SPECIFIC_PROTECTED);
+	wpabuf_put_be24(buf, OUI_WFA);
+	wpabuf_put_u8(buf, QM_ACTION_OUI_TYPE);
+	wpabuf_put_u8(buf, QM_DSCP_POLICY_RESP);
+
+	wpabuf_put_u8(buf, resp_data->solicited ?
+		      wpa_s->dscp_req_dialog_token : 0);
+
+	if (resp_data->more)
+		resp_control |= DSCP_POLICY_CTRL_MORE;
+	if (resp_data->reset)
+		resp_control |= DSCP_POLICY_CTRL_RESET;
+	wpabuf_put_u8(buf, resp_control);
+
+	wpabuf_put_u8(buf, resp_data->num_policies);
+	for (i = 0; i < resp_data->num_policies; i++) {
+		wpabuf_put_u8(buf, resp_data->policy[i].id);
+		wpabuf_put_u8(buf, resp_data->policy[i].status);
+	}
+
+	wpa_hexdump_buf(MSG_MSGDUMP, "DSCP response frame: ", buf);
+	ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
+				  wpa_s->own_addr, wpa_s->bssid,
+				  wpabuf_head(buf), wpabuf_len(buf), 0);
+	if (ret < 0) {
+		wpa_msg(wpa_s, MSG_INFO, "QM: Failed to send DSCP response");
+		goto fail;
+	}
+
+	/*
+	 * Mark DSCP request complete whether response sent is solicited or
+	 * unsolicited
+	 */
+	wpa_s->dscp_req_dialog_token = 0;
+
+fail:
+	wpabuf_free(buf);
+	return ret;
+}
+
+
+int wpas_send_dscp_query(struct wpa_supplicant *wpa_s, const char *domain_name,
+			 size_t domain_name_length)
+{
+	struct wpabuf *buf = NULL;
+	int ret, dscp_query_size;
+
+	if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid)
+		return -1;
+
+	if (!wpa_s->connection_dscp) {
+		wpa_printf(MSG_ERROR,
+			   "QM: Failed to send DSCP query - DSCP capability not enabled for the current association");
+		return -1;
+	}
+
+	if (wpa_s->wait_for_dscp_req) {
+		wpa_printf(MSG_INFO, "QM: Wait until AP sends a DSCP request");
+		return -1;
+	}
+
+#define DOMAIN_NAME_OFFSET (4 /* OUI */ + 1 /* Attr Id */ + 1 /* Attr len */)
+
+	if (domain_name_length > 255 - DOMAIN_NAME_OFFSET) {
+		wpa_printf(MSG_ERROR, "QM: Too long domain name");
+		return -1;
+	}
+
+	dscp_query_size = 1 + /* Category */
+			  4 + /* OUI Type */
+			  1 + /* OUI subtype */
+			  1; /* Dialog Token */
+	if (domain_name && domain_name_length)
+		dscp_query_size += 1 + /* Element ID */
+			1 + /* IE Length */
+			DOMAIN_NAME_OFFSET + domain_name_length;
+
+	buf = wpabuf_alloc(dscp_query_size);
+	if (!buf) {
+		wpa_printf(MSG_ERROR, "QM: Failed to allocate DSCP query");
+		return -1;
+	}
+
+	wpabuf_put_u8(buf, WLAN_ACTION_VENDOR_SPECIFIC_PROTECTED);
+	wpabuf_put_be32(buf, QM_ACTION_VENDOR_TYPE);
+	wpabuf_put_u8(buf, QM_DSCP_POLICY_QUERY);
+	wpa_s->dscp_query_dialog_token++;
+	if (wpa_s->dscp_query_dialog_token == 0)
+		wpa_s->dscp_query_dialog_token++;
+	wpabuf_put_u8(buf, wpa_s->dscp_query_dialog_token);
+
+	if (domain_name && domain_name_length) {
+		/* Domain Name attribute */
+		wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
+		wpabuf_put_u8(buf, DOMAIN_NAME_OFFSET + domain_name_length);
+		wpabuf_put_be32(buf, QM_IE_VENDOR_TYPE);
+		wpabuf_put_u8(buf, QM_ATTR_DOMAIN_NAME);
+		wpabuf_put_u8(buf, domain_name_length);
+		wpabuf_put_data(buf, domain_name, domain_name_length);
+	}
+#undef DOMAIN_NAME_OFFSET
+
+	ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
+				  wpa_s->own_addr, wpa_s->bssid,
+				  wpabuf_head(buf), wpabuf_len(buf), 0);
+	if (ret < 0) {
+		wpa_dbg(wpa_s, MSG_ERROR, "QM: Failed to send DSCP query");
+		wpa_s->dscp_query_dialog_token--;
+	}
+
+	wpabuf_free(buf);
+	return ret;
+}
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/rrm.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/rrm.c
index 8ba3dd2..573af19 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/rrm.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/rrm.c
@@ -555,14 +555,14 @@
 static int * wpas_op_class_freqs(const struct oper_class_map *op,
 				 struct hostapd_hw_modes *mode, int active)
 {
-	u8 channels_80mhz_5ghz[] = { 42, 58, 106, 122, 138, 155 };
-	u8 channels_160mhz_5ghz[] = { 50, 114 };
+	u8 channels_80mhz_5ghz[] = { 42, 58, 106, 122, 138, 155, 171 };
+	u8 channels_160mhz_5ghz[] = { 50, 114, 163 };
 	u8 channels_80mhz_6ghz[] = { 7, 23, 39, 55, 71, 87, 103, 119, 135, 151,
 				     167, 183, 199, 215 };
 	u8 channels_160mhz_6ghz[] = { 15, 47, 79, 111, 143, 175, 207 };
 	const u8 *channels = NULL;
 	size_t num_chan = 0;
-	int is_6ghz = is_6ghz_op_class(op->op_class);
+	bool is_6ghz = is_6ghz_op_class(op->op_class);
 
 	/*
 	 * When adding all channels in the operating class, 80 + 80 MHz
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/scan.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/scan.c
index a551ebb..4499639 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/scan.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/scan.c
@@ -392,6 +392,29 @@
 }
 
 
+#ifdef CONFIG_P2P
+static bool is_6ghz_supported(struct wpa_supplicant *wpa_s)
+{
+	struct hostapd_channel_data *chnl;
+	int i, j;
+
+	for (i = 0; i < wpa_s->hw.num_modes; i++) {
+		if (wpa_s->hw.modes[i].mode == HOSTAPD_MODE_IEEE80211A) {
+			chnl = wpa_s->hw.modes[i].channels;
+			for (j = 0; j < wpa_s->hw.modes[i].num_channels; j++) {
+				if (chnl[j].flag & HOSTAPD_CHAN_DISABLED)
+					continue;
+				if (is_6ghz_freq(chnl[j].freq))
+					return true;
+			}
+		}
+	}
+
+	return false;
+}
+#endif /* CONFIG_P2P */
+
+
 static void wpa_supplicant_optimize_freqs(
 	struct wpa_supplicant *wpa_s, struct wpa_driver_scan_params *params)
 {
@@ -521,7 +544,7 @@
 {
 	struct wpabuf *default_ies = NULL;
 	u8 ext_capab[18];
-	int ext_capab_len;
+	int ext_capab_len, frame_id;
 	enum wpa_driver_if_type type = WPA_IF_STATION;
 
 #ifdef CONFIG_P2P
@@ -545,6 +568,20 @@
 		wpas_mbo_scan_ie(wpa_s, default_ies);
 #endif /* CONFIG_MBO */
 
+	if (type == WPA_IF_P2P_CLIENT)
+		frame_id = VENDOR_ELEM_PROBE_REQ_P2P;
+	else
+		frame_id = VENDOR_ELEM_PROBE_REQ;
+
+	if (wpa_s->vendor_elem[frame_id]) {
+		size_t len;
+
+		len = wpabuf_len(wpa_s->vendor_elem[frame_id]);
+		if (len > 0 && wpabuf_resize(&default_ies, len) == 0)
+			wpabuf_put_buf(default_ies,
+				       wpa_s->vendor_elem[frame_id]);
+	}
+
 	if (default_ies)
 		wpa_drv_set_default_scan_ies(wpa_s, wpabuf_head(default_ies),
 					     wpabuf_len(default_ies));
@@ -670,30 +707,38 @@
 #endif /* CONFIG_P2P */
 
 
-static void wpa_setband_scan_freqs_list(struct wpa_supplicant *wpa_s,
-					enum hostapd_hw_mode band,
-					struct wpa_driver_scan_params *params,
-					int is_6ghz)
+int wpa_add_scan_freqs_list(struct wpa_supplicant *wpa_s,
+			    enum hostapd_hw_mode band,
+			    struct wpa_driver_scan_params *params, bool is_6ghz)
 {
 	/* Include only supported channels for the specified band */
 	struct hostapd_hw_modes *mode;
-	int count, i;
+	int num_chans = 0;
+	int *freqs, i;
 
 	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, band, is_6ghz);
-	if (mode == NULL) {
-		/* No channels supported in this band - use empty list */
-		params->freqs = os_zalloc(sizeof(int));
-		return;
+	if (!mode)
+		return -1;
+
+	if (params->freqs) {
+		while (params->freqs[num_chans])
+			num_chans++;
 	}
 
-	params->freqs = os_calloc(mode->num_channels + 1, sizeof(int));
-	if (params->freqs == NULL)
-		return;
-	for (count = 0, i = 0; i < mode->num_channels; i++) {
+	freqs = os_realloc(params->freqs,
+			   (num_chans + mode->num_channels + 1) * sizeof(int));
+	if (!freqs)
+		return -1;
+
+	params->freqs = freqs;
+	for (i = 0; i < mode->num_channels; i++) {
 		if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED)
 			continue;
-		params->freqs[count++] = mode->channels[i].freq;
+		params->freqs[num_chans++] = mode->channels[i].freq;
 	}
+	params->freqs[num_chans] = 0;
+
+	return 0;
 }
 
 
@@ -704,12 +749,16 @@
 		return; /* unknown what channels the driver supports */
 	if (params->freqs)
 		return; /* already using a limited channel set */
-	if (wpa_s->setband == WPA_SETBAND_5G)
-		wpa_setband_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211A,
-					    params, 0);
-	else if (wpa_s->setband == WPA_SETBAND_2G)
-		wpa_setband_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211G,
-					    params, 0);
+
+	if (wpa_s->setband_mask & WPA_SETBAND_5G)
+		wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211A, params,
+					false);
+	if (wpa_s->setband_mask & WPA_SETBAND_2G)
+		wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211G, params,
+					false);
+	if (wpa_s->setband_mask & WPA_SETBAND_6G)
+		wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211A, params,
+					true);
 }
 
 
@@ -1214,7 +1263,12 @@
 	wpa_setband_scan_freqs(wpa_s, &params);
 
 	/* See if user specified frequencies. If so, scan only those. */
-	if (wpa_s->conf->freq_list && !params.freqs) {
+	if (wpa_s->last_scan_req == INITIAL_SCAN_REQ &&
+	    wpa_s->conf->initial_freq_list && !params.freqs) {
+		wpa_dbg(wpa_s, MSG_DEBUG,
+			"Optimize scan based on conf->initial_freq_list");
+		int_array_concat(&params.freqs, wpa_s->conf->initial_freq_list);
+	} else if (wpa_s->conf->freq_list && !params.freqs) {
 		wpa_dbg(wpa_s, MSG_DEBUG,
 			"Optimize scan based on conf->freq_list");
 		int_array_concat(&params.freqs, wpa_s->conf->freq_list);
@@ -1287,6 +1341,12 @@
 		}
 	}
 
+	if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
+	    wpa_s->manual_non_coloc_6ghz) {
+		wpa_dbg(wpa_s, MSG_DEBUG, "Collocated 6 GHz logic is disabled");
+		params.non_coloc_6ghz = 1;
+	}
+
 	scan_params = &params;
 
 scan:
@@ -1319,6 +1379,34 @@
 			}
 		}
 	}
+
+	if (!params.freqs &&
+	    (wpa_s->p2p_in_invitation || wpa_s->p2p_in_provisioning) &&
+	    !is_p2p_allow_6ghz(wpa_s->global->p2p) &&
+	    is_6ghz_supported(wpa_s)) {
+		int i;
+
+		/* Exclude 5 GHz channels from the full scan for P2P connection
+		 * since the 6 GHz band is disabled for P2P uses. */
+		wpa_printf(MSG_DEBUG,
+			   "P2P: 6 GHz disabled - update the scan frequency list");
+		for (i = 0; i < wpa_s->hw.num_modes; i++) {
+			if (wpa_s->hw.modes[i].num_channels == 0)
+				continue;
+			if (wpa_s->hw.modes[i].mode == HOSTAPD_MODE_IEEE80211G)
+				wpa_add_scan_freqs_list(
+					wpa_s, HOSTAPD_MODE_IEEE80211G,
+					&params, false);
+			if (wpa_s->hw.modes[i].mode == HOSTAPD_MODE_IEEE80211A)
+				wpa_add_scan_freqs_list(
+					wpa_s, HOSTAPD_MODE_IEEE80211A,
+					&params, false);
+			if (wpa_s->hw.modes[i].mode == HOSTAPD_MODE_IEEE80211AD)
+				wpa_add_scan_freqs_list(
+					wpa_s, HOSTAPD_MODE_IEEE80211AD,
+					&params, false);
+		}
+	}
 #endif /* CONFIG_P2P */
 
 	ret = wpa_supplicant_trigger_scan(wpa_s, scan_params);
@@ -2021,14 +2109,22 @@
 		snr_b = snr_b_full = wb->level;
 	}
 
-	/* if SNR is close, decide by max rate or frequency band */
-	if (snr_a && snr_b && abs(snr_b - snr_a) < 7) {
+	/* If SNR is close, decide by max rate or frequency band. For cases
+	 * involving the 6 GHz band, use the throughput estimate irrespective
+	 * of the SNR difference since the LPI/VLP rules may result in
+	 * significant differences in SNR for cases where the estimated
+	 * throughput can be considerably higher with the lower SNR. */
+	if (snr_a && snr_b && (abs(snr_b - snr_a) < 7 ||
+			       is_6ghz_freq(wa->freq) ||
+			       is_6ghz_freq(wb->freq))) {
 		if (wa->est_throughput != wb->est_throughput)
 			return (int) wb->est_throughput -
 				(int) wa->est_throughput;
 	}
 	if ((snr_a && snr_b && abs(snr_b - snr_a) < 5) ||
 	    (wa->qual && wb->qual && abs(wb->qual - wa->qual) < 10)) {
+		if (is_6ghz_freq(wa->freq) ^ is_6ghz_freq(wb->freq))
+			return is_6ghz_freq(wa->freq) ? -1 : 1;
 		if (IS_5GHZ(wa->freq) ^ IS_5GHZ(wb->freq))
 			return IS_5GHZ(wa->freq) ? -1 : 1;
 	}
@@ -2189,9 +2285,10 @@
 void scan_snr(struct wpa_scan_res *res)
 {
 	if (res->flags & WPA_SCAN_NOISE_INVALID) {
-		res->noise = IS_5GHZ(res->freq) ?
-			DEFAULT_NOISE_FLOOR_5GHZ :
-			DEFAULT_NOISE_FLOOR_2GHZ;
+		res->noise = is_6ghz_freq(res->freq) ?
+			DEFAULT_NOISE_FLOOR_6GHZ :
+			(IS_5GHZ(res->freq) ?
+			 DEFAULT_NOISE_FLOOR_5GHZ : DEFAULT_NOISE_FLOOR_2GHZ);
 	}
 
 	if (res->flags & WPA_SCAN_LEVEL_DBM) {
@@ -2258,6 +2355,92 @@
 };
 
 
+static const struct minsnr_bitrate_entry vht160_table[] = {
+	{ 0, 0 },
+	{ 11, 58500 },  /* VHT160 MCS0 */
+	{ 14, 117000 }, /* VHT160 MCS1 */
+	{ 18, 175500 }, /* VHT160 MCS2 */
+	{ 20, 234000 }, /* VHT160 MCS3 */
+	{ 24, 351000 }, /* VHT160 MCS4 */
+	{ 27, 468000 }, /* VHT160 MCS5 */
+	{ 29, 526500 }, /* VHT160 MCS6 */
+	{ 34, 585000 }, /* VHT160 MCS7 */
+	{ 38, 702000 }, /* VHT160 MCS8 */
+	{ 40, 780000 }, /* VHT160 MCS9 */
+	{ -1, 780000 }  /* SNR > 37 */
+};
+
+
+static const struct minsnr_bitrate_entry he20_table[] = {
+	{ 0, 0 },
+	{ 2, 8600 },    /* HE20 MCS0 */
+	{ 5, 17200 },   /* HE20 MCS1 */
+	{ 9, 25800 },   /* HE20 MCS2 */
+	{ 11, 34400 },  /* HE20 MCS3 */
+	{ 15, 51600 },  /* HE20 MCS4 */
+	{ 18, 68800 },  /* HE20 MCS5 */
+	{ 20, 77400 },  /* HE20 MCS6 */
+	{ 25, 86000 },  /* HE20 MCS7 */
+	{ 29, 103200 }, /* HE20 MCS8 */
+	{ 31, 114700 }, /* HE20 MCS9 */
+	{ 34, 129000 }, /* HE20 MCS10 */
+	{ 36, 143400 }, /* HE20 MCS11 */
+	{ -1, 143400 }  /* SNR > 29 */
+};
+
+static const struct minsnr_bitrate_entry he40_table[] = {
+	{ 0, 0 },
+	{ 5, 17200 },   /* HE40 MCS0 */
+	{ 8, 34400 },   /* HE40 MCS1 */
+	{ 12, 51600 },  /* HE40 MCS2 */
+	{ 14, 68800 },  /* HE40 MCS3 */
+	{ 18, 103200 }, /* HE40 MCS4 */
+	{ 21, 137600 }, /* HE40 MCS5 */
+	{ 23, 154900 }, /* HE40 MCS6 */
+	{ 28, 172100 }, /* HE40 MCS7 */
+	{ 32, 206500 }, /* HE40 MCS8 */
+	{ 34, 229400 }, /* HE40 MCS9 */
+	{ 37, 258100 }, /* HE40 MCS10 */
+	{ 39, 286800 }, /* HE40 MCS11 */
+	{ -1, 286800 }  /* SNR > 34 */
+};
+
+static const struct minsnr_bitrate_entry he80_table[] = {
+	{ 0, 0 },
+	{ 8, 36000 },   /* HE80 MCS0 */
+	{ 11, 72100 },  /* HE80 MCS1 */
+	{ 15, 108100 }, /* HE80 MCS2 */
+	{ 17, 144100 }, /* HE80 MCS3 */
+	{ 21, 216200 }, /* HE80 MCS4 */
+	{ 24, 288200 }, /* HE80 MCS5 */
+	{ 26, 324300 }, /* HE80 MCS6 */
+	{ 31, 360300 }, /* HE80 MCS7 */
+	{ 35, 432400 }, /* HE80 MCS8 */
+	{ 37, 480400 }, /* HE80 MCS9 */
+	{ 40, 540400 }, /* HE80 MCS10 */
+	{ 42, 600500 }, /* HE80 MCS11 */
+	{ -1, 600500 }  /* SNR > 37 */
+};
+
+
+static const struct minsnr_bitrate_entry he160_table[] = {
+	{ 0, 0 },
+	{ 11, 72100 },   /* HE160 MCS0 */
+	{ 14, 144100 },  /* HE160 MCS1 */
+	{ 18, 216200 },  /* HE160 MCS2 */
+	{ 20, 288200 },  /* HE160 MCS3 */
+	{ 24, 432400 },  /* HE160 MCS4 */
+	{ 27, 576500 },  /* HE160 MCS5 */
+	{ 29, 648500 },  /* HE160 MCS6 */
+	{ 34, 720600 },  /* HE160 MCS7 */
+	{ 38, 864700 },  /* HE160 MCS8 */
+	{ 40, 960800 },  /* HE160 MCS9 */
+	{ 43, 1080900 }, /* HE160 MCS10 */
+	{ 45, 1201000 }, /* HE160 MCS11 */
+	{ -1, 1201000 }  /* SNR > 37 */
+};
+
+
 static unsigned int interpolate_rate(int snr, int snr0, int snr1,
 				     int rate0, int rate1)
 {
@@ -2302,11 +2485,34 @@
 }
 
 
+static unsigned int max_vht160_rate(int snr)
+{
+	return max_rate(vht160_table, snr, 1);
+}
+
+
+static unsigned int max_he_rate(const struct minsnr_bitrate_entry table[],
+				int snr)
+{
+	const struct minsnr_bitrate_entry *prev, *entry = table;
+
+	while (entry->minsnr != -1 && snr >= entry->minsnr)
+		entry++;
+	if (entry == table)
+		return 0;
+	prev = entry - 1;
+	if (entry->minsnr == -1)
+		return prev->bitrate;
+	return interpolate_rate(snr, prev->minsnr, entry->minsnr,
+				prev->bitrate, entry->bitrate);
+}
+
+
 unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
 			      const u8 *ies, size_t ies_len, int rate,
-			      int snr)
+			      int snr, int freq)
 {
-	enum local_hw_capab capab = wpa_s->hw_capab;
+	struct hostapd_hw_modes *hw_mode;
 	unsigned int est, tmp;
 	const u8 *ie;
 
@@ -2351,7 +2557,10 @@
 		rate = 54 * 2;
 	est = rate * 500;
 
-	if (capab == CAPAB_HT || capab == CAPAB_HT40 || capab == CAPAB_VHT) {
+	hw_mode = get_mode_with_freq(wpa_s->hw.modes, wpa_s->hw.num_modes,
+				     freq);
+
+	if (hw_mode && hw_mode->ht_capab) {
 		ie = get_ie(ies, ies_len, WLAN_EID_HT_CAP);
 		if (ie) {
 			tmp = max_ht20_rate(snr, false);
@@ -2360,7 +2569,8 @@
 		}
 	}
 
-	if (capab == CAPAB_HT40 || capab == CAPAB_VHT) {
+	if (hw_mode &&
+	    (hw_mode->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) {
 		ie = get_ie(ies, ies_len, WLAN_EID_HT_OPERATION);
 		if (ie && ie[1] >= 2 &&
 		    (ie[3] & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK)) {
@@ -2370,10 +2580,12 @@
 		}
 	}
 
-	if (capab == CAPAB_VHT) {
+	if (hw_mode && hw_mode->vht_capab) {
 		/* Use +1 to assume VHT is always faster than HT */
 		ie = get_ie(ies, ies_len, WLAN_EID_VHT_CAP);
 		if (ie) {
+			bool vht80 = false, vht160 = false;
+
 			tmp = max_ht20_rate(snr, true) + 1;
 			if (tmp > est)
 				est = tmp;
@@ -2387,13 +2599,82 @@
 					est = tmp;
 			}
 
+			/* Determine VHT BSS bandwidth based on IEEE Std
+			 * 802.11-2020, Table 11-23 (VHT BSs bandwidth) */
 			ie = get_ie(ies, ies_len, WLAN_EID_VHT_OPERATION);
-			if (ie && ie[1] >= 1 &&
-			    (ie[2] & VHT_OPMODE_CHANNEL_WIDTH_MASK)) {
+			if (ie && ie[1] >= 3) {
+				u8 cw = ie[2] & VHT_OPMODE_CHANNEL_WIDTH_MASK;
+				u8 seg0 = ie[3];
+				u8 seg1 = ie[4];
+
+				if (cw)
+					vht80 = true;
+				if (cw == 2 ||
+				    (cw == 3 &&
+				     (seg1 > 0 && abs(seg1 - seg0) == 16)))
+					vht160 = true;
+				if (cw == 1 &&
+				    ((seg1 > 0 && abs(seg1 - seg0) == 8) ||
+				     (seg1 > 0 && abs(seg1 - seg0) == 16)))
+					vht160 = true;
+			}
+
+			if (vht80) {
 				tmp = max_vht80_rate(snr) + 1;
 				if (tmp > est)
 					est = tmp;
 			}
+
+			if (vht160 &&
+			    (hw_mode->vht_capab &
+			     (VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
+			      VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))) {
+				tmp = max_vht160_rate(snr) + 1;
+				if (tmp > est)
+					est = tmp;
+			}
+		}
+	}
+
+	if (hw_mode && hw_mode->he_capab[IEEE80211_MODE_INFRA].he_supported) {
+		/* Use +2 to assume HE is always faster than HT/VHT */
+		struct ieee80211_he_capabilities *he;
+		struct he_capabilities *own_he;
+		u8 cw;
+
+		ie = get_ie_ext(ies, ies_len, WLAN_EID_EXT_HE_CAPABILITIES);
+		if (!ie || (ie[1] < 1 + IEEE80211_HE_CAPAB_MIN_LEN))
+			return est;
+		he = (struct ieee80211_he_capabilities *) &ie[3];
+		own_he = &hw_mode->he_capab[IEEE80211_MODE_INFRA];
+
+		tmp = max_he_rate(he20_table, snr) + 2;
+		if (tmp > est)
+			est = tmp;
+
+		cw = he->he_phy_capab_info[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
+			own_he->phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX];
+		if (cw &
+		    (IS_2P4GHZ(freq) ? HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_IN_2G :
+		     HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G)) {
+			tmp = max_he_rate(he40_table, snr) + 2;
+			if (tmp > est)
+				est = tmp;
+		}
+
+		if (!IS_2P4GHZ(freq) &&
+		    (cw & HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G)) {
+			tmp = max_he_rate(he80_table, snr) + 2;
+			if (tmp > est)
+				est = tmp;
+		}
+
+		if (!IS_2P4GHZ(freq) &&
+		    (cw & (HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
+			   HE_PHYCAP_CHANNEL_WIDTH_SET_80PLUS80MHZ_IN_5G))) {
+			tmp = max_he_rate(he160_table, snr) + 2;
+			if (tmp > est)
+				est = tmp;
 		}
 	}
 
@@ -2418,7 +2699,7 @@
 	if (!ie_len)
 		ie_len = res->beacon_ie_len;
 	res->est_throughput =
-		wpas_get_est_tpt(wpa_s, ies, ie_len, rate, snr);
+		wpas_get_est_tpt(wpa_s, ies, ie_len, rate, snr, res->freq);
 
 	/* TODO: channel utilization and AP load (e.g., from AP Beacon) */
 }
@@ -2639,6 +2920,8 @@
 	params->relative_rssi = src->relative_rssi;
 	params->relative_adjust_band = src->relative_adjust_band;
 	params->relative_adjust_rssi = src->relative_adjust_rssi;
+	params->p2p_include_6ghz = src->p2p_include_6ghz;
+	params->non_coloc_6ghz = src->non_coloc_6ghz;
 	return params;
 
 failed:
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/scan.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/scan.h
index c9ce2ce..15d691f 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/scan.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/scan.h
@@ -16,6 +16,7 @@
  */
 #define DEFAULT_NOISE_FLOOR_2GHZ (-89)
 #define DEFAULT_NOISE_FLOOR_5GHZ (-92)
+#define DEFAULT_NOISE_FLOOR_6GHZ (-92)
 
 /*
  * Channels with a great SNR can operate at full rate. What is a great SNR?
@@ -29,7 +30,10 @@
  */
 #define GREAT_SNR 25
 
-#define IS_5GHZ(n) (n > 4000)
+#define IS_2P4GHZ(n) (n >= 2412 && n <= 2484)
+#ifndef IS_5GHZ
+#define IS_5GHZ(n) (n > 4000 && n < 5895)
+#endif
 
 int wpa_supplicant_enabled_networks(struct wpa_supplicant *wpa_s);
 void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec);
@@ -84,7 +88,11 @@
 			 struct wpa_scan_res *res);
 unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
 			      const u8 *ies, size_t ies_len, int rate,
-			      int snr);
+			      int snr, int freq);
 void wpa_supplicant_set_default_scan_ies(struct wpa_supplicant *wpa_s);
+int wpa_add_scan_freqs_list(struct wpa_supplicant *wpa_s,
+			    enum hostapd_hw_mode band,
+			    struct wpa_driver_scan_params *params,
+			    bool is_6ghz);
 
 #endif /* SCAN_H */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/sme.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/sme.c
index d926b77..bff92d5 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/sme.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/sme.c
@@ -13,7 +13,6 @@
 #include "common/ieee802_11_defs.h"
 #include "common/ieee802_11_common.h"
 #include "common/ocv.h"
-#include "common/hw_features_common.h"
 #include "eapol_supp/eapol_supp_sm.h"
 #include "common/wpa_common.h"
 #include "common/sae.h"
@@ -138,6 +137,12 @@
 	}
 
 	bss = wpa_bss_get_bssid_latest(wpa_s, bssid);
+	if (!bss) {
+		wpa_printf(MSG_DEBUG,
+			   "SAE: BSS not available, update scan result to get BSS");
+		wpa_supplicant_update_scan_results(wpa_s);
+		bss = wpa_bss_get_bssid_latest(wpa_s, bssid);
+	}
 	if (bss) {
 		const u8 *rsnxe;
 
@@ -187,7 +192,6 @@
 	if (!use_pt &&
 	    sae_prepare_commit(wpa_s->own_addr, bssid,
 			       (u8 *) password, os_strlen(password),
-			       ssid->sae_password_id,
 			       &wpa_s->sme.sae) < 0) {
 		wpa_printf(MSG_DEBUG, "SAE: Could not pick PWE");
 		return NULL;
@@ -942,6 +946,11 @@
 	struct wpa_connect_work *cwork = work->ctx;
 	struct wpa_supplicant *wpa_s = work->wpa_s;
 
+	wpa_s->roam_in_progress = false;
+#ifdef CONFIG_WNM
+	wpa_s->bss_trans_mgmt_in_progress = false;
+#endif /* CONFIG_WNM */
+
 	if (deinit) {
 		if (work->started)
 			wpa_s->connect_work = NULL;
@@ -982,6 +991,18 @@
 		return;
 	}
 
+	if (wpa_s->roam_in_progress) {
+		wpa_dbg(wpa_s, MSG_DEBUG,
+			"SME: Reject sme_authenticate() in favor of explicit roam request");
+		return;
+	}
+#ifdef CONFIG_WNM
+	if (wpa_s->bss_trans_mgmt_in_progress) {
+		wpa_dbg(wpa_s, MSG_DEBUG,
+			"SME: Reject sme_authenticate() in favor of BSS transition management request");
+		return;
+	}
+#endif /* CONFIG_WNM */
 	if (radio_work_pending(wpa_s, "sme-connect")) {
 		/*
 		 * The previous sme-connect work might no longer be valid due to
@@ -1341,8 +1362,15 @@
 
 	if (status_code != WLAN_STATUS_SUCCESS &&
 	    status_code != WLAN_STATUS_SAE_HASH_TO_ELEMENT &&
-	    status_code != WLAN_STATUS_SAE_PK)
+	    status_code != WLAN_STATUS_SAE_PK) {
+		const u8 *bssid = sa ? sa : wpa_s->pending_bssid;
+
+		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_AUTH_REJECT MACSTR
+			" auth_type=%u auth_transaction=%u status_code=%u",
+			MAC2STR(bssid), WLAN_AUTH_SAE,
+			auth_transaction, status_code);
 		return -1;
+	}
 
 	if (auth_transaction == 1) {
 		u16 res;
@@ -1543,7 +1571,7 @@
 		int res;
 		res = sme_sae_auth(wpa_s, data->auth.auth_transaction,
 				   data->auth.status_code, data->auth.ies,
-				   data->auth.ies_len, 0, NULL);
+				   data->auth.ies_len, 0, data->auth.peer);
 		if (res < 0) {
 			wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
 			wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
@@ -1888,13 +1916,11 @@
 #endif /* CONFIG_DPP2 */
 
 	wpa_s->mscs_setup_done = false;
-	if (wpa_s->current_bss && wpa_s->robust_av.valid_config) {
+	if (wpa_bss_ext_capab(wpa_s->current_bss, WLAN_EXT_CAPAB_MSCS) &&
+	    wpa_s->robust_av.valid_config) {
 		struct wpabuf *mscs_ie;
 		size_t mscs_ie_len, buf_len, *wpa_ie_len, max_ie_len;
 
-		if (!wpa_bss_ext_capab(wpa_s->current_bss, WLAN_EXT_CAPAB_MSCS))
-			goto mscs_fail;
-
 		buf_len = 3 +	/* MSCS descriptor IE header */
 			  1 +	/* Request type */
 			  2 +	/* User priority control */
@@ -2371,14 +2397,13 @@
 }
 
 
-int sme_proc_obss_scan(struct wpa_supplicant *wpa_s,
-		       struct wpa_scan_results *scan_res)
+int sme_proc_obss_scan(struct wpa_supplicant *wpa_s)
 {
+	struct wpa_bss *bss;
 	const u8 *ie;
+	u16 ht_cap;
 	u8 chan_list[P2P_MAX_CHANNELS], channel;
 	u8 num_channels = 0, num_intol = 0, i;
-	size_t j;
-	int pri_freq, sec_freq;
 
 	if (!wpa_s->sme.sched_obss_scan)
 		return 0;
@@ -2406,36 +2431,22 @@
 
 	os_memset(chan_list, 0, sizeof(chan_list));
 
-	pri_freq = wpa_s->assoc_freq;
-
-	switch (wpa_s->sme.ht_sec_chan) {
-	case HT_SEC_CHAN_ABOVE:
-		sec_freq = pri_freq + 20;
-		break;
-	case HT_SEC_CHAN_BELOW:
-		sec_freq = pri_freq - 20;
-		break;
-	case HT_SEC_CHAN_UNKNOWN:
-	default:
-		wpa_msg(wpa_s, MSG_WARNING,
-			"Undefined secondary channel: drop OBSS scan results");
-		return 1;
-	}
-
-	for (j = 0; j < scan_res->num; j++) {
-		struct wpa_scan_res *bss = scan_res->res[j];
-		enum hostapd_hw_mode mode;
-		int res;
-
+	dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
 		/* Skip other band bss */
+		enum hostapd_hw_mode mode;
 		mode = ieee80211_freq_to_chan(bss->freq, &channel);
 		if (mode != HOSTAPD_MODE_IEEE80211G &&
 		    mode != HOSTAPD_MODE_IEEE80211B)
 			continue;
 
-		res = check_bss_coex_40mhz(bss, pri_freq, sec_freq);
-		if (res) {
-			if (res == 2)
+		ie = wpa_bss_get_ie(bss, WLAN_EID_HT_CAP);
+		ht_cap = (ie && (ie[1] == 26)) ? WPA_GET_LE16(ie + 2) : 0;
+		wpa_printf(MSG_DEBUG, "SME OBSS scan BSS " MACSTR
+			   " freq=%u chan=%u ht_cap=0x%x",
+			   MAC2STR(bss->bssid), bss->freq, channel, ht_cap);
+
+		if (!ht_cap || (ht_cap & HT_CAP_INFO_40MHZ_INTOLERANT)) {
+			if (ht_cap & HT_CAP_INFO_40MHZ_INTOLERANT)
 				num_intol++;
 
 			/* Check whether the channel is already considered */
@@ -2464,7 +2475,7 @@
 	int start, end;
 
 	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
-			HOSTAPD_MODE_IEEE80211G, 0);
+			HOSTAPD_MODE_IEEE80211G, false);
 	if (mode == NULL) {
 		/* No channels supported in this band - use empty list */
 		params->freqs = os_zalloc(sizeof(int));
@@ -2574,6 +2585,12 @@
 	    ssid == NULL || ssid->mode != WPAS_MODE_INFRA)
 		return;
 
+#ifdef CONFIG_HT_OVERRIDES
+	/* No need for OBSS scan if HT40 is explicitly disabled */
+	if (ssid->disable_ht40)
+		return;
+#endif /* CONFIG_HT_OVERRIDES */
+
 	if (!wpa_s->hw.modes)
 		return;
 
@@ -2887,11 +2904,17 @@
 }
 
 
-void sme_sa_query_rx(struct wpa_supplicant *wpa_s, const u8 *sa,
+void sme_sa_query_rx(struct wpa_supplicant *wpa_s, const u8 *da, const u8 *sa,
 		     const u8 *data, size_t len)
 {
 	if (len < 1 + WLAN_SA_QUERY_TR_ID_LEN)
 		return;
+	if (is_multicast_ether_addr(da)) {
+		wpa_printf(MSG_DEBUG,
+			   "IEEE 802.11: Ignore group-addressed SA Query frame (A1=" MACSTR " A2=" MACSTR ")",
+			   MAC2STR(da), MAC2STR(sa));
+		return;
+	}
 
 	wpa_dbg(wpa_s, MSG_DEBUG, "SME: Received SA Query frame from "
 		MACSTR " (trans_id %02x%02x)", MAC2STR(sa), data[1], data[2]);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/sme.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/sme.h
index 42d5a83..c797d2e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/sme.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/sme.h
@@ -29,7 +29,7 @@
 void sme_event_unprot_disconnect(struct wpa_supplicant *wpa_s, const u8 *sa,
 				 const u8 *da, u16 reason_code);
 void sme_event_ch_switch(struct wpa_supplicant *wpa_s);
-void sme_sa_query_rx(struct wpa_supplicant *wpa_s, const u8 *sa,
+void sme_sa_query_rx(struct wpa_supplicant *wpa_s, const u8 *da, const u8 *sa,
 		     const u8 *data, size_t len);
 void sme_state_changed(struct wpa_supplicant *wpa_s);
 void sme_disassoc_while_authenticating(struct wpa_supplicant *wpa_s,
@@ -37,8 +37,7 @@
 void sme_clear_on_disassoc(struct wpa_supplicant *wpa_s);
 void sme_deinit(struct wpa_supplicant *wpa_s);
 
-int sme_proc_obss_scan(struct wpa_supplicant *wpa_s,
-		       struct wpa_scan_results *scan_res);
+int sme_proc_obss_scan(struct wpa_supplicant *wpa_s);
 void sme_sched_obss_scan(struct wpa_supplicant *wpa_s, int enable);
 void sme_external_auth_trigger(struct wpa_supplicant *wpa_s,
 			       union wpa_event_data *data);
@@ -113,8 +112,7 @@
 {
 }
 
-static inline int sme_proc_obss_scan(struct wpa_supplicant *wpa_s,
-				     struct wpa_scan_results *scan_res)
+static inline int sme_proc_obss_scan(struct wpa_supplicant *wpa_s)
 {
 	return 0;
 }
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/systemd/wpa_supplicant.service.in b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/systemd/wpa_supplicant.service.in
index 75a37a8..58a6228 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/systemd/wpa_supplicant.service.in
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/systemd/wpa_supplicant.service.in
@@ -1,6 +1,7 @@
 [Unit]
 Description=WPA supplicant
 Before=network.target
+After=dbus.service
 Wants=network.target
 
 [Service]
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/twt.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/twt.c
new file mode 100755
index 0000000..6d1cf9a
--- /dev/null
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/twt.c
@@ -0,0 +1,419 @@
+/*
+ * wpa_supplicant - TWT
+ * Copyright (c) 2003-2016, Jouni Malinen <j@w1.fi>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "includes.h"
+
+#include "utils/common.h"
+#include "config.h"
+#include "wpa_supplicant_i.h"
+#include "driver_i.h"
+#include "scan.h"
+
+#ifdef CONFIG_TWT_OFFLOAD_IFX
+#define TWT_NONE 0
+#define TWT_IDLE 1
+#define TWT_ACTIVE 2
+#define TWT_TEARDOWN_ALL 128
+
+/**
+ * wpas_twt_offload_send_setup - Send TWT Setup frame to our AP
+ * @wpa_s: Pointer to wpa_supplicant
+ * @dtok: Dialog token
+ * @exponent: Wake-interval exponent
+ * @mantissa: Wake-interval mantissa
+ * @min_twt: Minimum TWT wake duration in units of 256 usec
+ * @setup_cmd: 0 == request, 1 == suggest, etc.  Table 9-297
+ * @twt: Target Wake Time
+ * @twt_offset: Target Wake Time TSF offset
+ * @requestor: Specify this is a TWT Requesting / Responding STA
+ * @trigger: Specify Trigger based / Non-Trigger based TWT Session
+ * @implicit: Specify Implicit / Explicit TWT session
+ * @flow_type: Specify Un-Announced / Announced TWT session
+ * @flow_id: Flow ID / Broacast TWT ID to be used in the TWT session
+ * @protection: Specifies whether Tx within SP is protected by RTS & CTS
+ * @twt_channel: Set by the HE SST non-AP STA
+ * @control: Control Field in the TWT Setup Action frame
+ * Returns: 0 in case of success, negative error code otherwise
+ *
+ */
+int wpas_twt_offload_send_setup(struct wpa_supplicant *wpa_s, u8 dtok, int exponent,
+				int mantissa, u8 min_twt, int setup_cmd, u64 twt,
+				u64 twt_offset, bool requestor, bool trigger,
+				bool implicit, bool flow_type, u8 flow_id,
+				bool protection, u8 twt_channel, u8 control)
+{
+	int ret = 0;
+	struct drv_setup_twt_params params;
+	u8 negotiation_type, twt_info_frame_disabled, min_twt_unit;
+
+	params.dtok = dtok;
+	params.min_twt = min_twt;
+	params.twt = twt;
+	params.twt_offset = twt_offset;
+	params.requestor = requestor ? 1 : 0;
+	params.trigger = trigger ? 1 : 0;
+	params.implicit = implicit ? 1 : 0;
+	params.flow_type = flow_type ? 1 : 0;
+	params.protection = protection ? 1 : 0;
+	params.twt_channel = twt_channel;
+	params.flow_id = 0xFF;
+	params.bcast_twt_id = 0xFF;
+
+	/* exponent range - 0 to 31 */
+	if (exponent >= 0 && exponent <= 0x1F) {
+		params.exponent = (u8)exponent;
+	} else {
+		wpa_printf(MSG_ERROR,
+				"TWT offload: setup cmd exponent %d not supported",
+				exponent);
+		ret = -EOPNOTSUPP;
+		goto fail;
+	}
+
+	/* mantissa range - 1 to 65535 */
+	if (mantissa > 0 && mantissa <= 0xFFFF) {
+		params.mantissa = (u16)mantissa;
+	} else {
+		wpa_printf(MSG_ERROR,
+				"TWT offload: setup cmd mantissa %d not supported",
+				mantissa);
+		ret = -EOPNOTSUPP;
+		goto fail;
+	}
+
+	/* Setup Command Field - IEEE 802.11ax-2021 Table 9-297 */
+	switch(setup_cmd) {
+		case 0: params.setup_cmd = IFX_TWT_OPER_SETUP_CMD_TYPE_REQUEST;
+			break;
+		case 1: params.setup_cmd = IFX_TWT_OPER_SETUP_CMD_TYPE_SUGGEST;
+			break;
+		case 2: params.setup_cmd = IFX_TWT_OPER_SETUP_CMD_TYPE_DEMAND;
+			break;
+		case 3: params.setup_cmd = IFX_TWT_OPER_SETUP_CMD_TYPE_GROUPING;
+			break;
+		case 4: params.setup_cmd = IFX_TWT_OPER_SETUP_CMD_TYPE_ACCEPT;
+			break;
+		case 5: params.setup_cmd = IFX_TWT_OPER_SETUP_CMD_TYPE_ALTERNATE;
+			break;
+		case 6: params.setup_cmd = IFX_TWT_OPER_SETUP_CMD_TYPE_DICTATE;
+			break;
+		case 7: params.setup_cmd = IFX_TWT_OPER_SETUP_CMD_TYPE_REJECT;
+			break;
+		default:
+			wpa_printf(MSG_ERROR,
+				   "TWT offload: specified Setup cmd type not supported");
+			ret = -EOPNOTSUPP;
+			goto fail;
+	}
+
+	/* Control Field - IEEE 802.11ax-2021 Figure 9-687 */
+	params.control = control;
+							/* NDP Paging Indicator : Bit 0		 */
+							/* Responder PM Mode : Bit 1		 */
+	negotiation_type = (control & 0xc) >> 2;	/* Negotiation type : Bit 2-3		 */
+	twt_info_frame_disabled = (control & 0x10) >> 4;/* TWT Information Frame Disabled: Bit 4 */
+	min_twt_unit = (control & 0x20) >> 5;		/* Wake Duration Unit : Bit 5		 */
+							/* Reserved : Bit 6-7			 */
+
+	/* Negotiation Type Field - IEEE 802.11ax-2021 Table 9.296a */
+	switch(negotiation_type) {
+		case 0:	/* Individual TWT */
+			params.negotiation_type = IFX_TWT_PARAM_NEGO_TYPE_ITWT;
+			params.flow_id = flow_id;
+			break;
+		case 1: /* Wake TBTT Negotiation */
+			params.negotiation_type = IFX_TWT_PARAM_NEGO_TYPE_WAKE_TBTT;
+			break;
+		case 2: /* Broadcast TWT IE in Beacon */
+			params.negotiation_type = IFX_TWT_PARAM_NEGO_TYPE_BTWT_IE_BCN;
+			break;
+		case 3: /* Broadcast TWT membership */
+			params.negotiation_type = IFX_TWT_PARAM_NEGO_TYPE_BTWT;
+			params.bcast_twt_id = flow_id;
+			break;
+		default:
+			wpa_printf(MSG_ERROR,
+				   "TWT offload: specified Nego type not supported");
+			ret = -EOPNOTSUPP;
+			goto fail;
+	}
+
+	params.twt_info_frame_disabled = twt_info_frame_disabled;
+	params.min_twt_unit = min_twt_unit;		/* 1 - in TUs, 0 - in 256us */
+
+	if (wpa_drv_setup_twt(wpa_s, &params)) {
+		wpa_printf(MSG_ERROR, "TWT offload: Failed to send TWT Setup Request");
+		ret = -ECANCELED;
+		goto fail;
+	}
+
+fail:
+	return ret;
+}
+
+/**
+ * wpas_twt_offload_send_teardown - send TWT teardown request to our AP
+ * @wpa_s: pointer to wpa_supplicant
+ * @flags: the byte that goes inside the twt teardown element
+ * returns: 0 in case of success, negative error code otherwise
+ *
+ */
+int wpas_twt_offload_send_teardown(struct wpa_supplicant *wpa_s, u8 flags)
+{
+	int ret = 0;
+	struct drv_teardown_twt_params params;
+	u8 negotiation_type, flow_id, teardown_all_twt;
+
+	/* TWT Flow Field - IEEE 802.11ax-2021 Figure 9-965 */
+	flow_id = flags & 0x07;			/* Flow ID : Bit 0-2		*/
+						/* Reserved : Bit 3-4		*/
+	negotiation_type = (flags & 0x60) >> 5;	/* Negotiation type : Bit 5-6	*/
+	teardown_all_twt = (flags & 0x80) >> 7;	/* Teardown all TWT : Bit 7	*/
+
+	/* Negotiation Type Field - IEEE 802.11ax-2021 Table 9.296a */
+	switch(negotiation_type) {
+		case 0:	/* Individual TWT */
+			params.negotiation_type = IFX_TWT_PARAM_NEGO_TYPE_ITWT;
+			params.flow_id = flow_id;
+			break;
+		case 1: /* Wake TBTT Negotiation */
+			params.negotiation_type = IFX_TWT_PARAM_NEGO_TYPE_WAKE_TBTT;
+			break;
+		case 2: /* Broadcast TWT IE in Beacon */
+			params.negotiation_type = IFX_TWT_PARAM_NEGO_TYPE_BTWT_IE_BCN;
+			break;
+		case 3: /* Broadcast TWT membership */
+			params.negotiation_type = IFX_TWT_PARAM_NEGO_TYPE_BTWT;
+			params.bcast_twt_id = flow_id;
+			break;
+		default:
+			wpa_printf(MSG_ERROR,
+				   "TWT offload: specified Nego Type Not supported");
+			ret = -EOPNOTSUPP;
+			goto fail;
+	}
+
+	params.teardown_all_twt = teardown_all_twt;
+
+	if (wpa_drv_teardown_twt(wpa_s, &params)) {
+		wpa_printf(MSG_ERROR, "TWT offload: Failed to send TWT Teardown frame");
+		ret = -ECANCELED;
+		goto fail;
+	}
+
+fail:
+	return ret;
+}
+
+int wpas_twt_offload_init_default_session(struct wpa_supplicant *wpa_s)
+{
+	int exponent = 10, mantissa = 8192, setup_cmd = 2, flow_id = 0xFF, ret = 0;
+	unsigned long long twt = 0, twt_offset = 0;
+	bool requestor = true, trigger = true, implicit = true, flow_type = true,
+	     protection = false;
+	u8 dtok = 1, min_twt = 255, twt_channel = 0,
+	   control = BIT(4); /* Control field (IEEE P802.11ax/D8.0 Figure
+                              * 9-687): B4 = TWT Information Frame Disabled */
+
+	if (wpa_s->conf->twt_def_algo == TWT_NONE) {
+		wpa_printf(MSG_DEBUG, "TWT offload: Default TWT is disabled");
+		ret = 0;
+		goto exit;
+	}
+
+	wpa_printf(MSG_DEBUG, "TWT offload: Init Default TWT, profile %d, freq %d",
+		   wpa_s->conf->twt_def_algo, wpa_s->assoc_freq);
+
+	if (wpa_s->conf->twt_def_algo == TWT_IDLE) {
+		/* TWT profile for Idle traffic */
+		if (IS_2P4GHZ(wpa_s->assoc_freq)) {
+			/*
+			 * 2G Band
+			 * SP=2ms and SI=614.4ms
+			 */
+			min_twt = 8;
+			mantissa = 600;
+			exponent = 10;
+		} else { /*
+			  * 5G or 6G Band
+			  * SP=512us and SI=614.4ms
+			  */
+			min_twt = 2;
+			mantissa = 600;
+			exponent = 10;
+		}
+	} else if (wpa_s->conf->twt_def_algo == TWT_ACTIVE) {
+		/*
+		 * TWT profile for Active traffic
+		 * 2G, 5G and 6G Bands
+		 * SP=8ms and SI=50ms
+		 */
+		min_twt = 31;
+		mantissa = 50000;
+		exponent = 0;
+	} else {
+		wpa_printf(MSG_ERROR, "TWT offload: Invalid Default TWT profile");
+		ret = -1;
+		goto exit;
+	}
+
+	ret = wpas_twt_offload_send_setup(wpa_s, dtok, exponent, mantissa,
+					  min_twt, setup_cmd, twt, twt_offset,
+					  requestor, trigger, implicit, flow_type,
+					  flow_id, protection, twt_channel,
+					  control);
+exit:
+	return ret;
+}
+
+int wpas_twt_offload_deinit_default_session(struct wpa_supplicant *wpa_s)
+{
+	int flags = TWT_TEARDOWN_ALL, ret = 0;
+
+	if (wpa_s->conf->twt_def_algo == TWT_NONE) {
+		ret = 0;
+		goto exit;
+	}
+
+	/* Clear all TWT sessions created by STA including default */
+	wpa_printf(MSG_DEBUG,
+		   "TWT offload: De-init Default TWT, profile %d, freq %d",
+		   wpa_s->conf->twt_def_algo, wpa_s->assoc_freq);
+
+	ret = wpas_twt_offload_send_teardown(wpa_s, flags);
+exit:
+	return ret;
+}
+
+#else
+
+/**
+ * wpas_twt_send_setup - Send TWT Setup frame (Request) to our AP
+ * @wpa_s: Pointer to wpa_supplicant
+ * @dtok: Dialog token
+ * @exponent: Wake-interval exponent
+ * @mantissa: Wake-interval mantissa
+ * @min_twt: Minimum TWT wake duration in units of 256 usec
+ * @setup_cmd: 0 == request, 1 == suggest, etc.  Table 9-297
+ * Returns: 0 in case of success, negative error code otherwise
+ *
+ */
+int wpas_twt_send_setup(struct wpa_supplicant *wpa_s, u8 dtok, int exponent,
+			int mantissa, u8 min_twt, int setup_cmd, u64 twt,
+			bool requestor, bool trigger, bool implicit,
+			bool flow_type, u8 flow_id, bool protection,
+			u8 twt_channel, u8 control)
+{
+	struct wpabuf *buf;
+	u16 req_type = 0;
+	int ret = 0;
+
+	if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid) {
+		wpa_printf(MSG_DEBUG,
+			   "TWT: No connection - cannot send TWT Setup frame");
+		return -ENOTCONN;
+	}
+
+	/* 3 = Action category + Action code + Dialog token */
+	/* 17 = TWT element */
+	buf = wpabuf_alloc(3 + 17);
+	if (!buf) {
+		wpa_printf(MSG_DEBUG,
+			   "TWT: Failed to allocate TWT Setup frame (Request)");
+		return -ENOMEM;
+	}
+
+	wpa_printf(MSG_DEBUG,
+		   "TWT: Setup request, dtok: %d  exponent: %d  mantissa: %d  min-twt: %d",
+		   dtok, exponent, mantissa, min_twt);
+
+	wpabuf_put_u8(buf, WLAN_ACTION_S1G);
+	wpabuf_put_u8(buf, S1G_ACT_TWT_SETUP);
+	wpabuf_put_u8(buf, dtok);
+
+	wpabuf_put_u8(buf, WLAN_EID_TWT);
+	wpabuf_put_u8(buf, 15); /* len */
+
+	wpabuf_put_u8(buf, control);
+
+	if (requestor)
+		req_type |= BIT(0); /* This STA is a TWT Requesting STA */
+	/* TWT Setup Command field */
+	req_type |= (setup_cmd & 0x7) << 1;
+	if (trigger)
+		req_type |= BIT(4); /* TWT SP includes trigger frames */
+	if (implicit)
+		req_type |= BIT(5); /* Implicit TWT */
+	if (flow_type)
+		req_type |= BIT(6); /* Flow Type: Unannounced TWT */
+	req_type |= (flow_id & 0x7) << 7;
+	req_type |= (exponent & 0x1f) << 10; /* TWT Wake Interval Exponent */
+	if (protection)
+		req_type |= BIT(15);
+	wpabuf_put_le16(buf, req_type);
+	wpabuf_put_le64(buf, twt);
+	wpabuf_put_u8(buf, min_twt); /* Nominal Minimum TWT Wake Duration */
+	wpabuf_put_le16(buf, mantissa); /* TWT Wake Interval Mantissa */
+	wpabuf_put_u8(buf, twt_channel); /* TWT Channel */
+
+	if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
+				wpa_s->own_addr, wpa_s->bssid,
+				wpabuf_head(buf), wpabuf_len(buf), 0) < 0) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to send TWT Setup Request");
+		ret = -ECANCELED;
+	}
+
+	wpabuf_free(buf);
+	return ret;
+}
+
+
+/**
+ * wpas_twt_send_teardown - Send TWT teardown request to our AP
+ * @wpa_s: Pointer to wpa_supplicant
+ * @flags: The byte that goes inside the TWT Teardown element
+ * Returns: 0 in case of success, negative error code otherwise
+ *
+ */
+int wpas_twt_send_teardown(struct wpa_supplicant *wpa_s, u8 flags)
+{
+	struct wpabuf *buf;
+	int ret = 0;
+
+	if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid) {
+		wpa_printf(MSG_DEBUG,
+			   "TWT: No connection - cannot send TWT Teardown frame");
+		return -ENOTCONN;
+	}
+
+	/* 3 = Action category + Action code + flags */
+	buf = wpabuf_alloc(3);
+	if (!buf) {
+		wpa_printf(MSG_DEBUG,
+			   "TWT: Failed to allocate TWT Teardown frame");
+		return -ENOMEM;
+	}
+
+	wpa_printf(MSG_DEBUG, "TWT: Teardown request, flags: 0x%x", flags);
+
+	wpabuf_put_u8(buf, WLAN_ACTION_S1G);
+	wpabuf_put_u8(buf, S1G_ACT_TWT_TEARDOWN);
+	wpabuf_put_u8(buf, flags);
+
+	if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
+				wpa_s->own_addr, wpa_s->bssid,
+				wpabuf_head(buf), wpabuf_len(buf), 0) < 0) {
+		wpa_printf(MSG_DEBUG, "TWT: Failed to send TWT Teardown frame");
+		ret = -ECANCELED;
+	}
+
+	wpabuf_free(buf);
+	return ret;
+}
+
+#endif /* CONFIG_TWT_OFFLOAD_IFX */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/vs2005/eapol_test/eapol_test.vcproj b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/vs2005/eapol_test/eapol_test.vcproj
index af7b3fe..c92b8fd 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/vs2005/eapol_test/eapol_test.vcproj
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/vs2005/eapol_test/eapol_test.vcproj
@@ -215,7 +215,7 @@
 				>

 			</File>

 			<File

-				RelativePath="..\..\blacklist.c"

+				RelativePath="..\..\bssid_ignore.c"

 				>

 			</File>

 			<File

@@ -231,6 +231,10 @@
 				>

 			</File>

 			<File

+				RelativePath="..\..\..\src\utils\config.c"

+				>

+			</File>

+			<File

 				RelativePath="..\..\config.c"

 				>

 			</File>

diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/vs2005/wpa_supplicant/wpa_supplicant.vcproj b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/vs2005/wpa_supplicant/wpa_supplicant.vcproj
index 51acab9..10c05b5 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/vs2005/wpa_supplicant/wpa_supplicant.vcproj
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/vs2005/wpa_supplicant/wpa_supplicant.vcproj
@@ -215,7 +215,7 @@
 				>

 			</File>

 			<File

-				RelativePath="..\..\blacklist.c"

+				RelativePath="..\..\bssid_ignore.c"

 				>

 			</File>

 			<File

@@ -231,6 +231,10 @@
 				>

 			</File>

 			<File

+				RelativePath="..\..\..\src\utils\config.c"

+				>

+			</File>

+			<File

 				RelativePath="..\..\config.c"

 				>

 			</File>

diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/vs2005/wpasvc/wpasvc.vcproj b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/vs2005/wpasvc/wpasvc.vcproj
index 6fd8af8..82d9033 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/vs2005/wpasvc/wpasvc.vcproj
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/vs2005/wpasvc/wpasvc.vcproj
@@ -215,7 +215,7 @@
 				>

 			</File>

 			<File

-				RelativePath="..\..\blacklist.c"

+				RelativePath="..\..\bssid_ignore.c"

 				>

 			</File>

 			<File

@@ -231,6 +231,10 @@
 				>

 			</File>

 			<File

+				RelativePath="..\..\..\src\utils\config.c"

+				>

+			</File>

+			<File

 				RelativePath="..\..\config.c"

 				>

 			</File>

diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wnm_sta.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wnm_sta.c
index 19f1eca..96160dc 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wnm_sta.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wnm_sta.c
@@ -552,7 +552,7 @@
 			freq = 2407 + chan * 5;
 		else if (chan == 14)
 			freq = 2484;
-		else if (chan >= 36 && chan <= 169)
+		else if (chan >= 36 && chan <= 177)
 			freq = 5000 + chan * 5;
 	}
 	return freq;
@@ -1097,6 +1097,8 @@
 			       struct wpa_bss *bss, struct wpa_ssid *ssid,
 			       int after_new_scan)
 {
+	struct wpa_radio_work *already_connecting;
+
 	wpa_dbg(wpa_s, MSG_DEBUG,
 		"WNM: Transition to BSS " MACSTR
 		" based on BSS Transition Management Request (old BSSID "
@@ -1121,9 +1123,18 @@
 		return;
 	}
 
+	already_connecting = radio_work_pending(wpa_s, "sme-connect");
 	wpa_s->reassociate = 1;
 	wpa_printf(MSG_DEBUG, "WNM: Issuing connect");
 	wpa_supplicant_connect(wpa_s, bss, ssid);
+
+	/*
+	 * Indicate that a BSS transition is in progress so scan results that
+	 * come in before the 'sme-connect' radio work gets executed do not
+	 * override the original connection attempt.
+	 */
+	if (!already_connecting && radio_work_pending(wpa_s, "sme-connect"))
+		wpa_s->bss_trans_mgmt_in_progress = true;
 	wnm_deallocate_memory(wpa_s);
 }
 
@@ -1343,11 +1354,11 @@
 				continue;
 			bss = wpa_s->current_bss;
 			ssid_ie = wpa_scan_get_ie(res, WLAN_EID_SSID);
-			if (bss && ssid_ie &&
+			if (bss && ssid_ie && ssid_ie[1] &&
 			    (bss->ssid_len != ssid_ie[1] ||
 			     os_memcmp(bss->ssid, ssid_ie + 2,
 				       bss->ssid_len) != 0))
-				continue;
+				continue; /* Skip entries for other ESSs */
 
 			/* Potential candidate found */
 			found = 1;
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpa_cli.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpa_cli.c
index 8f89c78..02c7fa4 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpa_cli.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpa_cli.c
@@ -1,6 +1,6 @@
 /*
  * WPA Supplicant - command line interface for wpa_supplicant daemon
- * Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2022, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -29,7 +29,7 @@
 
 static const char *const wpa_cli_version =
 "wpa_cli v" VERSION_STR "\n"
-"Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi> and contributors";
+"Copyright (c) 2004-2022, Jouni Malinen <j@w1.fi> and contributors";
 
 #define VENDOR_ELEM_FRAME_ID \
 	"  0: Probe Req (P2P), 1: Probe Resp (P2P) , 2: Probe Resp (GO), " \
@@ -500,11 +500,13 @@
 		"p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
 		"sae_groups", "dtim_period", "beacon_int",
 		"ap_vendor_elements", "ignore_old_scan_res", "freq_list",
-		"scan_cur_freq", "sched_scan_interval",
+		"scan_cur_freq", "scan_res_valid_for_connect",
+		"sched_scan_interval",
 		"tdls_external_control", "osu_dir", "wowlan_triggers",
 		"p2p_search_delay", "mac_addr", "rand_addr_lifetime",
 		"preassoc_mac_addr", "key_mgmt_offload", "passive_scan",
 		"reassoc_same_bss_optim", "wps_priority",
+		"ap_assocresp_elements",
 #ifdef CONFIG_TESTING_OPTIONS
 		"ignore_auth_resp",
 #endif /* CONFIG_TESTING_OPTIONS */
@@ -596,7 +598,8 @@
 		"wps_nfc_dev_pw_id", "ext_password_backend",
 		"p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
 		"dtim_period", "beacon_int", "ignore_old_scan_res",
-		"scan_cur_freq", "sched_scan_interval",
+		"scan_cur_freq", "scan_res_valid_for_connect",
+		"sched_scan_interval",
 		"sched_scan_start_delay",
 		"tdls_external_control", "osu_dir", "wowlan_triggers",
 		"p2p_search_delay", "mac_addr", "rand_addr_lifetime",
@@ -1298,9 +1301,10 @@
 }
 
 
-static int wpa_cli_cmd_blacklist(struct wpa_ctrl *ctrl, int argc, char *argv[])
+static int wpa_cli_cmd_bssid_ignore(struct wpa_ctrl *ctrl, int argc,
+				    char *argv[])
 {
-	return wpa_cli_cmd(ctrl, "BLACKLIST", 0, argc, argv);
+	return wpa_cli_cmd(ctrl, "BSSID_IGNORE", 0, argc, argv);
 }
 
 
@@ -1416,8 +1420,8 @@
 
 
 static const char *network_fields[] = {
-	"ssid", "scan_ssid", "bssid", "bssid_blacklist",
-	"bssid_whitelist", "psk", "proto", "key_mgmt",
+	"ssid", "scan_ssid", "bssid", "bssid_ignore",
+	"bssid_accept", "psk", "proto", "key_mgmt",
 	"bg_scan_period", "pairwise", "group", "auth_alg", "scan_freq",
 	"freq_list", "max_oper_chwidth", "ht40", "vht", "vht_center_freq1",
 	"vht_center_freq2", "ht", "edmg",
@@ -1597,6 +1601,7 @@
 	"min_dl_bandwidth_roaming", "min_ul_bandwidth_roaming", "max_bss_load",
 	"req_conn_capab", "ocsp", "sim_num", "realm", "username", "password",
 	"ca_cert", "client_cert", "private_key", "private_key_passwd", "imsi",
+	"ca_cert_id", "cert_id", "key_id", "engine_id", "engine",
 	"milenage", "domain_suffix_match", "domain", "phase1", "phase2",
 	"roaming_consortium", "required_roaming_consortium", "excluded_ssid",
 	"roaming_partner", "provisioning_sp"
@@ -2044,6 +2049,13 @@
 	return wpa_cli_cmd(ctrl, "CHAN_SWITCH", 2, argc, argv);
 }
 
+
+static int wpa_cli_cmd_update_beacon(struct wpa_ctrl *ctrl, int argc,
+				     char *argv[])
+{
+	return wpa_ctrl_command(ctrl, "UPDATE_BEACON");
+}
+
 #endif /* CONFIG_AP */
 
 
@@ -3008,6 +3020,20 @@
 }
 
 
+static int wpa_cli_cmd_twt_setup(struct wpa_ctrl *ctrl, int argc,
+				 char *argv[])
+{
+	return wpa_cli_cmd(ctrl, "TWT_SETUP", 0, argc, argv);
+}
+
+
+static int wpa_cli_cmd_twt_teardown(struct wpa_ctrl *ctrl, int argc,
+				    char *argv[])
+{
+	return wpa_cli_cmd(ctrl, "TWT_TEARDOWN", 0, argc, argv);
+}
+
+
 static int wpa_cli_cmd_erp_flush(struct wpa_ctrl *ctrl, int argc, char *argv[])
 {
 	return wpa_ctrl_command(ctrl, "ERP_FLUSH");
@@ -3151,6 +3177,20 @@
 
 #ifdef CONFIG_DPP2
 
+static int wpa_cli_cmd_dpp_controller_start(struct wpa_ctrl *ctrl, int argc,
+					    char *argv[])
+{
+	return wpa_cli_cmd(ctrl, "DPP_CONTROLLER_START", 1, argc, argv);
+}
+
+
+static int wpa_cli_cmd_dpp_controller_stop(struct wpa_ctrl *ctrl, int argc,
+					    char *argv[])
+{
+	return wpa_ctrl_command(ctrl, "DPP_CONTROLLER_STOP");
+}
+
+
 static int wpa_cli_cmd_dpp_chirp(struct wpa_ctrl *ctrl, int argc,
 				 char *argv[])
 {
@@ -3243,6 +3283,61 @@
 }
 
 
+#ifdef CONFIG_PASN
+
+static int wpa_cli_cmd_pasn_auth_start(struct wpa_ctrl *ctrl, int argc,
+				       char *argv[])
+{
+	return wpa_cli_cmd(ctrl, "PASN_AUTH_START", 4, argc, argv);
+}
+
+
+static int wpa_cli_cmd_pasn_auth_stop(struct wpa_ctrl *ctrl, int argc,
+				      char *argv[])
+{
+	return wpa_cli_cmd(ctrl, "PASN_AUTH_STOP", 0, argc, argv);
+}
+
+static int wpa_cli_cmd_ptksa_cache_list(struct wpa_ctrl *ctrl, int argc,
+					char *argv[])
+{
+	return wpa_cli_cmd(ctrl, "PTKSA_CACHE_LIST", 0, argc, argv);
+}
+
+
+static int wpa_cli_cmd_pasn_deauth(struct wpa_ctrl *ctrl, int argc,
+				   char *argv[])
+{
+	return wpa_cli_cmd(ctrl, "PASN_DEAUTH", 1, argc, argv);
+}
+
+#endif /* CONFIG_PASN */
+
+
+static int wpa_cli_cmd_mscs(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+	return wpa_cli_cmd(ctrl, "MSCS", 1, argc, argv);
+}
+
+
+static int wpa_cli_cmd_scs(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+	return wpa_cli_cmd(ctrl, "SCS", 2, argc, argv);
+}
+
+
+static int wpa_cli_cmd_dscp_resp(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+	return wpa_cli_cmd(ctrl, "DSCP_RESP", 1, argc, argv);
+}
+
+
+static int wpa_cli_cmd_dscp_query(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+	return wpa_cli_cmd(ctrl, "DSCP_QUERY", 1, argc, argv);
+}
+
+
 enum wpa_cli_cmd_flags {
 	cli_cmd_flag_none		= 0x00,
 	cli_cmd_flag_sensitive		= 0x01
@@ -3369,11 +3464,15 @@
 	{ "bssid", wpa_cli_cmd_bssid, wpa_cli_complete_network_id,
 	  cli_cmd_flag_none,
 	  "<network id> <BSSID> = set preferred BSSID for an SSID" },
-	{ "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss,
+	{ "bssid_ignore", wpa_cli_cmd_bssid_ignore, wpa_cli_complete_bss,
 	  cli_cmd_flag_none,
-	  "<BSSID> = add a BSSID to the blacklist\n"
-	  "blacklist clear = clear the blacklist\n"
-	  "blacklist = display the blacklist" },
+	  "<BSSID> = add a BSSID to the list of temporarily ignored BSSs\n"
+	  "bssid_ignore clear = clear the list of temporarily ignored BSSIDs\n"
+	  "bssid_ignore = display the list of temporarily ignored BSSIDs" },
+	{ "blacklist", /* deprecated alias for bssid_ignore */
+	  wpa_cli_cmd_bssid_ignore, wpa_cli_complete_bss,
+	  cli_cmd_flag_none,
+	  "= deprecated alias for bssid_ignore" },
 	{ "log_level", wpa_cli_cmd_log_level, NULL,
 	  cli_cmd_flag_none,
 	  "<level> [<timestamp>] = update the log level/timestamp\n"
@@ -3582,6 +3681,9 @@
 	  "<cs_count> <freq> [sec_channel_offset=] [center_freq1=]"
 	  " [center_freq2=] [bandwidth=] [blocktx] [ht|vht]"
 	  " = CSA parameters" },
+	{ "update_beacon", wpa_cli_cmd_update_beacon, NULL,
+	  cli_cmd_flag_none,
+	  "= update Beacon frame contents"},
 #endif /* CONFIG_AP */
 	{ "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none,
 	  "= notification of suspend/hibernate" },
@@ -3863,6 +3965,14 @@
 	  wpa_cli_cmd_neighbor_rep_request, NULL, cli_cmd_flag_none,
 	  "[ssid=<SSID>] [lci] [civic] = Trigger request to AP for neighboring AP report (with optional given SSID in hex or enclosed in double quotes, default: current SSID; with optional LCI and location civic request)"
 	},
+	{ "twt_setup",
+	  wpa_cli_cmd_twt_setup, NULL, cli_cmd_flag_none,
+	  "[dialog=<token>] [exponent=<exponent>] [mantissa=<mantissa>] [min_twt=<Min TWT>] [setup_cmd=<setup-cmd>] [twt=<u64>] [twt_offset=<u64> ][requestor=0|1] [trigger=0|1] [implicit=0|1] [flow_type=0|1] [flow_id=<3-bit-id>] [protection=0|1] [twt_channel=<twt chanel id>] [control=<control-u8>] = Send TWT Setup frame"
+	},
+	{ "twt_teardown",
+	  wpa_cli_cmd_twt_teardown, NULL, cli_cmd_flag_none,
+	  "[flags=<value>] = Send TWT Teardown frame"
+	},
 	{ "erp_flush", wpa_cli_cmd_erp_flush, NULL, cli_cmd_flag_none,
 	  "= flush ERP keys" },
 	{ "mac_rand_scan",
@@ -3923,6 +4033,12 @@
 	  cli_cmd_flag_none,
 	  "*|<id> = remove DPP pkex information" },
 #ifdef CONFIG_DPP2
+	{ "dpp_controller_start", wpa_cli_cmd_dpp_controller_start, NULL,
+	  cli_cmd_flag_none,
+	  "[tcp_port=<port>] [role=..] = start DPP controller" },
+	{ "dpp_controller_stop", wpa_cli_cmd_dpp_controller_stop, NULL,
+	  cli_cmd_flag_none,
+	  "= stop DPP controller" },
 	{ "dpp_chirp", wpa_cli_cmd_dpp_chirp, NULL,
 	  cli_cmd_flag_none,
 	  "own=<BI ID> iter=<count> = start DPP chirp" },
@@ -3933,6 +4049,32 @@
 #endif /* CONFIG_DPP */
 	{ "all_bss", wpa_cli_cmd_all_bss, NULL, cli_cmd_flag_none,
 	  "= list all BSS entries (scan results)" },
+#ifdef CONFIG_PASN
+	{ "pasn_auth_start", wpa_cli_cmd_pasn_auth_start, NULL,
+	  cli_cmd_flag_none,
+	  "bssid=<BSSID> akmp=<WPA key mgmt> cipher=<WPA cipher> group=<group> nid=<network id> = Start PASN authentication" },
+	{ "pasn_auth_stop", wpa_cli_cmd_pasn_auth_stop, NULL,
+	  cli_cmd_flag_none,
+	  "= Stop PASN authentication" },
+	{ "ptksa_cache_list", wpa_cli_cmd_ptksa_cache_list, NULL,
+	  cli_cmd_flag_none,
+	  "= Get the PTKSA Cache" },
+	{ "pasn_deauth", wpa_cli_cmd_pasn_deauth, NULL,
+	  cli_cmd_flag_none,
+	  "bssid=<BSSID> = Remove PASN PTKSA state" },
+#endif /* CONFIG_PASN */
+	{ "mscs", wpa_cli_cmd_mscs, NULL,
+	  cli_cmd_flag_none,
+	  "<add|remove|change> [up_bitmap=<hex byte>] [up_limit=<integer>] [stream_timeout=<in TUs>] [frame_classifier=<hex bytes>] = Configure MSCS request" },
+	{ "scs", wpa_cli_cmd_scs, NULL,
+	  cli_cmd_flag_none,
+	  "[scs_id=<decimal number>] <add|remove|change> [scs_up=<0-7>] [classifier_type=<4|10>] [classifier params based on classifier type] [tclas_processing=<0|1>] [scs_id=<decimal number>] ... = Send SCS request" },
+	{ "dscp_resp", wpa_cli_cmd_dscp_resp, NULL,
+	  cli_cmd_flag_none,
+	  "<[reset]>/<[solicited] [policy_id=1 status=0...]> [more] = Send DSCP response" },
+	{ "dscp_query", wpa_cli_cmd_dscp_query, NULL,
+	  cli_cmd_flag_none,
+	  "wildcard/domain_name=<string> = Send DSCP Query" },
 	{ NULL, NULL, NULL, cli_cmd_flag_none, NULL }
 };
 
@@ -4255,6 +4397,8 @@
 		wpa_cli_exec(action_file, ifname, pos);
 	} else if (str_starts(pos, WPS_EVENT_ACTIVE)) {
 		wpa_cli_exec(action_file, ifname, pos);
+	} else if (str_starts(pos, WPS_EVENT_OVERLAP)) {
+		wpa_cli_exec(action_file, ifname, pos);
 	} else if (str_starts(pos, WPS_EVENT_PIN_ACTIVE)) {
 		wpa_cli_exec(action_file, ifname, pos);
 	} else if (str_starts(pos, WPS_EVENT_CANCEL)) {
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpa_priv.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpa_priv.c
index c5d7168..5938aa9 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpa_priv.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpa_priv.c
@@ -1172,11 +1172,6 @@
 {
 #ifdef __linux__
 	int s, i;
-	/* When started from pcmcia-cs scripts, wpa_supplicant might start with
-	 * fd 0, 1, and 2 closed. This will cause some issues because many
-	 * places in wpa_supplicant are still printing out to stdout. As a
-	 * workaround, make sure that fd's 0, 1, and 2 are not used for other
-	 * sockets. */
 	for (i = 0; i < 3; i++) {
 		s = open("/dev/null", O_RDWR);
 		if (s > 2) {
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpa_supplicant.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpa_supplicant.c
index 97b27ba..574e6e6 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpa_supplicant.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpa_supplicant.c
@@ -1,6 +1,6 @@
 /*
  * WPA Supplicant
- * Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2022, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -41,9 +41,10 @@
 #include "common/hw_features_common.h"
 #include "common/gas_server.h"
 #include "common/dpp.h"
+#include "common/ptksa_cache.h"
 #include "p2p/p2p.h"
 #include "fst/fst.h"
-#include "blacklist.h"
+#include "bssid_ignore.h"
 #include "wpas_glue.h"
 #include "wps_supplicant.h"
 #include "ibss_rsn.h"
@@ -57,6 +58,14 @@
 #include "autoscan.h"
 #include "bss.h"
 #include "scan.h"
+#if defined(WAPI_ANDROID)
+#include "wapi/wapi_asue_i.h"
+#include "wapi/wapi_interface.h"
+#include "wapi/wapi_config.h"
+#ifdef ANDROID
+#include "keystore_get.h"
+#endif /* ANDROID */
+#endif 
 #include "offchannel.h"
 #ifdef BRCM_OKC
 #include "rsn_supp/wpa_i.h"
@@ -64,6 +73,9 @@
 #include "hs20_supplicant.h"
 #include "wnm_sta.h"
 #include "wpas_kay.h"
+#if defined(WAPI_ANDROID)
+#define KEYSTORE_MESSAGE_SIZE 65535
+#endif 
 #include "mesh.h"
 #ifdef CONFIG_DPP
 #include "dpp_supplicant.h"
@@ -79,7 +91,7 @@
 #define TIE_BREAKER     P2P
 const char *const wpa_supplicant_version =
 "wpa_supplicant v" VERSION_STR "\n"
-"Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi> and contributors";
+"Copyright (c) 2003-2022, Jouni Malinen <j@w1.fi> and contributors";
 
 const char *const wpa_supplicant_license =
 "This software may be distributed under the terms of the BSD license.\n"
@@ -231,7 +243,7 @@
 		bssid = wpa_s->pending_bssid;
 	wpa_msg(wpa_s, MSG_INFO, "Authentication with " MACSTR " timed out.",
 		MAC2STR(bssid));
-	wpa_blacklist_add(wpa_s, bssid);
+	wpa_bssid_ignore_add(wpa_s, bssid);
 	wpa_sm_notify_disassoc(wpa_s->wpa);
 	wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
 	wpa_s->reassociate = 1;
@@ -304,7 +316,7 @@
 {
 	wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling authentication timeout");
 	eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
-	wpa_blacklist_del(wpa_s, wpa_s->bssid);
+	wpa_bssid_ignore_del(wpa_s, wpa_s->bssid);
 	os_free(wpa_s->last_con_fail_realm);
 	wpa_s->last_con_fail_realm = NULL;
 	wpa_s->last_con_fail_realm_len = 0;
@@ -474,16 +486,22 @@
 }
 
 
+static void remove_bss_tmp_disallowed_entry(struct wpa_supplicant *wpa_s,
+					    struct wpa_bss_tmp_disallowed *bss)
+{
+	eloop_cancel_timeout(wpa_bss_tmp_disallow_timeout, wpa_s, bss);
+	dl_list_del(&bss->list);
+	os_free(bss);
+}
+
+
 void free_bss_tmp_disallowed(struct wpa_supplicant *wpa_s)
 {
 	struct wpa_bss_tmp_disallowed *bss, *prev;
 
 	dl_list_for_each_safe(bss, prev, &wpa_s->bss_tmp_disallowed,
-			      struct wpa_bss_tmp_disallowed, list) {
-		eloop_cancel_timeout(wpa_bss_tmp_disallow_timeout, wpa_s, bss);
-		dl_list_del(&bss->list);
-		os_free(bss);
-	}
+			      struct wpa_bss_tmp_disallowed, list)
+		remove_bss_tmp_disallowed_entry(wpa_s, bss);
 }
 
 
@@ -537,6 +555,12 @@
 	eapol_sm_register_scard_ctx(wpa_s->eapol, NULL);
 	l2_packet_deinit(wpa_s->l2);
 	wpa_s->l2 = NULL;
+#if defined(WAPI_ANDROID)
+        l2_packet_deinit(wpa_s->l2_wapi);
+        wpa_s->l2_wapi = NULL;
+        os_free(wpa_s->wapi_scan_res);
+        wpa_s->wapi_scan_res = NULL;
+#endif 
 	if (wpa_s->l2_br) {
 		l2_packet_deinit(wpa_s->l2_br);
 		wpa_s->l2_br = NULL;
@@ -587,9 +611,15 @@
 
 	wmm_ac_clear_saved_tspecs(wpa_s);
 	pmksa_candidate_free(wpa_s->wpa);
+	ptksa_cache_deinit(wpa_s->ptksa);
+	wpa_s->ptksa = NULL;
 	wpa_sm_deinit(wpa_s->wpa);
 	wpa_s->wpa = NULL;
-	wpa_blacklist_clear(wpa_s);
+	wpa_bssid_ignore_clear(wpa_s);
+
+#ifdef CONFIG_PASN
+	wpas_pasn_auth_stop(wpa_s);
+#endif /* CONFIG_PASN */
 
 	wpa_bss_deinit(wpa_s);
 
@@ -740,6 +770,12 @@
 	dpp_global_deinit(wpa_s->dpp);
 	wpa_s->dpp = NULL;
 #endif /* CONFIG_DPP */
+
+#ifdef CONFIG_PASN
+	wpas_pasn_auth_stop(wpa_s);
+#endif /* CONFIG_PASN */
+	wpas_scs_deinit(wpa_s);
+	wpas_dscp_deinit(wpa_s);
 }
 
 
@@ -780,6 +816,71 @@
 	wpa_s->keys_cleared = (u32) -1;
 }
 
+#if defined(WAPI_ANDROID)
+int wpa_state_to_wapi_state(enum wpa_states wpa_state)
+{
+        wpa_printf(MSG_DEBUG, "%s wpa_state : %d change to wapi_state",__FUNCTION__ ,wpa_state);
+        switch (wpa_state)
+        {
+        case WPA_DISCONNECTED:
+                return WAPI_DISCONNECTED;
+        case WPA_INACTIVE:
+                return WAPI_INACTIVE;
+        case WPA_SCANNING:
+                return WAPI_SCANNING;
+        case WPA_ASSOCIATING:
+                return WAPI_ASSOCIATING;
+        case WPA_ASSOCIATED:
+                return WAPI_ASSOCIATED;
+        case WPA_COMPLETED:
+                return WAPI_COMPLETED;
+        case WPA_INTERFACE_DISABLED:
+                return WAPI_UNDEFINED_1;
+        case WPA_AUTHENTICATING:
+                return WAPI_UNDEFINED_2;
+        default:
+                return -1;
+        }
+        return -1;
+}
+
+int wapi_state_to_wpa_state(int wapi_state)
+{
+        switch (wapi_state) {
+        case WAPI_DISCONNECTED:
+                return WPA_DISCONNECTED;
+        case WAPI_INACTIVE:
+                return WPA_INACTIVE;
+        case WAPI_SCANNING:
+                return WPA_SCANNING;
+        case WAPI_ASSOCIATING:
+                return WPA_ASSOCIATING;
+        case WAPI_ASSOCIATED:
+                return WPA_ASSOCIATED;
+        case WAPI_AUTHENICATING:
+                return WAPI_SPECIFIC;
+        case WAPI_CERT_HANDSHAKE:
+                return WAPI_SPECIFIC;
+        case WAPI_3WAY_HANDSHAKE:
+                return WPA_4WAY_HANDSHAKE;
+        case WAPI_3WAYING:
+                return WAPI_SPECIFIC;
+        case WAPI_GROUP_HANDSHAKE:
+                return WPA_GROUP_HANDSHAKE;
+        case WAPI_GROUPING:
+                return WAPI_SPECIFIC;
+        case WAPI_COMPLETED:
+                return WPA_COMPLETED;
+    case WAPI_UNDEFINED_1:
+                return WPA_INTERFACE_DISABLED;
+        case WAPI_UNDEFINED_2:
+                return WPA_AUTHENTICATING;
+        default:
+                return -1;
+        }
+        return -1;
+}
+#endif 
 
 /**
  * wpa_supplicant_state_txt - Get the connection state name as a text string
@@ -996,7 +1097,13 @@
 			ssid ? ssid->id : -1,
 			ssid && ssid->id_str ? ssid->id_str : "",
 			fils_hlp_sent ? " FILS_HLP_SENT" : "");
+
 #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
+#ifdef CONFIG_TWT_OFFLOAD_IFX
+		if (wpas_twt_offload_init_default_session(wpa_s))
+			wpa_msg(wpa_s, MSG_ERROR,
+				"Failed to esablish a TWT session by default after Connection");
+#endif /* CONFIG_TWT_OFFLOAD_IFX */
 		wpas_clear_temp_disabled(wpa_s, ssid, 1);
 		wpa_s->consecutive_conn_failures = 0;
 		wpa_s->new_connection = 0;
@@ -1071,6 +1178,10 @@
 	if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
 		wpa_supplicant_start_autoscan(wpa_s);
 
+#if defined(WAPI_ANDROID)
+        wpa_s->wapi_state = wpa_state_to_wapi_state(wpa_s->wpa_state);
+        wpa_printf(MSG_DEBUG, "%s wapi_state : %d\n",__FUNCTION__ ,wpa_s->wapi_state);
+#endif 
 	if (old_state >= WPA_ASSOCIATED && wpa_s->wpa_state < WPA_ASSOCIATED)
 		wmm_ac_notify_disassoc(wpa_s);
 
@@ -1131,13 +1242,19 @@
 void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s)
 {
 	enum wpa_states old_state = wpa_s->wpa_state;
+	enum wpa_states new_state;
+
+	if (old_state == WPA_SCANNING)
+		new_state = WPA_SCANNING;
+	else
+		new_state = WPA_DISCONNECTED;
 
 	wpa_s->pairwise_cipher = 0;
 	wpa_s->group_cipher = 0;
 	wpa_s->mgmt_group_cipher = 0;
 	wpa_s->key_mgmt = 0;
 	if (wpa_s->wpa_state != WPA_INTERFACE_DISABLED)
-		wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
+		wpa_supplicant_set_state(wpa_s, new_state);
 
 	if (wpa_s->wpa_state != old_state)
 		wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
@@ -1184,8 +1301,8 @@
 		    os_strcmp(conf->ctrl_interface,
 			      wpa_s->conf->ctrl_interface) != 0);
 
-	if (reconf_ctrl && wpa_s->ctrl_iface) {
-		wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
+	if (reconf_ctrl) {
+		wpa_supplicant_ctrl_iface_deinit(wpa_s, wpa_s->ctrl_iface);
 		wpa_s->ctrl_iface = NULL;
 	}
 
@@ -1232,7 +1349,7 @@
 		wpa_s->reassociate = 1;
 		wpa_supplicant_req_scan(wpa_s, 0, 0);
 	}
-	wpa_blacklist_clear(wpa_s);
+	wpa_bssid_ignore_clear(wpa_s);
 	wpa_dbg(wpa_s, MSG_DEBUG, "Reconfiguration completed");
 	return 0;
 }
@@ -1315,6 +1432,47 @@
 }
 
 
+void wpas_set_mgmt_group_cipher(struct wpa_supplicant *wpa_s,
+				struct wpa_ssid *ssid, struct wpa_ie_data *ie)
+{
+	int sel;
+
+	sel = ie->mgmt_group_cipher;
+	if (ssid->group_mgmt_cipher)
+		sel &= ssid->group_mgmt_cipher;
+	if (wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION ||
+	    !(ie->capabilities & WPA_CAPABILITY_MFPC))
+		sel = 0;
+	wpa_dbg(wpa_s, MSG_DEBUG,
+		"WPA: AP mgmt_group_cipher 0x%x network profile mgmt_group_cipher 0x%x; available mgmt_group_cipher 0x%x",
+		ie->mgmt_group_cipher, ssid->group_mgmt_cipher, sel);
+	if (sel & WPA_CIPHER_AES_128_CMAC) {
+		wpa_s->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
+		wpa_dbg(wpa_s, MSG_DEBUG,
+			"WPA: using MGMT group cipher AES-128-CMAC");
+	} else if (sel & WPA_CIPHER_BIP_GMAC_128) {
+		wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_GMAC_128;
+		wpa_dbg(wpa_s, MSG_DEBUG,
+			"WPA: using MGMT group cipher BIP-GMAC-128");
+	} else if (sel & WPA_CIPHER_BIP_GMAC_256) {
+		wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_GMAC_256;
+		wpa_dbg(wpa_s, MSG_DEBUG,
+			"WPA: using MGMT group cipher BIP-GMAC-256");
+	} else if (sel & WPA_CIPHER_BIP_CMAC_256) {
+		wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_CMAC_256;
+		wpa_dbg(wpa_s, MSG_DEBUG,
+			"WPA: using MGMT group cipher BIP-CMAC-256");
+	} else {
+		wpa_s->mgmt_group_cipher = 0;
+		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher");
+	}
+	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
+			 wpa_s->mgmt_group_cipher);
+	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP,
+			 wpas_get_ssid_pmf(wpa_s, ssid));
+}
+
+
 /**
  * wpa_supplicant_set_suites - Set authentication and encryption parameters
  * @wpa_s: Pointer to wpa_supplicant data
@@ -1514,6 +1672,9 @@
 
 	sel = ie.key_mgmt & ssid->key_mgmt;
 #ifdef CONFIG_SAE
+	/* Refer commit 828b06743f: SAE: Pass SAE password on connect
+	 * if driver advertises SAE authentication offload support.
+	 */
 	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE) &&
 	    !(wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SAE_OFFLOAD))
 		sel &= ~(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE);
@@ -1651,41 +1812,18 @@
 		return -1;
 	}
 
-	sel = ie.mgmt_group_cipher;
-	if (ssid->group_mgmt_cipher)
-		sel &= ssid->group_mgmt_cipher;
-	if (wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION ||
-	    !(ie.capabilities & WPA_CAPABILITY_MFPC))
-		sel = 0;
-	wpa_dbg(wpa_s, MSG_DEBUG,
-		"WPA: AP mgmt_group_cipher 0x%x network profile mgmt_group_cipher 0x%x; available mgmt_group_cipher 0x%x",
-		ie.mgmt_group_cipher, ssid->group_mgmt_cipher, sel);
-	if (sel & WPA_CIPHER_AES_128_CMAC) {
-		wpa_s->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
-		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
-			"AES-128-CMAC");
-	} else if (sel & WPA_CIPHER_BIP_GMAC_128) {
-		wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_GMAC_128;
-		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
-			"BIP-GMAC-128");
-	} else if (sel & WPA_CIPHER_BIP_GMAC_256) {
-		wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_GMAC_256;
-		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
-			"BIP-GMAC-256");
-	} else if (sel & WPA_CIPHER_BIP_CMAC_256) {
-		wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_CMAC_256;
-		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
-			"BIP-CMAC-256");
-	} else {
-		wpa_s->mgmt_group_cipher = 0;
-		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher");
+	if ((ie.capabilities & WPA_CAPABILITY_MFPC) && (ie.capabilities & WPA_CAPABILITY_MFPR) &&
+		(wpas_get_ssid_pmf(wpa_s, ssid) == MGMT_FRAME_PROTECTION_OPTIONAL)) {
+		wpa_msg(wpa_s, MSG_INFO,
+			"RSN: Management frame protection required!!! STA set only capable bit");
+		return -1;
 	}
-	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
-			 wpa_s->mgmt_group_cipher);
-	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP,
-			 wpas_get_ssid_pmf(wpa_s, ssid));
+
+	wpas_set_mgmt_group_cipher(wpa_s, ssid, &ie);
 #ifdef CONFIG_OCV
-	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_OCV, ssid->ocv);
+	if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) ||
+	    (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_OCV))
+		wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_OCV, ssid->ocv);
 #endif /* CONFIG_OCV */
 	sae_pwe = wpa_s->conf->sae_pwe;
 	if (ssid->sae_password_id && sae_pwe != 3)
@@ -1893,6 +2031,8 @@
 
 static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
 {
+	bool scs = true, mscs = true;
+
 	*pos = 0x00;
 
 	switch (idx) {
@@ -1936,6 +2076,12 @@
 #endif /* CONFIG_MBO */
 		break;
 	case 6: /* Bits 48-55 */
+#ifdef CONFIG_TESTING_OPTIONS
+		if (wpa_s->disable_scs_support)
+			scs = false;
+#endif /* CONFIG_TESTING_OPTIONS */
+		if (scs)
+			*pos |= 0x40; /* Bit 54 - SCS */
 		break;
 	case 7: /* Bits 56-63 */
 		break;
@@ -1952,7 +2098,12 @@
 #endif /* CONFIG_FILS */
 		break;
 	case 10: /* Bits 80-87 */
-		*pos |= 0x20; /* Bit 85 - Mirrored SCS */
+#ifdef CONFIG_TESTING_OPTIONS
+		if (wpa_s->disable_mscs_support)
+			mscs = false;
+#endif /* CONFIG_TESTING_OPTIONS */
+		if (mscs)
+			*pos |= 0x20; /* Bit 85 - Mirrored SCS */
 		break;
 	}
 }
@@ -1992,6 +2143,362 @@
 	return 2 + len;
 }
 
+#if defined(WAPI_ANDROID)
+int wapi_merge_cert_files(char *wapi_as_cert, char *wapi_user_cert, char *cert_name)
+{
+        char strBeginCert[] = "-----BEGIN CERTIFICATE-----";
+        char strEndCert[] = "-----END CERTIFICATE-----";
+        char strBeginASCert[] = "-----BEGIN ASU CERTIFICATE-----";
+        char strEndASCert[] = "-----END ASU CERTIFICATE-----";
+        char strBeginUserCert[] = "-----BEGIN USER CERTIFICATE-----";
+        char strEndUserCert[] = "-----END USER CERTIFICATE-----";
+        FILE *fpSrc;
+        FILE *fpDesc;
+        char line[512];
+        int iSearchBegin = 1;
+#ifdef ANDROID
+        int keystore = 0, length;
+        char *pCert, *pBegin, *pEnd;
+#if defined(JB_MR2) || defined(KK)
+        uint8_t *value = NULL;
+
+        if (wapi_as_cert && strncmp("keystore://", wapi_as_cert, 11) == 0) {
+                value = NULL;
+                if ((length = keystore_get(&wapi_as_cert[11], strlen(wapi_as_cert)-11, &value)) == -1) {
+                        wpa_printf(MSG_ERROR, "%s: Could not open %s\n", __FUNCTION__, wapi_as_cert);
+                        goto err;
+                }
+                keystore = 1;
+        } else
+#else
+        char value[KEYSTORE_MESSAGE_SIZE];
+
+        if (wapi_as_cert && strncmp("keystore://", wapi_as_cert, 11) == 0) {
+                memset(value, 0, KEYSTORE_MESSAGE_SIZE);
+                if ((length = keystore_get(&wapi_as_cert[11], strlen(wapi_as_cert)-11, (uint8_t**)&value)) == -1) {
+                        wpa_printf(MSG_ERROR, "%s: Could not open %s\n", __FUNCTION__, wapi_as_cert);
+                        goto err;
+                }
+                keystore = 1;
+        } else
+#endif /* JB_MR2 || KK */
+#endif /* ANDROID */
+        if ((fpSrc = fopen(wapi_as_cert, "r")) == NULL) {
+                wpa_printf(MSG_ERROR, "%s: Could not open %s\n", __FUNCTION__, wapi_as_cert);
+                goto err;
+        }
+
+        if ((fpDesc = fopen(cert_name, "w")) == NULL) {
+                wpa_printf(MSG_ERROR, "%s: Could not open %s\n", __FUNCTION__, cert_name);
+#ifdef ANDROID
+                if (!keystore)
+#endif /* ANDROID */
+                fclose(fpSrc);
+                goto err;
+        }
+
+#ifdef ANDROID
+        if (keystore) {
+                pCert = (char *)value;
+                pBegin = strstr(pCert, strBeginCert);
+                if (pBegin) {
+                        if (pBegin > pCert) {
+                                fwrite(pCert, 1, pBegin - pCert, fpDesc);
+                                pCert = pBegin;
+                                length -= (pBegin - pCert);
+                        }
+                        fwrite(strBeginASCert, 1, strlen(strBeginASCert), fpDesc);
+                        pCert += strlen(strBeginCert);
+                        length -= strlen(strBeginCert);
+                } else {
+                        wpa_printf(MSG_ERROR, "%s: Could not find begin in %s\n", __FUNCTION__, wapi_as_cert);
+                }
+                pEnd = strstr(pCert, strEndCert);
+                if (pEnd) {
+                        if (pEnd > pCert) {
+                                fwrite(pCert, 1, pEnd - pCert, fpDesc);
+                                pCert = pEnd;
+                                length -= (pEnd - pCert);
+                        }
+                        fwrite(strEndASCert, 1, strlen(strEndASCert), fpDesc);
+                        pCert += strlen(strEndCert);
+                        length -= strlen(strEndCert);
+                } else {
+                        wpa_printf(MSG_ERROR, "%s: Could not find end in %s\n", __FUNCTION__, wapi_as_cert);
+                }
+                if (length > 0) {
+                        fwrite(pCert, 1, length, fpDesc);
+                }
+        } else
+#endif /* ANDROID */
+        /* copy the AS file */
+        while ((fgets(line, sizeof(line), fpSrc)) != NULL) {
+                if (iSearchBegin == 1) {
+                        if (strstr(line, strBeginCert) != 0){
+                                fputs(strBeginASCert, fpDesc);
+                                iSearchBegin = 0;
+                        }
+                } else {
+                        if (strstr(line, strEndCert) != 0) {
+                                fputs(strEndASCert, fpDesc);
+                        } else {
+                                fputs(line, fpDesc);
+                        }
+                }
+        }
+
+#ifdef ANDROID
+#if defined(JB_MR2) || defined(KK)
+        if (NULL != value)
+                free(value);
+#endif /* JB_MR2 || KK */
+        if (!keystore)
+#endif /* ANDROID */
+        fclose(fpSrc);
+
+        /* open the user file */
+        iSearchBegin = 1;
+
+#ifdef ANDROID
+        keystore = 0;
+
+        if (wapi_user_cert && strncmp("keystore://", wapi_user_cert, 11) == 0) {
+#if defined(JB_MR2) || defined(KK)
+                value = NULL;
+                if ((length = keystore_get(&wapi_user_cert[11], strlen(wapi_user_cert)-11, &value)) == -1) {
+#else
+                memset(value, 0, KEYSTORE_MESSAGE_SIZE);
+                if ((length = keystore_get(&wapi_user_cert[11], strlen(wapi_user_cert)-11, (uint8_t**)&value)) == -1) {
+#endif /* JB_MR2 || KK */
+                        wpa_printf(MSG_ERROR, "%s: Could not open %s\n", __FUNCTION__, wapi_user_cert);
+                        fclose(fpDesc);
+                        goto err;
+                }
+                keystore = 1;
+        } else
+#endif /* ANDROID */
+        if ((fpSrc = fopen(wapi_user_cert, "r")) == NULL) {
+                wpa_printf(MSG_ERROR, "%s: Could not open %s\n", __FUNCTION__, wapi_user_cert);
+                fclose(fpDesc);
+                goto err;
+        }
+
+#ifdef ANDROID
+        if (keystore) {
+                pCert = (char *)value;
+                pBegin = strstr(pCert, strBeginCert);
+                if (pBegin) {
+                        if (pBegin > pCert) {
+                                fwrite(pCert, 1, pBegin - pCert, fpDesc);
+                                pCert = pBegin;
+                                length -= (pBegin - pCert);
+                        }
+                        fwrite(strBeginUserCert, 1, strlen(strBeginUserCert), fpDesc);
+                        pCert += strlen(strBeginCert);
+                        length -= strlen(strBeginCert);
+                } else {
+                        wpa_printf(MSG_ERROR, "%s: Could not find begin in %s\n", __FUNCTION__, wapi_user_cert);
+                }
+                pEnd = strstr(pCert, strEndCert);
+                if (pEnd) {
+                        if (pEnd > pCert) {
+                                fwrite(pCert, 1, pEnd - pCert, fpDesc);
+                                pCert = pEnd;
+                                length -= (pEnd - pCert);
+                        }
+                        fwrite(strEndUserCert, 1, strlen(strEndUserCert), fpDesc);
+                        pCert += strlen(strEndCert);
+                        length -= strlen(strEndCert);
+                } else {
+                        wpa_printf(MSG_ERROR, "%s: Could not find end in %s\n", __FUNCTION__, wapi_user_cert);
+                }
+                if (length > 0) {
+                        fwrite(pCert, 1, length, fpDesc);
+                }
+        } else
+#endif /* ANDROID */
+        /* copy the user file */
+        while ((fgets(line, sizeof(line), fpSrc)) != NULL) {
+                if (iSearchBegin == 1) {
+                        if (strstr(line, strBeginCert) != 0){
+                                fputs(strBeginUserCert, fpDesc);
+                                iSearchBegin = 0;
+                        }
+                } else {
+                        if (strstr(line, strEndCert) != 0){
+                                fputs(strEndUserCert, fpDesc);
+                        } else {
+                                fputs(line, fpDesc);
+                        }
+                }
+        }
+
+        fflush(fpDesc);
+
+#ifdef ANDROID
+        if (!keystore)
+#endif /* ANDROID */
+        fclose(fpSrc);
+        fclose(fpDesc);
+        return 0;
+
+err:
+#ifdef ANDROID
+#if defined(JB_MR2) || defined(KK)
+        if (NULL != value)
+                free(value);
+#endif /* JB_MR2 || KK */
+#endif /* ANDROID */
+        return -1;
+}
+
+/* initialize the wapi_config structure from a wpa_ssid structure */
+struct wapi_config * wapi_config_init(struct wpa_ssid *ssid, struct wpa_supplicant *wpa_s)
+{
+        struct wapi_config *config = NULL;
+        CNTAP_PARA lib_param;
+        u8 psk_type = 0;
+        struct wpa_global *eloop = (struct wpa_global *)eloop_get_user_data();
+#ifdef CONFIG_BRCM_AUTOMOTIVE
+        int check_ssid;
+#endif
+
+        wpa_printf(MSG_DEBUG, "wapi_config_init: Enter\n");
+        if(eloop->ifaces != NULL)
+                wpa_printf(MSG_DEBUG, "eloop->iface: %p\n",eloop->ifaces);
+        //if(eloop->ifaces->next != NULL) {
+        //        eloop->ifaces = eloop->ifaces->next;
+        //        wpa_printf(MSG_DEBUG, "eloop->iface->next: %p\n",eloop->ifaces);
+       // }
+        wpa_printf(MSG_DEBUG, "Entering %s...", __FUNCTION__);
+
+        config = os_malloc(sizeof(*config));
+        if (config == NULL)
+                return NULL;
+
+        os_memset(config, 0, sizeof(*config));
+
+        /* Get Authentication and Key Management Suites */
+        config->wapi_policy = ssid->wapi;
+
+        wpa_printf(MSG_DEBUG, "wapi_policy '%d'", config->wapi_policy);
+
+        if (config->wapi_policy & 0x08)
+        {
+                wpa_printf(MSG_DEBUG, " AUTH_TYPE_WAPI");
+                lib_param.authType = AUTH_TYPE_WAPI;
+        } else if (config->wapi_policy & 0x04)
+        {
+                wpa_printf(MSG_DEBUG, " AUTH_TYPE_WAPI_PSK");
+                lib_param.authType = AUTH_TYPE_WAPI_PSK;
+        } else {
+                wpa_printf(MSG_DEBUG, " AUTH_TYPE_NONE_WAPI");
+                lib_param.authType = AUTH_TYPE_NONE_WAPI;
+        }
+
+        if (config->wapi_policy != 0)
+        {
+                config->group_cipher = WAPI_CIPHER_SMS4;
+                config->pairwise_cipher = WAPI_CIPHER_SMS4;
+        }
+
+#if defined(CONFIG_BRCM_AUTOMOTIVE)
+        if (ssid->bssid_set && ssid->ssid_len == 0)
+                check_ssid = 0;
+        else
+                check_ssid = 1;
+
+        if (check_ssid) {
+                config->ssid_len = ssid->ssid_len;
+                config->ssid = (u8 *)os_strdup((const char *)ssid->ssid);
+        }
+#else
+        config->ssid_len = ssid->ssid_len;
+        config->ssid = (u8 *)os_strdup((const char *)ssid->ssid);
+#endif /* CONFIG_DRIVER_NL80211_IFX && CONFIG_BRCM_AUTOMOTIVE */
+
+        wpa_hexdump_ascii(MSG_DEBUG, " SSID:", config->ssid, config->ssid_len);
+        wpa_printf(MSG_DEBUG, "SSID '%s'", config->ssid);
+
+        eloop->cert_info.config.used_cert = ssid->cert_index; /* 1:x509 2:GBW */
+        wpa_printf(MSG_DEBUG, "cert_index %d", eloop->cert_info.config.used_cert);
+        wpa_printf(MSG_DEBUG, "ssid->cert_index=%d", ssid->cert_index);
+        wpa_printf(MSG_DEBUG, "ssid->wapi_as_cert=%s", ssid->wapi_as_cert);
+        wpa_printf(MSG_DEBUG, "ssid->wapi_user_cert=%s", ssid->wapi_user_cert);
+
+        if (config->wapi_policy & 0x08) {
+                if ((ssid->wapi_as_cert) && (ssid->wapi_user_cert))
+                {
+                        wpa_printf(MSG_DEBUG, "ssid->wapi_as_cert=%s", ssid->wapi_as_cert);
+                        wpa_printf(MSG_DEBUG, "ssid->wapi_user_cert=%s", ssid->wapi_user_cert);
+
+                        wpa_printf(MSG_DEBUG, "%s: the final mixed cert filename = %s\n",
+                                   __FUNCTION__, ssid->cert_name);
+                        if (wapi_merge_cert_files(ssid->wapi_as_cert, ssid->wapi_user_cert, ssid->cert_name)) {
+                                wpa_printf(MSG_ERROR, "%s: wapi_merge_cert_files() failed, exit...\n", __FUNCTION__);
+                                wapi_config_free(config);
+                                return NULL;
+                        }
+
+                        /* merge the as.cer with user.cer to make a mixed.cer */
+                        strcpy(eloop->cert_info.config.cert_name, ssid->cert_name);
+                        wpa_printf(MSG_DEBUG, "CERT_NAME '%s'", eloop->cert_info.config.cert_name);
+                        change_cert_format(eloop->cert_info.config.cert_name,
+                                           lib_param.para.user, 2048,
+                                           lib_param.para.as, 2048);
+                }
+                else {
+                        wpa_printf(MSG_ERROR, "wapi cert files not present");
+                        wapi_config_free(config);
+                        return NULL;
+                }
+        }
+
+        if (config->wapi_policy & WAPI_KEY_MGMT_PSK)
+        { /* bit 2:PSK */
+                psk_type = ssid->psk_key_type;
+                wpa_printf(MSG_DEBUG, "%s: PSK_KEY_TYPE '%d'", __FUNCTION__, psk_type);
+                wpa_printf(MSG_DEBUG, "%s: psk (%d)", __FUNCTION__, ssid->psk_set);
+                wpa_printf(MSG_DEBUG, "%s: PSK'%s'", __FUNCTION__, ssid->psk);
+                wpa_printf(MSG_DEBUG, "%s: passphrase'%s'", __FUNCTION__, ssid->passphrase);
+
+                lib_param.para.kt = psk_type;
+                if (ssid->passphrase != NULL) {
+                        wpa_printf(MSG_DEBUG, "%s: ssid->passphrase != NULL, use ssid->passphrase:%s\n",
+                                   __FUNCTION__, ssid->passphrase);
+                        lib_param.para.kl = strlen(ssid->passphrase);
+                        memcpy(lib_param.para.kv, ssid->passphrase, lib_param.para.kl);
+                }
+                else if (ssid->psk_set) {
+                        wpa_printf(MSG_DEBUG, "%s: ssid->passphrase == NULL, use ssid->psk: %s\n",
+                                   __FUNCTION__, ssid->psk);
+                        lib_param.para.kl = os_strlen((const char *)ssid->psk);
+
+                        memcpy(lib_param.para.kv, ssid->psk, lib_param.para.kl);
+                } else {
+                        wpa_printf(MSG_ERROR, "%s: passphrase and psk both NULL. Skip assoc.\n",
+                                   __FUNCTION__);
+                        wapi_config_free(config);
+                        return NULL;
+                }
+        }
+
+        /* do it after the wpa_s has been attached to global */
+        if (WAI_CNTAPPARA_SET(&lib_param, wpa_s->ifname) != 0) {
+                wpa_printf(MSG_DEBUG, "%s: WAI_CNTAPPARA_SET error\n", __FUNCTION__);
+                wapi_config_free(config);
+                if ((config->wapi_policy & 0x08) &&
+                    (ssid->wapi_as_cert) &&
+                    (ssid->wapi_user_cert)) {
+                        wpa_msg(eloop->ifaces, MSG_INFO, "WAPI: certificate initialization failed");
+                }
+                return NULL;
+        }
+
+        wpa_printf(MSG_DEBUG, "%s: leave\n", __FUNCTION__);
+        return config;
+}
+#endif 
 
 static int wpas_valid_bss(struct wpa_supplicant *wpa_s,
 			  struct wpa_bss *test_bss)
@@ -2284,6 +2791,24 @@
 }
 
 
+int wpas_restore_permanent_mac_addr(struct wpa_supplicant *wpa_s)
+{
+	if (wpa_drv_set_mac_addr(wpa_s, NULL) < 0) {
+		wpa_msg(wpa_s, MSG_INFO,
+			"Could not restore permanent MAC address");
+		return -1;
+	}
+	wpa_s->mac_addr_changed = 0;
+	if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
+		wpa_msg(wpa_s, MSG_INFO,
+			"Could not update MAC address information");
+		return -1;
+	}
+	wpa_msg(wpa_s, MSG_DEBUG, "Using permanent MAC address");
+	return 0;
+}
+
+
 static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit);
 
 /**
@@ -2340,27 +2865,19 @@
 	} else {
 #ifdef CONFIG_SAE
 		wpa_s_clear_sae_rejected(wpa_s);
-		wpa_s_setup_sae_pt(wpa_s->conf, ssid);
 #endif /* CONFIG_SAE */
 	}
+#ifdef CONFIG_SAE
+	wpa_s_setup_sae_pt(wpa_s->conf, ssid);
+#endif /* CONFIG_SAE */
 
 	if (rand_style > 0 && !wpa_s->reassoc_same_ess) {
 		if (wpas_update_random_addr(wpa_s, rand_style) < 0)
 			return;
 		wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
 	} else if (rand_style == 0 && wpa_s->mac_addr_changed) {
-		if (wpa_drv_set_mac_addr(wpa_s, NULL) < 0) {
-			wpa_msg(wpa_s, MSG_INFO,
-				"Could not restore permanent MAC address");
+		if (wpas_restore_permanent_mac_addr(wpa_s) < 0)
 			return;
-		}
-		wpa_s->mac_addr_changed = 0;
-		if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
-			wpa_msg(wpa_s, MSG_INFO,
-				"Could not update MAC address information");
-			return;
-		}
-		wpa_msg(wpa_s, MSG_DEBUG, "Using permanent MAC address");
 	}
 	wpa_s->last_ssid = ssid;
 
@@ -2412,10 +2929,6 @@
 			return;
 		}
 		wpa_s->current_bss = bss;
-		wpa_msg(wpa_s, MSG_INFO, MESH_GROUP_STARTED "ssid=\"%s\" id=%d",
-			wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
-			ssid->id);
-		wpas_notify_mesh_group_started(wpa_s, ssid);
 #else /* CONFIG_MESH */
 		wpa_msg(wpa_s, MSG_ERROR,
 			"mesh mode support not included in the build");
@@ -2517,6 +3030,23 @@
 }
 
 
+static bool ibss_mesh_is_80mhz_avail(int channel, struct hostapd_hw_modes *mode)
+{
+	int i;
+
+	for (i = channel; i < channel + 16; i += 4) {
+		struct hostapd_channel_data *chan;
+
+		chan = hw_get_channel_chan(mode, i, NULL);
+		if (!chan ||
+		    chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
+			return false;
+	}
+
+	return true;
+}
+
+
 void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s,
 			  const struct wpa_ssid *ssid,
 			  struct hostapd_freq_params *freq)
@@ -2526,7 +3056,10 @@
 	struct hostapd_hw_modes *mode = NULL;
 	int ht40plus[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157,
 			   184, 192 };
-	int vht80[] = { 36, 52, 100, 116, 132, 149 };
+	int bw80[] = { 5180, 5260, 5500, 5580, 5660, 5745, 5955,
+		       6035, 6115, 6195, 6275, 6355, 6435, 6515,
+		       6595, 6675, 6755, 6835, 6915, 6995 };
+	int bw160[] = { 5955, 6115, 6275, 6435, 6595, 6755, 6915 };
 	struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL;
 	u8 channel;
 	int i, chan_idx, ht40 = -1, res, obss_scan = 1;
@@ -2534,7 +3067,7 @@
 	struct hostapd_freq_params vht_freq;
 	int chwidth, seg0, seg1;
 	u32 vht_caps = 0;
-	int is_24ghz;
+	bool is_24ghz, is_6ghz;
 
 	freq->freq = ssid->frequency;
 
@@ -2586,9 +3119,18 @@
 	if (!mode)
 		return;
 
+	freq->channel = channel;
+
 	is_24ghz = hw_mode == HOSTAPD_MODE_IEEE80211G ||
 		hw_mode == HOSTAPD_MODE_IEEE80211B;
 
+	/* HT/VHT and corresponding overrides are not applicable to 6 GHz.
+	 * However, HE is mandatory for 6 GHz.
+	 */
+	is_6ghz = is_6ghz_freq(freq->freq);
+	if (is_6ghz)
+		goto skip_to_6ghz;
+
 #ifdef CONFIG_HT_OVERRIDES
 	if (ssid->disable_ht) {
 		freq->ht_enabled = 0;
@@ -2716,8 +3258,6 @@
 	    !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_VHT_IBSS))
 		return;
 
-	vht_freq = *freq;
-
 #ifdef CONFIG_VHT_OVERRIDES
 	if (ssid->disable_vht) {
 		freq->vht_enabled = 0;
@@ -2725,46 +3265,67 @@
 	}
 #endif /* CONFIG_VHT_OVERRIDES */
 
+skip_to_6ghz:
+	vht_freq = *freq;
+
+	/* 6 GHz does not have VHT enabled, so allow that exception here. */
 	vht_freq.vht_enabled = vht_supported(mode);
-	if (!vht_freq.vht_enabled)
+	if (!vht_freq.vht_enabled && !is_6ghz)
 		return;
 
 	/* Enable HE with VHT for 5 GHz */
 	freq->he_enabled = mode->he_capab[ieee80211_mode].he_supported;
 
 	/* setup center_freq1, bandwidth */
-	for (j = 0; j < ARRAY_SIZE(vht80); j++) {
-		if (freq->channel >= vht80[j] &&
-		    freq->channel < vht80[j] + 16)
+	for (j = 0; j < ARRAY_SIZE(bw80); j++) {
+		if (freq->freq >= bw80[j] &&
+		    freq->freq < bw80[j] + 80)
 			break;
 	}
 
-	if (j == ARRAY_SIZE(vht80))
+	if (j == ARRAY_SIZE(bw80) ||
+	    ieee80211_freq_to_chan(bw80[j], &channel) == NUM_HOSTAPD_MODES)
 		return;
 
-	for (i = vht80[j]; i < vht80[j] + 16; i += 4) {
-		struct hostapd_channel_data *chan;
-
-		chan = hw_get_channel_chan(mode, i, NULL);
-		if (!chan)
-			return;
-
-		/* Back to HT configuration if channel not usable */
-		if (chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
-			return;
-	}
+	/* Back to HT configuration if channel not usable */
+	if (!ibss_mesh_is_80mhz_avail(channel, mode))
+		return;
 
 	chwidth = CHANWIDTH_80MHZ;
-	seg0 = vht80[j] + 6;
+	seg0 = channel + 6;
 	seg1 = 0;
 
+	if ((mode->he_capab[ieee80211_mode].phy_cap[
+		     HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
+	     HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G) && is_6ghz) {
+		/* In 160 MHz, the initial four 20 MHz channels were validated
+		 * above; check the remaining four 20 MHz channels for the total
+		 * of 160 MHz bandwidth.
+		 */
+		if (!ibss_mesh_is_80mhz_avail(channel + 16, mode))
+			return;
+
+		for (j = 0; j < ARRAY_SIZE(bw160); j++) {
+			if (freq->freq == bw160[j]) {
+				chwidth = CHANWIDTH_160MHZ;
+				seg0 = channel + 14;
+				break;
+			}
+		}
+	}
+
 	if (ssid->max_oper_chwidth == CHANWIDTH_80P80MHZ) {
 		/* setup center_freq2, bandwidth */
-		for (k = 0; k < ARRAY_SIZE(vht80); k++) {
+		for (k = 0; k < ARRAY_SIZE(bw80); k++) {
 			/* Only accept 80 MHz segments separated by a gap */
-			if (j == k || abs(vht80[j] - vht80[k]) == 16)
+			if (j == k || abs(bw80[j] - bw80[k]) == 80)
 				continue;
-			for (i = vht80[k]; i < vht80[k] + 16; i += 4) {
+
+			if (ieee80211_freq_to_chan(bw80[k], &channel) ==
+			    NUM_HOSTAPD_MODES)
+				return;
+
+			for (i = channel; i < channel + 16; i += 4) {
 				struct hostapd_channel_data *chan;
 
 				chan = hw_get_channel_chan(mode, i, NULL);
@@ -2778,9 +3339,10 @@
 
 				/* Found a suitable second segment for 80+80 */
 				chwidth = CHANWIDTH_80P80MHZ;
-				vht_caps |=
-					VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
-				seg1 = vht80[k] + 6;
+				if (!is_6ghz)
+					vht_caps |=
+						VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
+				seg1 = channel + 6;
 			}
 
 			if (chwidth == CHANWIDTH_80P80MHZ)
@@ -2798,7 +3360,7 @@
 		}
 	} else if (ssid->max_oper_chwidth == CHANWIDTH_USE_HT) {
 		chwidth = CHANWIDTH_USE_HT;
-		seg0 = vht80[j] + 2;
+		seg0 = channel + 2;
 #ifdef CONFIG_HT_OVERRIDES
 		if (ssid->disable_ht40)
 			seg0 = 0;
@@ -2918,6 +3480,54 @@
 #endif /* CONFIG_FILS */
 
 
+static int wpas_populate_wfa_capa(struct wpa_supplicant *wpa_s,
+				  struct wpa_bss *bss,
+				  u8 *wpa_ie, size_t wpa_ie_len,
+				  size_t max_wpa_ie_len)
+{
+	struct wpabuf *wfa_ie = NULL;
+	u8 wfa_capa[1];
+	size_t wfa_ie_len, buf_len;
+
+	os_memset(wfa_capa, 0, sizeof(wfa_capa));
+	if (wpa_s->enable_dscp_policy_capa)
+		wfa_capa[0] |= WFA_CAPA_QM_DSCP_POLICY;
+
+	if (!wfa_capa[0])
+		return wpa_ie_len;
+
+	/* Wi-Fi Alliance element */
+	buf_len = 1 +	/* Element ID */
+		  1 +	/* Length */
+		  3 +	/* OUI */
+		  1 +	/* OUI Type */
+		  1 +	/* Capabilities Length */
+		  sizeof(wfa_capa);	/* Capabilities */
+	wfa_ie = wpabuf_alloc(buf_len);
+	if (!wfa_ie)
+		return wpa_ie_len;
+
+	wpabuf_put_u8(wfa_ie, WLAN_EID_VENDOR_SPECIFIC);
+	wpabuf_put_u8(wfa_ie, buf_len - 2);
+	wpabuf_put_be24(wfa_ie, OUI_WFA);
+	wpabuf_put_u8(wfa_ie, WFA_CAPA_OUI_TYPE);
+	wpabuf_put_u8(wfa_ie, sizeof(wfa_capa));
+	wpabuf_put_data(wfa_ie, wfa_capa, sizeof(wfa_capa));
+
+	wfa_ie_len = wpabuf_len(wfa_ie);
+	if (wpa_ie_len + wfa_ie_len <= max_wpa_ie_len) {
+		wpa_hexdump_buf(MSG_MSGDUMP, "WFA Capabilities element",
+				wfa_ie);
+		os_memcpy(wpa_ie + wpa_ie_len, wpabuf_head(wfa_ie),
+			  wfa_ie_len);
+		wpa_ie_len += wfa_ie_len;
+	}
+
+	wpabuf_free(wfa_ie);
+	return wpa_ie_len;
+}
+
+
 static u8 * wpas_populate_assoc_ies(
 	struct wpa_supplicant *wpa_s,
 	struct wpa_bss *bss, struct wpa_ssid *ssid,
@@ -3139,14 +3749,6 @@
 						    wpa_ie_len);
 	}
 
-	/*
-	 * Workaround: Add Extended Capabilities element only if the AP
-	 * included this element in Beacon/Probe Response frames. Some older
-	 * APs seem to have interoperability issues if this element is
-	 * included, so while the standard may require us to include the
-	 * element in all cases, it is justifiable to skip it to avoid
-	 * interoperability issues.
-	 */
 	if (ssid->p2p_group)
 		wpa_drv_get_ext_capa(wpa_s, WPA_IF_P2P_CLIENT);
 	else
@@ -3360,13 +3962,15 @@
 		wpa_ie_len += wpa_s->rsnxe_len;
 	}
 
-	if (bss && wpa_s->robust_av.valid_config) {
+#ifdef CONFIG_TESTING_OPTIONS
+	if (wpa_s->disable_mscs_support)
+		goto mscs_end;
+#endif /* CONFIG_TESTING_OPTIONS */
+	if (wpa_bss_ext_capab(bss, WLAN_EXT_CAPAB_MSCS) &&
+	    wpa_s->robust_av.valid_config) {
 		struct wpabuf *mscs_ie;
 		size_t mscs_ie_len, buf_len;
 
-		if (!wpa_bss_ext_capab(bss, WLAN_EXT_CAPAB_MSCS))
-			goto mscs_fail;
-
 		buf_len = 3 +	/* MSCS descriptor IE header */
 			  1 +	/* Request type */
 			  2 +	/* User priority control */
@@ -3377,7 +3981,7 @@
 		if (!mscs_ie) {
 			wpa_printf(MSG_INFO,
 				   "MSCS: Failed to allocate MSCS IE");
-			goto mscs_fail;
+			goto mscs_end;
 		}
 
 		wpas_populate_mscs_descriptor_ie(&wpa_s->robust_av, mscs_ie);
@@ -3391,7 +3995,10 @@
 
 		wpabuf_free(mscs_ie);
 	}
-mscs_fail:
+mscs_end:
+
+	wpa_ie_len = wpas_populate_wfa_capa(wpa_s, bss, wpa_ie, wpa_ie_len,
+					    max_wpa_ie_len);
 
 	if (ssid->multi_ap_backhaul_sta) {
 		size_t multi_ap_ie_len;
@@ -3452,13 +4059,11 @@
 	if (!wpa_ie)
 		return;
 
-	if (params.auth_alg != WPA_AUTH_ALG_FILS) {
-		os_free(wpa_ie);
-		return;
+	if (params.auth_alg == WPA_AUTH_ALG_FILS) {
+		wpa_s->auth_alg = params.auth_alg;
+		wpa_drv_update_connect_params(wpa_s, &params, mask);
 	}
 
-	wpa_s->auth_alg = params.auth_alg;
-	wpa_drv_update_connect_params(wpa_s, &params, mask);
 	os_free(wpa_ie);
 }
 #endif /* CONFIG_FILS && IEEE8021X_EAPOL */
@@ -3562,7 +4167,7 @@
 	if (hw_mode == NUM_HOSTAPD_MODES)
 		goto fail;
 
-	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, hw_mode, 0);
+	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, hw_mode, false);
 	if (!mode)
 		goto fail;
 
@@ -3605,6 +4210,11 @@
 
 static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
 {
+#if defined(WAPI_ANDROID)
+	static u8 ssid_buf[SSID_MAX_LEN+1];
+        u8 *wapi_ie;
+        u8 wapi_ie_len;
+#endif 
 	struct wpa_connect_work *cwork = work->ctx;
 	struct wpa_bss *bss = cwork->bss;
 	struct wpa_ssid *ssid = cwork->ssid;
@@ -3629,6 +4239,11 @@
        struct ieee80211_vht_capabilities vhtcaps_mask;
 #endif /* CONFIG_VHT_OVERRIDES */
 
+	wpa_s->roam_in_progress = false;
+#ifdef CONFIG_WNM
+	wpa_s->bss_trans_mgmt_in_progress = false;
+#endif /* CONFIG_WNM */
+
 	if (deinit) {
 		if (work->started) {
 			wpa_s->connect_work = NULL;
@@ -3654,6 +4269,20 @@
 	os_memset(&params, 0, sizeof(params));
 	wpa_s->reassociate = 0;
 	wpa_s->eap_expected_failure = 0;
+
+	/* Starting new association, so clear the possibly used WPA IE from the
+	 * previous association. */
+	wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
+	wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0);
+	wpa_s->rsnxe_len = 0;
+	wpa_s->mscs_setup_done = false;
+
+	wpa_ie = wpas_populate_assoc_ies(wpa_s, bss, ssid, &params, NULL);
+	if (!wpa_ie) {
+		wpas_connect_work_done(wpa_s);
+		return;
+	}
+
 	if (bss &&
 	    (!wpas_driver_bss_selection(wpa_s) || wpas_wps_searching(wpa_s))) {
 #ifdef CONFIG_IEEE80211R
@@ -3687,6 +4316,7 @@
 		wpa_s->scan_req = MANUAL_SCAN_REQ;
 		wpa_s->reassociate = 1;
 		wpa_supplicant_req_scan(wpa_s, 0, 0);
+		os_free(wpa_ie);
 		return;
 #endif /* CONFIG_WPS */
 	} else {
@@ -3701,19 +4331,131 @@
 		wpa_supplicant_cancel_sched_scan(wpa_s);
 
 	wpa_supplicant_cancel_scan(wpa_s);
+#if defined(WAPI_ANDROID)
+        if ( (ssid->wapi) || (ssid->proto & WPA_PROTO_WAPI) || (ssid->key_mgmt == WPA_KEY_MGMT_WAPI_PSK ) ||
+                (ssid->key_mgmt == WPA_KEY_MGMT_WAPI_CERT)) {
+                /* associating to a WAPI network */
+                wpa_printf(MSG_DEBUG, "[WAPI] ssid->wapi %d "
+                        "ssid->proto %d ssid->key_mgmt %d \n",
+                        ssid->wapi, ssid->proto, ssid->key_mgmt);
 
-	/* Starting new association, so clear the possibly used WPA IE from the
-	 * previous association. */
-	wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
-	wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0);
-	wpa_s->rsnxe_len = 0;
-	wpa_s->mscs_setup_done = false;
+                if (ssid->wapi == 0) {
+                        if (ssid->key_mgmt == WPA_KEY_MGMT_WAPI_PSK) {
+                                ssid->wapi = 7;
+                        }
+                        else if (ssid->key_mgmt == WPA_KEY_MGMT_WAPI_CERT) {
+                                ssid->wapi = 11;
+                        }
+                        else {
+                                wpa_printf(MSG_ERROR, "[WAPI] Unknown key mgmt type. Abort assoc.");
+                                wpas_connect_work_done(wpa_s);
+                                return;
+                        }
+                }
+                if (ssid->key_mgmt == WPA_KEY_MGMT_WAPI_PSK) {
+                                params.key_mgmt_suite = WPA_KEY_MGMT_WAPI_PSK;
+                } else if (ssid->key_mgmt == WPA_KEY_MGMT_WAPI_CERT) {
+                                params.key_mgmt_suite = WPA_KEY_MGMT_WAPI_CERT;
+                } else {
+                        params.key_mgmt_suite = WPA_KEY_MGMT_NONE;
+                }
 
-	wpa_ie = wpas_populate_assoc_ies(wpa_s, bss, ssid, &params, NULL);
-	if (!wpa_ie) {
-		wpas_connect_work_done(wpa_s);
-		return;
-	}
+                wpa_s->wapi_conf = wapi_config_init(ssid, wpa_s);
+                if (wpa_s->wapi_conf == NULL) {
+                        wpa_printf(MSG_ERROR, "[WAPI] Initialize wapi_conf failed. Abort assoc.\n");
+                        wpas_connect_work_done(wpa_s);
+                        return;
+                }
+                if (bss) {
+                        u8 *ie = (u8 *)wpa_bss_get_ie(bss, WLAN_EID_SSID);
+                        if(ie) {
+                                wpa_printf(MSG_DEBUG, "[WAPI] WLAN_EID_SSID Get ie: "
+                                        "[%02x][%02x][%02x][%02x][%02x][%02x][%02x][%02x][%02x][%02x]\n",
+                                           ie[0], ie[1], ie[2], ie[3], ie[4],
+                                           ie[5], ie[6], ie[7], ie[8], ie[9] );
+
+                                wpa_printf(MSG_DEBUG, "[WAPI] bss ie[1]=%d\n", ie[1]);
+                                params.bssid = bss->bssid;
+                                params.ssid = ssid_buf;
+
+                                if ( ie[1] >  SSID_MAX_LEN ) {
+                                        wpa_printf(MSG_ERROR, "[WAPI] ssid length is over %d, strip it!", SSID_MAX_LEN);
+                                }
+
+                                snprintf((char *) params.ssid,
+                                        ((ie[1]>SSID_MAX_LEN)? SSID_MAX_LEN:ie[1])+1, "%s",
+                                        ie ? wpa_ssid_txt(ie + 2, ie[1]) : "");
+
+
+                                params.ssid_len = os_strlen((const char *)params.ssid);
+
+                                params.freq.freq= bss->freq;
+                                wpa_printf(MSG_DEBUG, "[WAPI] params.ssid=%s\n", params.ssid);
+                                wpa_printf(MSG_DEBUG, "[WAPI] params.bssid=%s\n", params.bssid);
+                                wpa_printf(MSG_DEBUG, "[WAPI] params.key_mgmt=0x%x\n", params.key_mgmt_suite);
+                                wpa_printf(MSG_DEBUG, "[WAPI] bss done\n");
+                                wpa_sm_set_ap_wapi_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
+                        }
+                }
+                else {
+                        params.ssid = ssid->ssid;
+                        params.ssid_len = ssid->ssid_len;
+                }
+
+                if (ssid->mode == 1 && ssid->frequency > 0 && params.freq.freq == 0) {
+                        params.freq.freq = ssid->frequency; /* Initial channel for IBSS */
+                }
+                wpa_printf(MSG_DEBUG, "%s: params.freq=%d.\n", __FUNCTION__, params.freq.freq);
+                params.mode = ssid->mode;
+                wpa_printf(MSG_DEBUG, "%s: params.mode=%d...\n", __FUNCTION__, params.mode);
+
+                if (bss) {
+                        wpa_s->ap_wapi_ie_len =bss->wapi_ie_len;
+                        if (bss->wapi_ie_len) {
+                                wpa_printf(MSG_DEBUG, "%s: bss->wapi_ie_len..\n", __FUNCTION__);
+                                memcpy(wpa_s->ap_wapi_ie, wpa_bss_get_ie(bss, WLAN_EID_WAPI), bss->wapi_ie_len);
+                                wpa_hexdump(MSG_DEBUG, "wpa_s->ap_wapi_ie", wpa_s->ap_wapi_ie, wpa_s->ap_wapi_ie_len);
+                        }
+                }
+
+                /* set wpa_s->assoc_wapi_ie and wpa_s->assoc_wapi_ie */
+                params.wpa_ie_len = wpa_s->assoc_wapi_ie_len;
+                wpa_printf(MSG_DEBUG, "%s: params.wpa_ie_len=%d\n",
+                        __FUNCTION__, (int)params.wpa_ie_len);
+                /* to do: do I have to manually copy the contents into params.wpa_ie? */
+                params.wpa_ie = wpa_s->assoc_wapi_ie;
+
+                wpa_printf(MSG_DEBUG, "wapi_ie: [%02x][%02x][%02x][%02x]\n",
+                        params.wpa_ie[0], params.wpa_ie[1], params.wpa_ie[2], params.wpa_ie[3]);
+
+                if(bss) {
+                        u8 *ap_wapi_ie = (u8 *)wpa_bss_get_ie(bss, WLAN_EID_WAPI);
+                        if(ap_wapi_ie) {
+                                params.ap_wapi_ie = ap_wapi_ie;
+                                params.ap_wapi_ie_len = ap_wapi_ie ? ap_wapi_ie[1] + 2: 0;
+                                wpa_printf(MSG_DEBUG, "%s: params.ap_wapi_ie_len = %zu\n", __FUNCTION__,
+                                        params.ap_wapi_ie_len);
+                                wpa_printf(MSG_DEBUG, "%s: params.ap_wapi_ie_len: [%02x][%02x][%02x][%02x]\n",
+                            __FUNCTION__, params.ap_wapi_ie[0], params.ap_wapi_ie[1],
+                            params.ap_wapi_ie[2], params.ap_wapi_ie[3]);
+                        }
+                }
+               if (!memcmp(wpa_s->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN)) {
+
+                        /* Timeout for IEEE 802.11 authentication and association */
+                        wpa_supplicant_req_auth_timeout(wpa_s, 20, 0);
+
+                        wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
+                        if (wpa_drv_associate(wpa_s, &params)) {
+                                wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
+                                wpa_printf(MSG_ERROR, "[WAPI] wpa_drv_associate() failed\n");
+                        }
+                } else {
+                        wpa_printf(MSG_ERROR, "[WAPI] Skipping drv_associate call for wapi");
+                }
+        }
+        else {
+#endif 
 
 	wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
 	use_crypt = 1;
@@ -3920,6 +4662,9 @@
 			params.psk = ssid->psk;
 	}
 
+	/* Refer commit 828b06743f: SAE: Pass SAE password on connect if
+	 * driver advertises SAE authentication offload support.
+	 */
 	if ((wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SAE_OFFLOAD) &&
 	    wpa_key_mgmt_sae(params.key_mgmt_suite)) {
 		params.auth_alg = WPA_AUTH_ALG_SAE;
@@ -4014,7 +4759,7 @@
 	if (ret < 0) {
 		wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
 			"failed");
-		if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SANE_ERROR_CODES) {
+		if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_VALID_ERROR_CODES) {
 			/*
 			 * The driver is known to mean what is saying, so we
 			 * can stop right here; the association will not
@@ -4081,6 +4826,9 @@
 		 */
 		eapol_sm_invalidate_cached_session(wpa_s->eapol);
 	}
+#if defined(WAPI_ANDROID)
+        }
+#endif 
 	old_ssid = wpa_s->current_ssid;
 	wpa_s->current_ssid = ssid;
 
@@ -4111,6 +4859,9 @@
 	eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
 	if (old_ssid != wpa_s->current_ssid)
 		wpas_notify_network_changed(wpa_s);
+
+	wpas_scs_deinit(wpa_s);
+	wpas_dscp_deinit(wpa_s);
 	eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
 }
 
@@ -4169,7 +4920,7 @@
 			wpa_s->ifname);
 		wpas_notify_mesh_group_removed(wpa_s, mconf->meshid,
 					       mconf->meshid_len, reason_code);
-		wpa_supplicant_leave_mesh(wpa_s);
+		wpa_supplicant_leave_mesh(wpa_s, true);
 	}
 #endif /* CONFIG_MESH */
 
@@ -4532,6 +5283,82 @@
 
 
 /**
+ * wpas_remove_cred - Remove the specified credential and all the network
+ * entries created based on the removed credential
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * @cred: The credential to remove
+ * Returns: 0 on success, -1 on failure
+ */
+int wpas_remove_cred(struct wpa_supplicant *wpa_s, struct wpa_cred *cred)
+{
+	struct wpa_ssid *ssid, *next;
+	int id;
+
+	if (!cred) {
+		wpa_printf(MSG_DEBUG, "Could not find cred");
+		return -1;
+	}
+
+	id = cred->id;
+	if (wpa_config_remove_cred(wpa_s->conf, id) < 0) {
+		wpa_printf(MSG_DEBUG, "Could not find cred %d", id);
+		return -1;
+	}
+
+	wpa_msg(wpa_s, MSG_INFO, CRED_REMOVED "%d", id);
+
+	/* Remove any network entry created based on the removed credential */
+	ssid = wpa_s->conf->ssid;
+	while (ssid) {
+		next = ssid->next;
+
+		if (ssid->parent_cred == cred) {
+			wpa_printf(MSG_DEBUG,
+				   "Remove network id %d since it used the removed credential",
+				   ssid->id);
+			if (wpa_supplicant_remove_network(wpa_s, ssid->id) ==
+			    -1) {
+				wpa_printf(MSG_DEBUG,
+					   "Could not find network id=%d",
+					   ssid->id);
+			}
+		}
+
+		ssid = next;
+	}
+
+	return 0;
+}
+
+
+/**
+ * wpas_remove_cred - Remove all the Interworking credentials
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: 0 on success, -1 on failure
+ */
+int wpas_remove_all_creds(struct wpa_supplicant *wpa_s)
+{
+	int res, ret = 0;
+	struct wpa_cred *cred, *prev;
+
+	cred = wpa_s->conf->cred;
+	while (cred) {
+		prev = cred;
+		cred = cred->next;
+		res = wpas_remove_cred(wpa_s, prev);
+		if (res < 0) {
+			wpa_printf(MSG_DEBUG,
+				   "Removal of all credentials failed - failed to remove credential id=%d",
+				   prev->id);
+			ret = -1;
+		}
+	}
+
+	return ret;
+}
+
+
+/**
  * wpas_set_pkcs11_engine_and_module_path - Set PKCS #11 engine and module path
  * @wpa_s: wpa_supplicant structure for a network interface
  * @pkcs11_engine_path: PKCS #11 engine path or NULL
@@ -4878,8 +5705,13 @@
 	}
 
 	if (name == NULL) {
-		/* default to first driver in the list */
-		return select_driver(wpa_s, 0);
+		/* Default to first successful driver in the list */
+		for (i = 0; wpa_drivers[i]; i++) {
+			if (select_driver(wpa_s, i) == 0)
+				return 0;
+		}
+		/* Drivers have each reported failure, so no wpa_msg() here. */
+		return -1;
 	}
 
 	do {
@@ -4929,7 +5761,15 @@
 	wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
 	wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
 
+	if (wpa_s->own_disconnect_req) {
+		wpa_printf(MSG_DEBUG,
+			   "Drop received EAPOL frame as we are disconnecting");
+		return;
+	}
+
 #ifdef CONFIG_TESTING_OPTIONS
+	wpa_msg_ctrl(wpa_s, MSG_INFO, "EAPOL-RX " MACSTR " %zu",
+		     MAC2STR(src_addr), len);
 	if (wpa_s->ignore_auth_resp) {
 		wpa_printf(MSG_INFO, "RX EAPOL - ignore_auth_resp active!");
 		return;
@@ -5074,9 +5914,19 @@
 
 int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
 {
-	if ((!wpa_s->p2p_mgmt ||
-	     !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
+	if ((!wpa_s->p2p_mgmt ||	    
+	    !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
 	    !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
+#if defined(WAPI_ANDROID)
+                wpa_printf(MSG_DEBUG, "%s : wpa_s->driver->send_eapol ",__FUNCTION__);
+
+		l2_packet_deinit(wpa_s->l2_wapi);
+                wpa_s->l2_wapi = l2_packet_init(wpa_s->ifname,
+                                                wpa_drv_get_mac_addr(wpa_s),
+                                                ETH_P_WAI,
+                                                wapi_asue_rx_wai, wpa_s, 0);
+                wpa_printf(MSG_DEBUG, "wpa_s->l2_wapi = %p ", wpa_s->l2_wapi);
+#endif 
 		l2_packet_deinit(wpa_s->l2);
 		wpa_s->l2 = l2_packet_init(wpa_s->ifname,
 					   wpa_drv_get_mac_addr(wpa_s),
@@ -5084,7 +5934,11 @@
 					   wpas_eapol_needs_l2_packet(wpa_s) ?
 					   wpa_supplicant_rx_eapol : NULL,
 					   wpa_s, 0);
+#if defined(WAPI_ANDROID)
+                if (!(wpa_s->l2 && wpa_s->l2_wapi))
+#else
 		if (wpa_s->l2 == NULL)
+#endif 
 			return -1;
 
 		if (l2_packet_set_packet_filter(wpa_s->l2,
@@ -5097,11 +5951,42 @@
 				"Failed to get own L2 address");
 			return -1;
 		}
+#if defined(WAPI_ANDROID)
+	} else {
+                const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
+                if (addr)
+                        os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
+                wpa_printf(MSG_DEBUG, "%s : wpa_s->driver->send_eapol ", __FUNCTION__);
+
+                if (!wpa_s->p2p_mgmt) {
+			l2_packet_deinit(wpa_s->l2_wapi);
+                        wpa_s->l2_wapi = l2_packet_init(wpa_s->ifname,
+                                                wpa_drv_get_mac_addr(wpa_s),
+                                                ETH_P_WAI,
+                                                wapi_asue_rx_wai, wpa_s, 0);
+                        wpa_printf(MSG_DEBUG, "wpa_s->l2_wapi = %p ", wpa_s->l2_wapi);
+
+                        wpa_s->l2 = l2_packet_init(wpa_s->ifname,
+                                           wpa_drv_get_mac_addr(wpa_s),
+                                           ETH_P_EAPOL,
+                                           wpa_supplicant_rx_eapol, wpa_s, 0);
+                        if ( !(wpa_s->l2 && wpa_s->l2_wapi) )
+                                return -1;
+                }
+        }
+        if (wpa_s->l2_wapi && l2_packet_get_own_addr(wpa_s->l2_wapi, wpa_s->wapi_own_addr)) {
+                wpa_printf(MSG_ERROR, "Failed to get own WAPI L2 address");
+                return -1;
+        }
+        wpa_printf(MSG_ERROR, "Own WAPI MAC address: " MACSTR,
+                MAC2STR(wpa_s->wapi_own_addr));
+#else
 	} else {
 		const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
 		if (addr)
 			os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
 	}
+#endif 
 
 	wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
 	wpas_wps_update_mac_addr(wpa_s);
@@ -5294,12 +6179,18 @@
 	wpa_s->parent = parent ? parent : wpa_s;
 	wpa_s->p2pdev = wpa_s->parent;
 	wpa_s->sched_scanning = 0;
+	wpa_s->setband_mask = WPA_SETBAND_AUTO;
 
+#if defined(WAPI_ANDROID)
+        wpa_s->ap_wapi_ie_len = 0;
+        wpa_s->assoc_wapi_ie_len = 0;
+#endif 
 	dl_list_init(&wpa_s->bss_tmp_disallowed);
 	dl_list_init(&wpa_s->fils_hlp_req);
 #ifdef CONFIG_TESTING_OPTIONS
 	dl_list_init(&wpa_s->drv_signal_override);
 #endif /* CONFIG_TESTING_OPTIONS */
+	dl_list_init(&wpa_s->active_scs_ids);
 
 	return wpa_s;
 }
@@ -6038,7 +6929,7 @@
 		dl_list_for_each(tmp, &radio->work, struct wpa_radio_work,
 				 list) {
 			if (os_strcmp(tmp->type, "scan") == 0 &&
-			    radio->external_scan_running &&
+			    external_scan_running(radio) &&
 			    (((struct wpa_driver_scan_params *)
 			      tmp->ctx)->only_new_results ||
 			     tmp->wpa_s->clear_driver_scan_cache))
@@ -6094,7 +6985,7 @@
 			 * rejected by kernel.
 			 */
 			if (os_strcmp(tmp->type, "scan") == 0 &&
-			    radio->external_scan_running &&
+			    external_scan_running(radio) &&
 			    (((struct wpa_driver_scan_params *)
 			      tmp->ctx)->only_new_results ||
 			     tmp->wpa_s->clear_driver_scan_cache))
@@ -6133,7 +7024,7 @@
 		if (work->started)
 			return; /* already started and still in progress */
 
-		if (wpa_s && wpa_s->radio->external_scan_running) {
+		if (wpa_s && external_scan_running(wpa_s->radio)) {
 			wpa_printf(MSG_DEBUG, "Delay radio work start until externally triggered scan completes");
 			return;
 		}
@@ -6229,6 +7120,10 @@
 		   wpa_s->ifname, radio->name);
 	dl_list_del(&wpa_s->radio_list);
 	radio_remove_works(wpa_s, NULL, 0);
+	/* If the interface that triggered the external scan was removed, the
+	 * external scan is no longer running. */
+	if (wpa_s == radio->external_scan_req_interface)
+		radio->external_scan_req_interface = NULL;
 	wpa_s->radio = NULL;
 	if (!dl_list_empty(&radio->ifaces))
 		return; /* Interfaces remain for this radio */
@@ -6488,6 +7383,18 @@
 		wpa_s->confname = os_strdup(iface->confname);
 #endif /* CONFIG_BACKEND_FILE */
 		wpa_s->conf = wpa_config_read(wpa_s->confname, NULL);
+#if defined(WAPI_ANDROID)
+                wpa_printf(MSG_ERROR, "interface  %s\n",iface->ifname);
+                if ((!strncmp(iface->ifname,"eth",3) || !strncmp(iface->ifname,"wlan",4))
+                        && !wpa_s->global->wapi_initialized) {
+                        wpa_s->global->wapi_initialized = 1;
+                        wpa_printf(MSG_ERROR, " WIFI_lib_init WIFI_lib_init WIFI_lib_init WIFI_lib_init \n");
+                        if (WIFI_lib_init()) {
+                                wpa_printf(MSG_ERROR, "##### Failed to initialize WAPI lib, exit #####\n");
+                                return -1;
+                        }
+                }
+#endif 
 		if (wpa_s->conf == NULL) {
 			wpa_printf(MSG_ERROR, "Failed to read or parse "
 				   "configuration '%s'.", wpa_s->confname);
@@ -6850,8 +7757,12 @@
 
 	wpa_s->disconnected = 1;
 	if (wpa_s->drv_priv) {
-		/* Don't deauthenticate if WoWLAN is enabled */
-		if (!wpa_drv_get_wowlan(wpa_s)) {
+		/*
+		 * Don't deauthenticate if WoWLAN is enable and not explicitly
+		 * been configured to disconnect.
+		 */
+		if (!wpa_drv_get_wowlan(wpa_s) ||
+		    wpa_s->conf->wowlan_disconnect_on_deinit) {
 			wpa_supplicant_deauthenticate(
 				wpa_s, WLAN_REASON_DEAUTH_LEAVING);
 
@@ -6889,14 +7800,12 @@
 	if (terminate)
 		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
 
-	if (wpa_s->ctrl_iface) {
-		wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
-		wpa_s->ctrl_iface = NULL;
-	}
+	wpa_supplicant_ctrl_iface_deinit(wpa_s, wpa_s->ctrl_iface);
+	wpa_s->ctrl_iface = NULL;
 
 #ifdef CONFIG_MESH
 	if (wpa_s->ifmsh) {
-		wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh);
+		wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh, true);
 		wpa_s->ifmsh = NULL;
 	}
 #endif /* CONFIG_MESH */
@@ -7317,7 +8226,11 @@
 
 	wpa_printf(MSG_DEBUG, "wpa_supplicant v%s", VERSION_STR);
 
+#if defined(WAPI_ANDROID)
+        if (eloop_init(global)) {
+#else
 	if (eloop_init()) {
+#endif 
 		wpa_printf(MSG_ERROR, "Failed to initialize event loop");
 		wpa_supplicant_deinit(global);
 		return NULL;
@@ -7422,6 +8335,9 @@
 #ifdef CONFIG_WIFI_DISPLAY
 	wifi_display_deinit(global);
 #endif /* CONFIG_WIFI_DISPLAY */
+#if defined(WAPI_ANDROID)
+	WIFI_lib_exit();
+#endif 
 
 	while (global->ifaces)
 		wpa_supplicant_remove_iface(global, global->ifaces, 1);
@@ -7558,7 +8474,7 @@
 			continue;
 		if (bss->ssid_len == cbss->ssid_len &&
 		    os_memcmp(bss->ssid, cbss->ssid, bss->ssid_len) == 0 &&
-		    !wpa_blacklist_is_blacklisted(wpa_s, bss->bssid)) {
+		    !wpa_bssid_ignore_is_listed(wpa_s, bss->bssid)) {
 			add_freq(freqs, &num_freqs, bss->freq);
 			if (num_freqs == max_freqs)
 				break;
@@ -7588,7 +8504,7 @@
 	eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
 
 	/*
-	 * There is no point in blacklisting the AP if this event is
+	 * There is no point in ignoring the AP temporarily if this event is
 	 * generated based on local request to disconnect.
 	 */
 	if (wpa_s->own_disconnect_req || wpa_s->own_reconnect_req) {
@@ -7612,13 +8528,13 @@
 	}
 #endif /* ABOVE_10 */
 	/*
-	 * Add the failed BSSID into the blacklist and speed up next scan
+	 * Add the failed BSSID into the ignore list and speed up next scan
 	 * attempt if there could be other APs that could accept association.
 	 */
-	count = wpa_blacklist_add(wpa_s, bssid);
+	count = wpa_bssid_ignore_add(wpa_s, bssid);
 	if (count == 1 && wpa_s->current_bss) {
 		/*
-		 * This BSS was not in the blacklist before. If there is
+		 * This BSS was not in the ignore list before. If there is
 		 * another BSS available for the same ESS, we should try that
 		 * next. Otherwise, we may as well try this one once more
 		 * before allowing other, likely worse, ESSes to be considered.
@@ -7627,7 +8543,7 @@
 		if (freqs) {
 			wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS "
 				"has been seen; try it next");
-			wpa_blacklist_add(wpa_s, bssid);
+			wpa_bssid_ignore_add(wpa_s, bssid);
 			/*
 			 * On the next scan, go through only the known channels
 			 * used in this ESS based on previous scans to speed up
@@ -7685,6 +8601,46 @@
 
 
 #ifdef CONFIG_FILS
+
+void fils_pmksa_cache_flush(struct wpa_supplicant *wpa_s)
+{
+	struct wpa_ssid *ssid = wpa_s->current_ssid;
+	const u8 *realm, *username, *rrk;
+	size_t realm_len, username_len, rrk_len;
+	u16 next_seq_num;
+
+	/* Clear the PMKSA cache entry if FILS authentication was rejected.
+	 * Check for ERP keys existing to limit when this can be done since
+	 * the rejection response is not protected and such triggers should
+	 * really not allow internal state to be modified unless required to
+	 * avoid significant issues in functionality. In addition, drop
+	 * externally configure PMKSA entries even without ERP keys since it
+	 * is possible for an external component to add PMKSA entries for FILS
+	 * authentication without restoring previously generated ERP keys.
+	 *
+	 * In this case, this is needed to allow recovery from cases where the
+	 * AP or authentication server has dropped PMKSAs and ERP keys. */
+	if (!ssid || !ssid->eap.erp || !wpa_key_mgmt_fils(ssid->key_mgmt))
+		return;
+
+	if (eapol_sm_get_erp_info(wpa_s->eapol, &ssid->eap,
+				  &username, &username_len,
+				  &realm, &realm_len, &next_seq_num,
+				  &rrk, &rrk_len) != 0 ||
+	    !realm) {
+		wpa_dbg(wpa_s, MSG_DEBUG,
+			"FILS: Drop external PMKSA cache entry");
+		wpa_sm_aborted_external_cached(wpa_s->wpa);
+		wpa_sm_external_pmksa_cache_flush(wpa_s->wpa, ssid);
+		return;
+	}
+
+	wpa_dbg(wpa_s, MSG_DEBUG, "FILS: Drop PMKSA cache entry");
+	wpa_sm_aborted_cached(wpa_s->wpa);
+	wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
+}
+
+
 void fils_connection_failure(struct wpa_supplicant *wpa_s)
 {
 	struct wpa_ssid *ssid = wpa_s->current_ssid;
@@ -7933,6 +8889,16 @@
 }
 
 
+int pmf_in_use(struct wpa_supplicant *wpa_s, const u8 *addr)
+{
+	if (wpa_s->current_ssid == NULL ||
+	    wpa_s->wpa_state < WPA_4WAY_HANDSHAKE ||
+	    os_memcmp(addr, wpa_s->bssid, ETH_ALEN) != 0)
+		return 0;
+	return wpa_sm_pmf_enabled(wpa_s->wpa);
+}
+
+
 int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s)
 {
 	if (wpa_s->global->conc_pref == WPA_CONC_PREF_P2P)
@@ -8101,6 +9067,10 @@
 	eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
 	radio_remove_works(wpa_s, "connect", 0);
 	radio_remove_works(wpa_s, "sme-connect", 0);
+	wpa_s->roam_in_progress = false;
+#ifdef CONFIG_WNM
+	wpa_s->bss_trans_mgmt_in_progress = false;
+#endif /* CONFIG_WNM */
 }
 
 
@@ -8293,10 +9263,13 @@
 
 struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes,
 				   u16 num_modes, enum hostapd_hw_mode mode,
-				   int is_6ghz)
+				   bool is_6ghz)
 {
 	u16 i;
 
+	if (!modes)
+		return NULL;
+
 	for (i = 0; i < num_modes; i++) {
 		if (modes[i].mode != mode ||
 		    !modes[i].num_channels || !modes[i].channels)
@@ -8310,6 +9283,22 @@
 }
 
 
+struct hostapd_hw_modes * get_mode_with_freq(struct hostapd_hw_modes *modes,
+					     u16 num_modes, int freq)
+{
+	int i, j;
+
+	for (i = 0; i < num_modes; i++) {
+		for (j = 0; j < modes[i].num_channels; j++) {
+			if (freq == modes[i].channels[j].freq)
+				return &modes[i];
+		}
+	}
+
+	return NULL;
+}
+
+
 static struct
 wpa_bss_tmp_disallowed * wpas_get_disallowed_bss(struct wpa_supplicant *wpa_s,
 						 const u8 *bssid)
@@ -8357,8 +9346,7 @@
 	dl_list_for_each(tmp, &wpa_s->bss_tmp_disallowed,
 			 struct wpa_bss_tmp_disallowed, list) {
 		if (bss == tmp) {
-			dl_list_del(&tmp->list);
-			os_free(tmp);
+			remove_bss_tmp_disallowed_entry(wpa_s, tmp);
 			wpa_set_driver_tmp_disallow_list(wpa_s);
 			break;
 		}
@@ -8411,8 +9399,11 @@
 		return 0;
 
 	if (disallowed->rssi_threshold != 0 &&
-	    bss->level > disallowed->rssi_threshold)
+	    bss->level > disallowed->rssi_threshold) {
+		remove_bss_tmp_disallowed_entry(wpa_s, disallowed);
+		wpa_set_driver_tmp_disallow_list(wpa_s);
 		return 0;
+	}
 
 	return 1;
 }
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpa_supplicant.conf b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpa_supplicant.conf
index 46f7875..6619d6b 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpa_supplicant.conf
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpa_supplicant.conf
@@ -150,6 +150,9 @@
 # This timeout value is used in mesh STA to clean up inactive stations.
 #mesh_max_inactivity=300
 
+# Enable 802.11s layer-2 routing and forwarding (dot11MeshForwarding)
+#mesh_fwding=1
+
 # cert_in_cb - Whether to include a peer certificate dump in events
 # This controls whether peer certificates for authentication server and
 # its certificate chain are included in EAP peer certificate events. This is
@@ -366,7 +369,14 @@
 
 # Password (and passphrase, etc.) backend for external storage
 # format: <backend name>[:<optional backend parameters>]
+# Test backend which stores passwords in memory. Should only be used for
+# development purposes.
 #ext_password_backend=test:pw1=password|pw2=testing
+# File-based backend which reads passwords from a file. The parameter
+# identifies the file to read passwords from. The password file follows the
+# format of wpa_supplicant.conf and accepts simple `key=passphrase` formatted
+# passwords.
+#ext_password_backend=file:/path/to/passwords.conf
 
 
 # Disable P2P functionality
@@ -458,6 +468,9 @@
 # 1:  Scan current operating frequency if another VIF on the same radio
 #     is already associated.
 
+# Seconds to consider old scan results valid for association (default: 5)
+#scan_res_valid_for_connect=5
+
 # MAC address policy default
 # 0 = use permanent MAC address
 # 1 = use random MAC address for each ESS connection
@@ -978,10 +991,11 @@
 # WPA3-Personal-only mode: ieee80211w=2 and key_mgmt=SAE
 #
 # ocv: whether operating channel validation is enabled
-# This is a countermeasure against multi-channel man-in-the-middle attacks.
+# This is a countermeasure against multi-channel on-path attacks.
 # Enabling this automatically also enables ieee80211w, if not yet enabled.
 # 0 = disabled (default)
-# 1 = enabled
+# 1 = enabled if wpa_supplicant's SME in use. Otherwise enabled only when the
+#     driver indicates support for operating channel validation.
 #ocv=1
 #
 # auth_alg: list of allowed IEEE 802.11 authentication algorithms
@@ -1482,8 +1496,11 @@
 # 2: do not allow PFS to be used
 #dpp_pfs=0
 
-# Whether Beacon protection is enabled
-# This depends on management frame protection (ieee80211w) being enabled.
+# Whether beacon protection is enabled
+# This depends on management frame protection (ieee80211w) being enabled and
+# beacon protection support indication from the driver.
+# 0 = disabled (default)
+# 1 = enabled
 #beacon_prot=0
 
 # OWE DH Group
@@ -2006,12 +2023,12 @@
 	key_mgmt=NONE
 }
 
-# Example configuration blacklisting two APs - these will be ignored
+# Example configuration ignoring two APs - these will be ignored
 # for this network.
 network={
 	ssid="example"
 	psk="very secret passphrase"
-	bssid_blacklist=02:11:22:33:44:55 02:22:aa:44:55:66
+	bssid_ignore=02:11:22:33:44:55 02:22:aa:44:55:66
 }
 
 # Example configuration limiting AP selection to a specific set of APs;
@@ -2019,7 +2036,7 @@
 network={
 	ssid="example"
 	psk="very secret passphrase"
-	bssid_whitelist=02:55:ae:bc:00:00/ff:ff:ff:ff:00:00 00:00:77:66:55:44/00:00:ff:ff:ff:ff
+	bssid_accept=02:55:ae:bc:00:00/ff:ff:ff:ff:00:00 00:00:77:66:55:44/00:00:ff:ff:ff:ff
 }
 
 # Example config file that will only scan on channel 36.
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpa_supplicant_i.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpa_supplicant_i.h
index 4728c12..8faabf4 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpa_supplicant_i.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpa_supplicant_i.h
@@ -14,7 +14,14 @@
 #include "common/defs.h"
 #include "common/sae.h"
 #include "common/wpa_ctrl.h"
+#include "crypto/sha384.h"
+#include "eapol_supp/eapol_supp_sm.h"
 #include "wps/wps_defs.h"
+#if defined(WAPI_ANDROID)
+#include "wapi_asue.h"
+#include "wapi_config.h"
+#endif 
+#include "config.h"
 #include "config_ssid.h"
 #include "wmm_ac.h"
 
@@ -29,6 +36,9 @@
 #endif /* CONFIG_NO_STDOUT_DEBUG */
 
 #if !defined(OREO) && !defined(PIE) && !defined(ABOVE_10)
+#if defined(WAPI_ANDROID)
+struct wapi_asue_st *wpa_s;
+#endif
 #endif
 struct wpa_sm;
 struct wpa_supplicant;
@@ -38,6 +48,7 @@
 struct wpa_scan_results;
 struct hostapd_hw_modes;
 struct wpa_driver_associate_params;
+struct wpa_cred;
 
 /*
  * Forward declarations of private structures used within the ctrl_iface
@@ -48,10 +59,9 @@
 struct ctrl_iface_global_priv;
 struct wpas_dbus_priv;
 struct wpas_binder_priv;
-
-/* How many seconds to consider old scan results valid for association. */
-#define SCAN_RES_VALID_FOR_CONNECT 5
-
+#ifdef CONFIG_AIDL
+struct wpas_aidl_priv;
+#endif
 /**
  * struct wpa_interface - Parameters for wpa_supplicant_add_iface()
  */
@@ -286,8 +296,14 @@
 #ifdef CONFIG_HIDL
 	struct wpas_hidl_priv *hidl;
 #endif
+#ifdef CONFIG_AIDL
+	struct wpas_aidl_priv *aidl;
+#endif
 	void **drv_priv;
 	size_t drv_count;
+#if defined(WAPI_ANDROID)
+        struct _asue_cert_info cert_info;
+#endif 
 	struct os_time suspend_time;
 	struct p2p_data *p2p;
 	struct wpa_supplicant *p2p_init_wpa_s;
@@ -327,6 +343,9 @@
 #endif /* CONFIG_WIFI_DISPLAY */
 
 	struct psk_list_entry *add_psk; /* From group formation */
+#if defined(WAPI_ANDROID)
+        unsigned int wapi_initialized;
+#endif 
 /* Support STA+GC on DBDC, SBSC and not on SBDC. */
 	int rsdb_flag;
 };
@@ -342,12 +361,23 @@
 struct wpa_radio {
 	char name[16]; /* from driver_ops get_radio_name() or empty if not
 			* available */
-	unsigned int external_scan_running:1;
+	/** NULL if no external scan running. */
+	struct wpa_supplicant *external_scan_req_interface;
 	unsigned int num_active_works;
 	struct dl_list ifaces; /* struct wpa_supplicant::radio_list entries */
 	struct dl_list work; /* struct wpa_radio_work::list entries */
 };
 
+/**
+ * Checks whether an external scan is running on a given radio.
+ * @radio: Pointer to radio struct
+ * Returns: true if an external scan is running, false otherwise.
+ */
+static inline bool external_scan_running(struct wpa_radio *radio)
+{
+	return radio && radio->external_scan_req_interface;
+}
+
 #define MAX_ACTIVE_WORKS 2
 
 
@@ -529,6 +559,176 @@
 	bool valid_config;
 };
 
+struct dscp_policy_status {
+	u8 id;
+	u8 status;
+};
+
+struct dscp_resp_data {
+	bool more;
+	bool reset;
+	bool solicited;
+	struct dscp_policy_status *policy;
+	int num_policies;
+};
+
+#ifdef CONFIG_PASN
+
+struct pasn_fils {
+	u8 nonce[FILS_NONCE_LEN];
+	u8 anonce[FILS_NONCE_LEN];
+	u8 session[FILS_SESSION_LEN];
+	u8 erp_pmkid[PMKID_LEN];
+	bool completed;
+};
+
+struct wpas_pasn {
+	int akmp;
+	int cipher;
+	u16 group;
+	int freq;
+	size_t kdk_len;
+
+	u8 trans_seq;
+	u8 status;
+
+	u8 bssid[ETH_ALEN];
+	size_t pmk_len;
+	u8 pmk[PMK_LEN_MAX];
+	bool using_pmksa;
+
+	u8 hash[SHA384_MAC_LEN];
+
+	struct wpabuf *beacon_rsne_rsnxe;
+	struct wpa_ptk ptk;
+	struct crypto_ecdh *ecdh;
+
+	struct wpabuf *comeback;
+	u16 comeback_after;
+
+#ifdef CONFIG_SAE
+	struct sae_data sae;
+#endif /* CONFIG_SAE */
+
+	struct wpa_ssid *ssid;
+
+#ifdef CONFIG_FILS
+	struct pasn_fils fils;
+#endif /* CONFIG_FILS */
+
+#ifdef CONFIG_IEEE80211R
+	u8 pmk_r1[PMK_LEN_MAX];
+	size_t pmk_r1_len;
+	u8 pmk_r1_name[WPA_PMK_NAME_LEN];
+#endif /* CONFIG_IEEE80211R */
+};
+#endif /* CONFIG_PASN */
+
+
+enum ip_version {
+	IPV4 = 4,
+	IPV6 = 6,
+};
+
+
+struct ipv4_params {
+	struct in_addr src_ip;
+	struct in_addr dst_ip;
+	u16 src_port;
+	u16 dst_port;
+	u8 dscp;
+	u8 protocol;
+	u8 param_mask;
+};
+
+
+struct ipv6_params {
+	struct in6_addr src_ip;
+	struct in6_addr dst_ip;
+	u16 src_port;
+	u16 dst_port;
+	u8 dscp;
+	u8 next_header;
+	u8 flow_label[3];
+	u8 param_mask;
+};
+
+
+struct type4_params {
+	u8 classifier_mask;
+	enum ip_version ip_version;
+	union {
+		struct ipv4_params v4;
+		struct ipv6_params v6;
+	} ip_params;
+};
+
+
+struct type10_params {
+	u8 prot_instance;
+	u8 prot_number;
+	u8 *filter_value;
+	u8 *filter_mask;
+	size_t filter_len;
+};
+
+
+struct tclas_element {
+	u8 user_priority;
+	u8 classifier_type;
+	union {
+		struct type4_params type4_param;
+		struct type10_params type10_param;
+	} frame_classifier;
+};
+
+
+struct scs_desc_elem {
+	u8 scs_id;
+	enum scs_request_type request_type;
+	u8 intra_access_priority;
+	bool scs_up_avail;
+	struct tclas_element *tclas_elems;
+	unsigned int num_tclas_elem;
+	u8 tclas_processing;
+};
+
+
+struct scs_robust_av_data {
+	struct scs_desc_elem *scs_desc_elems;
+	unsigned int num_scs_desc;
+};
+
+
+enum scs_response_status {
+	SCS_DESC_SENT = 0,
+	SCS_DESC_SUCCESS = 1,
+};
+
+
+struct active_scs_elem {
+	struct dl_list list;
+	u8 scs_id;
+	enum scs_response_status status;
+};
+
+#ifdef CONFIG_AIDL
+struct dscp_policy_data {
+        u8 policy_id;
+        u8 req_type;
+        u8 dscp;
+        bool dscp_info;
+        const u8 *frame_classifier;
+        u8 frame_classifier_len;
+        struct type4_params type4_param;
+        const u8 *domain_name;
+        u8 domain_name_len;
+        u16 start_port;
+        u16 end_port;
+        bool port_range_info;
+};
+#endif
+
 /**
  * struct wpa_supplicant - Internal data for wpa_supplicant interface
  *
@@ -545,12 +745,19 @@
 	struct wpa_supplicant *p2pdev;
 	struct wpa_supplicant *next;
 	struct l2_packet_data *l2;
+#if defined(WAPI_ANDROID)
+        struct l2_packet_data *l2_wapi;
+        struct wpa_scan_results *wapi_scan_res;
+#endif 
 	struct l2_packet_data *l2_br;
 	struct os_reltime roam_start;
 	struct os_reltime roam_time;
 	struct os_reltime session_start;
 	struct os_reltime session_length;
 	unsigned char own_addr[ETH_ALEN];
+#if defined(WAPI_ANDROID)
+        unsigned char wapi_own_addr[ETH_ALEN];
+#endif 
 	unsigned char perm_addr[ETH_ALEN];
 	char ifname[100];
 #ifdef CONFIG_MATCH_IFACE
@@ -569,6 +776,9 @@
 #ifdef CONFIG_CTRL_IFACE_HIDL
 	const void *hidl_object_key;
 #endif /* CONFIG_CTRL_IFACE_HIDL */
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	const void *aidl_object_key;
+#endif /* CONFIG_CTRL_IFACE_AIDL */
 	char bridge_ifname[16];
 
 	char *confname;
@@ -584,6 +794,7 @@
 	u8 pending_bssid[ETH_ALEN]; /* If wpa_state == WPA_ASSOCIATING, this
 				     * field contains the target BSSID. */
 	int reassociate; /* reassociation requested */
+	bool roam_in_progress; /* roam in progress */
 	unsigned int reassoc_same_bss:1; /* reassociating to the same BSS */
 	unsigned int reassoc_same_ess:1; /* reassociating to the same ESS */
 	int disconnected; /* all connections disabled; i.e., do no reassociate
@@ -615,7 +826,7 @@
 	struct wpa_ssid_value *disallow_aps_ssid;
 	size_t disallow_aps_ssid_count;
 
-	enum set_band setband;
+	u32 setband_mask;
 
 	/* Preferred network for the next connection attempt */
 	struct wpa_ssid *next_ssid;
@@ -640,6 +851,7 @@
 
 	void (*scan_res_handler)(struct wpa_supplicant *wpa_s,
 				 struct wpa_scan_results *scan_res);
+	void (*scan_res_fail_handler)(struct wpa_supplicant *wpa_s);
 	struct dl_list bss; /* struct wpa_bss::list */
 	struct dl_list bss_id; /* struct wpa_bss::list_id */
 	size_t num_bss;
@@ -659,6 +871,8 @@
 	int interface_removed; /* whether the network interface has been
 				* removed */
 	struct wpa_sm *wpa;
+	struct ptksa_cache *ptksa;
+
 	struct eapol_sm *eapol;
 
 	struct ctrl_iface_priv *ctrl_iface;
@@ -685,7 +899,7 @@
 	unsigned int keys_cleared; /* bitfield of key indexes that the driver is
 				    * known not to be configured with a key */
 
-	struct wpa_blacklist *blacklist;
+	struct wpa_bssid_ignore *bssid_ignore;
 
 	/* Number of connection failures since last successful connection */
 	unsigned int consecutive_conn_failures;
@@ -735,6 +949,7 @@
 	unsigned int own_scan_requested:1;
 	unsigned int own_scan_running:1;
 	unsigned int clear_driver_scan_cache:1;
+	unsigned int manual_non_coloc_6ghz:1;
 	unsigned int manual_scan_id;
 	int scan_interval; /* time in sec between scans to find suitable AP */
 	int normal_scans; /* normal scans run before sched_scan */
@@ -759,6 +974,30 @@
 	unsigned int suitable_network;
 	unsigned int no_suitable_network;
 
+#if defined(WAPI_ANDROID)
+        struct wapi_config *wapi_conf;
+        int wai_received;
+        struct wapi_state_machine *wapi_sm;
+        int ctrl_sock; /* UNIX domain socket for control interface or -1 if
+                        * not used */
+        int cgi_sock; /* UNIX domain socket for control interface or -1 if
+                        * not used */
+        int rxfragstamp;
+        struct wapi_rxfrag *rxfrag;
+        u16 rxseq;
+        u16 txseq;
+
+
+        int wapi_state;
+        unsigned char last_wai_src[ETH_ALEN];
+        u8 pad;
+        u8 flag;
+        struct _resendbuf_st *buf;
+        u8 assoc_wapi_ie[256]; /* Own WAPI/RSN IE from (Re)AssocReq */
+        u8 ap_wapi_ie[256];
+        u8 ap_wapi_ie_len;
+        u8 assoc_wapi_ie_len;
+#endif 
 	u64 drv_flags;
 	u64 drv_flags2;
 	unsigned int drv_enc;
@@ -793,7 +1032,7 @@
 	struct wps_er *wps_er;
 	unsigned int wps_run;
 	struct os_reltime wps_pin_start_time;
-	int blacklist_cleared;
+	bool bssid_ignore_cleared;
 
 	struct wpabuf *pending_eapol_rx;
 	struct os_reltime pending_eapol_rx_time;
@@ -1001,6 +1240,7 @@
 	unsigned int p2p_disable_ip_addr_req:1;
 	unsigned int p2ps_method_config_any:1;
 	unsigned int p2p_cli_probe:1;
+	unsigned int p2p_go_allow_dfs:1;
 	enum hostapd_hw_mode p2p_go_acs_band;
 	int p2p_persistent_go_freq;
 	int p2p_persistent_id;
@@ -1148,6 +1388,7 @@
 	struct os_reltime wnm_cand_valid_until;
 	u8 wnm_cand_from_bss[ETH_ALEN];
 	enum bss_trans_mgmt_status_code bss_tm_status;
+	bool bss_trans_mgmt_in_progress;
 	struct wpabuf *coloc_intf_elems;
 	u8 coloc_intf_dialog_token;
 	u8 coloc_intf_auto_report;
@@ -1374,6 +1615,24 @@
 	unsigned int multi_ap_fronthaul:1;
 	struct robust_av_data robust_av;
 	bool mscs_setup_done;
+
+#ifdef CONFIG_PASN
+	struct wpas_pasn pasn;
+	struct wpa_radio_work *pasn_auth_work;
+#endif /* CONFIG_PASN */
+	struct scs_robust_av_data scs_robust_av_req;
+	u8 scs_dialog_token;
+#ifdef CONFIG_TESTING_OPTIONS
+	unsigned int disable_scs_support:1;
+	unsigned int disable_mscs_support:1;
+#endif /* CONFIG_TESTING_OPTIONS */
+	struct dl_list active_scs_ids;
+	bool ongoing_scs_req;
+	u8 dscp_req_dialog_token;
+	u8 dscp_query_dialog_token;
+	unsigned int enable_dscp_policy_capa:1;
+	unsigned int connection_dscp:1;
+	unsigned int wait_for_dscp_req:1;
 };
 
 
@@ -1399,9 +1658,12 @@
 int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s);
 int wpa_supplicant_update_bridge_ifname(struct wpa_supplicant *wpa_s,
 					const char *bridge_ifname);
+void wpas_set_mgmt_group_cipher(struct wpa_supplicant *wpa_s,
+				struct wpa_ssid *ssid, struct wpa_ie_data *ie);
 int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
 			      struct wpa_bss *bss, struct wpa_ssid *ssid,
 			      u8 *wpa_ie, size_t *wpa_ie_len);
+int wpas_restore_permanent_mac_addr(struct wpa_supplicant *wpa_s);
 void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
 			      struct wpa_bss *bss,
 			      struct wpa_ssid *ssid);
@@ -1431,6 +1693,8 @@
 				    struct wpa_ssid *ssid);
 void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
 				   struct wpa_ssid *ssid);
+int wpas_remove_cred(struct wpa_supplicant *wpa_s, struct wpa_cred *cred);
+int wpas_remove_all_creds(struct wpa_supplicant *wpa_s);
 int wpas_set_pkcs11_engine_and_module_path(struct wpa_supplicant *wpa_s,
 					   const char *pkcs11_engine_path,
 					   const char *pkcs11_module_path);
@@ -1472,6 +1736,7 @@
 void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s);
 void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid);
 void fils_connection_failure(struct wpa_supplicant *wpa_s);
+void fils_pmksa_cache_flush(struct wpa_supplicant *wpa_s);
 int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s);
 int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s);
 void wpas_auth_failed(struct wpa_supplicant *wpa_s, char *reason);
@@ -1489,6 +1754,25 @@
 
 int wpas_get_op_chan_phy(int freq, const u8 *ies, size_t ies_len,
 			 u8 *op_class, u8 *chan, u8 *phy_type);
+
+#ifdef CONFIG_TWT_OFFLOAD_IFX
+int wpas_twt_offload_send_setup(struct wpa_supplicant *wpa_s, u8 dtok, int exponent,
+				int mantissa, u8 min_twt, int setup_cmd, u64 twt,
+				u64 twt_offset, bool requestor, bool trigger,
+				bool implicit, bool flow_type, u8 flow_id,
+				bool protection, u8 twt_channel, u8 control);
+int wpas_twt_offload_send_teardown(struct wpa_supplicant *wpa_s, u8 flags);
+int wpas_twt_offload_init_default_session(struct wpa_supplicant *wpa_s);
+int wpas_twt_offload_deinit_default_session(struct wpa_supplicant *wpa_s);
+#else
+int wpas_twt_send_setup(struct wpa_supplicant *wpa_s, u8 dtok, int exponent,
+			int mantissa, u8 min_twt, int setup_cmd, u64 twt,
+			bool requestor, bool trigger, bool implicit,
+			bool flow_type, u8 flow_id, bool protection,
+			u8 twt_channel, u8 control);
+int wpas_twt_send_teardown(struct wpa_supplicant *wpa_s, u8 flags);
+#endif /* CONFIG_TWT_OFFLOAD_IFX */
+
 void wpas_rrm_reset(struct wpa_supplicant *wpa_s);
 void wpas_rrm_process_neighbor_rep(struct wpa_supplicant *wpa_s,
 				   const u8 *report, size_t report_len);
@@ -1542,7 +1826,7 @@
 
 /* op_classes.c */
 enum chan_allowed {
-	NOT_ALLOWED, NO_IR, ALLOWED
+	NOT_ALLOWED, NO_IR, RADAR, ALLOWED
 };
 
 enum chan_allowed verify_channel(struct hostapd_hw_modes *mode, u8 op_class,
@@ -1646,6 +1930,7 @@
 
 int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
 int wpas_get_ssid_pmf(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
+int pmf_in_use(struct wpa_supplicant *wpa_s, const u8 *addr);
 
 int wpas_init_ext_pw(struct wpa_supplicant *wpa_s);
 
@@ -1680,7 +1965,9 @@
 
 struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes,
 				   u16 num_modes, enum hostapd_hw_mode mode,
-				   int is_6ghz);
+				   bool is_6ghz);
+struct hostapd_hw_modes * get_mode_with_freq(struct hostapd_hw_modes *modes,
+					     u16 num_modes, int freq);
 
 void wpa_bss_tmp_disallow(struct wpa_supplicant *wpa_s, const u8 *bssid,
 			  unsigned int sec, int rssi_threshold);
@@ -1711,6 +1998,36 @@
 				       size_t len);
 void wpas_handle_assoc_resp_mscs(struct wpa_supplicant *wpa_s, const u8 *bssid,
 				 const u8 *ies, size_t ies_len);
+int wpas_send_scs_req(struct wpa_supplicant *wpa_s);
+void free_up_tclas_elem(struct scs_desc_elem *elem);
+void free_up_scs_desc(struct scs_robust_av_data *data);
+void wpas_handle_robust_av_scs_recv_action(struct wpa_supplicant *wpa_s,
+					   const u8 *src, const u8 *buf,
+					   size_t len);
+void wpas_scs_deinit(struct wpa_supplicant *wpa_s);
+void wpas_handle_qos_mgmt_recv_action(struct wpa_supplicant *wpa_s,
+				      const u8 *src,
+				      const u8 *buf, size_t len);
+void wpas_dscp_deinit(struct wpa_supplicant *wpa_s);
+int wpas_send_dscp_response(struct wpa_supplicant *wpa_s,
+			    struct dscp_resp_data *resp_data);
+void wpas_handle_assoc_resp_qos_mgmt(struct wpa_supplicant *wpa_s,
+				     const u8 *ies, size_t ies_len);
+int wpas_send_dscp_query(struct wpa_supplicant *wpa_s, const char *domain_name,
+			 size_t domain_name_length);
+
+int wpas_pasn_auth_start(struct wpa_supplicant *wpa_s,
+			 const u8 *bssid, int akmp, int cipher,
+			 u16 group, int network_id,
+			 const u8 *comeback, size_t comeback_len);
+void wpas_pasn_auth_stop(struct wpa_supplicant *wpa_s);
+int wpas_pasn_auth_tx_status(struct wpa_supplicant *wpa_s,
+			     const u8 *data, size_t data_len, u8 acked);
+int wpas_pasn_auth_rx(struct wpa_supplicant *wpa_s,
+		      const struct ieee80211_mgmt *mgmt, size_t len);
+
+int wpas_pasn_deauthenticate(struct wpa_supplicant *wpa_s, const u8 *bssid);
+
 #ifdef CONFIG_ANDROID12
 int disabled_freq(struct wpa_supplicant *wpa_s, int freq);
 #endif /* CONFIG_ANDROID12 */
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpas_glue.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpas_glue.c
index d309b8b..eb05726 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpas_glue.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpas_glue.c
@@ -16,6 +16,7 @@
 #include "config.h"
 #include "l2_packet/l2_packet.h"
 #include "common/wpa_common.h"
+#include "common/ptksa_cache.h"
 #include "wpa_supplicant_i.h"
 #include "driver_i.h"
 #include "rsn_supp/pmksa_cache.h"
@@ -94,8 +95,8 @@
  * @len: Frame payload length
  * Returns: >=0 on success, <0 on failure
  */
-static int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest,
-			  u16 proto, const u8 *buf, size_t len)
+int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest,
+		   u16 proto, const u8 *buf, size_t len)
 {
 #ifdef CONFIG_TESTING_OPTIONS
 	if (wpa_s->ext_eapol_frame_io && proto == ETH_P_EAPOL) {
@@ -168,20 +169,6 @@
 
 	if (pmksa_cache_get_current(wpa_s->wpa) &&
 	    type == IEEE802_1X_TYPE_EAPOL_START) {
-		/*
-		 * We were trying to use PMKSA caching and sending EAPOL-Start
-		 * would abort that and trigger full EAPOL authentication.
-		 * However, we've already waited for the AP/Authenticator to
-		 * start 4-way handshake or EAP authentication, and apparently
-		 * it has not done so since the startWhen timer has reached zero
-		 * to get the state machine sending EAPOL-Start. This is not
-		 * really supposed to happen, but an interoperability issue with
-		 * a deployed AP has been identified where the connection fails
-		 * due to that AP failing to operate correctly if PMKID is
-		 * included in the Association Request frame. To work around
-		 * this, assume PMKSA caching failed and try to initiate full
-		 * EAP authentication.
-		 */
 		if (!wpa_s->current_ssid ||
 		    wpa_s->current_ssid->eap_workaround) {
 			wpa_printf(MSG_DEBUG,
@@ -307,13 +294,13 @@
 		ieee802_1x_notify_create_actor(wpa_s, wpa_s->last_eapol_src);
 	}
 
-#if defined(BRCM_VE)
-	/* Always try and pass down the PMK/XXKey to the driver. */
-	if (result != EAPOL_SUPP_RESULT_SUCCESS)
+#ifdef BRCM_VE
+        /* Always try and pass down the PMK/XXKey to the driver. */
+        if (result != EAPOL_SUPP_RESULT_SUCCESS)
 #else
-	if (result != EAPOL_SUPP_RESULT_SUCCESS ||
-	    !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X))
-#endif /* CONFIG_DRIVER_NL80211_IFX && BRCM_VE */
+        if (result != EAPOL_SUPP_RESULT_SUCCESS ||
+            !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X))
+#endif
 		return;
 
 	if (!wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt))
@@ -782,6 +769,9 @@
 	const u8 *supp_rates, size_t supp_rates_len,
 	const struct ieee80211_ht_capabilities *ht_capab,
 	const struct ieee80211_vht_capabilities *vht_capab,
+	const struct ieee80211_he_capabilities *he_capab,
+	size_t he_capab_len,
+	const struct ieee80211_he_6ghz_band_cap *he_6ghz_he_capab,
 	u8 qosinfo, int wmm, const u8 *ext_capab, size_t ext_capab_len,
 	const u8 *supp_channels, size_t supp_channels_len,
 	const u8 *supp_oper_classes, size_t supp_oper_classes_len)
@@ -805,6 +795,9 @@
 
 	params.ht_capabilities = ht_capab;
 	params.vht_capabilities = vht_capab;
+	params.he_capab = he_capab;
+	params.he_capab_len = he_capab_len;
+	params.he_6ghz_capab = he_6ghz_he_capab;
 	params.qosinfo = qosinfo;
 	params.listen_interval = 0;
 	params.supp_rates = supp_rates;
@@ -1361,6 +1354,15 @@
 #endif /* CONFIG_NO_CONFIG_WRITE */
 }
 
+
+static void wpa_supplicant_store_ptk(void *ctx, u8 *addr, int cipher,
+				     u32 life_time, const struct wpa_ptk *ptk)
+{
+	struct wpa_supplicant *wpa_s = ctx;
+
+	ptksa_cache_add(wpa_s->ptksa, addr, cipher, life_time, ptk);
+}
+
 #endif /* CONFIG_NO_WPA */
 
 
@@ -1368,9 +1370,20 @@
 {
 #ifndef CONFIG_NO_WPA
 	struct wpa_sm_ctx *ctx;
+
+	wpa_s->ptksa = ptksa_cache_init();
+	if (!wpa_s->ptksa) {
+		wpa_printf(MSG_ERROR, "Failed to allocate PTKSA");
+		return -1;
+	}
+
 	ctx = os_zalloc(sizeof(*ctx));
 	if (ctx == NULL) {
 		wpa_printf(MSG_ERROR, "Failed to allocate WPA context.");
+
+		ptksa_cache_deinit(wpa_s->ptksa);
+		wpa_s->ptksa = NULL;
+
 		return -1;
 	}
 
@@ -1414,12 +1427,15 @@
 	ctx->fils_hlp_rx = wpa_supplicant_fils_hlp_rx;
 	ctx->channel_info = wpa_supplicant_channel_info;
 	ctx->transition_disable = wpa_supplicant_transition_disable;
+	ctx->store_ptk = wpa_supplicant_store_ptk;
 
 	wpa_s->wpa = wpa_sm_init(ctx);
 	if (wpa_s->wpa == NULL) {
-		wpa_printf(MSG_ERROR, "Failed to initialize WPA state "
-			   "machine");
+		wpa_printf(MSG_ERROR,
+			   "Failed to initialize WPA state machine");
 		os_free(ctx);
+		ptksa_cache_deinit(wpa_s->ptksa);
+		wpa_s->ptksa = NULL;
 		return -1;
 	}
 #endif /* CONFIG_NO_WPA */
@@ -1469,8 +1485,20 @@
 			conf.fils_cache_id =
 				wpa_bss_get_fils_cache_id(wpa_s->current_bss);
 #endif /* CONFIG_FILS */
+		if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_BEACON_PROTECTION) ||
+		    (wpa_s->drv_flags2 &
+		     WPA_DRIVER_FLAGS2_BEACON_PROTECTION_CLIENT))
+			conf.beacon_prot = ssid->beacon_prot;
+
+#ifdef CONFIG_PASN
+#ifdef CONFIG_TESTING_OPTIONS
+		conf.force_kdk_derivation = wpa_s->conf->force_kdk_derivation;
+#endif /* CONFIG_TESTING_OPTIONS */
+#endif /* CONFIG_PASN */
 		conf.beacon_prot = ssid->beacon_prot;
-		/* Refer commit ed56a660: Suppress deauth for PMKSA caching disabled */
+		/* Refer commit 09f46ec2: wpa_supplicant: suppress deauth
+		 * for PMKSA caching disabled
+		 */
 		conf.suppress_deauth_no_pmksa = ssid->suppress_deauth_no_pmksa;
 	}
 	wpa_sm_set_config(wpa_s->wpa, ssid ? &conf : NULL);
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpas_glue.h b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpas_glue.h
index 5585e56..338af4e 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpas_glue.h
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpas_glue.h
@@ -15,6 +15,8 @@
 int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s);
 void wpa_supplicant_rsn_supp_set_config(struct wpa_supplicant *wpa_s,
 					struct wpa_ssid *ssid);
+int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest,
+		   u16 proto, const u8 *buf, size_t len);
 
 const char * wpa_supplicant_ctrl_req_to_string(enum wpa_ctrl_req_type field,
 					       const char *default_txt,
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpas_module_tests.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpas_module_tests.c
index 1c136f7..ce5398c 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpas_module_tests.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wpas_module_tests.c
@@ -11,77 +11,77 @@
 #include "utils/common.h"
 #include "utils/module_tests.h"
 #include "wpa_supplicant_i.h"
-#include "blacklist.h"
+#include "bssid_ignore.h"
 
 
-static int wpas_blacklist_module_tests(void)
+static int wpas_bssid_ignore_module_tests(void)
 {
 	struct wpa_supplicant wpa_s;
 	int ret = -1;
 
 	os_memset(&wpa_s, 0, sizeof(wpa_s));
 
-	wpa_blacklist_clear(&wpa_s);
+	wpa_bssid_ignore_clear(&wpa_s);
 
-	if (wpa_blacklist_get(NULL, NULL) != NULL ||
-	    wpa_blacklist_get(NULL, (u8 *) "123456") != NULL ||
-	    wpa_blacklist_get(&wpa_s, NULL) != NULL ||
-	    wpa_blacklist_get(&wpa_s, (u8 *) "123456") != NULL)
+	if (wpa_bssid_ignore_get(NULL, NULL) != NULL ||
+	    wpa_bssid_ignore_get(NULL, (u8 *) "123456") != NULL ||
+	    wpa_bssid_ignore_get(&wpa_s, NULL) != NULL ||
+	    wpa_bssid_ignore_get(&wpa_s, (u8 *) "123456") != NULL)
 		goto fail;
 
-	if (wpa_blacklist_add(NULL, NULL) == 0 ||
-	    wpa_blacklist_add(NULL, (u8 *) "123456") == 0 ||
-	    wpa_blacklist_add(&wpa_s, NULL) == 0)
+	if (wpa_bssid_ignore_add(NULL, NULL) == 0 ||
+	    wpa_bssid_ignore_add(NULL, (u8 *) "123456") == 0 ||
+	    wpa_bssid_ignore_add(&wpa_s, NULL) == 0)
 		goto fail;
 
-	if (wpa_blacklist_del(NULL, NULL) == 0 ||
-	    wpa_blacklist_del(NULL, (u8 *) "123456") == 0 ||
-	    wpa_blacklist_del(&wpa_s, NULL) == 0 ||
-	    wpa_blacklist_del(&wpa_s, (u8 *) "123456") == 0)
+	if (wpa_bssid_ignore_del(NULL, NULL) == 0 ||
+	    wpa_bssid_ignore_del(NULL, (u8 *) "123456") == 0 ||
+	    wpa_bssid_ignore_del(&wpa_s, NULL) == 0 ||
+	    wpa_bssid_ignore_del(&wpa_s, (u8 *) "123456") == 0)
 		goto fail;
 
-	if (wpa_blacklist_add(&wpa_s, (u8 *) "111111") < 0 ||
-	    wpa_blacklist_add(&wpa_s, (u8 *) "111111") < 0 ||
-	    wpa_blacklist_add(&wpa_s, (u8 *) "222222") < 0 ||
-	    wpa_blacklist_add(&wpa_s, (u8 *) "333333") < 0 ||
-	    wpa_blacklist_add(&wpa_s, (u8 *) "444444") < 0 ||
-	    wpa_blacklist_del(&wpa_s, (u8 *) "333333") < 0 ||
-	    wpa_blacklist_del(&wpa_s, (u8 *) "xxxxxx") == 0 ||
-	    wpa_blacklist_get(&wpa_s, (u8 *) "xxxxxx") != NULL ||
-	    wpa_blacklist_get(&wpa_s, (u8 *) "111111") == NULL ||
-	    wpa_blacklist_get(&wpa_s, (u8 *) "222222") == NULL ||
-	    wpa_blacklist_get(&wpa_s, (u8 *) "444444") == NULL ||
-	    wpa_blacklist_del(&wpa_s, (u8 *) "111111") < 0 ||
-	    wpa_blacklist_del(&wpa_s, (u8 *) "222222") < 0 ||
-	    wpa_blacklist_del(&wpa_s, (u8 *) "444444") < 0 ||
-	    wpa_blacklist_add(&wpa_s, (u8 *) "111111") < 0 ||
-	    wpa_blacklist_add(&wpa_s, (u8 *) "222222") < 0 ||
-	    wpa_blacklist_add(&wpa_s, (u8 *) "333333") < 0)
+	if (wpa_bssid_ignore_add(&wpa_s, (u8 *) "111111") < 0 ||
+	    wpa_bssid_ignore_add(&wpa_s, (u8 *) "111111") < 0 ||
+	    wpa_bssid_ignore_add(&wpa_s, (u8 *) "222222") < 0 ||
+	    wpa_bssid_ignore_add(&wpa_s, (u8 *) "333333") < 0 ||
+	    wpa_bssid_ignore_add(&wpa_s, (u8 *) "444444") < 0 ||
+	    wpa_bssid_ignore_del(&wpa_s, (u8 *) "333333") < 0 ||
+	    wpa_bssid_ignore_del(&wpa_s, (u8 *) "xxxxxx") == 0 ||
+	    wpa_bssid_ignore_get(&wpa_s, (u8 *) "xxxxxx") != NULL ||
+	    wpa_bssid_ignore_get(&wpa_s, (u8 *) "111111") == NULL ||
+	    wpa_bssid_ignore_get(&wpa_s, (u8 *) "222222") == NULL ||
+	    wpa_bssid_ignore_get(&wpa_s, (u8 *) "444444") == NULL ||
+	    wpa_bssid_ignore_del(&wpa_s, (u8 *) "111111") < 0 ||
+	    wpa_bssid_ignore_del(&wpa_s, (u8 *) "222222") < 0 ||
+	    wpa_bssid_ignore_del(&wpa_s, (u8 *) "444444") < 0 ||
+	    wpa_bssid_ignore_add(&wpa_s, (u8 *) "111111") < 0 ||
+	    wpa_bssid_ignore_add(&wpa_s, (u8 *) "222222") < 0 ||
+	    wpa_bssid_ignore_add(&wpa_s, (u8 *) "333333") < 0)
 		goto fail;
 
-	wpa_blacklist_clear(&wpa_s);
+	wpa_bssid_ignore_clear(&wpa_s);
 
-	if (wpa_blacklist_add(&wpa_s, (u8 *) "111111") < 0 ||
-	    wpa_blacklist_add(&wpa_s, (u8 *) "222222") < 0 ||
-	    wpa_blacklist_add(&wpa_s, (u8 *) "333333") < 0 ||
-	    wpa_blacklist_add(&wpa_s, (u8 *) "444444") < 0 ||
-	    !wpa_blacklist_is_blacklisted(&wpa_s, (u8 *) "111111") ||
-	    wpa_blacklist_del(&wpa_s, (u8 *) "111111") < 0 ||
-	    wpa_blacklist_is_blacklisted(&wpa_s, (u8 *) "111111") ||
-	    wpa_blacklist_add(&wpa_s, (u8 *) "111111") < 0)
+	if (wpa_bssid_ignore_add(&wpa_s, (u8 *) "111111") < 0 ||
+	    wpa_bssid_ignore_add(&wpa_s, (u8 *) "222222") < 0 ||
+	    wpa_bssid_ignore_add(&wpa_s, (u8 *) "333333") < 0 ||
+	    wpa_bssid_ignore_add(&wpa_s, (u8 *) "444444") < 0 ||
+	    !wpa_bssid_ignore_is_listed(&wpa_s, (u8 *) "111111") ||
+	    wpa_bssid_ignore_del(&wpa_s, (u8 *) "111111") < 0 ||
+	    wpa_bssid_ignore_is_listed(&wpa_s, (u8 *) "111111") ||
+	    wpa_bssid_ignore_add(&wpa_s, (u8 *) "111111") < 0)
 		goto fail;
 
-	wpa_blacklist_update(&wpa_s);
+	wpa_bssid_ignore_update(&wpa_s);
 
-	if (!wpa_blacklist_is_blacklisted(&wpa_s, (u8 *) "111111"))
+	if (!wpa_bssid_ignore_is_listed(&wpa_s, (u8 *) "111111"))
 		goto fail;
 
 	ret = 0;
 fail:
-	wpa_blacklist_clear(&wpa_s);
+	wpa_bssid_ignore_clear(&wpa_s);
 
 	if (ret)
-		wpa_printf(MSG_ERROR, "blacklist module test failure");
+		wpa_printf(MSG_ERROR, "bssid_ignore module test failure");
 
 	return ret;
 }
@@ -93,7 +93,7 @@
 
 	wpa_printf(MSG_INFO, "wpa_supplicant module tests");
 
-	if (wpas_blacklist_module_tests() < 0)
+	if (wpas_bssid_ignore_module_tests() < 0)
 		ret = -1;
 
 #ifdef CONFIG_WPS
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wps_supplicant.c b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wps_supplicant.c
index c6205c6..98106db 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wps_supplicant.c
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpa_supplicant/wps_supplicant.c
@@ -26,7 +26,7 @@
 #include "wpa_supplicant_i.h"
 #include "driver_i.h"
 #include "notify.h"
-#include "blacklist.h"
+#include "bssid_ignore.h"
 #include "bss.h"
 #include "scan.h"
 #include "ap.h"
@@ -94,14 +94,14 @@
 		wpa_printf(MSG_DEBUG, "WPS: PIN registration with " MACSTR
 			   " did not succeed - continue trying to find "
 			   "suitable AP", MAC2STR(bssid));
-		wpa_blacklist_add(wpa_s, bssid);
+		wpa_bssid_ignore_add(wpa_s, bssid);
 
 		wpa_supplicant_deauthenticate(wpa_s,
 					      WLAN_REASON_DEAUTH_LEAVING);
 		wpa_s->reassociate = 1;
 		wpa_supplicant_req_scan(wpa_s,
-					wpa_s->blacklist_cleared ? 5 : 0, 0);
-		wpa_s->blacklist_cleared = 0;
+					wpa_s->bssid_ignore_cleared ? 5 : 0, 0);
+		wpa_s->bssid_ignore_cleared = false;
 		return 1;
 	}
 
@@ -372,6 +372,7 @@
 #ifdef CONFIG_WPS_REG_DISABLE_OPEN
 	int registrar = 0;
 #endif /* CONFIG_WPS_REG_DISABLE_OPEN */
+	bool add_sae;
 
 	if ((wpa_s->conf->wps_cred_processing == 1 ||
 	     wpa_s->conf->wps_cred_processing == 2) && cred->cred_attr) {
@@ -534,8 +535,12 @@
 	case WPS_AUTH_WPA2PSK:
 		ssid->auth_alg = WPA_AUTH_ALG_OPEN;
 		ssid->key_mgmt = WPA_KEY_MGMT_PSK;
-		if (wpa_s->conf->wps_cred_add_sae &&
-		    cred->key_len != 2 * PMK_LEN) {
+		add_sae = wpa_s->conf->wps_cred_add_sae;
+#ifdef CONFIG_P2P
+		if (ssid->p2p_group && is_p2p_6ghz_capable(wpa_s->global->p2p))
+			add_sae = true;
+#endif /* CONFIG_P2P */
+		if (add_sae && cred->key_len != 2 * PMK_LEN) {
 			ssid->auth_alg = 0;
 			ssid->key_mgmt |= WPA_KEY_MGMT_SAE;
 			ssid->ieee80211w = MGMT_FRAME_PROTECTION_OPTIONAL;
@@ -1139,7 +1144,7 @@
 	wpa_s->scan_runs = 0;
 	wpa_s->normal_scans = 0;
 	wpa_s->wps_success = 0;
-	wpa_s->blacklist_cleared = 0;
+	wpa_s->bssid_ignore_cleared = false;
 
 	wpa_supplicant_cancel_sched_scan(wpa_s);
 	wpa_supplicant_req_scan(wpa_s, 0, 0);
@@ -2885,10 +2890,11 @@
 
 	for (i = 0; i < wpa_s->num_wps_ap; i++) {
 		struct wps_ap_info *ap = &wpa_s->wps_ap[i];
-		struct wpa_blacklist *e = wpa_blacklist_get(wpa_s, ap->bssid);
+		struct wpa_bssid_ignore *e = wpa_bssid_ignore_get(wpa_s,
+								  ap->bssid);
 
 		wpa_printf(MSG_DEBUG, "WPS: AP[%d] " MACSTR " type=%d "
-			   "tries=%d last_attempt=%d sec ago blacklist=%d",
+			   "tries=%d last_attempt=%d sec ago bssid_ignore=%d",
 			   (int) i, MAC2STR(ap->bssid), ap->type, ap->tries,
 			   ap->last_attempt.sec > 0 ?
 			   (int) now.sec - (int) ap->last_attempt.sec : -1,
@@ -2950,7 +2956,7 @@
 				   MAC2STR(res->bssid), ap->type, type);
 			ap->type = type;
 			if (type != WPS_AP_NOT_SEL_REG)
-				wpa_blacklist_del(wpa_s, ap->bssid);
+				wpa_bssid_ignore_del(wpa_s, ap->bssid);
 		}
 		ap->pbc_active = pbc_active;
 		if (uuid)
diff --git a/src/lynq/packages/thirdpart/lynq-wg870/wpaspy/wpaspy.py b/src/lynq/packages/thirdpart/lynq-wg870/wpaspy/wpaspy.py
index c50cd53..5b8140b 100755
--- a/src/lynq/packages/thirdpart/lynq-wg870/wpaspy/wpaspy.py
+++ b/src/lynq/packages/thirdpart/lynq-wg870/wpaspy/wpaspy.py
@@ -21,14 +21,14 @@
         self.path = path
         self.port = port
 
-        try:
-            mode = os.stat(path).st_mode
-            if stat.S_ISSOCK(mode):
-                self.udp = False
-            else:
+        self.udp = False
+        if not path.startswith('/'):
+            try:
+                mode = os.stat(path).st_mode
+                if not stat.S_ISSOCK(mode):
+                    self.udp = True
+            except:
                 self.udp = True
-        except:
-            self.udp = True
 
         if not self.udp:
             self.s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
diff --git a/src/telephonyware/3.0/ccci_fsd/src/ccci_fsd.c b/src/telephonyware/3.0/ccci_fsd/src/ccci_fsd.c
index a16e649..badf0d2 100644
--- a/src/telephonyware/3.0/ccci_fsd/src/ccci_fsd.c
+++ b/src/telephonyware/3.0/ccci_fsd/src/ccci_fsd.c
@@ -84,6 +84,8 @@
 #define FS_WAKE_UNLOCK() release_wake_lock(FS_WAKE_LOCK_NAME)
 
 static char	   md_id = 0;
+static char debug_wakeup = 0; // jb.qi change for abnormal resume on 20230328
+
 /*
  * The maximum log level for messages to be logged to the syslog.
  * Only messages with a level lower than this will be printed to the console.
@@ -94,32 +96,36 @@
     LOG_LEVEL_INFO,
     LOG_LEVEL_DEBUG,
 };
-
+/*jb.qi change for abnormal resume start on 20230328*/
 #define DEBUGLEVEL LOG_LEVEL_ERR
 #define LOGD(fmt, ...) \
 do { \
-    if (LOG_LEVEL_DEBUG <= DEBUGLEVEL) \
+    if (debug_wakeup) \
+        ERROR(fmt, ##__VA_ARGS__); \
+    else if (LOG_LEVEL_DEBUG <= DEBUGLEVEL) \
         LOG(fmt, ##__VA_ARGS__); \
 } while(0)
 
 #define LOGI(fmt, ...) \
 do { \
-    if (LOG_LEVEL_INFO <= DEBUGLEVEL) \
+    if (debug_wakeup) \
+        ERROR(fmt, ##__VA_ARGS__); \
+    else if (LOG_LEVEL_INFO <= DEBUGLEVEL) \
         LOG(fmt, ##__VA_ARGS__); \
 } while(0)
 
 #define LOGW(fmt, ...) \
 do { \
-    if (LOG_LEVEL_WARNING <= DEBUGLEVEL) \
+    if (debug_wakeup || LOG_LEVEL_WARNING <= DEBUGLEVEL) \
         ERROR(fmt, ##__VA_ARGS__); \
 } while(0)
 
 #define LOGE(fmt, ...) \
 do { \
-    if (LOG_LEVEL_ERR <= DEBUGLEVEL) \
+    if (debug_wakeup || LOG_LEVEL_ERR <= DEBUGLEVEL) \
         ERROR(fmt, ##__VA_ARGS__); \
 } while(0)
-
+/*jb.qi change for abnormal resume end on 20230328*/
 #ifdef CCCI_FSD_UT
 #define dbg_printf(...) printf(__VA_ARGS__) //__android_log_print(ANDROID_LOG_DEBUG, MD_COMN_TAG, __VA_ARGS__);
 #else
@@ -738,7 +744,26 @@
 	return;
 
 }
-
+/*jb.qi change for abnormal resume start on 20230328*/
+static void print_file_name(const char *op_str, char *str, int len)
+{
+    if (!op_str || len < 0)
+        return;
+    if (len >= 8 && str)
+        if (str[0] == 0x2F)
+            LOGW("%s: [%02X%02X%02X%02X%02X%02X%02X%02X]\n", op_str,
+                (str[len-8]-32), (str[len-7]-32), (str[len-6]-32),
+                (str[len-5]-32), (str[len-4]-32), (str[len-3]-32),
+                (str[len-2]-32),(str[len-1]-32));
+	else
+            LOGW("%s: [%02X][%02X%02X%02X%02X%02X%02X%02X%02X]\n", op_str, str[0],
+                (str[len-8]-32), (str[len-7]-32), (str[len-6]-32),
+                (str[len-5]-32), (str[len-4]-32), (str[len-3]-32),
+                (str[len-2]-32),(str[len-1]-32));
+    else
+        LOGW("%s: [str_len = %d or no sub str]\n", op_str, len);
+}
+/*jb.qi change for abnormal resume end on 20230328*/
 static bool FS_GetPackInfo(FS_PACKET_INFO* pPackInfo, char* pData)
 {
 	unsigned int PackNum = *((unsigned int*)pData);
@@ -4433,10 +4458,25 @@
 				stream = (STREAM_DATA *)pkt_buff;
 				ccci_h = (CCCI_BUFF_T *)&stream->header;
 				ReqBufIndex = ccci_h->reserved;
-				LOGD("Read %d bytes from slot %d, CCCI_H data[0]=0x%X "
-						"data[1]=0x%X channel=0x%X reserved=0x%X\n", RetVal,
-						ReqBufIndex, ccci_h->data[0], ccci_h->data[1],
-						ccci_h->channel, ccci_h->reserved);
+				/*jb.qi change for abnormal resume start on 20230328*/
+				if (ccci_h->data[0] & CCCI_FS_AP_CCCI_WAKEUP) {
+					debug_wakeup = 1;
+					ccci_h->data[0] &= (~CCCI_FS_AP_CCCI_WAKEUP);
+				} else if (debug_wakeup) {
+					debug_wakeup = 0;
+				}
+
+				if (debug_wakeup)
+					LOGW("wakeup: Read %d bytes from slot %d, CCCI_H(0x%X)(0x%X)(0x%X)(0x%X), 0x%X\n",
+							RetVal, ReqBufIndex,
+							ccci_h->data[0], ccci_h->data[1], ccci_h->channel, ccci_h->reserved,
+							RetVal > sizeof(CCCI_BUFF_T) ? stream->payload.OperateID : -1);
+				else
+					LOGD("Read %d bytes from slot %d, CCCI_H data[0]=0x%X "
+							"data[1]=0x%X channel=0x%X reserved=0x%X\n", RetVal,
+							ReqBufIndex, ccci_h->data[0], ccci_h->data[1],
+							ccci_h->channel, ccci_h->reserved);
+				/*jb.qi change for abnormal resume end on 20230328*/
 				buffer_slot = (STREAM_DATA *)((char *)g_FsInfo.pFsBuf + (FS_MAX_BUF_SIZE + sizeof(STREAM_DATA))*ReqBufIndex);
 				p_fs_buff = (char *)buffer_slot;
 			                /******************************************
@@ -4518,7 +4558,54 @@
 		}
 
 		LOGD("OpID = 0X%X\n", pFsBuf->OperateID);
-
+		/*jb.qi change for abnormal resume start on 20230328*/
+		if (debug_wakeup) {
+			LOGW("[wakeup message] OpID = 0X%X\n", pFsBuf->OperateID);
+			switch (pFsBuf->OperateID) {
+				case FS_CCCI_OP_OPEN: // O
+				case FS_CCCI_OP_CREATEDIR: // CD
+				case FS_CCCI_OP_REMOVEDIR: // MD
+				case FS_CCCI_OP_RENAME: // RN_0
+				case FS_CCCI_OP_DELETE: // D
+				case FS_CCCI_OP_GETFOLDERSIZE: // FS
+				case FS_CCCI_OP_COUNT: // CN
+				case FS_CCCI_OP_GETATTRIBUTES: // A
+				case FS_CCCI_OP_GETFILEDETAIL: // GetFileDetail
+				case FS_CCCI_OP_XDELETE: // X
+				case FS_CCCI_OP_MOVE: // M_0
+				case FS_CCCI_OP_FINDFIRST: // FF
+				case FS_CCCI_OP_RESTORE: // RS
+				{
+					wchar_t* FileName = (wchar_t*)PackInfo[0].pData;
+					char ConvFileName[PATH_MAX] = {0};
+					FS_ConvWcsToCs(FileName, ConvFileName);
+					print_file_name("FILE", ConvFileName, strlen(ConvFileName));
+					break;
+				}
+				case FS_CCCI_OP_SEEK: // S
+				case FS_CCCI_OP_READ: // R
+				case FS_CCCI_OP_WRITE: // W
+				case FS_CCCI_OP_CLOSE: // C
+				case FS_CCCI_OP_GETFILESIZE: // F
+				case FS_CCCI_OP_FINDCLOSE: // FC
+				case FS_CCCI_OP_FINDNEXT: // FN
+				{
+					int HandleIndex = *((unsigned int*)PackInfo[0].pData);
+					if (HandleIndex < FS_FILE_MAX && HandleIndex >= 0) {
+						print_file_name("HANDLE", g_FsInfo.hFileHandle[HandleIndex].pFsFileName,
+								strlen(g_FsInfo.hFileHandle[HandleIndex].pFsFileName));
+					}
+					break;
+				}
+				case FS_CCCI_OP_GETCLUSTERSIZE: // CS
+				case FS_CCCI_OP_GETDRIVE: // GD
+				case FS_CCCI_OP_CLOSEALL: // CA
+				case FS_CCCI_OP_GETDISKINFO: // I
+				default:
+					break;
+			}
+		}
+		/*jb.qi change for abnormal resume end on 20230328*/
 		switch(pFsBuf->OperateID) {
 #ifdef CCCI_FSD_UT
 			/*ut test*/
diff --git a/src/telephonyware/3.0/ccci_fsd/src/ccci_fsd.h b/src/telephonyware/3.0/ccci_fsd/src/ccci_fsd.h
index 0d5317c..46967d3 100644
--- a/src/telephonyware/3.0/ccci_fsd/src/ccci_fsd.h
+++ b/src/telephonyware/3.0/ccci_fsd/src/ccci_fsd.h
@@ -376,6 +376,7 @@
 #define MAX_FS_PKT_BYTE (3584-128)
 #define MAX_FS_BUF_BYTE 4096
 
+#define CCCI_FS_AP_CCCI_WAKEUP (0x40000000) //jb.qi change for abnormal resume on 20230328
 #define CCCI_FS_REQ_SEND_AGAIN 0x80000000
 #define CCCI_FS_PEER_REQ_SEND_AGAIN(_p) (((((CCCI_BUFF_T*)(_p))->data[0] & CCCI_FS_REQ_SEND_AGAIN) != 0)? 1: 0)