[Feature] [A1 only] change wifi driver

Change-Id: I89453fb0729601b1e76c9ae8090df201a76db4ab
diff --git a/meta/meta-mediatek-mt2735/recipes-kernel/modules/files/wifi/wg870/18_52_14_mfg.trxs b/meta/meta-mediatek-mt2735/recipes-kernel/modules/files/wifi/wg870/18_52_14_mfg.trxs
deleted file mode 100755
index f8d3757..0000000
--- a/meta/meta-mediatek-mt2735/recipes-kernel/modules/files/wifi/wg870/18_52_14_mfg.trxs
+++ /dev/null
Binary files differ
diff --git a/meta/meta-mediatek-mt2735/recipes-kernel/modules/files/wifi/wg870/w870_rtecdc.trxs b/meta/meta-mediatek-mt2735/recipes-kernel/modules/files/wifi/wg870/w870_rtecdc.trxs
deleted file mode 100755
index a304cf7..0000000
--- a/meta/meta-mediatek-mt2735/recipes-kernel/modules/files/wifi/wg870/w870_rtecdc.trxs
+++ /dev/null
Binary files differ
diff --git a/meta/meta-mediatek-mt2735/recipes-kernel/modules/files/wifi/wg870/w870_rtecdc_mfg.trxs b/meta/meta-mediatek-mt2735/recipes-kernel/modules/files/wifi/wg870/w870_rtecdc_mfg.trxs
index f8d3757..eaeaa2b 100755
--- a/meta/meta-mediatek-mt2735/recipes-kernel/modules/files/wifi/wg870/w870_rtecdc_mfg.trxs
+++ b/meta/meta-mediatek-mt2735/recipes-kernel/modules/files/wifi/wg870/w870_rtecdc_mfg.trxs
Binary files differ
diff --git a/meta/meta-mediatek-mt2735/recipes-kernel/modules/files/wifi/wg870/wl_arm64_v18_15_1_20 b/meta/meta-mediatek-mt2735/recipes-kernel/modules/files/wifi/wg870/wl_arm64_v18_15_1_20
deleted file mode 100755
index 09413e5..0000000
--- a/meta/meta-mediatek-mt2735/recipes-kernel/modules/files/wifi/wg870/wl_arm64_v18_15_1_20
+++ /dev/null
Binary files differ
diff --git a/meta/meta-mediatek-mt2735/recipes-kernel/modules/wg870-drv-insmod.bb b/meta/meta-mediatek-mt2735/recipes-kernel/modules/wg870-drv-insmod.bb
index 3258b06..2d3c55f 100755
--- a/meta/meta-mediatek-mt2735/recipes-kernel/modules/wg870-drv-insmod.bb
+++ b/meta/meta-mediatek-mt2735/recipes-kernel/modules/wg870-drv-insmod.bb
@@ -3,9 +3,7 @@
 LIC_FILES_CHKSUM = "file://${COREBASE}/bitbake/COPYING;md5=751419260aa954499f7abaabaa882bbe"
 
 SRC_URI = "file://wifi/wg870/cyw955572fcipa_rev2.52.txt \
-			file://wifi/wg870/w870_rtecdc_mfg.trxs \
-			file://wifi/wg870/18_52_14_mfg.trxs \
-			file://wifi/wg870/w870_rtecdc.trxs"
+			file://wifi/wg870/w870_rtecdc_mfg.trxs"
 
 
 inherit  systemd
@@ -17,8 +15,7 @@
 do_install() {
 	install -d ${D}/etc
 	install -d ${D}/system/etc/firmware/wifi/wg870/
-	install -m 755 ${WORKDIR}/wifi/wg870/w870_rtecdc.trxs ${D}/system/etc/firmware/wifi/wg870/w870_rtecdc.trxs
 	install -m 755 ${WORKDIR}/wifi/wg870/w870_rtecdc_mfg.trxs ${D}/system/etc/firmware/wifi/wg870/w870_rtecdc_mfg.trxs
 	install -m 755 ${WORKDIR}/wifi/wg870/cyw955572fcipa_rev2.52.txt ${D}/system/etc/firmware/wifi/wg870/cyw955572fcipa_rev2.52.txt
-	install -m 755 ${WORKDIR}/wifi/wg870/18_52_14_mfg.trxs ${D}/system/etc/firmware/wifi/wg870/18_52_14_mfg.trxs
+	
 }
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 7f176b4..e16db13 100644
--- a/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/Makefile
+++ b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/Makefile
@@ -1,6 +1,6 @@
 # bcmdhd
 #
-# Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+# Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
 #
 # Copyright (C) 1999-2017, Broadcom Corporation
 #
@@ -211,6 +211,14 @@
 ifeq ($(CONFIG_ANDROID),y)
   DHDCFLAGS += -DKEEP_WIFION_OPTION
   DHDCFLAGS += -Wno-date-time
+
+# To support android12 Wifi-HAL
+ifeq ($(CONFIG_ANDROID12),y)
+ DHDCFLAGS += -DANDROID12_SUPPORT
+endif
+
+# To support ACS on hostapd
+# DHDCFLAGS += -DWL_SUPPORT_ACS_OFFLOAD
 endif
 
 # SoftAP
@@ -241,6 +249,11 @@
 DHDCFLAGS += -DDHD_4WAYM4_FAIL_DISCONNECT
 endif
 
+#6Ghz
+ifneq ($(CONFIG_BCMDHD_6E),)
+ DHDCFLAGS += -DWL_6E
+endif
+
 # Uncomment the below line for AP to receive disconnect management frame.
 # DHDCFLAGS += -DWL_CFG80211_AP_RX_MGMT_DISCONNECT
 
@@ -303,7 +316,6 @@
   DHDCFLAGS += -DPROP_TXSTATUS -DLIMIT_BORROW
   DHDCFLAGS += -DPROP_TXSTATUS_VSDB
   DHDCFLAGS += -DUSE_WL_FRAMEBURST
-  DHDCFLAGS += -DCUSTOM_AMPDU_MPDU=16
 # tput enhancement
   DHDCFLAGS += -DCUSTOM_GLOM_SETTING=8 -DCUSTOM_RXCHAIN=1
   DHDCFLAGS += -DUSE_DYNAMIC_F2_BLKSIZE -DDYNAMIC_F2_BLKSIZE_FOR_NONLEGACY=128
@@ -483,12 +495,17 @@
     dhd_linux.o dhd_linux_sched.o dhd_cfg80211.o dhd_linux_wq.o aiutils.o \
     bcmevent.o bcmutils.o bcmwifi_channels.o hndpmu.o linux_osl.o linux_pkt.o \
     sbutils.o siutils.o wl_android.o wl_roam.o wl_cfg80211.o wl_cfgscan.o wl_cfgp2p.o \
-    wl_cfg_btcoex.o wldev_common.o wl_linux_mon.o dhd_linux_platdev.o \
+    wl_cfg_btcoex.o wldev_common.o dhd_linux_platdev.o \
     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
 
+ifneq ($(CONFIG_DHD_MONITOR_INTERFACE),)
+    DHDCFLAGS += -DDHD_MONITOR_INTERFACE
+    DHDOFILES += wl_linux_mon.o
+endif
+
 ifneq ($(CONFIG_DHD_OF_SUPPORT),)
     DHDCFLAGS += -DDHD_OF_SUPPORT
     DHDOFILES += dhd_custom_msm.o
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
index 4d2bcd0..328f836 100644
--- 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,7 +2,7 @@
  * 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) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -147,18 +147,15 @@
  * http://hwnbu-twiki.broadcom.com/twiki/pub/Mwgroup/ArmDocumentation/SystemDiscovery.pdf
  */
 void
-ai_scan(si_t *sih, void *regs, uint devid)
+ai_scan(si_t *sih, void *regs, uint32 erombase, uint devid)
 {
 	si_info_t *sii = SI_INFO(sih);
 	si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
-	chipcregs_t *cc = (chipcregs_t *)regs;
-	uint32 erombase, *eromptr, *eromlim;
+	uint32 *eromptr, *eromlim;
 	axi_wrapper_t * axi_wrapper = sii->axi_wrapper;
 
 	BCM_REFERENCE(devid);
 
-	erombase = R_REG(sii->osh, &cc->eromptr);
-
 	switch (BUSTYPE(sih->bustype)) {
 	case SI_BUS:
 		eromptr = (uint32 *)REG_MAP(erombase, SI_CORE_SIZE);
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
index a631a12..1e5a250 100644
--- 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,7 +1,7 @@
 /*
  * bcmevent read-only data shared by kernel or app layers
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -205,6 +205,7 @@
 	BCMEVENT_NAME(WLC_E_RPSNOA),
 	BCMEVENT_NAME(WLC_E_PHY_CAL),
 	BCMEVENT_NAME(WLC_E_WA_LQM),
+	BCMEVENT_NAME(WLC_E_OVERTEMP),
 };
 
 const char *bcmevent_get_name(uint event_type)
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
index e639a6f..7173f1b 100644
--- 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,7 +1,7 @@
 /*
  * SDIO access interface for drivers - linux specific (pci only)
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -185,13 +185,13 @@
 	vendevid = bcmsdh_query_device(bcmsdh);
 
 	/* try to attach to the target device */
-#if defined(BCMSPI) && defined(BCMPCISPIHOST)
+#if defined(BCMSPI) && (defined(BCMPCISPIHOST) || defined(BCMSDIOH_SPI))
 	bcmsdh_osinfo->context = drvinfo.probe((vendevid >> 16), (vendevid & 0xFFFF), bus_num,
 		slot_num, 0, bus_type, (void *)regs, NULL, bcmsdh);
 #else
 	bcmsdh_osinfo->context = drvinfo.probe((vendevid >> 16), (vendevid & 0xFFFF), bus_num,
 		slot_num, 0, bus_type, (void *)regs, osh, bcmsdh);
-#endif /* BCMSPI && BCMPCISPIHOST */
+#endif /* BCMSPI && (BCMPCISPIHOST || BCMSDIOH_SPI) */
 	if (bcmsdh_osinfo->context == NULL) {
 		SDLX_MSG(("%s: device attach failed\n", __FUNCTION__));
 		goto err;
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
index d75e1e7..eef1190 100644
--- 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,7 +1,7 @@
 /*
  * Broadcom SPI Host Controller Driver - Linux Per-port
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -48,6 +48,7 @@
 #include <bcmspi.h>
 #endif /* BCMSPI_ANDROID */
 
+#ifndef GSPIBCM
 #ifndef BCMSPI_ANDROID
 extern uint sd_crc;
 module_param(sd_crc, uint, 0);
@@ -64,6 +65,7 @@
 	wait_queue_head_t intr_wait_queue;
 #endif /* !BCMSPI_ANDROID */
 };
+#endif /* !GSPIBCM */
 
 #ifndef BCMSPI_ANDROID
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
@@ -73,7 +75,7 @@
 #endif // endif
 
 /* For Broadcom PCI-SPI Host controller (Raggedstone) */
-#if defined(BCMSPI) && defined(BCMPCISPIHOST)
+#if defined(BCMSPI) && (defined(BCMPCISPIHOST) || defined(GSPIBCM))
 #ifndef SDLX_MSG
 #define SDLX_MSG(x) printf x
 #endif // endif
@@ -145,6 +147,7 @@
 {
 	osl_t *osh = NULL;
 	sdioh_info_t *sdioh = NULL;
+	void *bcmsdh;
 
 	int rc;
 
@@ -228,8 +231,13 @@
 		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;
 	}
@@ -270,6 +278,8 @@
 
 }
 #endif /* BCMSPI && BCMPCISPIHOST */
+
+#ifndef GSPIBCM
 /* Interrupt handler */
 static irqreturn_t
 sdspi_isr(int irq, void *dev_id
@@ -300,6 +310,7 @@
 		return IRQ_RETVAL(ours);
 	}
 }
+#endif /* !GSPIBCM */
 #endif /* !BCMSPI_ANDROID */
 
 #ifdef BCMSPI_ANDROID
@@ -359,7 +370,7 @@
 {
 	int error = 0;
 	sd_trace(("bcmsdh_gspi: %s Enter\n", __FUNCTION__));
-#if defined(BCMSPI) && defined(BCMPCISPIHOST)
+#if defined(BCMSPI) && (defined(BCMPCISPIHOST) || defined(GSPIBCM))
 	error = pci_module_init(&bcmsdh_pci_driver);
 #else
 	error = spi_register_driver(&bcmsdh_spi_driver);
@@ -374,13 +385,14 @@
 void bcmsdh_unregister_client_driver(void)
 {
 	sd_trace(("%s Enter\n", __FUNCTION__));
-#if defined(BCMSPI) && defined(BCMPCISPIHOST)
+#if defined(BCMSPI) && (defined(BCMPCISPIHOST) || defined(GSPIBCM))
 	pci_unregister_driver(&bcmsdh_pci_driver);
 #else
 	spi_unregister_driver(&bcmsdh_spi_driver);
 #endif /* BCMSPI && BCMPCISPIHOST */
 }
 
+#ifndef GSPIBCM
 /* Register with Linux for interrupts */
 int
 spi_register_irq(sdioh_info_t *sd, uint irq)
@@ -643,3 +655,4 @@
 	}
 }
 #endif /* !BCMSPI_ANDROID */
+#endif /* !GSPIBCM */
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
index 4490d07..c7ba27b 100644
--- 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,7 +1,7 @@
 /*
  * Broadcom BCMSDH to gSPI Protocol Conversion Layer
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -1185,6 +1185,7 @@
 
 		if (regdata & HIGH_SPEED_MODE) {
 			regdata &= ~HIGH_SPEED_MODE;
+			regdata |= CLOCK_POLARITY;
 			sd_trace(("Writing %08x to device at %08x\n", regdata, SPID_CONFIG));
 			if ((status = bcmspi_card_regwrite(sd, 0, SPID_CONFIG,
 			                                  4, regdata)) != SUCCESS)
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
index 2afa029..18747aa 100644
--- 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,7 +3,7 @@
  * 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) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -160,6 +160,35 @@
 #define WF_NUM_5G_160M_CHANS \
 	(sizeof(wf_5g_160m_chans)/sizeof(uint8))
 
+/* Based on IEEE 802.11ax D6.1 */
+/* 40MHz channels in 6GHz band */
+static const uint8 wf_6g_40m_chans[] =
+{3, 11, 19, 27, 35, 43, 51, 59, 67, 75, 83, 91, 99,
+107, 115, 123, 131, 139, 147, 155, 163, 171, 179,
+187, 195, 203, 211, 219, 227};
+#define WF_NUM_6G_40M_CHANS \
+	(sizeof(wf_6g_40m_chans)/sizeof(uint8))
+
+/* 80MHz channels in 6GHz band */
+static const uint8 wf_6g_80m_chans[] =
+{7, 23, 39, 55, 71, 87, 103, 119, 135, 151, 167, 183,
+199, 215};
+#define WF_NUM_6G_80M_CHANS \
+	(sizeof(wf_6g_80m_chans)/sizeof(uint8))
+
+/* 160MHz channels in 6GHz band */
+static const uint8 wf_6g_160m_chans[] =
+{15, 47, 79, 111, 143, 175, 207};
+#define WF_NUM_6G_160M_CHANS \
+	(sizeof(wf_6g_160m_chans)/sizeof(uint8))
+
+/* 6GHz PSC channels */
+uint8 wf_6g_psc_chans[] =
+{5, 21, 37, 53, 69, 85, 101, 117, 133, 149, 165, 181,
+197, 213, 229};
+#define WF_NUM_6G_PSC_CHANS \
+	(sizeof(wf_6g_psc_chans)/sizeof(uint8))
+
 /* opclass and channel information for US. Table E-1 */
 static const uint16 opclass_data[] = {
 	(WL_CHANSPEC_BAND_5G |((WL_CHANSPEC_BW_20)&WL_CHANSPEC_BW_MASK)),
@@ -645,10 +674,9 @@
 	uint chspec_bw = CHSPEC_BW(chanspec);
 	uint chspec_ch = CHSPEC_CHANNEL(chanspec);
 
-	/* must be 2G or 5G band */
 	if (CHSPEC_IS2G(chanspec)) {
-		/* must be valid bandwidth */
-		if (!BW_LE40(chspec_bw)) {
+		/* must be valid bandwidth and channel */
+		if (!BW_LE40(chspec_bw) || (chspec_ch > CH_MAX_2G_CHANNEL)) {
 			return TRUE;
 		}
 	} else if (CHSPEC_IS5G(chanspec)) {
@@ -671,8 +699,29 @@
 			/* invalid bandwidth */
 			return TRUE;
 		}
+	} else if (CHSPEC_IS6G(chanspec)) {
+		if (chspec_bw == WL_CHANSPEC_BW_8080) {
+			uint ch1_id, ch2_id;
+
+			/* channel IDs in 80+80 must be in range */
+			ch1_id = CHSPEC_CHAN1(chanspec);
+			ch2_id = CHSPEC_CHAN2(chanspec);
+			if (ch1_id >= WF_NUM_6G_80M_CHANS || ch2_id >= WF_NUM_6G_80M_CHANS)
+				return TRUE;
+
+		} else if (chspec_bw == WL_CHANSPEC_BW_20 || chspec_bw == WL_CHANSPEC_BW_40 ||
+		           chspec_bw == WL_CHANSPEC_BW_80 || chspec_bw == WL_CHANSPEC_BW_160) {
+
+			if (chspec_ch > MAXCHANNEL) {
+				return TRUE;
+			}
+		} else {
+			/* invalid bandwidth */
+			return TRUE;
+		}
 	} else {
-		/* must be 2G or 5G band */
+
+		/* must be 2G, 5G or 6G band */
 		return TRUE;
 	}
 
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 9e1bff0..4b22113 100644
--- 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,7 +3,7 @@
  * This header file housing the define and function prototype use by
  * both the wl driver, tools & Apps.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -117,7 +117,7 @@
 #define WL_CHANSPEC_BAND_SHIFT		14u
 #define WL_CHANSPEC_BAND_2G		0x0000u
 #define WL_CHANSPEC_BAND_3G		0x4000u
-#define WL_CHANSPEC_BAND_4G		0x8000u
+#define WL_CHANSPEC_BAND_6G		0x8000u
 #define WL_CHANSPEC_BAND_5G		0xc000u
 #define INVCHANSPEC			255u
 #define MAX_CHANSPEC			0xFFFFu
@@ -375,6 +375,7 @@
 #define BW_LE80(bw)		(BW_LE40(bw) || ((bw) == WL_CHANSPEC_BW_80))
 #define BW_LE160(bw)		(BW_LE80(bw) || ((bw) == WL_CHANSPEC_BW_160))
 
+#define CHSPEC_IS6G(chspec)	(((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_6G)
 #define CHSPEC_IS5G(chspec)	(((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G)
 #define CHSPEC_IS2G(chspec)	(((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G)
 #define CHSPEC_SB_UPPER(chspec)	\
@@ -502,6 +503,12 @@
 #define WLC_2G_25MHZ_OFFSET		5	/* 2.4GHz band channel offset */
 
 /**
+ * Starting frequence of 6 GHz channels.
+ * Wi-Fi 6E operates in the 6 GHz band from 5.925 to 7.125 GHz.
+ */
+#define FREQ_START_6G_CHANNEL		5925	/* 6G band starting frequence */
+
+/**
  *  No of sub-band vlaue of the specified Mhz chanspec
  */
 #define WF_NUM_SIDEBANDS_40MHZ   2
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 c1be625..cf3d66f 100644
--- 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,7 +4,7 @@
  * 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) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
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
index 5c20413..fda0c7e 100644
--- 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,7 +1,7 @@
 /*
  * DHD Protocol Module for CDC and BDC.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -156,10 +156,18 @@
 	 * value which is 8Kbytes for various 'get' commands to 2000.  48 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;
 	}
+#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_common.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_common.c
index 7ae36f7..0c68520 100644
--- 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,7 +1,7 @@
 /*
  * Broadcom Dongle Host Driver (DHD), common DHD core.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -546,7 +546,7 @@
 int
 dhd_sssr_mempool_init(dhd_pub_t *dhd)
 {
-	dhd->sssr_mempool = (uint8 *) MALLOCZ(dhd->osh, DHD_SSSR_MEMPOOL_SIZE);
+	dhd->sssr_mempool = (uint8 *) VMALLOCZ(dhd->osh, DHD_SSSR_MEMPOOL_SIZE);
 	if (dhd->sssr_mempool == NULL) {
 		DHD_ERROR(("%s: MALLOC of sssr_mempool failed\n",
 			__FUNCTION__));
@@ -559,7 +559,7 @@
 dhd_sssr_mempool_deinit(dhd_pub_t *dhd)
 {
 	if (dhd->sssr_mempool) {
-		MFREE(dhd->osh, dhd->sssr_mempool, DHD_SSSR_MEMPOOL_SIZE);
+		VMFREE(dhd->osh, dhd->sssr_mempool, DHD_SSSR_MEMPOOL_SIZE);
 		dhd->sssr_mempool = NULL;
 	}
 }
@@ -3102,6 +3102,11 @@
 				elqm_basic->tx_rate, elqm_basic->rx_rate));
 			break;
 		}
+	case WLC_E_OVERTEMP:
+	{
+		DHD_EVENT(("MACEVENT: %s\n", event_name));
+		break;
+	}
 	default:
 		DHD_INFO(("MACEVENT: %s %d, MAC %s, status %d, reason %d, auth %d\n",
 		       event_name, event_type, eabuf, (int)status, (int)reason,
@@ -3563,6 +3568,13 @@
 			dhd_event(dhd_pub->info, (char *)pvt_data, evlen, *ifidx);
 		break;
 	}
+#ifdef WL_CFG80211
+	case WLC_E_OVERTEMP:
+	{
+		wl_cfg80211_overtemp_event(dhd_idx2net(dhd_pub, event->ifidx));
+		break;
+	}
+#endif /* WL_CFG80211 */
 
 	case WLC_E_NDIS_LINK:
 		break;
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
index 46df5a8..453b371 100644
--- 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,7 +1,7 @@
 /*
  * Platform Dependent file for Qualcomm MSM/APQ
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -36,7 +36,12 @@
 #include <linux/err.h>
 #include <linux/gpio.h>
 #include <linux/skbuff.h>
+#if defined(CONFIG_WIFI_CONTROL_FUNC)
 #include <linux/wlan_plat.h>
+#else
+#include <linux/version.h>
+#include <dhd_linux.h>
+#endif /* CONFIG_WIFI_CONTROL_FUNC */
 #include <linux/mmc/host.h>
 #include <linux/msm_pcie.h>
 #include <linux/fcntl.h>
@@ -55,7 +60,9 @@
 extern void *dhd_wlan_mem_prealloc(int section, unsigned long size);
 #endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */
 
-#define WIFI_TURNON_DELAY       200
+#ifndef WIFI_TURNON_DELAY
+#define WIFI_TURNON_DELAY	200
+#endif /* WIFI_TURNON_DELAY */
 static int wlan_reg_on = -1;
 #ifdef CUSTOM_DT_COMPAT_ENTRY
 #define DHD_DT_COMPAT_ENTRY		CUSTOM_DT_COMPAT_ENTRY
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 6751a3b..2713bb3 100644
--- 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,7 +2,7 @@
  * 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) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -327,7 +327,7 @@
 #endif // endif
 
 #ifdef DHD_FW_COREDUMP
-static int dhd_mem_dump(void *dhd_info, void *event_info, u8 event);
+static void dhd_mem_dump(void *dhd_info, void *event_info, u8 event);
 #endif /* DHD_FW_COREDUMP */
 
 #ifdef DHD_LOG_DUMP
@@ -874,9 +874,11 @@
 static void dhd_suspend_lock(dhd_pub_t *dhdp);
 static void dhd_suspend_unlock(dhd_pub_t *dhdp);
 
+#ifdef DHD_MONITOR_INTERFACE
 /* Monitor interface */
 int dhd_monitor_init(void *dhd_pub);
 int dhd_monitor_uninit(void);
+#endif /* DHD_MONITOR_INTERFACE */
 
 #ifdef DHD_PM_CONTROL_FROM_FILE
 bool g_pm_control;
@@ -3096,6 +3098,9 @@
 	int ret = 0;
 
 	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+#if defined(SUPPORT_RANDOM_MAC_SCAN)
+	struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
+#endif // endif
 	struct sockaddr *sa = (struct sockaddr *)addr;
 	int ifidx;
 	dhd_if_t *dhdif;
@@ -3106,6 +3111,15 @@
 
 	dhdif = dhd->iflist[ifidx];
 
+	if ((dhdif != NULL) &&
+#if defined(SUPPORT_RANDOM_MAC_SCAN)
+	(!(cfg->random_mac_enabled)) &&
+#endif // endif
+	(dhdif->idx > 0)) {
+		DHD_ERROR(("%s: Intf[%s] Blocking MAC Overwrite \n", __FUNCTION__, dhdif->name));
+		return 0;
+	}
+
 	dhd_net_if_lock_local(dhd);
 	memcpy(dhdif->mac_addr, sa->sa_data, ETHER_ADDR_LEN);
 	dhdif->set_macaddress = TRUE;
@@ -3485,6 +3499,9 @@
 	return ret;
 }
 
+#ifndef DHD_MONITOR_INTERFACE
+static
+#endif /* DHD_MONITOR_INTERFACE */
 #ifdef CFI_CHECK
 netdev_tx_t BCMFASTPATH
 #else /* CFI_CHECK */
@@ -3667,7 +3684,13 @@
 				dhd_ifname(&dhd->pub, ifidx)));
 	}
 #endif /* DHD_PSTA */
-
+#ifdef CONFIG_ARCH_MSM
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
+	if (skb->sk) {
+		sk_pacing_shift_update(skb->sk, 8);
+	}
+#endif /* LINUX_VERSION_CODE >= 4.16.0 */
+#endif /* CONFIG_ARCH_MSM */
 #ifdef DHDTCPSYNC_FLOOD_BLK
 	if (dhd_tcpdata_get_flag(&dhd->pub, pktbuf) == FLAG_SYNCACK) {
 		ifp->tsyncack_txed ++;
@@ -8404,6 +8427,15 @@
 	memset(dhd, 0, sizeof(dhd_info_t));
 	dhd_state |= DHD_ATTACH_STATE_DHD_ALLOC;
 
+#ifdef SHOW_LOGTRACE
+	/* Create ring proc entries */
+	dhd_dbg_ring_proc_create(&dhd->pub);
+
+	if (dhd_init_logtrace_process(dhd) != BCME_OK) {
+		goto fail;
+	}
+#endif /* SHOW_LOGTRACE */
+
 	dhd->unit = dhd_found + instance_base; /* do not increment dhd_found, yet */
 
 	dhd->pub.osh = osh;
@@ -8572,9 +8604,11 @@
 		goto fail;
 	}
 
+#ifdef DHD_MONITOR_INTERFACE
 	dhd_monitor_init(&dhd->pub);
+#endif /* DHD_MONITOR_INTERFACE */
 	dhd_state |= DHD_ATTACH_STATE_CFG80211;
-#endif // endif
+#endif /* WL_CFG80211 */
 
 #if defined(WL_WIRELESS_EXT)
 	/* Attach and link in the iw */
@@ -8597,12 +8631,12 @@
 	}
 #endif /* SHOW_LOGTRACE */
 
+#ifdef DEBUGABILITY
 	/* attach debug if support */
 	if (dhd_os_dbg_attach(&dhd->pub)) {
 		DHD_ERROR(("%s debug module attach failed\n", __FUNCTION__));
 		goto fail;
 	}
-#ifdef DEBUGABILITY
 #if defined(SHOW_LOGTRACE) && defined(DBG_RING_LOG_INIT_DEFAULT)
 	/* enable verbose ring to support dump_trace_buf */
 	dhd_os_start_logging(&dhd->pub, FW_VERBOSE_RING_NAME, 3, 0, 0, 0);
@@ -8689,9 +8723,6 @@
 
 #ifdef SHOW_LOGTRACE
 	skb_queue_head_init(&dhd->evt_trace_queue);
-
-	/* Create ring proc entries */
-	dhd_dbg_ring_proc_create(&dhd->pub);
 #endif /* SHOW_LOGTRACE */
 
 	/* Set up the bottom half handler */
@@ -8866,12 +8897,6 @@
 #endif /* DNGL_AXI_ERROR_LOGGING */
 #endif /* BCMPCIE && ETD */
 
-#ifdef SHOW_LOGTRACE
-	if (dhd_init_logtrace_process(dhd) != BCME_OK) {
-		goto fail;
-	}
-#endif /* SHOW_LOGTRACE */
-
 	DHD_SSSR_MEMPOOL_INIT(&dhd->pub);
 
 #ifdef EWP_EDL
@@ -9124,6 +9149,7 @@
 		DHD_ERROR(("nvram path not found\n"));
 		return FALSE;
 	}
+	DHD_ERROR(("2--firmware path [%s]-[%s]\n", dhdinfo->fw_path, dhdinfo->nv_path));
 
 	return TRUE;
 }
@@ -10147,7 +10173,7 @@
 		DHD_ERROR(("Firmware version = %s\n", buf));
 		strncpy(fw_version, buf, FW_VER_STR_LEN);
 		fw_version[FW_VER_STR_LEN-1] = '\0';
-#if defined(BCMSDIO) || defined(BCMPCIE)
+#if defined(BCMSDIO) || defined(BCMPCIE) || defined(BCMSPI)
 		dhd_set_version_info(dhd, buf);
 #endif /* BCMSDIO || BCMPCIE */
 	}
@@ -11059,6 +11085,9 @@
 		setbit(eventmask_msg->mask, WLC_E_LDF_HOGGER);
 #endif /* ENABLE_HOGSQS */
 
+		/* over temp event */
+		setbit(eventmask_msg->mask, WLC_E_OVERTEMP);
+
 		/* Write updated Event mask */
 		eventmask_msg->ver = EVENTMSGS_VER;
 		eventmask_msg->command = EVENTMSGS_SET_MASK;
@@ -12194,7 +12223,7 @@
 	dhd_info_t *dhd;
 	unsigned long flags;
 	int timer_valid = FALSE;
-	struct net_device *dev;
+	struct net_device *dev = NULL;
 #ifdef WL_CFG80211
 	struct bcm_cfg80211 *cfg = NULL;
 #endif // endif
@@ -12205,7 +12234,8 @@
 	if (!dhd)
 		return;
 
-	dev = dhd->iflist[0]->net;
+	if (dhd->iflist[0])
+		dev = dhd->iflist[0]->net;
 
 	if (dev) {
 		rtnl_lock();
@@ -12451,10 +12481,12 @@
 			ASSERT(0);
 		} else {
 			wl_cfg80211_detach(cfg);
+#ifdef DHD_MONITOR_INTERFACE
 			dhd_monitor_uninit();
+#endif /* DHD_MONITOR_INTERFACE */
 		}
 	}
-#endif // endif
+#endif /* WL_CFG80211 */
 
 #ifdef DHD_PCIE_NATIVE_RUNTIMEPM
 	destroy_workqueue(dhd->tx_wq);
@@ -17422,7 +17454,7 @@
 		log_dump_type_t *flush_type = NULL;
 #endif /* DHD_DUMP_FILE_WRITE_FROM_KERNEL && DHD_LOG_DUMP */
 		dhd_info->scheduled_memdump = FALSE;
-		(void)dhd_mem_dump((void *)dhdp->info, (void *)dump, 0);
+		dhd_mem_dump((void *)dhdp->info, (void *)dump, 0);
 #if defined(DHD_DUMP_FILE_WRITE_FROM_KERNEL) && defined(DHD_LOG_DUMP)
 		/* for dongle init fail cases, 'dhd_mem_dump' does
 		 * not call 'dhd_log_dump', so call it here.
@@ -17448,9 +17480,9 @@
 	DHD_GENERAL_UNLOCK(dhdp, flags);
 	DHD_ERROR(("%s: scheduling mem dump.. \n", __FUNCTION__));
 	dhd_deferred_schedule_work(dhdp->info->dhd_deferred_wq, (void *)dump,
-		DHD_WQ_WORK_SOC_RAM_DUMP, (void *)dhd_mem_dump, DHD_WQ_WORK_PRIORITY_HIGH);
+		DHD_WQ_WORK_SOC_RAM_DUMP, dhd_mem_dump, DHD_WQ_WORK_PRIORITY_HIGH);
 }
-static int
+static void
 dhd_mem_dump(void *handle, void *event_info, u8 event)
 {
 	dhd_info_t *dhd = handle;
@@ -17463,13 +17495,13 @@
 
 	if (!dhd) {
 		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
-		return -ENODEV;
+		return;
 	}
 
 	dhdp = &dhd->pub;
 	if (!dhdp) {
 		DHD_ERROR(("%s: dhdp is NULL\n", __FUNCTION__));
-		return -ENODEV;
+		return;
 	}
 
 	DHD_GENERAL_LOCK(dhdp, flags);
@@ -17614,8 +17646,8 @@
 		dhdp->hang_was_pending = 0;
 	}
 #endif /* OEM_ANDROID */
-	DHD_ERROR(("%s: EXIT \n", __FUNCTION__));
-	return ret;
+	DHD_ERROR(("%s: EXIT %d\n", __FUNCTION__, ret));
+	return;
 }
 #endif /* DHD_FW_COREDUMP */
 
@@ -20040,8 +20072,8 @@
 	dld_buf_special->buffer = DHD_OS_PREALLOC(dhd, prealloc_idx++,
 			dld_buf_size[DLD_BUF_TYPE_SPECIAL]);
 #else
-	prealloc_buf = MALLOCZ(dhd->osh, LOG_DUMP_TOTAL_BUFSIZE);
-	dld_buf_special->buffer = MALLOCZ(dhd->osh, dld_buf_size[DLD_BUF_TYPE_SPECIAL]);
+	prealloc_buf = VMALLOCZ(dhd->osh, LOG_DUMP_TOTAL_BUFSIZE);
+	dld_buf_special->buffer = VMALLOCZ(dhd->osh, dld_buf_size[DLD_BUF_TYPE_SPECIAL]);
 #endif /* CONFIG_DHD_USE_STATIC_BUF && DHD_USE_STATIC_MEMDUMP */
 	if (!prealloc_buf) {
 		DHD_ERROR(("Failed to pre-allocate memory for log buffers !\n"));
@@ -20201,10 +20233,10 @@
 	}
 #else
 	if (prealloc_buf) {
-		MFREE(dhd->osh, prealloc_buf, LOG_DUMP_TOTAL_BUFSIZE);
+		VMFREE(dhd->osh, prealloc_buf, LOG_DUMP_TOTAL_BUFSIZE);
 	}
 	if (dld_buf_special->buffer) {
-		MFREE(dhd->osh, dld_buf_special->buffer,
+		VMFREE(dhd->osh, dld_buf_special->buffer,
 				dld_buf_size[DLD_BUF_TYPE_SPECIAL]);
 	}
 #endif /* CONFIG_DHD_USE_STATIC_BUF */
@@ -20279,10 +20311,10 @@
 	}
 #else
 	if (dld_buf->buffer) {
-		MFREE(dhd->osh, dld_buf->buffer, LOG_DUMP_TOTAL_BUFSIZE);
+		VMFREE(dhd->osh, dld_buf->buffer, LOG_DUMP_TOTAL_BUFSIZE);
 	}
 	if (dld_buf_special->buffer) {
-		MFREE(dhd->osh, dld_buf_special->buffer,
+		VMFREE(dhd->osh, dld_buf_special->buffer,
 				dld_buf_size[DLD_BUF_TYPE_SPECIAL]);
 	}
 #endif /* CONFIG_DHD_USE_STATIC_BUF */
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 a5ceced..c9b63b2 100644
--- 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,7 +2,7 @@
  * 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) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -1510,6 +1510,8 @@
 	}
 
 	/* Releae the kobject */
-	kobject_put(&dhd->dhd_kobj);
-	kobject_put(&dhd->dhd_conf_file_kobj);
+	if (dhd->dhd_kobj.state_initialized)
+		kobject_put(&dhd->dhd_kobj);
+	if (dhd->dhd_conf_file_kobj.state_initialized)
+		kobject_put(&dhd->dhd_conf_file_kobj);
 }
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 9c43430..0e573c8 100644
--- 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,7 +3,7 @@
  * 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) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -2073,7 +2073,7 @@
 
 	dhd_pktid_map_sz = DHD_PKTID_MAP_SZ(num_items);
 
-	map = (dhd_pktid_map_t *)VMALLOC(osh, dhd_pktid_map_sz);
+	map = (dhd_pktid_map_t *)VMALLOCZ(osh, dhd_pktid_map_sz);
 	if (map == NULL) {
 		DHD_ERROR(("%s:%d: MALLOC failed for size %d\n",
 			__FUNCTION__, __LINE__, dhd_pktid_map_sz));
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 ca9caf6..1f2d0a8 100644
--- 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,7 +1,7 @@
 /*
  * DHD Bus Module for PCIE
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -139,6 +139,9 @@
 extern int host_edl_support;
 #endif // endif
 
+#define D2H_HS_START_STATE (1 << D2H_START_SHIFT)
+#define D2H_HS_READY_STATE (1 << D2H_START_SHIFT | 1 << D2H_READY_SHIFT)
+
 /* This can be overwritten by module parameter(dma_ring_indices) defined in dhd_linux.c */
 uint dma_ring_indices = 0;
 /* This can be overwritten by module parameter(h2d_phase) defined in dhd_linux.c */
@@ -780,6 +783,7 @@
 		/* software resources */
 		if (!(bus->dhd = dhd_attach(osh, bus, PCMSGBUF_HDRLEN))) {
 			DHD_ERROR(("%s: dhd_attach failed\n", __FUNCTION__));
+			ret = BCME_ERROR;
 			break;
 		}
 
@@ -1484,6 +1488,8 @@
 	volatile void *regsva = (volatile void*)bus->regs;
 	uint16 devid;
 	uint32 val;
+	uint32 reg_val = 0;
+	bool is_pcie_reset = FALSE;
 	uint32 secureboot;
 	sbpcieregs_t *sbpcieregs;
 	bool dongle_isolation;
@@ -1528,6 +1534,20 @@
 
 		/* Set bar0 window to si_pcie_enum_base */
 		dhdpcie_bus_cfg_set_bar0_win(bus, si_pcie_enum_base(devid));
+		sbpcieregs = (sbpcieregs_t*)(bus->regs);
+		DHD_INFO(("%s: before read reg_val:%d\n", __FUNCTION__, reg_val));
+		reg_val = R_REG(osh, &sbpcieregs->u1.dar_64.d2h_msg_reg0);
+		DHD_INFO(("%s: after reg_val:%d\n", __FUNCTION__, reg_val));
+		if (reg_val != D2H_HS_START_STATE || reg_val != (D2H_HS_READY_STATE)) {
+		/* si_attach() will provide an SI handle and scan the backplane */
+			if (!(bus->sih = si_attach((uint)devid, osh, regsva, PCI_BUS, bus,
+			     &bus->vars, &bus->varsz))) {
+				DHD_ERROR(("%s: si_attach failed!\n", __FUNCTION__));
+				goto fail;
+			}
+			dhdpcie_dongle_reset(bus);
+			is_pcie_reset = TRUE;
+		}
 
 		/* Pre ChipID access sequence, make sure that
 		 * bootloader is ready before ChipID access.
@@ -1655,7 +1675,7 @@
 	 * This is required to avoid spurious interrupts to the Host and bring back
 	 * dongle to a sane state (on host soft-reboot / watchdog-reboot).
 	 */
-	if (dongle_isolation == FALSE) {
+	if (dongle_isolation == FALSE && is_pcie_reset == FALSE) {
 		dhdpcie_dongle_reset(bus);
 	}
 #endif /* !DHD_SKIP_DONGLE_RESET_IN_ATTACH */
@@ -3439,6 +3459,7 @@
 	uint readlen = 0;
 	uint i = 0;
 
+	DHD_ERROR(("dhdpcie_bus_readconsole\n"));
 	if (!DHD_FWLOG_ON())
 		return 0;
 
@@ -3483,7 +3504,7 @@
 	if (idx == c->last)
 		return BCME_OK;
 
-	DHD_ERROR(("conlog: addr=0x%x, idx=0x%x, last=0x%x \n", c->log.buf,
+	DHD_ERROR(("cy2-conlog: addr=0x%x, idx=0x%x, last=0x%x \n", c->log.buf,
 	   idx, c->last));
 
 	/* Read the console buffer data to a local buffer */
@@ -3491,6 +3512,7 @@
 	 * 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) {
@@ -3521,6 +3543,7 @@
 	/* 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++) {
@@ -3539,6 +3562,7 @@
 		}
 	}
 
+	DHD_ERROR(("read console finish\n"));
 	return BCME_OK;
 
 } /* dhdpcie_bus_readconsole */
@@ -7305,6 +7329,7 @@
 	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,
@@ -7334,6 +7359,7 @@
 #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;
@@ -7411,6 +7437,7 @@
 						__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",
@@ -7434,8 +7461,10 @@
 			}
 		}
 	} 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;
@@ -7459,6 +7488,7 @@
 				(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;
@@ -7488,6 +7518,7 @@
 				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))) {
@@ -7502,6 +7533,7 @@
 
 			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__));
@@ -7580,12 +7612,16 @@
 			/* 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 */
+			DHD_ERROR(("dhdpcie_bus_download_state 3\n"));
+			/*
 			if ((bcmerror = dhdpcie_bus_readconsole(bus)) < 0) {
 				DHD_ERROR(("%s: Final pass console buffer read failed\n",
 					__FUNCTION__));
 			}
+			//*/
 
 			/* Set write_vars done bit to let BL jump to mainline FW */
 			if ((bcmerror = dhdpcie_dongle_host_post_varswrite(bus, &bl_hs_addrs))) {
@@ -7614,6 +7650,7 @@
 					__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__));
@@ -7629,6 +7666,7 @@
 		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_linux.c b/src/kernel/linux/v4.19/drivers/net/wireless/bcmdhd/dhd_pcie_linux.c
index 6e81e06..426afe7 100644
--- 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,7 +1,7 @@
 /*
  * Linux DHD Bus Module for PCIE
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -87,6 +87,15 @@
 #ifdef FORCE_TPOWERON
 extern uint32 tpoweron_scale;
 #endif /* FORCE_TPOWERON */
+
+#if defined(CONFIG_ARCH_MSM)
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0))
+#ifndef MSM_PCIE_CONFIG_NO_CFG_RESTORE
+#define MSM_PCIE_CONFIG_NO_CFG_RESTORE	0
+#endif /* MSM_PCIE_CONFIG_NO_CFG_RESTORE */
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) */
+#endif /* CONFIG_ARCH_MSM */
+
 /* user defined data structures  */
 
 typedef bool (*dhdpcie_cb_fn_t)(void *);
@@ -1756,8 +1765,10 @@
 		goto err;
 	}
 	DHD_ERROR(("PCIe:%s:enabled link\n", __FUNCTION__));
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0))
 	/* recover the config space of both RC and Endpoint */
 	msm_pcie_recover_config(pdev);
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0) */
 #endif /* CONFIG_ARCH_MSM && !ENABLE_INSMOD_NO_FW_LOAD */
 #ifdef EXYNOS_PCIE_MODULE_PATCH
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
@@ -2329,7 +2340,9 @@
 	ret = msm_pcie_pm_control(MSM_PCIE_RESUME, bus->dev->bus->number,
 		bus->dev, NULL, options);
 	if (bus->no_cfg_restore && !ret) {
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0))
 		msm_pcie_recover_config(bus->dev);
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0) */
 		bus->no_cfg_restore = 0;
 	}
 #else
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 7752ed4..cda805f 100644
--- 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,7 +1,7 @@
 /*
  * DHD Bus Module for SDIO
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -452,6 +452,8 @@
 	char		*btfw_path;	/* module_param: path to BT firmware image */
 	uint32		bt_use_count; /* Counter that tracks whether BT is using the bus */
 #endif /* defined (BT_OVER_SDIO) */
+	bool		chipidpresent;	/* ChipID is present in SDIO core enum address space */
+	bool		secureboot;		/* security related features are present */
 } dhd_bus_t;
 
 /*
@@ -727,12 +729,12 @@
 static int dhdsdio_devcap_set(dhd_bus_t *bus, uint8 cap);
 static int dhdsdio_readshared_console(dhd_bus_t *bus);
 static int dhdsdio_download_state(dhd_bus_t *bus, bool enter);
+static int dhdsdio_wait_bootloader_ready(dhd_bus_t *bus, hs_addrs_t *addr);
 static int dhdsdio_dongle_host_get_handshake_address(dhd_bus_t *bus, hs_addrs_t *addr);
 static int dhdsdio_dongle_host_pre_handshake(dhd_bus_t *bus, hs_addrs_t *addr);
 static int dhdsdio_dongle_host_post_handshake(dhd_bus_t *bus, hs_addrs_t *addr);
 static int dhdsdio_dongle_host_chk_validation(dhd_bus_t *bus, hs_addrs_t *addr);
 static int dhdsdio_dongle_host_post_varswrite(dhd_bus_t *bus, hs_addrs_t *addr);
-int dhdsdio_dongle_host_post_wd_reset_sequence(dhd_bus_t *bus);
 int dhdsdio_dongle_host_pre_wd_reset_sequence(dhd_bus_t *bus);
 
 static int dhdsdio_handshake_msg_reg_write(dhd_bus_t *bus, volatile void *addr,
@@ -2253,6 +2255,8 @@
 		head_padding = 0;
 		alloc_new_pkt = TRUE;
 	} else {
+		/* gSPI expects that hw-header-len is equal to spi-command-len */
+#ifndef BCMSPI
 		uint cur_chain_total_len;
 		int chain_tail_padding = 0;
 
@@ -2301,6 +2305,7 @@
 		 */
 #endif /* DHDENABLE_TAILPAD */
 		tail_padding += chain_tail_padding;
+#endif /* !BCMSPI */
 	}
 
 	DHD_INFO(("%s sdhdr len + orig_pkt_len %d h_pad %d t_pad %d pad_pkt_len %d\n",
@@ -3609,11 +3614,12 @@
 	if (idx == c->last)
 		return BCME_OK;
 
-	DHD_ERROR(("conlog: addr=0x%x, idx=0x%x, last=0x%x \n", c->log.buf,
+	DHD_ERROR(("cy-conlog: addr=0x%x, idx=0x%x, last=0x%x \n", c->log.buf,
 	   idx, c->last));
 
 	/* 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;
 
@@ -4740,8 +4746,7 @@
 	if (!bus->sih)
 		return BCME_ERROR;
 
-	if (bus->sih->chip == CYW55500_CHIP_ID ||
-	    bus->sih->chip == CYW55560_CHIP_ID) {
+	if (bus->secureboot) {
 		/* Host bootloader handshake TCM/REGS addresses init */
 		bcmerror = dhdsdio_dongle_host_get_handshake_address(bus, &bl_hs_addrs);
 		if (bcmerror) {
@@ -4816,10 +4821,8 @@
 			 * [done at else] Populate the reset vector
 			 * [done at else] Remove ARM halt
 			 */
-			if (bus->sih->chip == CYW55500_CHIP_ID ||
-			    bus->sih->chip == CYW55560_CHIP_ID) {
-
-				/* Skip ARM halt and reset in case of 555x0 */
+			if (bus->secureboot) {
+				/* Skip ARM halt and reset in case of security bootloader */
 
 				/* Bootloader host pre handshake function */
 				if ((bcmerror =	dhdsdio_dongle_host_pre_handshake
@@ -4896,9 +4899,7 @@
 				goto fail;
 			}
 		} else {
-
-			if (bus->sih->chip == CYW55500_CHIP_ID ||
-			    bus->sih->chip == CYW55560_CHIP_ID) {
+			if (bus->secureboot) {
 #ifdef DHD_DEBUG
 				/* Console buffer read - Second pass */
 				if ((bcmerror = dhdsdio_readconsole(bus)) < 0) {
@@ -4961,8 +4962,7 @@
 			}
 			/* write address 0 with reset instruction */
 			/* Except for chips eg. CYW555x0, which runs bootloader */
-			if (bus->sih->chip != CYW55500_CHIP_ID &&
-			    bus->sih->chip != CYW55560_CHIP_ID) {
+			if (!bus->secureboot) {
 				bcmerror = dhdsdio_membytes(bus, TRUE, 0,
 						(uint8 *)&bus->resetinstr, sizeof(bus->resetinstr));
 
@@ -4986,8 +4986,7 @@
 		}
 
 		/* now remove reset and halt and continue to run CR4 */
-		if (bus->sih->chip == CYW55500_CHIP_ID ||
-		    bus->sih->chip == CYW55560_CHIP_ID) {
+		if (bus->secureboot) {
 #ifdef DHD_DEBUG
 			/* Console buffer read - Final pass */
 			if ((bcmerror = dhdsdio_readconsole(bus)) < 0) {
@@ -5020,8 +5019,7 @@
 
 fail:
 	if (bcmerror) {
-		if (bus->sih->chip == CYW55500_CHIP_ID ||
-		    bus->sih->chip == CYW55560_CHIP_ID) {
+		if (bus->secureboot) {
 			/* Read the shared structure to determine console address */
 			if (dhdsdio_readshared_console(bus) < 0) {
 				DHD_ERROR(("%s: Shared region not initialized\n",
@@ -5059,7 +5057,7 @@
 }
 
 static int
-dhdsdio_dongle_host_pre_handshake(dhd_bus_t *bus, hs_addrs_t *addr)
+dhdsdio_wait_bootloader_ready(dhd_bus_t *bus, hs_addrs_t *addr)
 {
 	int bcmerror = BCME_OK;
 	int h2d_reg = 0x00000000;
@@ -5071,20 +5069,26 @@
 	}
 
 	bcmerror = dhdsdio_dongle_host_handshake_spinwait(bus, addr->d2h,
-		D2H_READY_SHIFT, D2H_READY_TIMEOUT_MS);
-	if (!bcmerror) {
-
-		/* Set H2D_DL_START indication to dongle that Host shall start FW download */
-		h2d_reg = 0;
-		setbit(&h2d_reg, H2D_DL_START_SHIFT);
-		bcmerror = dhdsdio_handshake_msg_reg_write(bus, addr->h2d, &h2d_reg);
-	}
+			D2H_READY_SHIFT, D2H_READY_TIMEOUT_MS);
 
 err:
 	return bcmerror;
 }
 
 static int
+dhdsdio_dongle_host_pre_handshake(dhd_bus_t *bus, hs_addrs_t *addr)
+{
+	int bcmerror = BCME_OK;
+	int h2d_reg = 0x00000000;
+
+	/* Set H2D_DL_START indication to dongle that Host shall start FW download */
+	setbit(&h2d_reg, H2D_DL_START_SHIFT);
+	bcmerror = dhdsdio_handshake_msg_reg_write(bus, addr->h2d, &h2d_reg);
+
+	return bcmerror;
+}
+
+static int
 dhdsdio_dongle_host_post_handshake(dhd_bus_t *bus, hs_addrs_t *addr)
 {
 	int bcmerror = BCME_OK;
@@ -5178,45 +5182,6 @@
 	return bcmerror;
 }
 
-int
-dhdsdio_dongle_host_post_wd_reset_sequence(dhd_bus_t *bus)
-{
-	int32 bcmerror = BCME_ERROR;
-	volatile void *d2h_reg = NULL;
-	volatile void *h2d_reg = NULL;
-	uint32 d2h_reg_val = 0x0;
-	uint32 h2d_reg_val = 0x0;
-	int32 idx = 0;
-
-	d2h_reg = (uint32 *)SDIO_FN1_MSG_D2H_REG0;
-	h2d_reg = (uint32 *)SDIO_FN1_MSG_H2D_REG0;
-
-	bcmerror = dhdsdio_handshake_msg_reg_write(bus, h2d_reg, &h2d_reg_val);
-
-	for (idx = D2H_READY_WD_RESET_COUNT; idx > 0; idx--) {
-
-		OSL_SLEEP(D2H_READY_WD_RESET_MS);
-		if (!(idx % D2H_READY_WD_RESET_DBG_PRINT_MS)) {
-			DHD_ERROR(("Waiting for D2H_READY %d\n",
-				idx/D2H_READY_WD_RESET_DBG_PRINT_MS));
-		}
-		dhdsdio_handshake_msg_reg_read(bus, d2h_reg, &d2h_reg_val);
-		if (isset(&d2h_reg_val, D2H_READY_SHIFT)) {
-			break;
-		}
-
-	}
-
-	if (!idx) {
-		DHD_ERROR(("%s: error - Waiting for D2H_READY timeout %d\n",
-			__FUNCTION__, idx));
-	} else {
-		bcmerror = BCME_OK;
-	}
-
-	return bcmerror;
-}
-
 static int
 dhdsdio_handshake_msg_reg_write(dhd_bus_t *bus, volatile void *addr, uint32 *buffer)
 {
@@ -8231,7 +8196,7 @@
 	return rv;
 }
 
-#if defined(DHD_DEBUG) && !defined(BCMSDIOLITE)
+#if defined(DHD_DEBUG) && !defined(BCMSDIOLITE) && !defined(BCMSPI)
 static void
 dhd_dump_cis(uint fn, uint8 *cis)
 {
@@ -8391,7 +8356,7 @@
 	}
 
 	if (osh == NULL) {
-#if defined(BCMSPI) && defined(BCMPCISPIHOST)
+#if defined(BCMSPI) && (defined(BCMPCISPIHOST) || defined(BCMSDIOH_SPI))
 		/* bcmsdh_probe() calls drvinfo.probe() that is this function with osh as NULL */
 		if (!(osh = osl_attach(sdh, DHD_BUS, TRUE))) {
 			DHD_ERROR(("%s: osl_attach failed!\n", __FUNCTION__));
@@ -8400,7 +8365,7 @@
 #else
 		DHD_ERROR(("%s: osh is NULL!\n", __FUNCTION__));
 		goto forcereturn;
-#endif /* BCMSPI && defined(BCMPCISPIHOST) */
+#endif /* BCMSPI && (defined(BCMPCISPIHOST) || defined(BCMSDIOH_SPI)) */
 	}
 
 	/* Allocate private bus interface state */
@@ -8529,27 +8494,73 @@
 dhdsdio_probe_attach(struct dhd_bus *bus, osl_t *osh, void *sdh, void *regsva,
                      uint16 devid)
 {
-#ifndef BCMSPI
+#ifdef BCMSPI
+	uint32 spidreg = 0;
+#else
 	uint8 clkctl = 0;
-#endif /* !BCMSPI */
+	uint8 cardcap = 0;
+#endif /* BCMSPI */
 	uint fn, numfn;
 	uint8 *cis[SDIOD_MAX_IOFUNCS];
 	int32 value;
 	int32 size;
 	int err = 0;
+	hs_addrs_t bl_hs_addrs = {NULL, NULL};
 
 	BCM_REFERENCE(value);
 	bus->alp_only = TRUE;
 	bus->sih = NULL;
 
+#ifdef BCMSPI
+	spidreg = bcmsdh_cfg_read_word(sdh, SDIO_FUNC_0, SPID_RESET_BP, NULL);
+	if (spidreg & SPID_SECURE_MODE) {
+		DHD_INFO(("Security related features are present\n"));
+		bus->secureboot = TRUE;
+	}
+	if (spidreg & SPID_CHIPID_PRESENT) {
+		DHD_INFO(("Chip ID is present in SPI core\n"));
+		bus->chipidpresent = true;
+	}
+#else
+	cardcap = dhdsdio_devcap_get(bus);
+	if (cardcap & SDIOD_CCCR_BRCM_CARDCAP_SECURE_MODE) {
+		DHD_INFO(("Security related features are present\n"));
+		bus->secureboot = TRUE;
+	}
+	if (cardcap & SDIOD_CCCR_BRCM_CARDCAP_CHIPID_PRESENT) {
+		DHD_INFO(("Chip ID is present in SDIO core\n"));
+		bus->chipidpresent = true;
+	}
+#endif /* BCMSPI */
+
+	if (bus->secureboot) {
+		/* Should not do any backplane access before bootloader is ready */
+		dhdsdio_dongle_host_get_handshake_address(bus, &bl_hs_addrs);
+		err = dhdsdio_wait_bootloader_ready(bus, &bl_hs_addrs);
+		if (err) {
+			DHD_ERROR(("Bootloader ready timeout\n"));
+			goto fail;
+		}
+	}
+
+	if (bus->chipidpresent) {
+		/* Get SDIO core base address */
+		bus->regs = si_get_sdio_addrbase(sdh);
+	}
+
 	/* Return the window to backplane enumeration space for core access */
 	if (dhdsdio_set_siaddr_window(bus, si_enum_base(devid))) {
 		DHD_ERROR(("%s: FAILED to return to SI_ENUM_BASE\n", __FUNCTION__));
 	}
 
 #if defined(DHD_DEBUG) && !defined(CUSTOMER_HW4_DEBUG)
-	DHD_ERROR(("F1 signature read @0x18000000=0x%4x\n",
-		bcmsdh_reg_read(bus->sdh, si_enum_base(devid), 4)));
+	if (bus->chipidpresent) {
+		DHD_ERROR(("F1 signature read @0x%lx=0x%4x\n",
+			(unsigned long)&bus->regs->chipid, R_REG(osh, &bus->regs->chipid)));
+	} else {
+		DHD_ERROR(("F1 signature read @0x18000000=0x%4x\n",
+			bcmsdh_reg_read(bus->sdh, si_enum_base(devid), 4)));
+	}
 #endif /* DHD_DEBUG && !CUSTOMER_HW4_DEBUG */
 
 #ifndef BCMSPI	/* wake-wlan in gSPI will bring up the htavail/alpavail clocks. */
@@ -8562,105 +8573,128 @@
 
 	if (err || ((clkctl & ~SBSDIO_AVBITS) != DHD_INIT_CLKCTL1)) {
 		DHD_ERROR(("dhdsdio_probe: ChipClkCSR access: err %d wrote 0x%02x read 0x%02x\n",
-		           err, DHD_INIT_CLKCTL1, clkctl));
+				err, DHD_INIT_CLKCTL1, clkctl));
 		goto fail;
 	}
 
 #endif /* !BCMSPI */
-#ifndef BCMSPI
-		numfn = bcmsdh_query_iofnum(sdh);
-		ASSERT(numfn <= SDIOD_MAX_IOFUNCS);
-
-		/* Make sure ALP is available before trying to read CIS */
-		SPINWAIT(((clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
-		                                    SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
-		          !SBSDIO_ALPAV(clkctl)), PMU_MAX_TRANSITION_DLY);
-
-		/* Now request ALP be put on the bus */
-		bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
-		                 DHD_INIT_CLKCTL2, &err);
-		OSL_DELAY(65);
+#ifdef BCMSPI
+	/* internally func is hardcoded to 1 as gSPI has cis on F1 only */
+	fn = 0;
+	value = F0_BLOCK_SIZE;
+	/* Get block size from sd */
+	if (bcmsdh_iovar_op(sdh, "sd_blocksize", &fn, sizeof(int32),
+			&size, sizeof(int32), FALSE) != BCME_OK) {
+		size = 0;
+		DHD_ERROR(("%s: fail on fn %d %s get\n",
+				__FUNCTION__, fn, "sd_blocksize"));
+	} else {
+		DHD_INFO(("%s: Initial value for fn %d %s is %d\n",
+				__FUNCTION__, fn, "sd_blocksize", size));
+	}
+	if (size != 0 && size < value) {
+		value = size;
+	}
+	value = fn << 16 | value;
+	if (bcmsdh_iovar_op(sdh, "sd_blocksize", NULL, 0, &value,
+			sizeof(value), TRUE) != BCME_OK) {
+		bus->blocksize = 0;
+		DHD_ERROR(("%s: fail on fn %d %s set\n", __FUNCTION__,
+				fn, "sd_blocksize"));
+	}
+	BCM_REFERENCE(cis);
+	BCM_REFERENCE(numfn);
 #else
-		numfn = 0; /* internally func is hardcoded to 1 as gSPI has cis on F1 only */
-#endif /* !BCMSPI */
-#ifndef BCMSDIOLITE
-		for (fn = 0; fn <= numfn; fn++) {
-			if (!(cis[fn] = MALLOC(osh, SBSDIO_CIS_SIZE_LIMIT))) {
-				DHD_INFO(("dhdsdio_probe: fn %d cis malloc failed\n", fn));
-				break;
-			}
-			bzero(cis[fn], SBSDIO_CIS_SIZE_LIMIT);
+	numfn = bcmsdh_query_iofnum(sdh);
+	ASSERT(numfn <= SDIOD_MAX_IOFUNCS);
 
-			if ((err = bcmsdh_cis_read(sdh, fn, cis[fn],
-			                                 SBSDIO_CIS_SIZE_LIMIT))) {
-				DHD_INFO(("dhdsdio_probe: fn %d cis read err %d\n", fn, err));
-				MFREE(osh, cis[fn], SBSDIO_CIS_SIZE_LIMIT);
-				break;
-			}
+	/* Make sure ALP is available before trying to read CIS */
+	SPINWAIT(((clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+			SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
+			!SBSDIO_ALPAV(clkctl)), PMU_MAX_TRANSITION_DLY);
+
+	/* Now request ALP be put on the bus */
+	bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+			DHD_INIT_CLKCTL2, &err);
+	OSL_DELAY(65);
+#ifndef BCMSDIOLITE
+	for (fn = 0; fn <= numfn; fn++) {
+		if (!(cis[fn] = MALLOC(osh, SBSDIO_CIS_SIZE_LIMIT))) {
+			DHD_INFO(("dhdsdio_probe: fn %d cis malloc failed\n", fn));
+			break;
+		}
+		bzero(cis[fn], SBSDIO_CIS_SIZE_LIMIT);
+
+		if ((err = bcmsdh_cis_read(sdh, fn, cis[fn],
+				SBSDIO_CIS_SIZE_LIMIT))) {
+			DHD_INFO(("dhdsdio_probe: fn %d cis read err %d\n", fn, err));
+			MFREE(osh, cis[fn], SBSDIO_CIS_SIZE_LIMIT);
+			break;
+		}
 
 		/* Reading the F1, F2 and F3 max blocksize values from CIS
-		  * and writing into the F1, F2 and F3	block size registers.
-		  * There is no max block size register value available for F0 in CIS register.
-		  * So, setting default value for F0 block size as 32 (which was set earlier
-		  * in iovar). IOVAR takes only one arguement.
-		  * So, we are passing the function number alongwith the value (fn<<16)
-		*/
-			if (!fn)
-				value = F0_BLOCK_SIZE;
-			else
-				value = (cis[fn][25]<<8) | cis[fn][24] | (fn<<16);
-			/* Get block size from sd */
-			if (bcmsdh_iovar_op(sdh, "sd_blocksize", &fn, sizeof(int32),
+		 * and writing into the F1, F2 and F3	block size registers.
+		 * There is no max block size register value available for F0 in CIS register.
+		 * So, setting default value for F0 block size as 32 (which was set earlier
+		 * in iovar). IOVAR takes only one arguement.
+		 * So, we are passing the function number alongwith the value (fn<<16)
+		 */
+		if (!fn)
+			value = F0_BLOCK_SIZE;
+		else
+			value = (cis[fn][25]<<8) | cis[fn][24] | (fn<<16);
+		/* Get block size from sd */
+		if (bcmsdh_iovar_op(sdh, "sd_blocksize", &fn, sizeof(int32),
 				&size, sizeof(int32), FALSE) != BCME_OK) {
-				size = 0;
-				DHD_ERROR(("%s: fail on fn %d %s get\n",
+			size = 0;
+			DHD_ERROR(("%s: fail on fn %d %s get\n",
 					__FUNCTION__, fn, "sd_blocksize"));
-			} else {
-				DHD_INFO(("%s: Initial value for fn %d %s is %d\n",
+		} else {
+			DHD_INFO(("%s: Initial value for fn %d %s is %d\n",
 					__FUNCTION__, fn, "sd_blocksize", size));
-			}
-			if (size != 0 && size < value) {
-				value = size;
-			}
-			value = fn << 16 | value;
-			if (bcmsdh_iovar_op(sdh, "sd_blocksize", NULL, 0, &value,
+		}
+		if (size != 0 && size < value) {
+			value = size;
+		}
+		value = fn << 16 | value;
+		if (bcmsdh_iovar_op(sdh, "sd_blocksize", NULL, 0, &value,
 				sizeof(value), TRUE) != BCME_OK) {
-				bus->blocksize = 0;
-				DHD_ERROR(("%s: fail on fn %d %s set\n", __FUNCTION__,
+			bus->blocksize = 0;
+			DHD_ERROR(("%s: fail on fn %d %s set\n", __FUNCTION__,
 					fn, "sd_blocksize"));
-			}
+		}
 
-			/* F2 blocksize value can be taken in order of precedence of
-			 *	insmod argument
-			 *	build flag variable
-			 *	CIS tuple
-			 *	default parameter
-			 */
-			if (fn == F2_BLOCK) {
-				if (!sd_f2_blocksize) {
+		/* F2 blocksize value can be taken in order of precedence of
+		 *	insmod argument
+		 *	build flag variable
+		 *	CIS tuple
+		 *	default parameter
+		 */
+		if (fn == F2_BLOCK) {
+			if (!sd_f2_blocksize) {
 #ifdef CUSTOM_SDIO_F2_BLKSIZE
-					sd_f2_blocksize = CUSTOM_SDIO_F2_BLKSIZE;
+				sd_f2_blocksize = CUSTOM_SDIO_F2_BLKSIZE;
 #else
-					sd_f2_blocksize = ((uint16)value ? (uint16)value :
+				sd_f2_blocksize = ((uint16)value ? (uint16)value :
 						DEFAULT_SDIO_F2_BLKSIZE);
 #endif /* CUSTOM_SDIO_F2_BLKSIZE */
-				}
-
-				value = (fn << SDIO_FUNC_BLOCK_SIZE_SHIFT) | sd_f2_blocksize;
-				if (bcmsdh_iovar_op(sdh, "sd_blocksize",
-					NULL, 0, &value, sizeof(fn), TRUE) != BCME_OK) {
-					DHD_ERROR(("%s: Set F2 Block size error\n",
-					__FUNCTION__));
-					goto fail;
-				}
 			}
 
+			value = (fn << SDIO_FUNC_BLOCK_SIZE_SHIFT) | sd_f2_blocksize;
+			if (bcmsdh_iovar_op(sdh, "sd_blocksize",
+					NULL, 0, &value, sizeof(fn), TRUE) != BCME_OK) {
+				DHD_ERROR(("%s: Set F2 Block size error\n",
+						__FUNCTION__));
+				goto fail;
+			}
+		}
+
 #ifdef DHD_DEBUG
-			if (DHD_INFO_ON()) {
-				dhd_dump_cis(fn, cis[fn]);
-			}
-#endif /* DHD_DEBUG */
+		if (DHD_INFO_ON()) {
+			dhd_dump_cis(fn, cis[fn]);
 		}
+#endif /* DHD_DEBUG */
+	}
 	while (fn-- > 0) {
 		ASSERT(cis[fn]);
 		MFREE(osh, cis[fn], SBSDIO_CIS_SIZE_LIMIT);
@@ -8669,11 +8703,12 @@
 	BCM_REFERENCE(cis);
 	BCM_REFERENCE(fn);
 #endif /* !BCMSDIOLITE */
-
+#endif /* !BCMSPI */
 	if (err) {
 		DHD_ERROR(("dhdsdio_probe: failure reading or parsing CIS\n"));
 		goto fail;
 	}
+
 	/* si_attach() will provide an SI handle and scan the backplane */
 	if (!(bus->sih = si_attach((uint)devid, osh, regsva, DHD_BUS, sdh,
 	                           &bus->vars, &bus->varsz))) {
@@ -9152,8 +9187,7 @@
 			dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
 		}
 		if (KSO_ENAB(bus) && (dongle_isolation == FALSE)) {
-			if (bus->sih->chip == CYW55500_CHIP_ID ||
-			    bus->sih->chip == CYW55560_CHIP_ID) {
+			if (bus->secureboot) {
 				/*
 				 * CYW555x0 - As part of watchdog reset, ARM gets
 				 * reset and bootloader starts from fresh,
@@ -9168,22 +9202,30 @@
 				}
 			}
 
-			si_watchdog(bus->sih, 4);
-
-			/*
-			 * CYW555x0 - Once watchdog reset initiated,
-			 * bootloader takes much time to be ready,
-			 * [BL_READY bit set]
-			 */
-			if (bus->sih->chip == CYW55500_CHIP_ID ||
-			    bus->sih->chip == CYW55560_CHIP_ID) {
-				if ((bcmerror =
-					dhdsdio_dongle_host_post_wd_reset_sequence(bus)))
-				{
-					DHD_ERROR(("%s: error %d post wd reset seq.\n",
-						__FUNCTION__, bcmerror));
+			if (bus->chipidpresent) {
+				/*
+				 * Configure registers to trigger WLAN reset on
+				 * "SDIO Soft Reset", and set RES bit to trigger SDIO as
+				 * well as WLAN reset (instead of using PMU/CC Watchdog register)
+				 */
+				uint8 cardctl;
+				cardctl = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0,
+						SDIOD_CCCR_BRCM_CARDCTL, &bcmerror);
+				cardctl |= SDIOD_CCCR_BRCM_WLANRST_ONF0ABORT;
+				if (!bcmerror) {
+					bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0,
+							SDIOD_CCCR_BRCM_CARDCTL, cardctl,
+							&bcmerror);
 				}
+				if (!bcmerror) {
+					bcmerror = bcmsdh_abort(bus->sdh, SDIO_FUNC_0 | 0x8);
+					DHD_ERROR(("%s: Set WLANRST in cardctl error %d\n",
+							__FUNCTION__, bcmerror));
+				}
+			} else {
+				si_watchdog(bus->sih, 4);
 			}
+
 		}
 #endif /* !defined(BCMLXSDMMC) */
 		if (bus->dhd) {
@@ -9750,6 +9792,9 @@
 
 	sdh = bus->sdh;
 	do {
+		if (fn == 2)
+			bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_CHIP_CTRL_DATA, 0x80, NULL);
+
 		ret = bcmsdh_send_buf(bus->sdh, addr, fn, flags, buf, nbytes,
 			pkt, complete_fn, handle);
 
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
index 31cfe7b..0005403 100644
--- 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,7 +1,7 @@
 /*
  * DHD PROP_TXSTATUS Module.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -3536,7 +3536,6 @@
 		}
 	}
 
-	ASSERT(entry->onbus_pkts_count > 0);
 	if (entry->onbus_pkts_count > 0)
 		entry->onbus_pkts_count--;
 	if (entry->suppressed &&
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 8030e49..02f58c0 100644
--- 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,7 +1,7 @@
 /*
  * Fundamental types and constants relating to 802.11
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -509,17 +509,23 @@
 #define DOT11_WIDE_BW_IE_LEN     3       /* length of IE data, not including 2 byte header */
 /** VHT Transmit Power Envelope IE data structure */
 BWL_PRE_PACKED_STRUCT struct dot11_vht_transmit_power_envelope {
-	uint8 id;				/* id DOT11_MNG_WIDE_BW_CHANNEL_SWITCH_ID */
+	uint8 id;				/* id DOT11_MNG_TRANSMIT_POWER_ENVELOPE_ID */
 	uint8 len;				/* length of IE */
 	uint8 transmit_power_info;
 	uint8 local_max_transmit_power_20;
 } BWL_POST_PACKED_STRUCT;
 typedef struct dot11_vht_transmit_power_envelope dot11_vht_transmit_power_envelope_ie_t;
 
-/* vht transmit power envelope IE length depends on channel width */
-#define DOT11_VHT_TRANSMIT_PWR_ENVELOPE_IE_LEN_40MHZ	1
-#define DOT11_VHT_TRANSMIT_PWR_ENVELOPE_IE_LEN_80MHZ	2
-#define DOT11_VHT_TRANSMIT_PWR_ENVELOPE_IE_LEN_160MHZ	3
+/* Transmit power envelope IE length depends on channel width */
+#define DOT11_TRANSMIT_PWR_ENVELOPE_IE_LEN_20MHZ	0
+#define DOT11_TRANSMIT_PWR_ENVELOPE_IE_LEN_40MHZ	1
+#define DOT11_TRANSMIT_PWR_ENVELOPE_IE_LEN_80MHZ	2
+#define DOT11_TRANSMIT_PWR_ENVELOPE_IE_LEN_160MHZ	3
+
+/* vht transmit power envelope IE length. (Keeping these for backward compatibility) */
+#define DOT11_VHT_TRANSMIT_PWR_ENVELOPE_IE_LEN_40MHZ	DOT11_TRANSMIT_PWR_ENVELOPE_IE_LEN_40MHZ
+#define DOT11_VHT_TRANSMIT_PWR_ENVELOPE_IE_LEN_80MHZ	DOT11_TRANSMIT_PWR_ENVELOPE_IE_LEN_80MHZ
+#define DOT11_VHT_TRANSMIT_PWR_ENVELOPE_IE_LEN_160MHZ	DOT11_TRANSMIT_PWR_ENVELOPE_IE_LEN_160MHZ
 
 BWL_PRE_PACKED_STRUCT struct dot11_obss_coex {
 	uint8	id;
@@ -1513,7 +1519,8 @@
 #define	DOT11_MNG_VHT_OPERATION_ID		192	/* d11 mgmt VHT op id */
 #define	DOT11_MNG_EXT_BSSLOAD_ID		193	/* d11 mgmt VHT extended bss load id */
 #define DOT11_MNG_WIDE_BW_CHANNEL_SWITCH_ID	194	/* Wide BW Channel Switch IE */
-#define DOT11_MNG_VHT_TRANSMIT_POWER_ENVELOPE_ID 195	/* VHT transmit Power Envelope IE */
+#define DOT11_MNG_TRANSMIT_POWER_ENVELOPE_ID	195	/* VHT transmit Power Envelope IE */
+#define DOT11_MNG_VHT_TRANSMIT_POWER_ENVELOPE_ID (DOT11_MNG_TRANSMIT_POWER_ENVELOPE_ID)
 #define DOT11_MNG_CHANNEL_SWITCH_WRAPPER_ID	196	/* Channel Switch Wrapper IE */
 #define DOT11_MNG_AID_ID			197	/* Association ID  IE */
 #define	DOT11_MNG_OPER_MODE_NOTIF_ID		199	/* d11 mgmt VHT oper mode notif */
@@ -1641,6 +1648,7 @@
 #define DOT11_BSS_MEMBERSHIP_HT         0xFF  /* Basic 0x80 + 127, HT Required to join */
 #define DOT11_BSS_MEMBERSHIP_VHT        0xFE  /* Basic 0x80 + 126, VHT Required to join */
 #define DOT11_BSS_MEMBERSHIP_HE         0xFD  /* Basic 0x80 + 125, HE Required to join */
+#define DOT11_BSS_MEMBERSHIP_SAE_H2E_ONLY         0xFB  /* Basic 0x80 + 123, H2E Required to join */
 
 /* ERP info element bit values */
 #define DOT11_MNG_ERP_LEN			1	/* ERP is currently 1 byte long */
@@ -5067,6 +5075,15 @@
 
 typedef struct sae_token_container_ie sae_token_container_ie_t;
 
+BWL_PRE_PACKED_STRUCT struct sae_rejected_groups_ie {
+	uint8 id;
+	uint8 len;
+	uint8 id_ext;
+	uint8 data[1]; /* WPA3 SAE Rejected groups */
+} BWL_POST_PACKED_STRUCT;
+
+typedef struct sae_rejected_groups_ie sae_rejected_groups_ie_t;
+
 /* 802.11u interworking access network options */
 #define IW_ANT_MASK					0x0f
 #define IW_INTERNET_MASK				0x10
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
index b3d0679..24fe183 100644
--- 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,7 +2,7 @@
  * 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) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -355,6 +355,7 @@
 /* b1-b7: Channel Width Support field */
 #define HE_PHY_CH_WIDTH_2G_40		0x01
 #define HE_PHY_CH_WIDTH_5G_80		0x02
+#define HE_PHY_CH_WIDTH_6G_40_80	HE_PHY_CH_WIDTH_5G_80
 #define HE_PHY_CH_WIDTH_5G_160		0x04
 #define HE_PHY_CH_WIDTH_5G_80P80	0x08
 #define HE_PHY_CH_WIDTH_2G_40_RU	0x10
@@ -847,9 +848,6 @@
 
 typedef struct he_6gband_cap_ie he_6gband_cap_ie_t;
 
-/* This marks the end of a packed structure section. */
-#include <packed_section_end.h>
-
 /* HE Action Frame */
 #define HE_AF_CAT_OFF	0
 #define HE_AF_ACT_OFF	1
@@ -1012,4 +1010,54 @@
 #define HE_N_TAIL			6	/* tail field bits for BCC */
 #define HE_N_SERVICE			16	/* bits in service field */
 #define HE_T_MAX_PE			16	/* max Packet extension duration */
+
+/*  HE Transmit Power Envelope(TPE) IE related */
+
+/**
+ * ref: (802.11ax D8.0 Figure 9-617 Page 176)
+ *
+ *   Transmit Power Information field format
+ */
+#define HE_TPE_TX_PWR_INFO_COUNT_MASK        0x7
+#define HE_TPE_TX_PWR_INFO_COUNT_SHIFT       0
+#define HE_TPE_TX_PWR_INFO_INTERPRET_MASK    0x38
+#define HE_TPE_TX_PWR_INFO_INTERPRET_SHIFT   3
+#define HE_TPE_TX_PWR_INFO_CATEGORY_MASK     0xC0
+#define HE_TPE_TX_PWR_INFO_CATEGORY_SHIFT    6
+
+/**
+ *  ref: (802.11ax D8.0 Table 9-275a Page 177)
+ *
+ *    Maximum Transmit Power Interpretation subfield encoding
+ */
+#define HE_TPE_MAX_TX_PWR_INTERPRET_LOCAL_EIRP               0
+#define HE_TPE_MAX_TX_PWR_INTERPRET_LOCAL_EIRP_PSD           1
+#define HE_TPE_MAX_TX_PWR_INTERPRET_REGULATORY_EIRP          2
+#define HE_TPE_MAX_TX_PWR_INTERPRET_REGULATORY_EIRP_PSD      3
+
+/** Set Maximum Transmit Power Interpretation on TX PWR INFO field */
+#define HE_TX_PWR_INFO_LOC_EIRP ((HE_TPE_MAX_TX_PWR_INTERPRET_LOCAL_EIRP << \
+		HE_TPE_TX_PWR_INFO_INTERPRET_SHIFT) & HE_TPE_TX_PWR_INFO_INTERPRET_MASK)
+#define HE_TX_PWR_INFO_LOC_EIRP_PSD     ((HE_TPE_MAX_TX_PWR_INTERPRET_LOCAL_EIRP_PSD << \
+		HE_TPE_TX_PWR_INFO_INTERPRET_SHIFT) & HE_TPE_TX_PWR_INFO_INTERPRET_MASK)
+#define HE_TX_PWR_INFO_REG_EIRP         ((HE_TPE_MAX_TX_PWR_INTERPRET_REGULATORY_EIRP << \
+		HE_TPE_TX_PWR_INFO_INTERPRET_SHIFT) & HE_TPE_TX_PWR_INFO_INTERPRET_MASK)
+#define HE_TX_PWR_INFO_REG_EIRP_PSD     ((HE_TPE_MAX_TX_PWR_INTERPRET_REGULATORY_EIRP_PSD << \
+		HE_TPE_TX_PWR_INFO_INTERPRET_SHIFT) & HE_TPE_TX_PWR_INFO_INTERPRET_MASK)
+
+/** HE Transmit Power Envelope IE data structure */
+BWL_PRE_PACKED_STRUCT struct he_transmit_power_envelope {
+	uint8 id;                   /* id DOT11_MNG_TRANSMIT_POWER_ENVELOPE_ID */
+	uint8 len;                  /* length of IE */
+	uint8 transmit_power_info;
+	union {
+		uint8 max_transmit_power_20;
+		uint8 max_transmit_psd_1;
+	};
+} BWL_POST_PACKED_STRUCT;
+typedef struct he_transmit_power_envelope he_transmit_power_envelope_ie_t;
+
+/* This marks the end of a packed structure section. */
+#include <packed_section_end.h>
+
 #endif /* _802_11ax_h_ */
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
index 36de297..c40af1d 100644
--- 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,7 +3,7 @@
  *
  * Dependencies: bcmeth.h
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -311,9 +311,10 @@
 #define WLC_E_IND_DOS_STATUS            191
 #define WLC_E_LDF_HOGGER		192 	/* Detection Hogger Squasher -Cambium */
 #define WLC_E_DLTRO         193     /*   DHCP lease time renew offload */
-#define WLC_E_LAST			194	/* highest val + 1 for range checking */
-#if (WLC_E_LAST > 194)
-#error "WLC_E_LAST: Invalid value for last event; must be <= 193."
+#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."
 #endif /* WLC_E_LAST */
 
 /* define an API for getting the string name of an event */
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
index 9ba30d6..84eacf9 100644
--- 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,7 +1,7 @@
 /*
  * Definitions for nl80211 vendor command/event access to host driver
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -46,8 +46,8 @@
 	BRCM_VENDOR_SCMD_FRAMEBURST     = 6,
 	BRCM_VENDOR_SCMD_MPC            = 7,
 	BRCM_VENDOR_SCMD_BAND           = 8,
-	BRCM_VENDOR_SCMD_MAX            = 9
-
+	BRCM_VENDOR_SCMD_ACS            = 9,
+	BRCM_VENDOR_SCMD_MAX
 };
 
 struct bcm_nlmsg_hdr {
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 0ad4819..9e8f463 100644
--- 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
@@ -11,30 +11,30 @@
 #ifndef _epivers_h_
 #define _epivers_h_
 
-#define	EPI_MAJOR_VERSION	100
+#define	EPI_MAJOR_VERSION	0
 
-#define	EPI_MINOR_VERSION	10
+#define	EPI_MINOR_VERSION	0
 
-#define	EPI_RC_NUMBER		52
+#define	EPI_RC_NUMBER		0
 
 #define	EPI_INCREMENTAL_NUMBER	0
 
 #define	EPI_BUILD_NUMBER	0
 
-#define	EPI_VERSION		100, 10, 52, 0
+#define	EPI_VERSION		0, 0, 0, 0
 
-#define	EPI_VERSION_NUM		0x640a3400
+#define	EPI_VERSION_NUM		0x00000000
 
-#define EPI_VERSION_DEV		100.10.52
+#define EPI_VERSION_DEV		0.0.0
 
 /* Driver Version String, ASCII, 32 chars max */
 #ifdef BCMINTERNAL
-#define	EPI_VERSION_STR		"100.10.52 (1d305b2 BCMINT)"
+#define	EPI_VERSION_STR		"manifest (4622e1d BCMINT)"
 #else
 #ifdef WLTEST
-#define	EPI_VERSION_STR		"100.10.52 (1d305b2 WLTEST)"
+#define	EPI_VERSION_STR		"manifest (4622e1d WLTEST)"
 #else
-#define	EPI_VERSION_STR		"100.10.52 (1d305b2)"
+#define	EPI_VERSION_STR		"manifest (4622e1d)"
 #endif
 #endif /* BCMINTERNAL */
 
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
index 1d9a66a..a52198b 100644
--- 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,7 +1,7 @@
 /*
  * Fundamental types and constants relating to WFA MBO
  * (Multiband Operation)
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -177,10 +177,10 @@
 	uint8 cell_pref;
 } BWL_POST_PACKED_STRUCT wifi_mbo_cell_data_conn_pref_attr_t;
 
-/* Cellular Data Conn Pref attr: Cellular Pref field values */
+/* Cellular Data Conn Pref attr: Cellular Pref field values. Per MBO Spec. v1.1 */
 enum {
-	MBO_CELLULAR_DATA_CONN_EXCLUDED = 1,
-	MBO_CELLULAR_DATA_CONN_NOT_PREFERRED = 2,
+	MBO_CELLULAR_DATA_CONN_EXCLUDED = 0,
+	MBO_CELLULAR_DATA_CONN_NOT_PREFERRED = 1,
 	MBO_CELLULAR_DATA_CONN_PREFERRED = 255
 };
 
@@ -262,6 +262,9 @@
 /* oui:3 bytes + oui type:1 byte + sub type:1 byte */
 #define MBO_ANQP_ELEM_NO_PAYLOAD_LEN  5
 
+#define MBO_ANQP_VS_ELEM_SIZE (sizeof(wifi_mbo_anqp_elem_t))
+#define MBO_ANQP_VS_ELEM_LENGTH (MBO_ANQP_VS_ELEM_SIZE - 4)
+
 /* MBO ANQP Subtype Values */
 enum {
 	MBO_ANQP_ELEM_MBO_QUERY_LIST = 1,
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
index e52c41c..cd27717 100644
--- 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,7 +1,7 @@
 /*
  * SiliconBackplane GCI core hardware definitions
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -149,7 +149,9 @@
 	uint32 otpprogdata;				/* 0x328 */
 	uint32 PAD[PADSZ(0x32c, 0x3f8)];		/* 0x32c-0x3f8 */
 	uint32 otpECCstatus;				/* 0x3FC */
-	uint32 PAD[PADSZ(0x400, 0xbfc)];		/* 0x400-0xbfc */
+	uint32 PAD[PADSZ(0x400, 0x6fc)];		/* 0x400-0x6fc */
+	uint32 ctss_clk_ctrl_status;			/* 0x700 */
+	uint32 PAD[PADSZ(0x704, 0xbfc)];                /* 0x704-0xbfc */
 	uint32 lhl_core_capab_adr;			/* 0xC00 */
 	uint32 lhl_main_ctl_adr;			/* 0xC04 */
 	uint32 lhl_pmu_ctl_adr;				/* 0xC08 */
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
index 59639e9..19f921c 100644
--- 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,7 +4,7 @@
  *
  * SDIO core support 1bit, 4 bit SDIO mode as well as SPI mode.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -117,9 +117,9 @@
 							 * external pads in tri-state; requires
 							 * sdio bus power cycle to clear (rev 9)
 							 */
-#define SBSDIO_DEVCTL_EN_F2_BLK_WATERMARK 0x10  /* Enable function 2 tx for each block */
 #define SBSDIO_DEVCTL_F2WM_ENAB		0x10		/* Enable F2 Watermark */
 #define SBSDIO_DEVCTL_NONDAT_PADS_ISO 	0x20		/* Isolate sdio clk and cmd (non-data) */
+#define SBSDIO_DEVCTL_ADDR_RESET	0x40		/* Reset SB Address to default value */
 
 /* SBSDIO_FUNC1_CHIPCLKCSR */
 #define SBSDIO_FORCE_ALP		0x01		/* Force ALP request to backplane */
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
index a4ea048..2edda4a 100644
--- 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,7 +2,7 @@
  * Broadcom SiliconBackplane SDIO/PCMCIA hardware-specific
  * device core support
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -51,21 +51,21 @@
 typedef volatile struct {
 	dma64p_t dma64regs[2];
 	dma64diag_t dmafifo;		/* DMA Diagnostic Regs, 0x280-0x28c */
-	uint32 PAD[92];
+	uint32 PAD[28];
 } sdiodma64_t;
 
 /* dma32 sdiod corerev == 0 */
 typedef volatile struct {
 	dma32regp_t dma32regs[2];	/* dma tx & rx, 0x200-0x23c */
 	dma32diag_t dmafifo;		/* DMA Diagnostic Regs, 0x240-0x24c */
-	uint32 PAD[108];
+	uint32 PAD[44];
 } sdiodma32_t;
 
 /* dma32 regs for pcmcia core */
 typedef volatile struct {
 	dma32regp_t dmaregs;		/* DMA Regs, 0x200-0x21c, rev8 */
 	dma32diag_t dmafifo;		/* DMA Diagnostic Regs, 0x220-0x22c */
-	uint32 PAD[116];
+	uint32 PAD[52];
 } pcmdma32_t;
 
 /* core registers */
@@ -140,6 +140,11 @@
 		sdiodma64_t sdiod64;
 	} dma;
 
+	uint32 PAD[12];			/* 0x300-0x32c */
+	uint32 chipid;			/* SDIO ChipID Register, 0x330, rev31 */
+	uint32 eromptr;			/* SDIO EromPtrOffset Register, 0x334, rev31 */
+	uint32 PAD[50];
+
 	/* SDIO/PCMCIA CIS region */
 	char cis[512];			/* 512 byte CIS, 0x400-0x5ff, rev6 */
 
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 9b53584..1e9658b 100644
--- 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,7 +2,7 @@
  * SDIO spec header file
  * Protocol and standard (common) device definitions
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -90,11 +90,18 @@
 #define SDIOD_CCCR_INTR_EXTN		0x16
 
 /* Broadcom extensions (corerev >= 1) */
-#define SDIOD_CCCR_BRCM_CARDCAP		0xf0
+#define SDIOD_CCCR_BRCM_CARDCAP					0xf0
 #define SDIOD_CCCR_BRCM_CARDCAP_CMD14_SUPPORT	0x02
-#define SDIOD_CCCR_BRCM_CARDCAP_CMD14_EXT	0x04
-#define SDIOD_CCCR_BRCM_CARDCAP_CMD_NODEC	0x08
-#define SDIOD_CCCR_BRCM_CARDCTL			0xf1
+#define SDIOD_CCCR_BRCM_CARDCAP_CMD14_EXT		0x04
+#define SDIOD_CCCR_BRCM_CARDCAP_CMD_NODEC		0x08
+#define SDIOD_CCCR_BRCM_CARDCAP_CHIPID_PRESENT	0x40
+#define	SDIOD_CCCR_BRCM_CARDCAP_SECURE_MODE		0x80
+
+#define SDIOD_CCCR_BRCM_CARDCTL				0xf1
+#define SDIOD_CCCR_BRCM_CISLOADED			0x1
+#define SDIOD_CCCR_BRCM_WLANRST_ONF0ABORT	0x2
+#define SDIOD_CCCR_BRCM_SDIORST_ONWLANRST	0x20
+
 #define SDIOD_CCCR_BRCM_SEPINT			0xf2
 
 /* cccr_sdio_rev */
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
index d992283..03b2ab8 100644
--- 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,7 +2,7 @@
  * Misc utility routines for accessing the SOC Interconnects
  * of Broadcom HNBU chips.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -99,6 +99,7 @@
 
 	bool	_multibp_enable;
 	bool	secureboot;
+	bool    chipidpresent;
 };
 
 /* for HIGH_ONLY driver, the si_t must be writable to allow states sync from BMAC to HIGH driver
@@ -369,6 +370,7 @@
 
 #ifdef BCMSDIO
 extern void si_sdio_init(si_t *sih);
+extern void *si_get_sdio_addrbase(void *sdh);
 #endif // endif
 
 extern uint16 si_d11_devid(si_t *sih);
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
index ffb1e3b..9426078 100644
--- 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,7 +1,7 @@
 /*
  * SPI device spec header file
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -101,6 +101,10 @@
 #define RESET_ON_BT_BP_RESET	0x8	/* enable reset for BT backplane */
 #define RESET_SPI		0x80	/* reset the above enabled logic */
 
+/* Bit mask for card capability */
+#define SPID_CHIPID_PRESENT		0x20	/* duplicate of cardcapability chipid present */
+#define SPID_SECURE_MODE		0x40	/* duplicate of cardcapability secure mode */
+
 /* Bit mask for SPID_INTR_REG device register */
 #define DATA_UNAVAILABLE	0x0001	/* Requested data not available; Clear by writing a "1" */
 #define F2_F3_FIFO_RD_UNDERFLOW	0x0002
@@ -164,7 +168,12 @@
 #define SPI_FUNC_2		2
 #define SPI_FUNC_3		3
 
-#define WAIT_F2RXFIFORDY	100
-#define WAIT_F2RXFIFORDY_DELAY	20
+#ifdef BCMQT
+#define WAIT_F2RXFIFORDY        200
+#define WAIT_F2RXFIFORDY_DELAY  100
+#else
+#define WAIT_F2RXFIFORDY        100
+#define WAIT_F2RXFIFORDY_DELAY  20
+#endif // endif
 
 #endif /* _SPI_H */
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
index 4d64e6e..b1cfe0e 100644
--- 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,7 +6,7 @@
  *
  * Definitions subject to change without notice.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -6623,7 +6623,6 @@
 } wl_pkteng_rx_pkt_t;
 
 #define WL_PKTENG_RU_FILL_VER_1		1u
-#define WL_PKTENG_RU_FILL_VER_2		2u
 // struct for ru packet engine
 typedef struct wl_pkteng_ru_v1 {
 	uint16 version;			/* ver is 1 */
@@ -6633,8 +6632,8 @@
 	uint8 mcs_val;			/* mcs allocated value */
 	uint8 nss_val;			/* num of spatial streams */
 	uint32 num_bytes;		/* approx num of bytes to calculate other required params */
-	uint8 cp_ltf_val ;		/* GI and LTF symbol size */
-	uint8 he_ltf_symb ;		/* num of HE-LTF symbols */
+	uint8 cp_ltf_val;		/* GI and LTF symbol size */
+	uint8 he_ltf_symb;		/* num of HE-LTF symbols */
 	uint8 stbc;			/* STBC support */
 	uint8 coding_val;		/* BCC/LDPC coding support */
 	uint8 pe_category;		/* PE duration 0/8/16usecs  */
@@ -6643,35 +6642,13 @@
 	uint8 trig_tx;			/* form and transmit the trigger frame */
 	uint8 trig_type;		/* type of trigger frame */
 	uint8 trig_period;		/* trigger tx periodicity TBD */
-	uint8 nuserinfo;		/* Number of Userinfo fields */
+	uint8 nuserinfo;		/* number of Userinfo fields */
 	struct ether_addr dest;		/* destination address for un-associated mode */
+	uint8 ppdu_format;		/* trigger frame format */
 } wl_pkteng_ru_v1_t;
 
-typedef struct wl_pkteng_ru_v2 {
-	uint16 version;			/* ver is 1 */
-	uint16 length;			/* size of complete structure */
-	uint8 bw;			/* bandwidth info */
-	uint8 ru_alloc_val;		/* ru allocation index number */
-	uint8 mcs_val;			/* mcs allocated value */
-	uint8 nss_val;			/* num of spatial streams */
-	uint32 num_bytes;		/* approx num of bytes to calculate other required params */
-	struct ether_addr dest;		/* destination address for un-associated mode */
-	uint8 cp_ltf_val ;		/* GI and LTF symbol size */
-	uint8 he_ltf_symb ;		/* num of HE-LTF symbols */
-	uint8 stbc;			/* STBC support */
-	uint8 coding_val;		/* BCC/LDPC coding support */
-	uint8 pe_category;		/* PE duration 0/8/16usecs  */
-	uint8 dcm;			/* dual carrier modulation */
-	uint8 mumimo_ltfmode;		/* ltf mode */
-	uint8 trig_tx;			/* form and transmit the trigger frame */
-	uint8 trig_type;		/* type of trigger frame */
-	uint8 trig_period;		/* trigger tx periodicity TBD */
-	uint8 tgt_rssi; /* target rssi value in encoded format */
-	uint8 pad[3];		/* 3 byte padding to make structure size a multiple of 32bits */
-} wl_pkteng_ru_v2_t;
-
 #ifndef WL_PKTENG_RU_VER
-/* App uses the latest version - source picks it up from wlc_types.h */
+/* This is for the App; source picks it up from wlc_types.h */
 typedef wl_pkteng_ru_v1_t wl_pkteng_ru_fill_t;
 #endif // endif
 
@@ -17045,6 +17022,7 @@
 	WL_HE_CMD_PREPUNCRX_EN = 26,
 	WL_HE_CMD_MIMOCAP_EN = 27,
 #endif // endif
+	WL_HE_CMD_MUEDCA_OPT = 28,
 	WL_HE_CMD_LAST
 };
 
@@ -17418,6 +17396,7 @@
 	WL_MBO_CMD_DBG_EVENT_CHECK = 13,
 	WL_MBO_CMD_EVENT_MASK = 14,
 	WL_MBO_CMD_ASSOC_DISALLOWED = 15,
+	WL_MBO_CMD_CELLULAR_DATA_PREF = 16,
 	/* Add before this !! */
 	WL_MBO_CMD_LAST
 };
@@ -17435,7 +17414,8 @@
 	WL_MBO_XTLV_BTQ_TRIG_RSSI_DELTA = 0xa,
 	WL_MBO_XTLV_ANQP_CELL_SUPP      = 0xb,
 	WL_MBO_XTLV_BIT_MASK		= 0xc,
-	WL_MBO_XTLV_ASSOC_DISALLOWED	= 0xd
+	WL_MBO_XTLV_ASSOC_DISALLOWED	= 0xd,
+	WL_MBO_XTLV_CELLULAR_DATA_PREF = 0xe
 };
 
 /* event bit mask flags for MBO */
@@ -19140,7 +19120,10 @@
 #define TRIG_PROFILES 6	/* Packet profiles to compute cmn and usr info params */
 #define HE_TRIG_FRM_NUSERINFO 1 /* Default number of user info fields */
 #define TRIG_TX_MIN_IP_ARGS 1
-#define TRIG_TX_MAX_IP_ARGS 3
+#define TRIG_TX_MAX_IP_ARGS 4
+
+#define HE_TRIG_NON_HT_PPDU	0
+#define HE_TRIG_VHT_PPDU	1
 
 typedef struct {
 	uint8 ru_alloc_val;             /* ru allocation index number */
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 b6ec056..0e07134 100644
--- 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,7 +4,7 @@
  *
  * Definitions subject to change without notice.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -478,10 +478,11 @@
 #endif /* BCMCCX */
 #define SES_OW_ENABLED		0x0040	/* to go into transition mode without setting wep */
 #define SMS4_ENABLED		0x0100
+#define AES_GCMP256             0x0200
 
 #define WSEC_WEP_ENABLED(wsec)	((wsec) & WEP_ENABLED)
 #define WSEC_TKIP_ENABLED(wsec)	((wsec) & TKIP_ENABLED)
-#define WSEC_AES_ENABLED(wsec)	((wsec) & AES_ENABLED)
+#define WSEC_AES_ENABLED(wsec)	((wsec) & (AES_ENABLED | AES_GCMP256))
 
 /* Macros to check if algorithm is enabled */
 #define	WSEC_INFO_ALGO_ENABLED(_wi, _algo) \
@@ -560,6 +561,12 @@
 
 #define WPA3_AUTH_SAE                  0x10000 /* SAE authentication with SHA-256 */
 
+#define WPA3_AUTH_MASK			(WPA3_AUTH_SAE_PSK | WPA3_AUTH_SAE_FBT |\
+					 WPA3_AUTH_OWE | WPA3_AUTH_1X_SUITE_B_SHA256 |\
+					 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)
+
 /* pmkid */
 #define	MAXPMKID		16
 
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 fb7253d..080f60cc 100644
--- 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,7 +1,7 @@
 /*
  * Fundamental types and constants relating to WPA
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -74,6 +74,7 @@
 #define WPA_IE_TAG_FIXED_LEN	6
 
 #define BIP_OUI_TYPE WPA2_OUI "\x06"
+#define BIP_GMAC_256_OUI_TYPE WPA2_OUI "\x0c"
 
 typedef BWL_PRE_PACKED_STRUCT struct {
 	uint8 tag;	/* TAG */
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 b66b0ea..e42b1ca 100644
--- 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,7 +1,7 @@
 /*
  * Linux OS Independent Layer
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -771,7 +771,11 @@
 #endif /* CONFIG_DHD_USE_STATIC_BUF */
 
 	flags = CAN_SLEEP() ? GFP_KERNEL: GFP_ATOMIC;
+#if defined(DHD_USE_KVMALLOC) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
+	if ((addr = kvmalloc(size, flags)) == NULL) {
+#else
 	if ((addr = kmalloc(size, flags)) == NULL) {
+#endif // endif
 		if (osh)
 			osh->failed++;
 		return (NULL);
@@ -830,7 +834,11 @@
 
 		atomic_sub(size, &osh->cmn->malloced);
 	}
+#if defined(DHD_USE_KVMALLOC) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
+	kvfree(addr);
+#else
 	kfree(addr);
+#endif // endif
 }
 
 void *
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 f983855..8b17cb8 100644
--- 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,7 +2,7 @@
  * 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) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -374,6 +374,7 @@
 	bool pci, pcie, pcie_gen2 = FALSE;
 	uint i;
 	uint pciidx, pcieidx, pcirev, pcierev;
+	struct si_pub *sih = &sii->pub;
 
 #if defined(BCM_BACKPLANE_TIMEOUT) || defined(AXI_TIMEOUTS)
 	/* first, enable backplane timeouts */
@@ -396,37 +397,38 @@
 		}
 	}
 
-	/* get chipcommon capabilites */
-	sii->pub.cccaps = R_REG(sii->osh, &cc->capabilities);
-	/* get chipcommon extended capabilities */
+	if (!sih->chipidpresent) {
+		/* get chipcommon capabilites */
+		sii->pub.cccaps = R_REG(sii->osh, &cc->capabilities);
+		/* get chipcommon extended capabilities */
+		if (CCREV(sii->pub.ccrev) >= 35)
+			sii->pub.cccaps_ext = R_REG(sii->osh, &cc->capabilities_ext);
 
-	if (CCREV(sii->pub.ccrev) >= 35)
-		sii->pub.cccaps_ext = R_REG(sii->osh, &cc->capabilities_ext);
+		/* get pmu rev and caps */
+		if (sii->pub.cccaps & CC_CAP_PMU) {
+			if (AOB_ENAB(&sii->pub)) {
+				uint pmucoreidx;
+				pmuregs_t *pmu;
+				struct si_pub *sih = &sii->pub;
 
-	/* get pmu rev and caps */
-	if (sii->pub.cccaps & CC_CAP_PMU) {
-		if (AOB_ENAB(&sii->pub)) {
-			uint pmucoreidx;
-			pmuregs_t *pmu;
-			struct si_pub *sih = &sii->pub;
+				pmucoreidx = si_findcoreidx(&sii->pub, PMU_CORE_ID, 0);
+				if (!GOODIDX(pmucoreidx)) {
+					SI_ERROR(("si_buscore_setup: si_findcoreidx failed\n"));
+					return FALSE;
+				}
 
-			pmucoreidx = si_findcoreidx(&sii->pub, PMU_CORE_ID, 0);
-			if (!GOODIDX(pmucoreidx)) {
-				SI_ERROR(("si_buscore_setup: si_findcoreidx failed\n"));
-				return FALSE;
-			}
+				pmu = si_setcoreidx(&sii->pub, pmucoreidx);
+				sii->pub.pmucaps = R_REG(sii->osh, &pmu->pmucapabilities);
+				si_setcoreidx(&sii->pub, SI_CC_IDX);
 
-			pmu = si_setcoreidx(&sii->pub, pmucoreidx);
-			sii->pub.pmucaps = R_REG(sii->osh, &pmu->pmucapabilities);
-			si_setcoreidx(&sii->pub, SI_CC_IDX);
+				sii->pub.gcirev = si_corereg(sih, GCI_CORE_IDX(sih),
+						GCI_OFFSETOF(sih, gci_corecaps0), 0, 0) &
+						GCI_CAP0_REV_MASK;
+			} else
+				sii->pub.pmucaps = R_REG(sii->osh, &cc->pmucapabilities);
 
-			sii->pub.gcirev = si_corereg(sih,
-					GCI_CORE_IDX(sih),
-					GCI_OFFSETOF(sih, gci_corecaps0), 0, 0) & GCI_CAP0_REV_MASK;
-		} else
-			sii->pub.pmucaps = R_REG(sii->osh, &cc->pmucapabilities);
-
-		sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
+			sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
+		}
 	}
 
 	SI_MSG(("Chipc: rev %d, caps 0x%x, chipst 0x%x pmurev %d, pmucaps 0x%x\n",
@@ -641,6 +643,39 @@
 }
 #endif /* BCM_BACKPLANE_TIMEOUT */
 
+#ifdef BCMSDIO
+void *
+si_get_sdio_addrbase(void *sdh)
+{
+	uint8 devctl;
+	int err = 0;
+	uint32 addr = 0;
+
+	devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err);
+	if (err)
+		return NULL;
+
+	bcmsdh_cfg_write(sdh, SDIO_FUNC_1,
+			SBSDIO_DEVICE_CTL, devctl | SBSDIO_DEVCTL_ADDR_RESET, &err);
+	if (err)
+		goto exit;
+
+	addr |= (bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, NULL) << 8) |
+		(bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID, NULL) << 16) |
+		(bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH, NULL) << 24);
+
+	SI_MSG(("%s: sdiod core address is 0x%x\n", __FUNCTION__, addr));
+exit:
+	if (err) {
+		SI_ERROR(("%s: Get SDIO core base address failed, err=%d", __FUNCTION__, err));
+		addr = 0;
+	}
+	bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err);
+
+	return (void *)((uintptr)addr);
+}
+#endif /* BCMSDIO */
+
 /**
  * Allocate an si handle. This function may be called multiple times. This function is called by
  * both si_attach() and si_kattach().
@@ -653,13 +688,19 @@
                        uint bustype, void *sdh, char **vars, uint *varsz)
 {
 	struct si_pub *sih = &sii->pub;
-	uint32 w, savewin;
+	uint32 w = 0;
+	uint32 savewin;
 	chipcregs_t *cc;
 	char *pvars = NULL;
 	uint origidx;
 #ifdef NVSRCX
 	char *sromvars;
 #endif // endif
+	uint32 erombase;
+#ifdef BCMSDIO
+	uint8 cardcap;
+	sdpcmd_regs_t *sdioc;
+#endif // endif
 
 	ASSERT(GOODREGS(regs));
 
@@ -703,12 +744,26 @@
 		if (!regs)
 			return NULL;
 		cc = (chipcregs_t *)regs;
+		erombase = R_REG(osh, &cc->eromptr);
 #ifdef BCMSDIO
 	} else if ((bustype == SDIO_BUS) || (bustype == SPI_BUS)) {
 		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;
+			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
 	} else {
 		cc = (chipcregs_t *)REG_MAP(SI_ENUM_BASE(sih), SI_CORE_SIZE);
+		erombase = R_REG(osh, &cc->eromptr);
 	}
 
 	sih->bustype = bustype;
@@ -735,7 +790,8 @@
 		SI_ERROR(("%s: chipcommon register space is null \n", __FUNCTION__));
 		return NULL;
 	}
-	w = R_REG(osh, &cc->chipid);
+	if (!w)
+		w = R_REG(osh, &cc->chipid);
 	if ((w & 0xfffff) == 148277) w -= 65532;
 	sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
 	/* Might as wll fill in chip id rev & pkg */
@@ -788,7 +844,7 @@
 			sii->axi_wrapper = NULL;
 		}
 
-		ai_scan(&sii->pub, (void *)(uintptr)cc, devid);
+		ai_scan(&sii->pub, (void *)(uintptr)cc, erombase,  devid);
 	} else if (CHIPTYPE(sii->pub.socitype) == SOCI_UBUS) {
 		SI_MSG(("Found chip type UBUS (0x%08x), chip id = 0x%4x\n", w, sih->chip));
 		/* pass chipc address instead of original core base */
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
index fcb868d..e42df98 100644
--- 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,7 +1,7 @@
 /*
  * Include file private to the SOC Interconnect support files.
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -281,7 +281,7 @@
 extern si_t *ai_attach(uint pcidev, osl_t *osh, void *regs, uint bustype,
                        void *sdh, char **vars, uint *varsz);
 extern si_t *ai_kattach(osl_t *osh);
-extern void ai_scan(si_t *sih, void *regs, uint devid);
+extern void ai_scan(si_t *sih, void *regs, uint32 erombase, uint devid);
 
 extern uint ai_flag(si_t *sih);
 extern uint ai_flag_alt(si_t *sih);
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 2ebb419..e53298b 100644
--- 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,7 +1,7 @@
 /*
  * Linux cfg80211 driver - Android related functions
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -91,13 +91,6 @@
 #define CMD_START		"START"
 #define CMD_STOP		"STOP"
 
-#ifdef AUTOMOTIVE_FEATURE
-#define CMD_SCAN_ACTIVE         "SCAN-ACTIVE"
-#define CMD_SCAN_PASSIVE        "SCAN-PASSIVE"
-#define CMD_RSSI                "RSSI"
-#define CMD_LINKSPEED		"LINKSPEED"
-#endif /* AUTOMOTIVE_FEATURE */
-
 #define CMD_RXFILTER_START	"RXFILTER-START"
 #define CMD_RXFILTER_STOP	"RXFILTER-STOP"
 #define CMD_RXFILTER_ADD	"RXFILTER-ADD"
@@ -117,6 +110,7 @@
 #define CMD_COUNTRY		"COUNTRY"
 #define CMD_CHANNELS_IN_CC      "CHANNELS_IN_CC"
 #define CMD_P2P_SET_NOA		"P2P_SET_NOA"
+#define CMD_BLOCKASSOC         "BLOCKASSOC"
 #if !defined WL_ENABLE_P2P_IF
 #define CMD_P2P_GET_NOA			"P2P_GET_NOA"
 #endif /* WL_ENABLE_P2P_IF */
@@ -139,11 +133,6 @@
 #endif /* WL_SUPPORT_AUTO_CHANNEL */
 
 #define CMD_CHANSPEC      "CHANSPEC"
-#ifdef AUTOMOTIVE_FEATURE
-#define CMD_DATARATE      "DATARATE"
-#define CMD_80211_MODE    "MODE"  /* 802.11 mode a/b/g/n/ac */
-#define CMD_ASSOC_CLIENTS "ASSOCLIST"
-#endif /* AUTOMOTIVE_FEATURE */
 #define CMD_SET_CSA       "SETCSA"
 #define CMD_RSDB_MODE	"RSDB_MODE"
 #ifdef WL_SUPPORT_AUTO_CHANNEL
@@ -187,9 +176,6 @@
 #define CMD_WLS_BATCHING	"WLS_BATCHING"
 #endif /* PNO_SUPPORT */
 
-#ifdef AUTOMOTIVE_FEATURE
-#define	CMD_HAPD_MAC_FILTER	"HAPD_MAC_FILTER"
-#endif /* AUTOMOTIVE_FEATURE */
 #define CMD_ADDIE		"ADD_IE"
 #define CMD_DELIE		"DEL_IE"
 
@@ -204,10 +190,6 @@
 #define CMD_ROAMSCANPERIOD_GET "GETROAMSCANPERIOD"
 #define CMD_FULLROAMSCANPERIOD_SET "SETFULLROAMSCANPERIOD"
 #define CMD_FULLROAMSCANPERIOD_GET "GETFULLROAMSCANPERIOD"
-#ifdef AUTOMOTIVE_FEATURE
-#define CMD_COUNTRYREV_SET "SETCOUNTRYREV"
-#define CMD_COUNTRYREV_GET "GETCOUNTRYREV"
-#endif /* AUTOMOTIVE_FEATURE */
 #endif /* ROAM_API */
 
 #if defined(SUPPORT_RANDOM_MAC_SCAN)
@@ -1190,111 +1172,6 @@
 }
 #endif /* WLWFDS */
 
-#ifdef AUTOMOTIVE_FEATURE
-static int wl_android_get_link_speed(struct net_device *net, char *command, int total_len)
-{
-	int link_speed;
-	int bytes_written;
-	int error;
-
-	error = wldev_get_link_speed(net, &link_speed);
-	if (error) {
-		DHD_ERROR(("Get linkspeed failed \n"));
-		return -1;
-	}
-
-	/* Convert Kbps to Android Mbps */
-	link_speed = link_speed / 1000;
-	bytes_written = snprintf(command, total_len, "LinkSpeed %d", link_speed);
-	DHD_INFO(("wl_android_get_link_speed: command result is %s\n", command));
-	return bytes_written;
-}
-
-static int wl_android_get_rssi(struct net_device *net, char *command, int total_len)
-{
-	wlc_ssid_t ssid = {0, {0}};
-	int bytes_written = 0;
-	int error = 0;
-	scb_val_t scbval;
-	char *delim = NULL;
-	struct net_device *target_ndev = net;
-#ifdef WL_VIRTUAL_APSTA
-	char *pos = NULL;
-	struct bcm_cfg80211 *cfg;
-#endif /* WL_VIRTUAL_APSTA */
-
-	delim = strchr(command, ' ');
-	/* For Ap mode rssi command would be
-	 * driver rssi <sta_mac_addr>
-	 * for STA/GC mode
-	 * driver rssi
-	*/
-	if (delim) {
-		/* Ap/GO mode
-		* driver rssi <sta_mac_addr>
-		*/
-		DHD_TRACE(("wl_android_get_rssi: cmd:%s\n", delim));
-		/* skip space from delim after finding char */
-		delim++;
-		if (!(bcm_ether_atoe((delim), &scbval.ea))) {
-			DHD_ERROR(("wl_android_get_rssi: address err\n"));
-			return -1;
-		}
-		scbval.val = htod32(0);
-		DHD_TRACE(("wl_android_get_rssi: address:"MACDBG, MAC2STRDBG(scbval.ea.octet)));
-#ifdef WL_VIRTUAL_APSTA
-		/* RSDB AP may have another virtual interface
-		 * In this case, format of private command is as following,
-		 * DRIVER rssi <sta_mac_addr> <AP interface name>
-		 */
-
-		/* Current position is start of MAC address string */
-		pos = delim;
-		delim = strchr(pos, ' ');
-		if (delim) {
-			/* skip space from delim after finding char */
-			delim++;
-			if (strnlen(delim, IFNAMSIZ)) {
-				cfg = wl_get_cfg(net);
-				target_ndev = wl_get_ap_netdev(cfg, delim);
-				if (target_ndev == NULL)
-					target_ndev = net;
-			}
-		}
-#endif /* WL_VIRTUAL_APSTA */
-	}
-	else {
-		/* STA/GC mode */
-		bzero(&scbval, sizeof(scb_val_t));
-	}
-
-	error = wldev_get_rssi(target_ndev, &scbval);
-	if (error)
-		return -1;
-
-	error = wldev_get_ssid(target_ndev, &ssid);
-	if (error)
-		return -1;
-	if ((ssid.SSID_len == 0) || (ssid.SSID_len > DOT11_MAX_SSID_LEN)) {
-		DHD_ERROR(("wl_android_get_rssi: wldev_get_ssid failed\n"));
-	} else if (total_len <= ssid.SSID_len) {
-		return -ENOMEM;
-	} else {
-		memcpy(command, ssid.SSID, ssid.SSID_len);
-		bytes_written = ssid.SSID_len;
-	}
-	if ((total_len - bytes_written) < (strlen(" rssi -XXX") + 1))
-		return -ENOMEM;
-
-	bytes_written += scnprintf(&command[bytes_written], total_len - bytes_written,
-		" rssi %d", scbval.val);
-	command[bytes_written] = '\0';
-
-	DHD_TRACE(("wl_android_get_rssi: command result is %s (%d)\n", command, bytes_written));
-	return bytes_written;
-}
-#endif /* AUTOMOTIVE_FEATURE */
-
 static int wl_android_set_suspendopt(struct net_device *dev, char *command)
 {
 	int suspend_flag;
@@ -1340,25 +1217,6 @@
 	return ret;
 }
 
-#ifdef AUTOMOTIVE_FEATURE
-int wl_android_get_80211_mode(struct net_device *dev, char *command, int total_len)
-{
-	uint8 mode[5];
-	int  error = 0;
-	int bytes_written = 0;
-
-	error = wldev_get_mode(dev, mode, sizeof(mode));
-	if (error)
-		return -1;
-
-	DHD_INFO(("wl_android_get_80211_mode: mode:%s\n", mode));
-	bytes_written = snprintf(command, total_len, "%s %s", CMD_80211_MODE, mode);
-	DHD_INFO(("wl_android_get_80211_mode: command:%s EXIT\n", command));
-	return bytes_written;
-
-}
-#endif /* AUTOMOTIVE_FEATURE */
-
 extern chanspec_t
 wl_chspec_driver_to_host(chanspec_t chanspec);
 int wl_android_get_chanspec(struct net_device *dev, char *command, int total_len)
@@ -1443,64 +1301,6 @@
 }
 
 /* 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)
-{
-	int  error = 0;
-	int datarate = 0;
-	int bytes_written = 0;
-
-	error = wldev_get_datarate(dev, &datarate);
-	if (error)
-		return -1;
-
-	DHD_INFO(("wl_android_get_datarate: datarate:%d\n", datarate));
-
-	bytes_written = snprintf(command, total_len, "%s %d", CMD_DATARATE, (datarate/2));
-	return bytes_written;
-}
-
-int wl_android_get_assoclist(struct net_device *dev, char *command, int total_len)
-{
-	int  error = 0;
-	int bytes_written = 0;
-	uint i;
-	int len = 0;
-	char mac_buf[MAX_NUM_OF_ASSOCLIST *
-		sizeof(struct ether_addr) + sizeof(uint)] = {0};
-	struct maclist *assoc_maclist = (struct maclist *)mac_buf;
-
-	DHD_TRACE(("wl_android_get_assoclist: ENTER\n"));
-
-	assoc_maclist->count = htod32(MAX_NUM_OF_ASSOCLIST);
-
-	error = wldev_ioctl_get(dev, WLC_GET_ASSOCLIST, assoc_maclist, sizeof(mac_buf));
-	if (error)
-		return -1;
-
-	assoc_maclist->count = dtoh32(assoc_maclist->count);
-	bytes_written = snprintf(command, total_len, "%s listcount: %d Stations:",
-		CMD_ASSOC_CLIENTS, assoc_maclist->count);
-
-	for (i = 0; i < assoc_maclist->count; i++) {
-		len = snprintf(command + bytes_written, total_len - bytes_written, " " MACDBG,
-			MAC2STRDBG(assoc_maclist->ea[i].octet));
-		/* A return value of '(total_len - bytes_written)' or more means that the
-		 * output was truncated
-		 */
-		if ((len > 0) && (len < (total_len - bytes_written))) {
-			bytes_written += len;
-		} else {
-			DHD_ERROR(("wl_android_get_assoclist: Insufficient buffer %d,"
-				" bytes_written %d\n",
-				total_len, bytes_written));
-			bytes_written = -1;
-			break;
-		}
-	}
-	return bytes_written;
-}
-#endif /* AUTOMOTIVE_FEATURE */
 static int wl_android_get_channel_list(struct net_device *dev, char *command, int total_len)
 {
 
@@ -1549,6 +1349,33 @@
 	return (pos - command);
 }
 
+int wl_android_block_associations(struct net_device *dev, char *command, int total_len)
+{
+
+	int enable_blockassoc = 0, bytes_written = 0, ret = 0;
+
+	if (*(command + strlen(CMD_BLOCKASSOC)) == '\0') {
+		ret = wldev_iovar_getint(dev, "block_assoc", &enable_blockassoc);
+		if (ret != BCME_OK) {
+			DHD_ERROR(("%s: Failed to get status of block_assoc error(%d)\n", __FUNCTION__, ret));
+			return ret;
+		}
+                bytes_written = snprintf(command, total_len, "%s %d", CMD_BLOCKASSOC, enable_blockassoc);
+                return bytes_written;
+	}
+        command = (command + strlen(CMD_BLOCKASSOC));
+        command++;
+        enable_blockassoc = bcm_atoi(command);
+        DHD_INFO(("%s: Block associations in AP mode = %d\n", __FUNCTION__, enable_blockassoc));
+        ret = wldev_iovar_setint(dev, "block_assoc", enable_blockassoc);
+	if (ret != BCME_OK){
+		DHD_ERROR(("%s: Failed to set block_assoc in AP mode %d\n", __FUNCTION__, ret));
+		return ret;
+	}
+
+        return 0;
+}
+
 extern chanspec_t
 wl_chspec_host_to_driver(chanspec_t chanspec);
 static int wl_android_set_csa(struct net_device *dev, char *command)
@@ -2231,83 +2058,6 @@
 	return bytes_written;
 }
 
-#ifdef AUTOMOTIVE_FEATURE
-int wl_android_set_country_rev(
-	struct net_device *dev, char* command)
-{
-	int error = 0;
-	wl_country_t cspec = {{0}, 0, {0} };
-	char country_code[WLC_CNTRY_BUF_SZ];
-	char smbuf[WLC_IOCTL_SMLEN];
-	int rev = 0;
-
-	/*
-	 * SETCOUNTRYREV driver command provides support setting the country.
-	 * e.g US, DE, JP etc via supplicant. Once set, band and channels
-	 * too automatically gets updated based on the country.
-	 * Usage:
-	 * > IFNAME=wlan0 DRIVER SETCOUNTRYREV JP
-	 * OK
-	 */
-
-	bzero(country_code, sizeof(country_code));
-	sscanf(command+sizeof("SETCOUNTRYREV"), "%3s %10d", country_code, &rev);
-	WL_TRACE(("country_code = %s, rev = %d\n", country_code, rev));
-
-	memcpy(cspec.country_abbrev, country_code, sizeof(country_code));
-	memcpy(cspec.ccode, country_code, sizeof(country_code));
-	cspec.rev = rev;
-
-	error = wldev_iovar_setbuf(dev, "country", (char *)&cspec,
-		sizeof(cspec), smbuf, sizeof(smbuf), NULL);
-
-	if (error) {
-		DHD_ERROR(("wl_android_set_country_rev: set country '%s/%d' failed code %d\n",
-			cspec.ccode, cspec.rev, error));
-	} else {
-		dhd_bus_country_set(dev, &cspec, true);
-		DHD_INFO(("wl_android_set_country_rev: set country '%s/%d'\n",
-			cspec.ccode, cspec.rev));
-	}
-
-	return error;
-}
-
-static int wl_android_get_country_rev(
-	struct net_device *dev, char *command, int total_len)
-{
-	int error;
-	int bytes_written;
-	char smbuf[WLC_IOCTL_SMLEN];
-	wl_country_t cspec;
-
-	/*
-	 * GETCOUNTRYREV driver command provides support getting the country.
-	 * e.g US, DE, JP etc via supplicant.
-	 * Usage:
-	 * > IFNAME=wlan0 DRIVER GETCOUNTRYREV
-	 * GETCOUNTRYREV JP 0
-	 */
-
-	error = wldev_iovar_getbuf(dev, "country", NULL, 0, smbuf,
-		sizeof(smbuf), NULL);
-
-	if (error) {
-		DHD_ERROR(("wl_android_get_country_rev: get country failed code %d\n",
-			error));
-		return -1;
-	} else {
-		memcpy(&cspec, smbuf, sizeof(cspec));
-		DHD_INFO(("wl_android_get_country_rev: get country '%c%c %d'\n",
-			cspec.ccode[0], cspec.ccode[1], cspec.rev));
-	}
-
-	bytes_written = snprintf(command, total_len, "%s %c%c %d",
-		CMD_COUNTRYREV_GET, cspec.ccode[0], cspec.ccode[1], cspec.rev);
-
-	return bytes_written;
-}
-#endif /* AUTOMOTIVE_FEATURE */
 #endif /* ROAM_API */
 
 #ifdef WES_SUPPORT
@@ -4017,87 +3767,6 @@
  * HAPD_MAC_FILTER mac_mode mac_cnt mac_addr1 mac_addr2
  *
  */
-#ifdef AUTOMOTIVE_FEATURE
-static int
-wl_android_set_mac_address_filter(struct net_device *dev, char* str)
-{
-	int i;
-	int ret = 0;
-	int macnum = 0;
-	int macmode = MACLIST_MODE_DISABLED;
-	struct maclist *list;
-	char eabuf[ETHER_ADDR_STR_LEN];
-	const char *token;
-	struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
-
-	/* string should look like below (macmode/macnum/maclist) */
-	/*   1 2 00:11:22:33:44:55 00:11:22:33:44:ff  */
-
-	/* get the MAC filter mode */
-	token = strsep((char**)&str, " ");
-	if (!token) {
-		return -1;
-	}
-	macmode = bcm_atoi(token);
-
-	if (macmode < MACLIST_MODE_DISABLED || macmode > MACLIST_MODE_ALLOW) {
-		DHD_ERROR(("wl_android_set_mac_address_filter: invalid macmode %d\n", macmode));
-		return -1;
-	}
-
-	token = strsep((char**)&str, " ");
-	if (!token) {
-		return -1;
-	}
-	macnum = bcm_atoi(token);
-	if (macnum < 0 || macnum > MAX_NUM_MAC_FILT) {
-		DHD_ERROR(("wl_android_set_mac_address_filter: invalid number of MAC"
-			" address entries %d\n",
-			macnum));
-		return -1;
-	}
-	/* allocate memory for the MAC list */
-	list = (struct maclist*) MALLOCZ(cfg->osh, sizeof(int) +
-		sizeof(struct ether_addr) * macnum);
-	if (!list) {
-		DHD_ERROR(("wl_android_set_mac_address_filter : failed to allocate memory\n"));
-		return -1;
-	}
-	/* prepare the MAC list */
-	list->count = htod32(macnum);
-	bzero((char *)eabuf, ETHER_ADDR_STR_LEN);
-	for (i = 0; i < list->count; i++) {
-		token = strsep((char**)&str, " ");
-		if (token == NULL) {
-			DHD_ERROR(("wl_android_set_mac_address_filter : No mac address present\n"));
-			ret = -EINVAL;
-			goto exit;
-		}
-		strlcpy(eabuf, token, sizeof(eabuf));
-		if (!(ret = bcm_ether_atoe(eabuf, &list->ea[i]))) {
-			DHD_ERROR(("wl_android_set_mac_address_filter : mac parsing err index=%d,"
-				" addr=%s\n",
-				i, eabuf));
-			list->count = i;
-			break;
-		}
-		DHD_INFO(("wl_android_set_mac_address_filter : %d/%d MACADDR=%s",
-			i, list->count, eabuf));
-	}
-	if (i == 0)
-		goto exit;
-
-	/* set the list */
-	if ((ret = wl_android_set_ap_mac_list(dev, macmode, list)) != 0)
-		DHD_ERROR(("wl_android_set_mac_address_filter: Setting MAC list failed error=%d\n",
-			ret));
-
-exit:
-	MFREE(cfg->osh, list, sizeof(int) + sizeof(struct ether_addr) * macnum);
-
-	return ret;
-}
-#endif /* AUTOMOTIVE_FEATURE */
 /**
  * Global function definitions (declared in wl_android.h)
  */
@@ -9111,20 +8780,6 @@
 #endif /* BT_OVER_SDIO */
 #endif /* SUPPORT_DEEP_SLEEP */
 	}
-#ifdef AUTOMOTIVE_FEATURE
-	else if (strnicmp(command, CMD_SCAN_ACTIVE, strlen(CMD_SCAN_ACTIVE)) == 0) {
-		wl_cfg80211_set_passive_scan(net, command);
-	}
-	else if (strnicmp(command, CMD_SCAN_PASSIVE, strlen(CMD_SCAN_PASSIVE)) == 0) {
-		wl_cfg80211_set_passive_scan(net, command);
-	}
-	else if (strnicmp(command, CMD_RSSI, strlen(CMD_RSSI)) == 0) {
-		bytes_written = wl_android_get_rssi(net, command, priv_cmd.total_len);
-	}
-	else if (strnicmp(command, CMD_LINKSPEED, strlen(CMD_LINKSPEED)) == 0) {
-		bytes_written = wl_android_get_link_speed(net, command, priv_cmd.total_len);
-	}
-#endif /* AUTOMOTIVE_FEATURE */
 #ifdef PKT_FILTER_SUPPORT
 	else if (strnicmp(command, CMD_RXFILTER_START, strlen(CMD_RXFILTER_START)) == 0) {
 		bytes_written = net_os_enable_packet_filter(net, 1);
@@ -9244,16 +8899,9 @@
 		bytes_written = wl_android_set_csa(net, command);
 	} else if (strnicmp(command, CMD_CHANSPEC, strlen(CMD_CHANSPEC)) == 0) {
 		bytes_written = wl_android_get_chanspec(net, command, priv_cmd.total_len);
+	} else if (strnicmp(command, CMD_BLOCKASSOC, strlen(CMD_BLOCKASSOC)) == 0) {
+               bytes_written = wl_android_block_associations(net, command, priv_cmd.total_len);
 	}
-#ifdef AUTOMOTIVE_FEATURE
-	 else if (strnicmp(command, CMD_DATARATE, strlen(CMD_DATARATE)) == 0) {
-		bytes_written = wl_android_get_datarate(net, command, priv_cmd.total_len);
-	} else if (strnicmp(command, CMD_80211_MODE, strlen(CMD_80211_MODE)) == 0) {
-		bytes_written = wl_android_get_80211_mode(net, command, priv_cmd.total_len);
-	} else if (strnicmp(command, CMD_ASSOC_CLIENTS, strlen(CMD_ASSOC_CLIENTS)) == 0) {
-		bytes_written = wl_android_get_assoclist(net, command, priv_cmd.total_len);
-	}
-#endif /* AUTOMOTIVE_FEATURE */
 	 else if (strnicmp(command, CMD_RSDB_MODE, strlen(CMD_RSDB_MODE)) == 0) {
 		bytes_written = wl_android_get_rsdb_mode(net, command, priv_cmd.total_len);
 	}
@@ -9290,24 +8938,6 @@
 		bytes_written = wl_android_get_full_roam_scan_period(net, command,
 		priv_cmd.total_len);
 	}
-#ifdef AUTOMOTIVE_FEATURE
-	 else if (strnicmp(command, CMD_COUNTRYREV_SET,
-		strlen(CMD_COUNTRYREV_SET)) == 0) {
-		bytes_written = wl_android_set_country_rev(net, command);
-#ifdef FCC_PWR_LIMIT_2G
-		if (wldev_iovar_setint(net, "fccpwrlimit2g", FALSE)) {
-			DHD_ERROR(("wl_handle_private_cmd: fccpwrlimit2g"
-				" deactivation is failed\n"));
-		} else {
-			DHD_ERROR(("wl_handle_private_cmd: fccpwrlimit2g is deactivated\n"));
-		}
-#endif /* FCC_PWR_LIMIT_2G */
-	} else if (strnicmp(command, CMD_COUNTRYREV_GET,
-		strlen(CMD_COUNTRYREV_GET)) == 0) {
-		bytes_written = wl_android_get_country_rev(net, command,
-		priv_cmd.total_len);
-	}
-#endif /* AUTOMOTIVE_FEATURE */
 #endif /* ROAM_API */
 #ifdef WES_SUPPORT
 	else if (strnicmp(command, CMD_GETROAMSCANCONTROL, strlen(CMD_GETROAMSCANCONTROL)) == 0) {
@@ -9619,12 +9249,6 @@
 		wl_android_set_hide_ssid(net, (const char*)(command+skip));
 	}
 #endif /* SUPPORT_HIDDEN_AP */
-#ifdef AUTOMOTIVE_FEATURE
-	else if (strnicmp(command, CMD_HAPD_MAC_FILTER, strlen(CMD_HAPD_MAC_FILTER)) == 0) {
-		int skip = strlen(CMD_HAPD_MAC_FILTER) + 1;
-		wl_android_set_mac_address_filter(net, command+skip);
-	}
-#endif /* AUTOMOTIVE_FEATURE */
 	else if (strnicmp(command, CMD_SETROAMMODE, strlen(CMD_SETROAMMODE)) == 0)
 		bytes_written = wl_android_set_roam_mode(net, command);
 #if defined(BCMFW_ROAM_ENABLE)
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 004318d..65c3572 100644
--- 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,7 +1,7 @@
 /*
  * Linux cfg80211 driver
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -274,7 +274,11 @@
 _Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"")
 #endif // endif
 static const struct ieee80211_regdomain brcm_regdom = {
+#ifdef WL_6E
+	.n_reg_rules = 5,
+#else
 	.n_reg_rules = 4,
+#endif /* WL_6E */
 	.alpha2 =  "99",
 	.reg_rules = {
 		/* IEEE 802.11b/g, channels 1..11 */
@@ -287,7 +291,12 @@
 		/* IEEE 802.11a, channel 36..64 */
 		REG_RULE(5150-10, 5350+10, 80, 6, 20, 0),
 		/* IEEE 802.11a, channel 100..165 */
-		REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), }
+		REG_RULE(5470-10, 5850+10, 80, 6, 20, 0),
+#ifdef WL_6E
+		/* IEEE 802.11ax, 6E */
+		REG_RULE(5935-10, 7115+10, 80, 6, 20, 0),
+#endif /* WL_6E */
+		}
 };
 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == \
 	4 && __GNUC_MINOR__ >= 6))
@@ -827,7 +836,7 @@
 
 static s32 wl_get_assoc_ies(struct bcm_cfg80211 *cfg, struct net_device *ndev);
 static s32 wl_ch_to_chanspec(struct net_device *dev, int ch,
-	struct wl_join_params *join_params, size_t *join_params_size);
+	struct wl_join_params *join_params, size_t *join_params_size, uint32 center_freq);
 void wl_cfg80211_clear_security(struct bcm_cfg80211 *cfg);
 
 /*
@@ -921,6 +930,7 @@
 /*
  * Some external functions, TODO: move them to dhd_linux.h
  */
+#ifdef DHD_MONITOR_INTERFACE
 int dhd_add_monitor(const char *name, struct net_device **new_ndev);
 int dhd_del_monitor(struct net_device *ndev);
 int dhd_monitor_init(void *dhd_pub);
@@ -931,12 +941,13 @@
 int
 #endif /* CFI_CHECK */
 dhd_start_xmit(struct sk_buff *skb, struct net_device *net);
+#endif /* DHD_MONITOR_INTERFACE */
 
 #ifdef ESCAN_CHANNEL_CACHE
 void reset_roam_cache(struct bcm_cfg80211 *cfg);
 void add_roam_cache(struct bcm_cfg80211 *cfg, wl_bss_info_t *bi);
 int  get_roam_channel_list(int target_chan, chanspec_t *channels,
-	int n_channels, const wlc_ssid_t *ssid, int ioctl_ver);
+	int n_channels, const wlc_ssid_t *ssid, int ioctl_ver, uint32 center_freq);
 void set_roam_band(int band);
 #endif /* ESCAN_CHANNEL_CACHE */
 
@@ -1126,6 +1137,17 @@
 	.max_power		= 30,				\
 }
 
+#ifdef WL_6E
+#define CHAN6G(_channel, _flags) {				\
+	.band			= IEEE80211_BAND_6GHZ,		\
+	.center_freq		= 5950 + (5 * (_channel)),	\
+	.hw_value		= (_channel),			\
+	.flags			= (_flags),			\
+	.max_antenna_gain	= 0,				\
+	.max_power		= 30,				\
+}
+#endif /* WL_6E */
+
 #define RATE_TO_BASE100KBPS(rate)   (((rate) * 10) / 2)
 #define RATETAB_ENT(_rateid, _flags) \
 	{								\
@@ -1189,6 +1211,26 @@
 	CHAN5G(165, 0)
 };
 
+#ifdef WL_6E
+static struct ieee80211_channel __wl_6ghz_a_channels[] = {
+	CHAN6G(1, 0), CHAN6G(5, 0), CHAN6G(9, 0), CHAN6G(13, 0),
+	CHAN6G(17, 0), CHAN6G(21, 0), CHAN6G(25, 0), CHAN6G(29, 0),
+	CHAN6G(33, 0), CHAN6G(37, 0), CHAN6G(41, 0), CHAN6G(45, 0),
+	CHAN6G(49, 0), CHAN6G(53, 0),	CHAN6G(57, 0), CHAN6G(61, 0),
+	CHAN6G(65, 0), CHAN6G(69, 0), CHAN6G(73, 0), CHAN6G(77, 0),
+	CHAN6G(81, 0), CHAN6G(85, 0), CHAN6G(89, 0), CHAN6G(93, 0),
+	CHAN6G(97, 0), CHAN6G(101, 0), CHAN6G(105, 0), CHAN6G(109, 0),
+	CHAN6G(113, 0), CHAN6G(117, 0), CHAN6G(121, 0), CHAN6G(125, 0),
+	CHAN6G(129, 0), CHAN6G(133, 0), CHAN6G(137, 0), CHAN6G(141, 0),
+	CHAN6G(145, 0), CHAN6G(149, 0), CHAN6G(153, 0), CHAN6G(157, 0),
+	CHAN6G(161, 0), CHAN6G(165, 0), CHAN6G(169, 0), CHAN6G(173, 0),
+	CHAN6G(177, 0), CHAN6G(181, 0), CHAN6G(185, 0), CHAN6G(189, 0),
+	CHAN6G(193, 0), CHAN6G(197, 0), CHAN6G(201, 0), CHAN6G(205, 0),
+	CHAN6G(209, 0), CHAN6G(213, 0), CHAN6G(217, 0), CHAN6G(221, 0),
+	CHAN6G(225, 0), CHAN6G(229, 0), CHAN6G(233, 0)
+};
+#endif /* WL_6E */
+
 static struct ieee80211_supported_band __wl_band_2ghz = {
 	.band = IEEE80211_BAND_2GHZ,
 	.channels = __wl_2ghz_channels,
@@ -1205,6 +1247,16 @@
 	.n_bitrates = wl_a_rates_size
 };
 
+#ifdef WL_6E
+static struct ieee80211_supported_band __wl_band_6ghz = {
+	.band = IEEE80211_BAND_6GHZ,
+	.channels = __wl_6ghz_a_channels,
+	.n_channels = ARRAY_SIZE(__wl_6ghz_a_channels),
+	.bitrates = wl_a_rates,
+	.n_bitrates = wl_a_rates_size,
+};
+#endif /* WL_6E */
+
 static const u32 __wl_cipher_suites[] = {
 	WLAN_CIPHER_SUITE_WEP40,
 	WLAN_CIPHER_SUITE_WEP104,
@@ -1919,8 +1971,12 @@
 			WL_DBG(("wlfc_on:%d \n", cfg->wlfc_on));
 		}
 	} else {
-			dhd_wlfc_deinit(dhd);
-			cfg->wlfc_on = false;
+			dhd_wlfc_get_enable(dhd, &wlfc_enabled);
+			if (wlfc_enabled && cfg->wlfc_on && dhd->op_mode != DHD_FLAG_HOSTAP_MODE &&
+				dhd->op_mode != DHD_FLAG_IBSS_MODE) {
+				dhd_wlfc_deinit(dhd);
+				cfg->wlfc_on = false;
+			}
 	}
 #endif /* defined(BCMSDIO) */
 #endif /* PROP_TXSTATUS_VSDB */
@@ -2125,7 +2181,6 @@
 			wl_android_bcnrecv_stop(ndev, WL_BCNRECV_CONCURRENCY);
 #endif /* WL_BCNRECV */
 			wl_cfg80211_scan_abort(cfg);
-			wl_wlfc_enable(cfg, true);
 #ifdef WLTDLS
 			/* disable TDLS if number of connected interfaces is >= 1 */
 			wl_cfg80211_tdls_config(cfg, TDLS_STATE_IF_CREATE, false);
@@ -2173,6 +2228,7 @@
 			wl_cfg80211_clear_per_bss_ies(cfg, wdev);
 			break;
 		case WL_IF_CHANGE_DONE:
+			wl_wlfc_enable(cfg, true);
 			if (wl_mode == WL_MODE_BSS) {
 				/* Enable buffering of PTK key till EAPOL 4/4 is sent out */
 				wldev_iovar_setint(ndev, "buf_key_b4_m4", 1);
@@ -2790,6 +2846,7 @@
 }
 #endif /* WL_IFACE_MGMT */
 
+#ifdef DHD_MONITOR_INTERFACE
 static struct wireless_dev *
 wl_cfg80211_add_monitor_if(struct wiphy *wiphy, const char *name)
 {
@@ -2817,6 +2874,7 @@
 	return ndev->ieee80211_ptr;
 #endif /* WL_ENABLE_P2P_IF || WL_CFG80211_P2P_DEV_IF */
 }
+#endif /* DHD_MONITOR_INTERFACE */
 
 static struct wireless_dev *
 wl_cfg80211_add_ibss(struct wiphy *wiphy, u16 wl_iftype, char const *name)
@@ -3146,9 +3204,11 @@
 		case WL_IF_TYPE_IBSS:
 			wdev = wl_cfg80211_add_ibss(wiphy, wl_iftype, name);
 			break;
+#ifdef DHD_MONITOR_INTERFACE
 		case WL_IF_TYPE_MONITOR:
 			wdev = wl_cfg80211_add_monitor_if(wiphy, name);
 			break;
+#endif /* DHD_MONITOR_INTERFACE */
 		case WL_IF_TYPE_STA:
 		case WL_IF_TYPE_AP:
 		case WL_IF_TYPE_NAN:
@@ -3683,9 +3743,7 @@
 	case NL80211_IFTYPE_AP_VLAN:
 		{
 			if (!wl_get_drv_status(cfg, AP_CREATED, ndev)) {
-#if !defined(OEM_ANDROID)
 				dhd->op_mode = DHD_FLAG_HOSTAP_MODE;
-#endif /* BCMDONGLEHOST */
 				err = wl_cfg80211_set_ap_role(cfg, ndev);
 				if (unlikely(err)) {
 					WL_ERR(("set ap role failed!\n"));
@@ -6931,7 +6989,7 @@
 		memcpy(ssid.SSID, sme->ssid, sme->ssid_len);
 		ssid.SSID_len = (uint32)sme->ssid_len;
 		chan_cnt = get_roam_channel_list(cfg->channel, chanspec_list,
-				MAX_ROAM_CHANNEL, &ssid, ioctl_version);
+				MAX_ROAM_CHANNEL, &ssid, ioctl_version, chan->center_freq);
 		WL_DBG(("RCC channel count:%d \n", chan_cnt));
 	}
 #endif /* ESCAN_CHANNEL_CACHE */
@@ -7010,8 +7068,22 @@
 	/* increate dwell time to receive probe response or detect Beacon
 	* from target AP at a noisy air only during connect command
 	*/
+#ifdef WL_6E
+	if (chan->center_freq > FREQ_START_6G_CHANNEL) {
+		ext_join_params->scan.active_time = chan_cnt ?
+			WL_SCAN_JOIN_ACTIVE_DWELL_TIME_MS_6E : -1;
+		ext_join_params->scan.passive_time = chan_cnt ?
+			WL_SCAN_JOIN_PASSIVE_DWELL_TIME_MS_6E : -1;
+	} else {
+		ext_join_params->scan.active_time = chan_cnt ?
+			WL_SCAN_JOIN_ACTIVE_DWELL_TIME_MS : -1;
+		ext_join_params->scan.passive_time = chan_cnt ?
+			WL_SCAN_JOIN_PASSIVE_DWELL_TIME_MS : -1;
+	}
+#else
 	ext_join_params->scan.active_time = chan_cnt ? WL_SCAN_JOIN_ACTIVE_DWELL_TIME_MS : -1;
 	ext_join_params->scan.passive_time = chan_cnt ? WL_SCAN_JOIN_PASSIVE_DWELL_TIME_MS : -1;
+#endif /* WL_6E */
 	/* Set up join scan parameters */
 	ext_join_params->scan.scan_type = -1;
 	ext_join_params->scan.nprobes = chan_cnt ?
@@ -7142,7 +7214,8 @@
 	else
 		memcpy(&join_params.params.bssid, &ether_bcast, ETH_ALEN);
 
-	if (wl_ch_to_chanspec(dev, cfg->channel, &join_params, &join_params_size) < 0) {
+	if (wl_ch_to_chanspec(dev, cfg->channel, &join_params, &join_params_size,
+		chan->center_freq) < 0) {
 		WL_ERR(("Invalid chanspec\n"));
 		return -EINVAL;
 	}
@@ -8780,13 +8853,17 @@
 			WL_DBG(("%02x\n", pmk_list->pmkids.pmkid[i].pmkid[j]));
 		}
 	}
-	if (cfg->wlc_ver.wlc_ver_major >= MIN_PMKID_LIST_V3_FW_MAJOR) {
+	if (cfg->wlc_ver.wlc_ver_major > MIN_PMKID_LIST_V3_FW_MAJOR) {
 			pmk_list->pmkids.version = PMKID_LIST_VER_3;
 			err = wldev_iovar_setbuf(dev, "pmkid_info", (char *)pmk_list,
 				sizeof(*pmk_list), cfg->ioctl_buf,
 				WLC_IOCTL_MAXLEN, &cfg->ioctl_buf_sync);
 	}
-	else if (cfg->wlc_ver.wlc_ver_major == MIN_PMKID_LIST_V2_FW_MAJOR) {
+	/* For wlc_ver_major 13 sending pmkid version as 2
+	 * as firmware has not implemented the pmkid list ver 3
+	 */
+	else if (cfg->wlc_ver.wlc_ver_major == MIN_PMKID_LIST_V2_FW_MAJOR ||
+		 cfg->wlc_ver.wlc_ver_major == MIN_PMKID_LIST_V3_FW_MAJOR) {
 		u32 v2_list_size = (u32)(sizeof(pmkid_list_v2_t) + npmkids*sizeof(pmkid_v2_t));
 		pmkid_list_v2_t *pmkid_v2_list = (pmkid_list_v2_t *)MALLOCZ(cfg->osh, v2_list_size);
 
@@ -10394,8 +10471,16 @@
 	struct wiphy *wiphy = wdev->wiphy;
 	struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
 
+#ifdef WL_6E
+	if (band == IEEE80211_BAND_5GHZ || band == IEEE80211_BAND_6GHZ) {
+		if (band == IEEE80211_BAND_5GHZ)
+			param.band = WLC_BAND_5G;
+		else if (band == IEEE80211_BAND_6GHZ)
+			param.band = WLC_BAND_6G;
+#else
 	if (band == IEEE80211_BAND_5GHZ) {
 		param.band = WLC_BAND_5G;
+#endif /* WL_6E AP */
 		channel_width = wl_get_chanwidth_by_netdev(cfg, ndev);
 		switch (channel_width) {
 			case WL_CHANSPEC_BW_80:
@@ -10765,6 +10850,9 @@
 			gval = SMS4_ENABLED;
 			break;
 #endif // endif
+		case WPA_CIPHER_AES_GCM256:
+			gval = AES_GCMP256;
+			break;
 		default:
 			WL_ERR(("No Security Info\n"));
 			break;
@@ -10794,6 +10882,9 @@
 			pval = SMS4_ENABLED;
 			break;
 #endif // endif
+		case WPA_CIPHER_AES_GCM256:
+			pval = AES_GCMP256;
+			break;
 		default:
 			WL_ERR(("No Security Info\n"));
 	}
@@ -10834,6 +10925,9 @@
 		case RSN_AKM_SAE_PSK:
 			wpa_auth |= WPA3_AUTH_SAE_PSK;
 			break;
+		case RSN_AKM_SUITEB_SHA384_1X:
+			wpa_auth |= WPA3_AUTH_1X_SUITE_B_SHA384;
+			break;
 #endif /* WL_SAE */
 #endif /* MFP */
 		default:
@@ -13722,7 +13816,7 @@
 	wdev->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
 #else
 	wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
-#endif // endif
+#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(3, 14, 0) */
 	wiphy_apply_custom_regulatory(wdev->wiphy, &brcm_regdom);
 
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 14, 0)) || defined(WL_VENDOR_EXT_SUPPORT)
@@ -13899,6 +13993,11 @@
 	notif_bss_info->channel =
 		wf_chspec_ctlchan(wl_chspec_driver_to_host(bi->chanspec));
 
+#ifdef WL_6E
+	if (CHSPEC_IS6G(wl_chspec_driver_to_host(bi->chanspec))) {
+		band = wiphy->bands[IEEE80211_BAND_6GHZ];
+	} else
+#endif /* WL_6E */
 	if (notif_bss_info->channel <= CH_MAX_2G_CHANNEL)
 		band = wiphy->bands[IEEE80211_BAND_2GHZ];
 	else
@@ -13950,9 +14049,9 @@
 	}
 	memcpy(tmp_buf, bi->SSID, bi->SSID_len);
 	tmp_buf[bi->SSID_len] = '\0';
-	WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM"
+	WL_DBG(("SSID : \"%s\", rssi %d, channel %d, freq %d, capability : 0x04%x, bssid %pM"
 			"mgmt_type %d frame_len %d\n", tmp_buf,
-			notif_bss_info->rssi, notif_bss_info->channel,
+			notif_bss_info->rssi, notif_bss_info->channel, freq,
 			mgmt->u.beacon.capab_info, &bi->BSSID, mgmt_type,
 			notif_bss_info->frame_len));
 
@@ -14805,12 +14904,17 @@
 #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
 	freq = ieee80211_channel_to_frequency(channel);
 #else
+#ifdef WL_6E
+	if (CHSPEC_IS6G(wl_chspec_driver_to_host(bi->chanspec))) {
+		freq = ieee80211_channel_to_frequency(channel, IEEE80211_BAND_6GHZ);
+	} else
+#endif /* WL_6E */
 	if (channel > 14) {
 		freq = ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
 	} else {
 		freq = ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
 	}
-#endif // endif
+#endif /* LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !(WL_COMPAT_WIRELESS) */
 	rate = 0;
 	err = wldev_ioctl_get(dev, WLC_GET_RATE, &rate, sizeof(rate));
 	if (err) {
@@ -16255,7 +16359,7 @@
 }
 
 static s32 wl_ch_to_chanspec(struct net_device *dev, int ch, struct wl_join_params *join_params,
-	size_t *join_params_size)
+	size_t *join_params_size, uint32 center_freq)
 {
 	chanspec_t chanspec = 0, chspec;
 	struct bcm_cfg80211 *cfg =
@@ -16265,6 +16369,11 @@
 		join_params->params.chanspec_num = 1;
 		join_params->params.chanspec_list[0] = ch;
 
+#ifdef WL_6E
+		if (center_freq > FREQ_START_6G_CHANNEL) {
+			chanspec |= WL_CHANSPEC_BAND_6G;
+		} else
+#endif /* WL_6E */
 		if (join_params->params.chanspec_list[0] <= CH_MAX_2G_CHANNEL)
 			chanspec |= WL_CHANSPEC_BAND_2G;
 		else
@@ -16297,7 +16406,7 @@
 		 */
 		int n_channels;
 		n_channels = get_roam_channel_list(ch, join_params->params.chanspec_list,
-			MAX_ROAM_CHANNEL, &join_params->ssid, ioctl_version);
+			MAX_ROAM_CHANNEL, &join_params->ssid, ioctl_version, center_freq);
 		join_params->params.chanspec_num = htod32(n_channels);
 		*join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE +
 			join_params->params.chanspec_num * sizeof(chanspec_t);
@@ -16369,9 +16478,14 @@
 #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
 		freq = ieee80211_channel_to_frequency(channel);
 #else
+#ifdef WL_6E
+		band = CHSPEC_IS6G(wl_chspec_driver_to_host(bi->chanspec))? IEEE80211_BAND_6GHZ :
+			(channel <= CH_MAX_2G_CHANNEL) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
+#else
 		band = (channel <= CH_MAX_2G_CHANNEL) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
+#endif /* WL_6E */
 		freq = ieee80211_channel_to_frequency(channel, band);
-#endif // endif
+#endif /* LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !(WL_COMPAT_WIRELESS) */
 		bss->channel = ieee80211_get_channel(wiphy, freq);
 #if defined(WL_CFG80211_P2P_DEV_IF)
 		ie = (const u8 *)bss->ies->data;
@@ -17223,6 +17337,11 @@
 		}
 	}
 
+#ifdef WL_6E
+		if (CHSPEC_IS6G(ntoh16(rxframe->channel))) {
+			band = wiphy->bands[IEEE80211_BAND_6GHZ];
+		} else
+#endif /* WL_6E */
 	if (channel <= CH_MAX_2G_CHANNEL)
 		band = wiphy->bands[IEEE80211_BAND_2GHZ];
 	else
@@ -19710,7 +19829,11 @@
 {
 	struct wiphy *wiphy;
 	struct net_device *dev = bcmcfg_to_prmry_ndev(cfg);
+#ifdef WL_6E
+	u32 bandlist[4];
+#else
 	u32 bandlist[3];
+#endif /* WL_6E */
 	u32 nband = 0;
 	u32 i = 0;
 	s32 err = 0;
@@ -19798,6 +19921,12 @@
 			index = IEEE80211_BAND_2GHZ;
 			bands[index] = &__wl_band_2ghz;
 		}
+#ifdef WL_6E
+		else if (bandlist[i] == WLC_BAND_6G && __wl_band_6ghz.n_channels > 0) {
+			index = IEEE80211_BAND_6GHZ;
+			bands[index] = &__wl_band_6ghz;
+		}
+#endif /* WL_6E */
 
 		if ((index >= 0) && nmode) {
 			wl_update_ht_cap(bands[index], bw_cap[index], nchain);
@@ -19806,6 +19935,9 @@
 
 	wiphy->bands[IEEE80211_BAND_2GHZ] = bands[IEEE80211_BAND_2GHZ];
 	wiphy->bands[IEEE80211_BAND_5GHZ] = bands[IEEE80211_BAND_5GHZ];
+#ifdef WL_6E
+	wiphy->bands[IEEE80211_BAND_6GHZ] = bands[IEEE80211_BAND_6GHZ];
+#endif /* WL_6E */
 
 	/* check if any bands populated otherwise makes 2Ghz as default */
 	if (wiphy->bands[IEEE80211_BAND_2GHZ] == NULL &&
@@ -19934,7 +20066,9 @@
 	}
 #endif /* DHD_LOSSLESS_ROAMING */
 
+#ifdef DHD_MONITOR_INTERFACE
 	err = dhd_monitor_init(cfg->pub);
+#endif /* DHD_MONITOR_INTERFACE */
 
 #ifdef WL_HOST_BAND_MGMT
 	/* By default the curr_band is initialized to BAND_AUTO */
@@ -20165,7 +20299,10 @@
 	DHD_OS_SCAN_WAKE_UNLOCK((dhd_pub_t *)(cfg->pub));
 #endif // endif
 
+#ifdef DHD_MONITOR_INTERFACE
 	dhd_monitor_uninit();
+#endif /* DHD_MONITOR_INTERFACE */
+
 #ifdef WLAIBSS_MCHAN
 	bcm_cfg80211_del_ibss_if(cfg->wdev->wiphy, cfg->ibss_cfgdev);
 #endif /* WLAIBSS_MCHAN */
@@ -25603,3 +25740,43 @@
 	return err;
 }
 #endif /* WL_WIPSEVT */
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 11, 1))
+void
+wl_cfg80211_overtemp_event(struct net_device *ndev)
+{
+	return;
+}
+#else
+void
+wl_cfg80211_overtemp_event(struct net_device *ndev)
+{
+	struct bcm_cfg80211 *cfg = wl_get_cfg(ndev);
+	struct wiphy *wiphy;
+	struct sk_buff *skb;
+	gfp_t kflags;
+
+	kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
+
+	if (!cfg || !cfg->wdev) {
+		WL_ERR(("cfg=%p wdev=%p\n", cfg, (cfg ? cfg->wdev : NULL)));
+		return;
+	}
+
+	wiphy = cfg->wdev->wiphy;
+	if (!wiphy) {
+		WL_ERR(("wiphy is NULL\n"));
+		return;
+	}
+
+#if (defined(CONFIG_ARCH_MSM) && defined(SUPPORT_WDEV_CFG80211_VENDOR_EVENT_ALLOC)) || \
+	LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
+	skb = cfg80211_vendor_event_alloc(wiphy, ndev_to_wdev(ndev), 0,
+		BRCM_VENDOR_EVENT_OVERTEMP, kflags);
+#else
+	skb = cfg80211_vendor_event_alloc(wiphy, 0, BRCM_VENDOR_EVENT_OVERTEMP,
+		kflags);
+#endif // endif
+	cfg80211_vendor_event(skb, kflags);
+}
+#endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(3, 11, 1) */
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 18433ea..9f13f01 100644
--- 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,7 +1,7 @@
 /*
  * Linux cfg80211 driver
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -125,6 +125,7 @@
 /* Newer kernels use defines from nl80211.h */
 #define IEEE80211_BAND_2GHZ	NL80211_BAND_2GHZ
 #define IEEE80211_BAND_5GHZ	NL80211_BAND_5GHZ
+#define IEEE80211_BAND_6GHZ	NL80211_BAND_6GHZ
 #define IEEE80211_BAND_60GHZ NL80211_BAND_60GHZ
 #define IEEE80211_NUM_BANDS	NUM_NL80211_BANDS
 #endif /* LINUX_VER >= 4.7 */
@@ -340,6 +341,10 @@
 #define WL_SCAN_JOIN_ACTIVE_DWELL_TIME_MS	320
 #define WL_SCAN_JOIN_PASSIVE_DWELL_TIME_MS	400
 #define WL_AF_TX_MAX_RETRY	5
+#ifdef WL_6E
+#define WL_SCAN_JOIN_ACTIVE_DWELL_TIME_MS_6E	80
+#define WL_SCAN_JOIN_PASSIVE_DWELL_TIME_MS_6E	130
+#endif /* WL_6E */
 
 #define WL_AF_SEARCH_TIME_MAX		450
 #define WL_AF_TX_EXTRA_TIME_MAX		200
@@ -1161,6 +1166,58 @@
 #define DHD_NUM_STATIC_IFACES           2
 #endif // endif
 
+#ifdef WL_SUPPORT_ACS_OFFLOAD
+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
+};
+
+/* defined in "hostapd/src/common/defs.h" */
+enum hostapd_hw_mode {
+        HOSTAPD_MODE_IEEE80211B,
+        HOSTAPD_MODE_IEEE80211G,
+        HOSTAPD_MODE_IEEE80211A,
+        HOSTAPD_MODE_IEEE80211AD,
+        HOSTAPD_MODE_IEEE80211ANY,
+        NUM_HOSTAPD_MODES
+};
+
+typedef struct drv_acs_offload_params {
+        /* Selected mode (HOSTAPD_MODE_*) */
+        enum hostapd_hw_mode hw_mode;
+        /* Indicates whether HT is enabled */
+        int ht_enabled;
+        /* Indicates whether HT40 is enabled */
+        int ht40_enabled;
+        /* Indicates whether VHT is enabled */
+        int vht_enabled;
+        /* Configured ACS channel width */
+        u16 ch_width;
+	u8 band;
+        /* ACS frequency list info */
+	int chan_cnt;
+        int *channels;
+} drv_acs_offload_params_t;
+
+typedef struct acs_offload_work {
+        struct delayed_work work;
+	struct wireless_dev *wdev;	/* representing cfg cfg80211 device */
+        struct net_device *ndev;
+        chanspec_t selected;
+        drv_acs_offload_params_t parameter;
+} acs_offload_work_t;
+#endif // endif
 typedef struct buf_data {
 	u32 ver; /* version of struct */
 	u32 len; /* Total len */
@@ -1427,6 +1484,7 @@
 	struct net_device *static_ndev[DHD_MAX_STATIC_IFS];
 	uint8 static_ndev_state[DHD_MAX_STATIC_IFS];
 	bool hal_started;
+	u32 hal_pid;
 	wl_wlc_version_t wlc_ver;
 	bool scan_params_v2;
 #ifdef DHD_BANDSTEER
@@ -1441,6 +1499,9 @@
        bool in_csa;
        timer_list_compat_t csa_timeout;   /* Timer for csa timeout */
 #endif // endif
+#ifdef WL_SUPPORT_ACS_OFFLOAD
+	acs_offload_work_t *acs_offload;
+#endif // endif
 };
 #define WL_STATIC_IFIDX	(DHD_MAX_IFS + DHD_MAX_STATIC_IFS - 1)
 enum static_ndev_states {
@@ -2584,6 +2645,8 @@
 #define WL_HE_FEATURES_HE_P2P		0x20
 #endif /* WL_DISABLE_HE_SOFTAP || WL_DISABLE_HE_P2P */
 extern s32 wl_cfg80211_config_suspend_events(struct net_device *ndev, bool enable);
+void wl_cfg80211_overtemp_event(struct net_device *ndev);
+
 #ifdef WL11U
 extern bcm_tlv_t *
 wl_cfg80211_find_interworking_ie(const u8 *parse, u32 len);
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 4aacd91..96cf7a5 100644
--- 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,7 +1,7 @@
 /*
  * Linux cfg80211 driver scan related code
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -972,6 +972,11 @@
 			}
 #endif /* LINUX_VER >= 3.6 */
 
+#ifdef WL_6E
+			if (request->channels[i]->band == IEEE80211_BAND_6GHZ) {
+				chanspec |= WL_CHANSPEC_BAND_6G;
+			} else
+#endif /* WL_6E */
 			if (request->channels[i]->band == IEEE80211_BAND_2GHZ) {
 #ifdef WL_HOST_BAND_MGMT
 				if (cfg->curr_band == WLC_BAND_5G) {
@@ -1218,6 +1223,7 @@
 					return err;
 				}
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
+				wl_cfg80211_ch_switch_notify(net, chanspec, bcmcfg_to_wiphy(cfg));
 				if (!cfg80211_chandef_valid(&wdev->chandef)) {
 					wl_cfg80211_ch_switch_notify(net,
 						0x1001, bcmcfg_to_wiphy(cfg));
@@ -1225,8 +1231,6 @@
 						"it MUST be stopped or"
 						" moved to a valid channel immediately\n",
 						CHSPEC_CHANNEL(chanspec)));
-				}else {
-					wl_cfg80211_ch_switch_notify(net, chanspec, bcmcfg_to_wiphy(cfg));
 				}
 #endif /* LINUX_VERSION_CODE >= (3, 5, 0) */
 			}
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 1b972c4..b21ba31 100644
--- 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,7 +1,7 @@
 /*
  * Linux cfg80211 Vendor Extension Code
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -423,6 +423,41 @@
 }
 
 #ifdef GSCAN_SUPPORT
+static int
+wl_cfgvendor_gscan_get_capabilities(struct wiphy *wiphy,
+	struct wireless_dev *wdev, const void  *data, int len)
+{
+	int err = 0;
+	struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+	dhd_pno_gscan_capabilities_t *reply = NULL;
+	uint32 reply_len = 0;
+
+	reply = dhd_dev_pno_get_gscan(bcmcfg_to_prmry_ndev(cfg),
+	   DHD_PNO_GET_CAPABILITIES, NULL, &reply_len);
+	if (!reply) {
+		WL_ERR(("Could not get capabilities\n"));
+		err = -EINVAL;
+		return err;
+	}
+
+	err =  wl_cfgvendor_send_cmd_reply(wiphy, reply, reply_len);
+	if (unlikely(err)) {
+		WL_ERR(("Vendor Command reply failed ret:%d \n", err));
+	}
+
+	MFREE(cfg->osh, reply, reply_len);
+	return err;
+}
+#else
+static int
+wl_cfgvendor_gscan_get_capabilities(struct wiphy *wiphy,
+	struct wireless_dev *wdev, const void  *data, int len)
+{
+	return WIFI_ERROR_NOT_SUPPORTED;
+}
+#endif /* GSCAN_SUPPORT */
+
+#ifdef GSCAN_SUPPORT
 int
 wl_cfgvendor_send_hotlist_event(struct wiphy *wiphy,
 	struct net_device *dev, void  *data, int len, wl_vendor_event_t event)
@@ -485,32 +520,6 @@
 }
 
 static int
-wl_cfgvendor_gscan_get_capabilities(struct wiphy *wiphy,
-	struct wireless_dev *wdev, const void  *data, int len)
-{
-	int err = 0;
-	struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
-	dhd_pno_gscan_capabilities_t *reply = NULL;
-	uint32 reply_len = 0;
-
-	reply = dhd_dev_pno_get_gscan(bcmcfg_to_prmry_ndev(cfg),
-	   DHD_PNO_GET_CAPABILITIES, NULL, &reply_len);
-	if (!reply) {
-		WL_ERR(("Could not get capabilities\n"));
-		err = -EINVAL;
-		return err;
-	}
-
-	err =  wl_cfgvendor_send_cmd_reply(wiphy, reply, reply_len);
-	if (unlikely(err)) {
-		WL_ERR(("Vendor Command reply failed ret:%d \n", err));
-	}
-
-	MFREE(cfg->osh, reply, reply_len);
-	return err;
-}
-
-static int
 wl_cfgvendor_gscan_get_batch_results(struct wiphy *wiphy,
 	struct wireless_dev *wdev, const void  *data, int len)
 {
@@ -1308,9 +1317,16 @@
 	}
 	return err;
 }
+#else
+static int wl_cfgvendor_set_rssi_monitor(struct wiphy *wiphy,
+	struct wireless_dev *wdev, const void  *data, int len)
+{
+	return WIFI_ERROR_NOT_SUPPORTED;
+}
 #endif /* RSSI_MONITOR_SUPPORT */
 
 #ifdef DHD_WAKE_STATUS
+#define MAX_WAKE_EVENT_CNT (MIN(32, WLC_E_LAST))
 static int
 wl_cfgvendor_get_wake_reason_stats(struct wiphy *wiphy,
         struct wireless_dev *wdev, const void *data, int len)
@@ -1328,7 +1344,7 @@
 
 	pwake_count_info = dhd_get_wakecount(dhdp);
 	mem_needed =  VENDOR_REPLY_OVERHEAD + (ATTRIBUTE_U32_LEN * 20) +
-		(WLC_E_LAST * sizeof(uint));
+		(MAX_WAKE_EVENT_CNT * sizeof(uint));
 
 	skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, mem_needed);
 	if (unlikely(!skb)) {
@@ -1343,12 +1359,14 @@
 		WL_ERR(("Failed to put Total count of CMD event, ret=%d\n", ret));
 		goto exit;
 	}
-	ret = nla_put_u32(skb, WAKE_STAT_ATTRIBUTE_CMD_EVENT_COUNT_USED, WLC_E_LAST);
+
+	ret = nla_put_u32(skb, WAKE_STAT_ATTRIBUTE_CMD_EVENT_COUNT_USED, MAX_WAKE_EVENT_CNT);
 	if (unlikely(ret)) {
 		WL_ERR(("Failed to put Max count of event used, ret=%d\n", ret));
 		goto exit;
 	}
-	ret = nla_put(skb, WAKE_STAT_ATTRIBUTE_CMD_EVENT_WAKE, (WLC_E_LAST * sizeof(uint)),
+
+	ret = nla_put(skb, WAKE_STAT_ATTRIBUTE_CMD_EVENT_WAKE, (MAX_WAKE_EVENT_CNT * sizeof(uint)),
 		pwake_count_info->rc_event);
 	if (unlikely(ret)) {
 		WL_ERR(("Failed to put Event wake data, ret=%d\n", ret));
@@ -1428,7 +1446,7 @@
 		WL_ERR(("Failed to put Total wake due to Other RX Multicast, ret=%d\n", ret));
 		goto exit;
 	}
-#endif /* #ifdef DHD_WAKE_RX_STATUS */
+#endif /* DHD_WAKE_RX_STATUS */
 	ret = cfg80211_vendor_cmd_reply(skb);
 	if (unlikely(ret)) {
 		WL_ERR(("Vendor cmd reply for -get wake status failed:%d \n", ret));
@@ -1443,6 +1461,13 @@
 	}
 	return ret;
 }
+#else
+static int
+wl_cfgvendor_get_wake_reason_stats(struct wiphy *wiphy,
+        struct wireless_dev *wdev, const void *data, int len)
+{
+	return WIFI_ERROR_NOT_SUPPORTED;
+}
 #endif /* DHD_WAKE_STATUS */
 
 #ifdef DHDTCPACK_SUPPRESS
@@ -1596,8 +1621,42 @@
 	cfg->hal_started = false;
 	return BCME_OK;
 }
+
+static int
+wl_cfgvendor_set_hal_pid(struct wiphy *wiphy,
+		struct wireless_dev *wdev, const void  *data, int len)
+{
+	struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+	int ret = BCME_OK;
+	int type;
+
+	WL_INFORM(("%s,[DUMP] SET HAL_PID\n", __FUNCTION__));
+	if (data) {
+		type = nla_type(data);
+		if (type == SET_HAL_START_ATTRIBUTE_EVENT_SOCK_PID) {
+			cfg->hal_pid = nla_get_u32(data);
+		}
+	} else {
+		ret = BCME_ERROR;
+	}
+
+	return ret;
+}
 #endif /* WL_CFG80211 */
 
+static int
+wl_cfgvendor_chavoid_set_config(struct wiphy *wiphy,
+		struct wireless_dev *wdev, const void  *data, int len)
+{
+	return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+static int
+wl_cfgvendor_usable_channel(struct wiphy *wiphy,
+		struct wireless_dev *wdev, const void  *data, int len)
+{
+	return WIFI_ERROR_NOT_SUPPORTED;
+}
 #ifdef RTT_SUPPORT
 void
 wl_cfgvendor_rtt_evt(void *ctx, void *rtt_data)
@@ -6340,6 +6399,12 @@
 	}
 	return err;
 }
+#else
+static int wl_cfgvendor_lstats_get_info(struct wiphy *wiphy,
+	struct wireless_dev *wdev, const void  *data, int len)
+{
+	return WIFI_ERROR_NOT_SUPPORTED;
+}
 #endif /* LINKSTAT_SUPPORT */
 
 #ifdef DHD_LOG_DUMP
@@ -7508,6 +7573,25 @@
 
 	return ret;
 }
+#else
+
+static int wl_cfgvendor_dbg_start_pkt_fate_monitoring(struct wiphy *wiphy,
+	struct wireless_dev *wdev, const void *data, int len)
+{
+	return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+static int wl_cfgvendor_dbg_get_tx_pkt_fates(struct wiphy *wiphy,
+	struct wireless_dev *wdev, const void  *data, int len)
+{
+	return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+static int wl_cfgvendor_dbg_get_rx_pkt_fates(struct wiphy *wiphy,
+	struct wireless_dev *wdev, const void  *data, int len)
+{
+	return WIFI_ERROR_NOT_SUPPORTED;
+}
 #endif /* DBG_PKT_MON */
 
 #ifdef KEEP_ALIVE
@@ -7774,6 +7858,12 @@
 	const struct nlattr *iter;
 	int ret = BCME_OK, rem, type;
 	u8 enable = 0;
+	dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub);
+
+	if (dhdp && !FW_SUPPORTED(dhdp, ndoe)) {
+		ret = WIFI_ERROR_NOT_SUPPORTED;
+		goto exit;
+	}
 
 	nla_for_each_attr(iter, data, len, rem) {
 		type = nla_type(iter);
@@ -7796,6 +7886,12 @@
 exit:
 	return ret;
 }
+#else
+static int wl_cfgvendor_configure_nd_offload(struct wiphy *wiphy,
+	struct wireless_dev *wdev, const void  *data, int len)
+{
+	return WIFI_ERROR_NOT_SUPPORTED;
+}
 #endif /* NDO_CONFIG_SUPPORT */
 
 /* for kernel >= 4.13 NL80211 wl_cfg80211_set_pmk have to be used. */
@@ -7887,8 +7983,620 @@
 	return ret;
 }
 
+static int
+wl_cfgvendor_set_multista_primary_connection(struct wiphy *wiphy,
+        struct wireless_dev *wdev, const void  *data, int len)
+{
+	return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+static int
+wl_cfgvendor_set_multista_use_case(struct wiphy *wiphy,
+        struct wireless_dev *wdev, const void  *data, int len)
+{
+	return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+#ifdef WL_SUPPORT_ACS_OFFLOAD
+
+#define ACS_OFFLOAD_DELAY		50
+#define ACS_OFFLOAD_BUF_SIZE		1024
+#define ACS_MAX_RETRY			10
+#define ACS_OFFLOAD_DEFAULT_CH_2G	6
+#define ACS_OFFLOAD_DEFAULT_CH_5G	149
+
+typedef struct acs_offload_report {
+	u32 primary_freq;
+	u32 second_freq;
+	u16 ch_width;
+	u8 vht_seg0_center;
+	u8 vht_seg1_center;
+	enum hostapd_hw_mode hw_mode;
+}acs_offload_report_t;
+
+static int
+wl_cfgvendor_acs_offload_report(acs_offload_work_t *acs_offload,
+				acs_offload_report_t *report) {
+	chanspec_t chspec = 0;
+
+	u32 ctl_freq, ctl_ch, bw, sb, band;
+
+	if (!acs_offload  || !report) {
+		WL_ERR(("ACS: failed %p, %p\n",acs_offload, report));
+		return BCME_BADARG;
+	}
+
+	/* if chanspec is invalid, changing to default */
+	if (!wf_chspec_valid(acs_offload->selected)) {
+		int channel = 0;
+		int bw = WL_CHANSPEC_BW_20;
+		if (acs_offload->parameter.band == WLC_BAND_2G) {
+			channel = ACS_OFFLOAD_DEFAULT_CH_2G;
+			bw = WL_CHANSPEC_BW_20;
+		}
+		else {
+			channel = ACS_OFFLOAD_DEFAULT_CH_5G;
+			if (acs_offload->parameter.ch_width == 80)
+				bw = WL_CHANSPEC_BW_80;
+			else if (acs_offload->parameter.ch_width == 40)
+				bw = WL_CHANSPEC_BW_40;
+		}
+		chspec = wf_channel2chspec(channel, bw);
+
+		WL_ERR(("ACS: %x is wrong chanspec, changing to default %x\n",
+			acs_offload->selected, chspec));
+	}
+	else
+		chspec = acs_offload->selected;
+
+	bzero(report, sizeof(acs_offload_report_t));
+
+	band = CHSPEC_BAND(chspec);
+	if (band == WL_CHANSPEC_BAND_2G)
+		report->hw_mode = HOSTAPD_MODE_IEEE80211G;
+	else
+		report->hw_mode = HOSTAPD_MODE_IEEE80211A;
+
+	ctl_ch = wf_chspec_ctlchan(chspec);
+	ctl_freq = ieee80211_channel_to_frequency( ctl_ch,
+			(band==WL_CHANSPEC_BAND_2G)?IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ);
+	bw = CHSPEC_BW(chspec);
+	sb = CHSPEC_CTL_SB(chspec);
+
+	WL_ERR(("ACS: ctl_freq=%d, center_ch=%d, band=0x%X, bw=0x%X, sb=0x%X\n",
+		ctl_freq, ctl_ch, band, bw, sb));
+
+	report->ch_width = bw;
+	switch(bw) {
+		case WL_CHANSPEC_BW_80:
+			if (acs_offload->parameter.vht_enabled && acs_offload->parameter.ch_width == 80) {
+				report->ch_width = 80;
+				ctl_ch = wf_chspec_primary80_channel(chspec);
+				if (ctl_ch == INVCHANNEL){
+					report->ch_width = 0;
+					break;
+				}
+				report->vht_seg0_center = ctl_ch;
+				report->vht_seg1_center = 0;
+				switch(sb) {
+					case WL_CHANSPEC_CTL_SB_LL:
+					case WL_CHANSPEC_CTL_SB_LU:
+						report->primary_freq = ctl_freq;
+						report->second_freq = ctl_freq + 20;
+						break;
+					case WL_CHANSPEC_CTL_SB_UL:
+					case WL_CHANSPEC_CTL_SB_UU:
+						report->primary_freq = ctl_freq;
+						report->second_freq = ctl_freq - 20;
+					default:
+						report->ch_width = 0;
+						break;
+				}
+				break;
+			}
+		case WL_CHANSPEC_BW_40:
+			if (acs_offload->parameter.ht40_enabled) {
+				report->ch_width = 40;
+				switch(sb) {
+					case WL_CHANSPEC_CTL_SB_U:
+						report->primary_freq = ctl_freq;
+						report->second_freq = ctl_freq - 20;
+						break;
+					case WL_CHANSPEC_CTL_SB_L:
+						report->primary_freq = ctl_freq;
+						report->second_freq = ctl_freq + 20;
+						break;
+					default :
+						report->ch_width = 0;
+						break;
+				}
+			}
+			break;
+		default :
+			report->ch_width = 20;
+			report->primary_freq = ctl_freq;
+			report->second_freq = 0;
+	}
+
+	if (!report->ch_width) {
+		ctl_ch = wf_chspec_ctlchan(chspec);
+		report->primary_freq = ctl_freq;
+		report->second_freq = 0;
+		report->ch_width = 20;
+	}
+	WL_ERR(("ACS: report pri = %d, sec = %d, width = %d,  vht_seg0 = %d, vht_seg1 = %d\n",
+		report->primary_freq, report->second_freq, report->ch_width,
+		report->vht_seg0_center, report->vht_seg1_center));
+
+	return BCME_OK;
+}
+
+static void
+wl_cfgvendor_acs_offload_deinit(acs_offload_work_t *acs_offload) {
+	if (acs_offload) {
+		drv_acs_offload_params_t *params = &acs_offload->parameter;
+		if (params->channels) {
+			kfree(params->channels);
+		}
+		acs_offload->selected = 0;
+		cancel_delayed_work_sync(&acs_offload->work);
+		kfree(acs_offload);
+	}
+}
+
+static void wl_cfgvendor_acs_offload_work_handler(struct work_struct *work) {
+	acs_offload_work_t *acs_offload = (acs_offload_work_t *)work;
+	struct net_device *ndev = acs_offload->ndev;
+	struct wireless_dev *wdev = NULL;
+	struct wiphy *wiphy = NULL;
+	gfp_t kflags;
+	struct sk_buff *msg = NULL;
+	int ret = BCME_OK;
+	int len = 0;
+	acs_offload_report_t report={0x00, };
+
+	do {
+		if (!acs_offload) {
+			ret = BCME_BADARG;
+			break;
+		}
+
+		wdev = acs_offload->wdev;
+		if (!wdev) {
+			ret = BCME_BADARG;
+			break;
+		}
+
+		ndev = wdev_to_ndev(wdev);
+
+		if (!ndev || !ndev->ieee80211_ptr || !ndev->ieee80211_ptr->wiphy) {
+			ret = BCME_BADARG;
+			break;
+		}
+
+		wiphy = ndev->ieee80211_ptr->wiphy;
+
+		if (wl_cfgvendor_acs_offload_report(acs_offload, &report) != BCME_OK)
+			break;
+
+		len = sizeof(acs_offload_report_t);
+		kflags = in_atomic()? GFP_ATOMIC:GFP_KERNEL;
+
+		msg = CFG80211_VENDOR_EVENT_ALLOC(wiphy, wdev, len, BRCM_VENDOR_EVENT_ACS, kflags);
+		if (!msg) {
+			ret = BCME_NOMEM;
+			WL_ERR(("ACS: Failed :: not enough memory\n"));
+			break;
+		}
+
+		ret = nla_put_u32(msg, BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ, report.primary_freq);
+		if (ret < 0) {
+			WL_ERR(("ACS: Failed to put BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ : %d\n", ret));
+			break;
+		}
+		ret = nla_put_u32(msg, BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ, report.second_freq);
+		if (ret < 0) {
+			WL_ERR(("ACS: Failed to put BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ : %d\n", ret));
+			break;
+		}
+		ret = nla_put_u8(msg, BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL, report.vht_seg0_center);
+		if (ret < 0) {
+			WL_ERR(("ACS: Failed to put BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL : %d\n", ret));
+			break;
+		}
+		ret = nla_put_u8(msg, BRCM_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL, report.vht_seg1_center);
+		if (ret < 0) {
+			WL_ERR(("ACS: Failed to put BRCM_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL : %d\n", ret));
+			break;
+		}
+		ret = nla_put_u16(msg, BRCM_VENDOR_ATTR_ACS_CHWIDTH, report.ch_width);
+		if (ret < 0) {
+			WL_ERR(("ACS: Failed to put BRCM_VENDOR_ATTR_ACS_CHWIDTH : %d\n", ret));
+			break;
+		}
+		ret = nla_put_u8(msg, BRCM_VENDOR_ATTR_ACS_HW_MODE, report.hw_mode);
+		if (ret < 0) {
+			WL_ERR(("ACS: Failed to put BRCM_VENDOR_ATTR_ACS_HW_MODE : %d\n", ret));
+			break;
+		}
+
+		cfg80211_vendor_event(msg, kflags);
+	}while(0);
+
+	if (ret < 0) {
+		WL_ERR(("ACS: failed : %d\n", ret));
+		if (msg){
+			dev_kfree_skb_any(msg);
+		}
+	}
+}
+
+static int
+wl_cfgvendor_acs_offload_init(struct bcm_cfg80211 *cfg, struct wireless_dev *wdev) {
+	gfp_t kflags;
+	acs_offload_work_t *acs = NULL;
+
+	kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
+	if (!cfg->acs_offload) {
+		cfg->acs_offload = kzalloc(sizeof(acs_offload_work_t), kflags);
+		if (!cfg->acs_offload) {
+			WL_ERR(("ACS: Failed to allocate acs_offload\n"));
+			return BCME_NOMEM;
+		}
+	}
+	else
+		cancel_delayed_work_sync(&cfg->acs_offload->work);
+
+	acs = cfg->acs_offload;
+	acs->selected = 0;
+	acs->wdev = wdev;
+	INIT_DELAYED_WORK(&acs->work, wl_cfgvendor_acs_offload_work_handler);
+	return BCME_OK;
+}
+
+static int
+wl_cfgvendor_acs_offload(struct wiphy *wiphy,
+        struct wireless_dev *wdev, const void  *data, int len)
+{
+	struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+	struct net_device *ndev = bcmcfg_to_prmry_ndev(cfg);
+	drv_acs_offload_params_t *params = NULL;
+	const struct nlattr *iter;
+	wl_uint32_list_t *list;
+
+	void *buf = NULL;
+	int rem, type, i;
+	int ret=BCME_OK;
+	int chosen = 0, retry=0, buflen=0;
+	int selected = 0, bw = 0;
+	int spect = 0;
+
+	if (wl_cfgvendor_acs_offload_init(cfg, wdev) != BCME_OK)
+		goto failed;
+
+	params = &cfg->acs_offload->parameter;
+
+	/* the structure reassembly */
+	nla_for_each_attr(iter, data, len, rem) {
+		type = nla_type(iter);
+		switch(type) {
+			case BRCM_VENDOR_ATTR_ACS_HW_MODE:
+				params->hw_mode = nla_get_u8(iter);
+				switch (params->hw_mode) {
+					case HOSTAPD_MODE_IEEE80211B:
+					case HOSTAPD_MODE_IEEE80211G:
+						params->band = WLC_BAND_2G;
+						break;
+					case HOSTAPD_MODE_IEEE80211A:
+						params->band = WLC_BAND_5G;
+						break;
+					case HOSTAPD_MODE_IEEE80211ANY:
+						params->band = WLC_BAND_AUTO;
+						break;
+					default :
+						params->band = WLC_BAND_INVALID;
+						break;
+				};
+				break;
+			case BRCM_VENDOR_ATTR_ACS_HT_ENABLED:
+				params->ht_enabled = nla_get_u8(iter);
+				break;
+			case BRCM_VENDOR_ATTR_ACS_HT40_ENABLED:
+				params->ht40_enabled = nla_get_u8(iter);
+				break;
+			case BRCM_VENDOR_ATTR_ACS_VHT_ENABLED:
+				params->vht_enabled = nla_get_u8(iter);
+				break;
+			case BRCM_VENDOR_ATTR_ACS_CHWIDTH:
+				params->ch_width = nla_get_u16(iter);
+				break;
+			case BRCM_VENDOR_ATTR_ACS_FREQ_LIST:
+				if (nla_len(iter)) {
+					params->channels = kzalloc(nla_len(iter), GFP_KERNEL);
+					bcopy((uint8 *)nla_data(iter), params->channels,
+						nla_len(iter));
+					params->chan_cnt = nla_len(iter) / sizeof(int);
+				}
+				break;
+		}
+	}
+
+	WL_INFORM_MEM(("ACS: hw_mode=%d, band=%d ht_enabled:%d,%d vht_enabled:%d ch_width:%d ch_cnt:%d\n",
+			params->hw_mode, params->band, params->ht_enabled , params->ht40_enabled,
+			params->vht_enabled, params->ch_width, params->chan_cnt));
+
+	/* if band of station and band for acs are same, use same chanspec to make SCC */
+	if ( wl_cfg80211_get_sta_channel(cfg) ) {
+		int chsp;
+		chanspec_t chspec;
+
+		ret = wldev_iovar_getint(ndev, "chanspec", &chsp);
+
+		if (ret != BCME_OK) {
+			WL_ERR(("Failed to get chanspec : %d\n", ret));
+			goto failed;
+		}
+		chspec = wl_chspec_driver_to_host(chsp);
+
+		if( (CHSPEC_IS2G(chspec) && params->band == WLC_BAND_2G) ||
+		    (CHSPEC_IS5G(chspec) && params->band == WLC_BAND_5G)) {
+			cfg->acs_offload->selected = chspec;
+			goto done;
+		}
+	}
+
+	/* Convert frequency to channel */
+
+	for (i=0;i<params->chan_cnt;++i){
+		params->channels[i] = ieee80211_frequency_to_channel(params->channels[i]);
+	}
+
+	buf = (u8 *)kzalloc(ACS_OFFLOAD_BUF_SIZE, GFP_KERNEL);
+	list = (wl_uint32_list_t *)buf;
+
+	for(i = 0;i<params->chan_cnt;++i) {
+		list->element[i] = wl_ch_host_to_driver(params->channels[i]);
+	}
+
+	ret = wldev_ioctl_get(ndev, WLC_GET_SPECT_MANAGMENT, &spect, sizeof(spect));
+	if (ret) {
+		WL_ERR(("ACS: error getting the spect, ret = %d\n",ret));
+		goto failed;
+	}
+
+	if (spect > 0) {
+	        ret = wl_cfg80211_set_spect(ndev, 0);
+		if (ret) {
+			WL_ERR(("ACS: error setting the spect, ret = %d\n",ret));
+			goto failed;
+		}
+	}
+
+	buflen = sizeof(uint32) * (list->count + 1);
+        ret = wldev_ioctl_set(ndev, WLC_START_CHANNEL_SEL, (void *)buf, buflen);
+        if (ret < 0) {
+                WL_ERR(("ACS: can't start ACS, err = %d\n", ret));
+                selected = 0;
+        }
+
+	if (params->band == WLC_BAND_AUTO)
+		OSL_SLEEP(1000);
+	else
+		OSL_SLEEP(500);
+
+	retry = ACS_MAX_RETRY;
+	while (retry--) {
+		ret = wldev_ioctl_get(ndev, WLC_GET_CHANNEL_SEL, &chosen,
+					sizeof(chosen));
+		if (ret < 0) {
+			chosen = 0;
+		} else {
+			chosen = dtoh32(chosen);
+		}
+
+		if (chosen) {
+			selected = CHSPEC_CHANNEL((chanspec_t)chosen);
+			WL_ERR(("ACS: Got the acs chan : %d\n",selected));
+			break;
+		}
+		OSL_SLEEP(250);
+	};
+
+	if (spect > 0) {
+	        ret = wl_cfg80211_set_spect(ndev, spect);
+		if (ret) {
+			WL_ERR(("ACS: error restoring the spect, ret = %d\n",ret));
+			goto failed;
+		}
+	}
+	goto done;
+failed:
+	if (params->chan_cnt) {
+		kfree(params->channels);
+		params->channels = NULL;
+		params->chan_cnt = 0;
+	}
+
+	if (params->band == WLC_BAND_2G)
+		selected = ACS_OFFLOAD_DEFAULT_CH_2G;
+	else {
+		selected = ACS_OFFLOAD_DEFAULT_CH_5G;
+
+done:
+	if (buf)
+		kfree(buf);
+	if (!cfg->acs_offload->selected) {
+		bw = ACS_OFFLOAD_DEFAULT_CH_2G;
+		if (params->ch_width == 80)
+			bw = WL_CHANSPEC_BW_80;
+		else if (params->ch_width == 40)
+			bw = WL_CHANSPEC_BW_40;
+		}
+		cfg->acs_offload->selected = wf_channel2chspec(selected, bw);
+	}
+
+	cfg->acs_offload->ndev = ndev;
+
+	schedule_delayed_work(&cfg->acs_offload->work,
+			msecs_to_jiffies((const unsigned int)ACS_OFFLOAD_DELAY));
+
+	return ret;
+}
+#endif // endif
+
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
 #define WL_VENDOR_POLICY_RAW_DATA .policy = VENDOR_CMD_RAW_DATA
+
+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},
+};
+
+const struct nla_policy andr_wifi_attr_policy[ANDR_WIFI_ATTRIBUTE_MAX] = {
+	[ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET] = {.type = NLA_U32},
+	[ANDR_WIFI_ATTRIBUTE_FEATURE_SET] = {.type = NLA_U32},
+	[ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI] = {.type = NLA_NUL_STRING, .len = 3},
+	[ANDR_WIFI_ATTRIBUTE_NODFS_SET] = {.type = NLA_U32},
+	[ANDR_WIFI_ATTRIBUTE_COUNTRY] = {.type = NLA_NUL_STRING, .len = 3},
+	[ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_VALUE] = {.type = NLA_U8},
+	[ANDR_WIFI_ATTRIBUTE_TCPACK_SUP_VALUE] = {.type = NLA_U32},
+	[ANDR_WIFI_ATTRIBUTE_LATENCY_MODE] = {.type = NLA_U32},
+	[ANDR_WIFI_ATTRIBUTE_RANDOM_MAC] = {.type = NLA_U32},
+	[ANDR_WIFI_ATTRIBUTE_TX_POWER_SCENARIO] = {.type = NLA_S8},
+	[ANDR_WIFI_ATTRIBUTE_THERMAL_MITIGATION] = {.type = NLA_S8},
+	[ANDR_WIFI_ATTRIBUTE_THERMAL_COMPLETION_WINDOW] = {.type = NLA_U32},
+	[ANDR_WIFI_ATTRIBUTE_VOIP_MODE] = {.type = NLA_U32},
+	[ANDR_WIFI_ATTRIBUTE_DTIM_MULTIPLIER] = {.type = NLA_U32},
+};
+#ifdef DHD_WAKE_STATUS
+const struct nla_policy wake_stat_attr_policy[WAKE_STAT_ATTRIBUTE_MAX] = {
+	[WAKE_STAT_ATTRIBUTE_TOTAL_CMD_EVENT] = {.type = NLA_U32},
+	[WAKE_STAT_ATTRIBUTE_CMD_EVENT_WAKE] = {.type = NLA_BINARY},
+	[WAKE_STAT_ATTRIBUTE_CMD_EVENT_COUNT] = {.type = NLA_U32},
+	[WAKE_STAT_ATTRIBUTE_CMD_EVENT_COUNT_USED] = {.type = NLA_U32},
+	[WAKE_STAT_ATTRIBUTE_TOTAL_DRIVER_FW] = {.type = NLA_U32},
+	[WAKE_STAT_ATTRIBUTE_DRIVER_FW_WAKE] = {.type = NLA_U32},
+	[WAKE_STAT_ATTRIBUTE_DRIVER_FW_COUNT] = {.type = NLA_U32},
+	[WAKE_STAT_ATTRIBUTE_DRIVER_FW_COUNT_USED] = {.type = NLA_U32},
+	[WAKE_STAT_ATTRIBUTE_TOTAL_RX_DATA_WAKE] = {.type = NLA_U32},
+	[WAKE_STAT_ATTRIBUTE_RX_UNICAST_COUNT] = {.type = NLA_U32},
+	[WAKE_STAT_ATTRIBUTE_RX_MULTICAST_COUNT] = {.type = NLA_U32},
+	[WAKE_STAT_ATTRIBUTE_RX_BROADCAST_COUNT] = {.type = NLA_U32},
+	[WAKE_STAT_ATTRIBUTE_RX_ICMP_PKT] = {.type = NLA_U32},
+	[WAKE_STAT_ATTRIBUTE_RX_ICMP6_PKT] = {.type = NLA_U32},
+	[WAKE_STAT_ATTRIBUTE_RX_ICMP6_RA] = {.type = NLA_U32},
+	[WAKE_STAT_ATTRIBUTE_RX_ICMP6_NA] = {.type = NLA_U32},
+	[WAKE_STAT_ATTRIBUTE_RX_ICMP6_NS] = {.type = NLA_U32},
+	[WAKE_STAT_ATTRIBUTE_IPV4_RX_MULTICAST_ADD_CNT] = {.type = NLA_U32},
+	[WAKE_STAT_ATTRIBUTE_IPV6_RX_MULTICAST_ADD_CNT] = {.type = NLA_U32},
+	[WAKE_STAT_ATTRIBUTE_OTHER_RX_MULTICAST_ADD_CNT] = {.type = NLA_U32},
+	[WAKE_STAT_ATTRIBUTE_RX_MULTICAST_PKT_INFO] = {.type = NLA_NESTED},
+};
+#endif /* DHD_WAKE_STATUS */
+
+const struct nla_policy gscan_attr_policy[GSCAN_ATTRIBUTE_MAX] = {
+	[GSCAN_ATTRIBUTE_BAND] = {.type = NLA_U32},
+	[GSCAN_ATTRIBUTE_NUM_CHANNELS] = {.type = NLA_U32},
+	[GSCAN_ATTRIBUTE_CHANNEL_LIST] = {.type = NLA_BINARY},
+	[GSCAN_ATTRIBUTE_WHITELIST_SSID] = {.type = NLA_BINARY},
+	[GSCAN_ATTRIBUTE_NUM_WL_SSID] = {.type = NLA_U32},
+	[GSCAN_ATTRIBUTE_WL_SSID_LEN] = {.type = NLA_U32},
+	[GSCAN_ATTRIBUTE_WL_SSID_FLUSH] = {.type = NLA_U32},
+	[GSCAN_ATTRIBUTE_WHITELIST_SSID_ELEM] = {.type = NLA_NESTED},
+	[GSCAN_ATTRIBUTE_NUM_BSSID] = {.type = NLA_U32},
+	[GSCAN_ATTRIBUTE_BSSID_PREF_LIST] = {.type = NLA_NESTED},
+	[GSCAN_ATTRIBUTE_BSSID_PREF_FLUSH] = {.type = NLA_U32},
+	[GSCAN_ATTRIBUTE_BSSID_PREF] = {.type = NLA_BINARY, .len = ETH_ALEN},
+	[GSCAN_ATTRIBUTE_RSSI_MODIFIER] = {.type = NLA_U32},
+	[GSCAN_ATTRIBUTE_BSSID_BLACKLIST_FLUSH] = {.type = NLA_U32},
+	[GSCAN_ATTRIBUTE_BLACKLIST_BSSID] = {.type = NLA_BINARY, .len = ETH_ALEN},
+	[GSCAN_ATTRIBUTE_ROAM_STATE_SET] = {.type = NLA_U32},
+};
+
+const struct nla_policy debug_attr_policy[DEBUG_ATTRIBUTE_MAX] = {
+	[DEBUG_ATTRIBUTE_GET_DRIVER] = {.type = NLA_BINARY},
+	[DEBUG_ATTRIBUTE_GET_FW] = {.type = NLA_BINARY},
+	[DEBUG_ATTRIBUTE_RING_ID] = {.type = NLA_U32},
+	[DEBUG_ATTRIBUTE_RING_NAME] = {.type = NLA_NUL_STRING},
+	[DEBUG_ATTRIBUTE_RING_FLAGS] = {.type = NLA_U32},
+	[DEBUG_ATTRIBUTE_LOG_LEVEL] = {.type = NLA_U32},
+	[DEBUG_ATTRIBUTE_LOG_TIME_INTVAL] = {.type = NLA_U32},
+	[DEBUG_ATTRIBUTE_LOG_MIN_DATA_SIZE] = {.type = NLA_U32},
+	[DEBUG_ATTRIBUTE_FW_DUMP_LEN] = {.type = NLA_U32},
+	[DEBUG_ATTRIBUTE_FW_DUMP_DATA] = {.type = NLA_U64},
+	[DEBUG_ATTRIBUTE_FW_ERR_CODE] = {.type = NLA_U32},
+	[DEBUG_ATTRIBUTE_RING_DATA] = {.type = NLA_BINARY},
+	[DEBUG_ATTRIBUTE_RING_STATUS] = {.type = NLA_BINARY},
+	[DEBUG_ATTRIBUTE_RING_NUM] = {.type = NLA_U32},
+	[DEBUG_ATTRIBUTE_DRIVER_DUMP_LEN] = {.type = NLA_U32},
+	[DEBUG_ATTRIBUTE_DRIVER_DUMP_DATA] = {.type = NLA_BINARY},
+	[DEBUG_ATTRIBUTE_PKT_FATE_NUM] = {.type = NLA_U32},
+	[DEBUG_ATTRIBUTE_PKT_FATE_DATA] = {.type = NLA_U64},
+	[DEBUG_ATTRIBUTE_HANG_REASON] = {.type = NLA_BINARY},
+};
+
+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},
+	[SET_HAL_START_ATTRIBUTE_EVENT_SOCK_PID] = {.type = NLA_U32},
+};
+
+const struct nla_policy rssi_monitor_attr_policy[RSSI_MONITOR_ATTRIBUTE_MAX] = {
+	[RSSI_MONITOR_ATTRIBUTE_MAX_RSSI] = { .type = NLA_U32 },
+	[RSSI_MONITOR_ATTRIBUTE_MIN_RSSI] = { .type = NLA_U32 },
+	[RSSI_MONITOR_ATTRIBUTE_START] = { .type = NLA_U32 }
+};
+
+const struct nla_policy mkeep_alive_attr_policy[MKEEP_ALIVE_ATTRIBUTE_MAX] = {
+	[MKEEP_ALIVE_ATTRIBUTE_ID] = {.type = NLA_U8},
+	[MKEEP_ALIVE_ATTRIBUTE_IP_PKT] = {.type = NLA_BINARY},
+	[MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN] = {.type = NLA_U16},
+	[MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR] = {.type = NLA_BINARY},
+	[MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR] = {.type = NLA_BINARY},
+	[MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC] = {.type = NLA_U32},
+	[MKEEP_ALIVE_ATTRIBUTE_ETHER_TYPE] = {.type = NLA_U16 }
+};
+
+const struct nla_policy chavoid_attr_policy[CHAVOID_ATTRIBUTE_MAX] = {
+	[CHAVOID_ATTRIBUTE_CNT] = {.type = NLA_U32},
+	[CHAVOID_ATTRIBUTE_MANDATORY] = {.type = NLA_U32},
+	[CHAVOID_ATTRIBUTE_CONFIG] = {.type = NLA_NESTED},
+	[CHAVOID_ATTRIBUTE_BAND] = {.type = NLA_U32},
+	[CHAVOID_ATTRIBUTE_CHANNEL] = {.type = NLA_U32},
+	[CHAVOID_ATTRIBUTE_PWRCAP] = {.type = NLA_U32},
+};
+
+const struct nla_policy usablech_attr_policy[USABLECHAN_ATTRIBUTE_MAX] = {
+	[USABLECHAN_ATTRIBUTE_BAND] = {.type = NLA_U32},
+	[USABLECHAN_ATTRIBUTE_IFACE] = {.type = NLA_U32},
+	[USABLECHAN_ATTRIBUTE_FILTER] = {.type = NLA_U32},
+	[USABLECHAN_ATTRIBUTE_MAX_SIZE] = {.type = NLA_U32},
+	[USABLECHAN_ATTRIBUTE_SIZE] = {.type = NLA_U32},
+	[USABLECHAN_ATTRIBUTE_CHANNELS] = {.type = NLA_BINARY},
+};
+
+const struct nla_policy multista_attr_policy[MULTISTA_ATTRIBUTE_MAX] = {
+	[MULTISTA_ATTRIBUTE_PRIM_CONN_IFACE] = { .type = NLA_NUL_STRING },
+	[MULTISTA_ATTRIBUTE_USE_CASE] = { .type = NLA_U32 },
+};
+
+#ifdef WL_SUPPORT_ACS_OFFLOAD
+const struct nla_policy acs_offload_attr_policy[BRCM_VENDOR_ATTR_ACS_LAST] = {
+        [BRCM_VENDOR_ATTR_ACS_CHANNEL_INVALID] = { .type = NLA_U8 },
+        [BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ] = { .type = NLA_U32 },
+        [BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ] = { .type = NLA_U32 },
+        [BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL] = { .type = NLA_U8 },
+        [BRCM_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL] = { .type = NLA_U8 },
+        [BRCM_VENDOR_ATTR_ACS_HW_MODE] = { .type = NLA_U8 },
+        [BRCM_VENDOR_ATTR_ACS_HT_ENABLED] = { .type = NLA_U8 },
+        [BRCM_VENDOR_ATTR_ACS_HT40_ENABLED] = { .type = NLA_U8 },
+        [BRCM_VENDOR_ATTR_ACS_VHT_ENABLED] = { .type = NLA_U8 },
+        [BRCM_VENDOR_ATTR_ACS_CHWIDTH] = { .type = NLA_U16 },
+        [BRCM_VENDOR_ATTR_ACS_CH_LIST] = { .type = NLA_BINARY },
+        [BRCM_VENDOR_ATTR_ACS_FREQ_LIST] = { .type = NLA_BINARY },
+};
+#endif // endif
+
 #else
 #define WL_VENDOR_POLICY_RAW_DATA
 #endif /* LINUX_VER >= 5.3 */
@@ -7928,7 +8636,10 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_priv_string_handler,
-		WL_VENDOR_POLICY_RAW_DATA
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = brcm_drv_attr_policy,
+		.maxattr = BRCM_ATTR_DRIVER_MAX
+#endif // endif
 	},
 #ifdef BCM_PRIV_CMD_SUPPORT
 	{
@@ -7938,7 +8649,10 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_priv_bcm_handler,
-		WL_VENDOR_POLICY_RAW_DATA
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = brcm_drv_attr_policy,
+		.maxattr = BRCM_ATTR_DRIVER_MAX
+#endif // endif
 	},
 #endif /* BCM_PRIV_CMD_SUPPORT */
 #ifdef WL_SAE
@@ -7949,10 +8663,12 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_set_sae_password,
-		WL_VENDOR_POLICY_RAW_DATA
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = brcm_drv_attr_policy,
+		.maxattr = BRCM_ATTR_DRIVER_MAX
+#endif // endif
 	},
 #endif /* WL_SAE */
-#ifdef GSCAN_SUPPORT
 	{
 		{
 			.vendor_id = OUI_GOOGLE,
@@ -7960,8 +8676,12 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_gscan_get_capabilities,
-		WL_VENDOR_POLICY_RAW_DATA
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = gscan_attr_policy,
+		.maxattr = BRCM_ATTR_DRIVER_MAX
+#endif // endif
 	},
+#ifdef GSCAN_SUPPORT
 	{
 		{
 			.vendor_id = OUI_GOOGLE,
@@ -8025,7 +8745,10 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_gscan_get_channel_list,
-		WL_VENDOR_POLICY_RAW_DATA
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy=gscan_attr_policy,
+		.maxattr=GSCAN_ATTRIBUTE_MAX
+#endif // endif
 	},
 #endif /* GSCAN_SUPPORT || DHD_GET_VALID_CHANNELS */
 #ifdef RTT_SUPPORT
@@ -8091,7 +8814,10 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_get_feature_set,
-		WL_VENDOR_POLICY_RAW_DATA
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = andr_wifi_attr_policy,
+		.maxattr = ANDR_WIFI_ATTRIBUTE_MAX
+#endif // endif
 	},
 	{
 		{
@@ -8100,7 +8826,10 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_get_feature_set_matrix,
-		WL_VENDOR_POLICY_RAW_DATA
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = andr_wifi_attr_policy,
+		.maxattr = ANDR_WIFI_ATTRIBUTE_MAX
+#endif // endif
 	},
 	{
 		{
@@ -8109,7 +8838,10 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_set_pno_rand_mac_oui,
-		WL_VENDOR_POLICY_RAW_DATA
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = andr_wifi_attr_policy,
+		.maxattr = ANDR_WIFI_ATTRIBUTE_MAX
+#endif // endif
 	},
 #ifdef CUSTOM_FORCE_NODFS_FLAG
 	{
@@ -8119,7 +8851,10 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_set_nodfs_flag,
-		WL_VENDOR_POLICY_RAW_DATA
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = andr_wifi_attr_policy,
+		.maxattr = ANDR_WIFI_ATTRIBUTE_MAX
+#endif // endif
 	},
 #endif /* CUSTOM_FORCE_NODFS_FLAG */
 	{
@@ -8129,9 +8864,11 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_set_country,
-		WL_VENDOR_POLICY_RAW_DATA
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = andr_wifi_attr_policy,
+		.maxattr = ANDR_WIFI_ATTRIBUTE_MAX
+#endif // endif
 	},
-#ifdef LINKSTAT_SUPPORT
 	{
 		{
 			.vendor_id = OUI_GOOGLE,
@@ -8141,8 +8878,6 @@
 		.doit = wl_cfgvendor_lstats_get_info,
 		WL_VENDOR_POLICY_RAW_DATA
 	},
-#endif /* LINKSTAT_SUPPORT */
-
 #ifdef GSCAN_SUPPORT
 	{
 		{
@@ -8191,7 +8926,10 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_set_ssid_whitelist,
-		WL_VENDOR_POLICY_RAW_DATA
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = gscan_attr_policy,
+		.maxattr = GSCAN_ATTRIBUTE_MAX
+#endif // endif
 
 	},
 	{
@@ -8201,7 +8939,10 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_set_bssid_blacklist,
-		WL_VENDOR_POLICY_RAW_DATA
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = gscan_attr_policy,
+		.maxattr = GSCAN_ATTRIBUTE_MAX
+#endif // endif
 	},
 #endif /* GSCAN_SUPPORT || ROAMEXP_SUPPORT */
 #ifdef ROAMEXP_SUPPORT
@@ -8212,7 +8953,10 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_set_fw_roaming_state,
-		WL_VENDOR_POLICY_RAW_DATA
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = gscan_attr_policy,
+		.maxattr = GSCAN_ATTRIBUTE_MAX
+#endif // endif
 	},
 	{
 		{
@@ -8231,7 +8975,10 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_dbg_get_version,
-		WL_VENDOR_POLICY_RAW_DATA
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = debug_attr_policy,
+		.maxattr = DEBUG_ATTRIBUTE_MAX
+#endif // endif
 	},
 #ifdef DHD_LOG_DUMP
 	{
@@ -8269,7 +9016,11 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_dbg_start_logging,
-		WL_VENDOR_POLICY_RAW_DATA
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = debug_attr_policy,
+		.maxattr = DEBUG_ATTRIBUTE_MAX
+#endif // endif
+
 	},
 	{
 		{
@@ -8287,7 +9038,10 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_dbg_get_ring_status,
-		WL_VENDOR_POLICY_RAW_DATA
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = debug_attr_policy,
+		.maxattr = DEBUG_ATTRIBUTE_MAX
+#endif // endif
 	},
 	{
 		{
@@ -8296,7 +9050,10 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_dbg_get_ring_data,
-		WL_VENDOR_POLICY_RAW_DATA
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = debug_attr_policy,
+		.maxattr = DEBUG_ATTRIBUTE_MAX
+#endif // endif
 	},
 	{
 		{
@@ -8307,7 +9064,6 @@
 		.doit = wl_cfgvendor_dbg_get_feature,
 		WL_VENDOR_POLICY_RAW_DATA
 	},
-#ifdef DBG_PKT_MON
 	{
 		{
 			.vendor_id = OUI_GOOGLE,
@@ -8315,7 +9071,10 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_dbg_start_pkt_fate_monitoring,
-		WL_VENDOR_POLICY_RAW_DATA
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = debug_attr_policy,
+		.maxattr = DEBUG_ATTRIBUTE_MAX
+#endif // endif
 	},
 	{
 		{
@@ -8324,7 +9083,10 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_dbg_get_tx_pkt_fates,
-		WL_VENDOR_POLICY_RAW_DATA
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = debug_attr_policy,
+		.maxattr = DEBUG_ATTRIBUTE_MAX
+#endif // endif
 	},
 	{
 		{
@@ -8333,9 +9095,11 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_dbg_get_rx_pkt_fates,
-		WL_VENDOR_POLICY_RAW_DATA
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = debug_attr_policy,
+		.maxattr = DEBUG_ATTRIBUTE_MAX
+#endif // endif
 	},
-#endif /* DBG_PKT_MON */
 #ifdef KEEP_ALIVE
 	{
 		{
@@ -8526,7 +9290,6 @@
 		WL_VENDOR_POLICY_RAW_DATA
 	},
 #endif /* PKT_FILTER_SUPPORT && APF */
-#ifdef NDO_CONFIG_SUPPORT
 	{
 		{
 			.vendor_id = OUI_GOOGLE,
@@ -8534,10 +9297,11 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_configure_nd_offload,
-		WL_VENDOR_POLICY_RAW_DATA
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = andr_wifi_attr_policy,
+		.maxattr = ANDR_WIFI_ATTRIBUTE_MAX
+#endif // endif
 	},
-#endif /* NDO_CONFIG_SUPPORT */
-#ifdef RSSI_MONITOR_SUPPORT
 	{
 		{
 			.vendor_id = OUI_GOOGLE,
@@ -8545,9 +9309,11 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_set_rssi_monitor,
-		WL_VENDOR_POLICY_RAW_DATA
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = rssi_monitor_attr_policy,
+		.maxattr = RSSI_MONITOR_ATTRIBUTE_MAX
+#endif // endif
 	},
-#endif /* RSSI_MONITOR_SUPPORT */
 #ifdef DHD_WAKE_STATUS
 	{
 		{
@@ -8556,7 +9322,10 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_get_wake_reason_stats,
-		WL_VENDOR_POLICY_RAW_DATA
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = wake_stat_attr_policy,
+		.maxattr = WAKE_STAT_ATTRIBUTE_MAX
+#endif // endif
 	},
 #endif /* DHD_WAKE_STATUS */
 #ifdef DHDTCPACK_SUPPRESS
@@ -8609,7 +9378,10 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_set_hal_started,
-		WL_VENDOR_POLICY_RAW_DATA
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = hal_start_attr_policy,
+		.maxattr = SET_HAL_START_ATTRIBUTE_MAX
+#endif // endif
 	},
 	{
 		{
@@ -8620,6 +9392,18 @@
 		.doit = wl_cfgvendor_stop_hal,
 		WL_VENDOR_POLICY_RAW_DATA
 	},
+	{
+		{
+			.vendor_id = OUI_GOOGLE,
+			.subcmd = DEBUG_SET_HAL_PID
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = wl_cfgvendor_set_hal_pid,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = hal_start_attr_policy,
+		.maxattr = SET_HAL_START_ATTRIBUTE_MAX
+#endif // endif
+	},
 #endif /* WL_CFG80211 */
 	{
 		{
@@ -8628,7 +9412,10 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_set_latency_mode,
-		WL_VENDOR_POLICY_RAW_DATA
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = andr_wifi_attr_policy,
+		.maxattr = ANDR_WIFI_ATTRIBUTE_MAX
+#endif // endif
 	},
 	{
 		{
@@ -8637,8 +9424,73 @@
 		},
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
 		.doit = wl_cfgvendor_set_tx_power_scenario,
-		WL_VENDOR_POLICY_RAW_DATA
-	}
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = andr_wifi_attr_policy,
+		.maxattr = ANDR_WIFI_ATTRIBUTE_MAX
+#endif // endif
+	},
+	{
+		{
+			.vendor_id = OUI_GOOGLE,
+			.subcmd = CHAVOID_SUBCMD_SET_CONFIG
+		},
+			.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+			.doit = wl_cfgvendor_chavoid_set_config,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+			.policy = chavoid_attr_policy,
+			.maxattr = CHAVOID_ATTRIBUTE_MAX
+#endif // endif
+	},
+	{
+		{
+			.vendor_id = OUI_GOOGLE,
+			.subcmd = WIFI_SUBCMD_USABLE_CHANNEL
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = wl_cfgvendor_usable_channel,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = usablech_attr_policy,
+		.maxattr = USABLECHAN_ATTRIBUTE_MAX
+#endif // endif
+	},
+	{
+		{
+			.vendor_id = OUI_GOOGLE,
+			.subcmd = WIFI_SUBCMD_SET_MULTISTA_PRIMARY_CONNECTION
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = wl_cfgvendor_set_multista_primary_connection,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = multista_attr_policy,
+		.maxattr = MULTISTA_ATTRIBUTE_MAX
+#endif // endif
+	},
+	{
+		{
+			.vendor_id = OUI_GOOGLE,
+			.subcmd = WIFI_SUBCMD_SET_MULTISTA_USE_CASE
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = wl_cfgvendor_set_multista_use_case,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = multista_attr_policy,
+		.maxattr = MULTISTA_ATTRIBUTE_MAX
+#endif // endif
+	},
+#ifdef WL_SUPPORT_ACS_OFFLOAD
+	{
+		{
+			.vendor_id = OUI_BRCM,
+			.subcmd = BRCM_VENDOR_SCMD_ACS
+		},
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+		.doit = wl_cfgvendor_acs_offload,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
+		.policy = acs_offload_attr_policy,
+		.maxattr = BRCM_VENDOR_ATTR_ACS_LAST
+#endif /* LINUX_VERSION >= 5.3 */
+	},
+#endif // endif
 
 };
 
@@ -8682,7 +9534,11 @@
 		{ OUI_BRCM, BRCM_VENDOR_EVENT_PORT_AUTHORIZED},
 		{ OUI_GOOGLE, GOOGLE_FILE_DUMP_EVENT },
 		{ OUI_BRCM, BRCM_VENDOR_EVENT_CU},
-		{ OUI_BRCM, BRCM_VENDOR_EVENT_WIPS}
+		{ OUI_BRCM, BRCM_VENDOR_EVENT_WIPS},
+		{ OUI_BRCM, NAN_ASYNC_RESPONSE_DISABLED},
+		{ OUI_BRCM, BRCM_VENDOR_EVENT_RCC_INFO},
+		{ OUI_BRCM, BRCM_VENDOR_EVENT_ACS},
+		{ OUI_BRCM, BRCM_VENDOR_EVENT_OVERTEMP},
 };
 
 int wl_cfgvendor_attach(struct wiphy *wiphy, dhd_pub_t *dhd)
@@ -8709,6 +9565,9 @@
 
 int wl_cfgvendor_detach(struct wiphy *wiphy)
 {
+#ifdef WL_SUPPORT_ACS_OFFLOAD
+	struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+#endif // endif
 	WL_INFORM_MEM(("Vendor: Unregister BRCM cfg80211 vendor interface \n"));
 
 	wiphy->vendor_commands  = NULL;
@@ -8716,6 +9575,10 @@
 	wiphy->n_vendor_commands = 0;
 	wiphy->n_vendor_events  = 0;
 
+#ifdef WL_SUPPORT_ACS_OFFLOAD
+	wl_cfgvendor_acs_offload_deinit(cfg->acs_offload);
+#endif // endif
+
 	return 0;
 }
 #endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(3, 13, 0)) || defined(WL_VENDOR_EXT_SUPPORT) */
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 233c6b1..05a4fee 100644
--- 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,7 +1,7 @@
 /*
  * Linux cfg80211 Vendor Extension Code
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -137,6 +137,37 @@
 	ANDROID_NL80211_SUBCMD_TX_POWER_RANGE_START = 0x1900,
 	ANDROID_NL80211_SUBCMD_TX_POWER_RANGE_END   = 0x1910,
 
+	/* define all thermal mode related commands between 0x1920 and 0x192F */
+	ANDROID_NL80211_SUBCMD_MITIGATION_RANGE_START = 0x1920,
+	ANDROID_NL80211_SUBCMD_MITIGATION_RANGE_END   = 0x192F,
+
+	/* define all DSCP related commands between 0x2000 and 0x20FF */
+	ANDROID_NL80211_SUBCMD_DSCP_RANGE_START =   0x2000,
+	ANDROID_NL80211_SUBCMD_DSCP_RANGE_END   =   0x20FF,
+
+	/* define all Channel Avoidance related commands between 0x2100 and 0x211F */
+	ANDROID_NL80211_SUBCMD_CHAVOID_RANGE_START =    0x2100,
+	ANDROID_NL80211_SUBCMD_CHAVOID_RANGE_END   =    0x211F,
+
+	/* define all OTA Download related commands between 0x2120 and 0x212F */
+	ANDROID_NL80211_SUBCMD_OTA_DOWNLOAD_START   = 0x2120,
+	ANDROID_NL80211_SUBCMD_OTA_DOWNLOAD_END     = 0x212F,
+
+	/* define all VOIP mode config related commands between 0x2130 and 0x213F */
+	ANDROID_NL80211_SUBCMD_VIOP_MODE_START =        0x2130,
+	ANDROID_NL80211_SUBCMD_VIOP_MODE_END =          0x213F,
+
+	/* define all TWT related commands between 0x2140 and 0x214F */
+	ANDROID_NL80211_SUBCMD_TWT_START =              0x2140,
+	ANDROID_NL80211_SUBCMD_TWT_END =                0x214F,
+
+	/* define all Usable Channel related commands between 0x2150 and 0x215F */
+	ANDROID_NL80211_SUBCMD_USABLE_CHANNEL_START =   0x2150,
+	ANDROID_NL80211_SUBCMD_USABLE_CHANNEL_END =     0x215F,
+
+	/* define all init/deinit related commands between 0x2160 and 0x216F */
+	ANDROID_NL80211_SUBCMD_INIT_DEINIT_RANGE_START = 0x2160,
+	ANDROID_NL80211_SUBCMD_INIT_DEINIT_RANGE_END   = 0x216F,
 	/* This is reserved for future usage */
 
 } ANDROID_VENDOR_SUB_COMMAND;
@@ -171,6 +202,11 @@
 	WIFI_SUBCMD_FW_ROAM_POLICY,
 	WIFI_SUBCMD_ROAM_CAPABILITY,
 	WIFI_SUBCMD_SET_LATENCY_MODE,     /*0x101b*/
+	WIFI_SUBCMD_SET_MULTISTA_PRIMARY_CONNECTION,
+	WIFI_SUBCMD_SET_MULTISTA_USE_CASE,
+	WIFI_SUBCMD_SET_DTIM_CONFIG,
+	GSCAN_SUBCMD_MAX,
+
 	RTT_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_RTT_RANGE_START,
 	RTT_SUBCMD_CANCEL_CONFIG,
 	RTT_SUBCMD_GETCAPABILITY,
@@ -198,31 +234,52 @@
 	DEBUG_FILE_DUMP_DONE_IND,
 	DEBUG_SET_HAL_START,
 	DEBUG_SET_HAL_STOP,
+	DEBUG_SET_HAL_PID,
 
 	WIFI_OFFLOAD_SUBCMD_START_MKEEP_ALIVE = ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START,
 	WIFI_OFFLOAD_SUBCMD_STOP_MKEEP_ALIVE,
 
 	NAN_WIFI_SUBCMD_ENABLE = ANDROID_NL80211_SUBCMD_NAN_RANGE_START,	 /* 0x1700 */
-	NAN_WIFI_SUBCMD_DISABLE,						 /* 0x1701 */
-	NAN_WIFI_SUBCMD_REQUEST_PUBLISH,					 /* 0x1702 */
-	NAN_WIFI_SUBCMD_REQUEST_SUBSCRIBE,					 /* 0x1703 */
-	NAN_WIFI_SUBCMD_CANCEL_PUBLISH,						 /* 0x1704 */
-	NAN_WIFI_SUBCMD_CANCEL_SUBSCRIBE,					 /* 0x1705 */
-	NAN_WIFI_SUBCMD_TRANSMIT,						 /* 0x1706 */
-	NAN_WIFI_SUBCMD_CONFIG,							 /* 0x1707 */
-	NAN_WIFI_SUBCMD_TCA,							 /* 0x1708 */
-	NAN_WIFI_SUBCMD_STATS,							 /* 0x1709 */
-	NAN_WIFI_SUBCMD_GET_CAPABILITIES,					 /* 0x170A */
-	NAN_WIFI_SUBCMD_DATA_PATH_IFACE_CREATE,					 /* 0x170B */
-	NAN_WIFI_SUBCMD_DATA_PATH_IFACE_DELETE,					 /* 0x170C */
-	NAN_WIFI_SUBCMD_DATA_PATH_REQUEST,					 /* 0x170D */
-	NAN_WIFI_SUBCMD_DATA_PATH_RESPONSE,					 /* 0x170E */
-	NAN_WIFI_SUBCMD_DATA_PATH_END,						 /* 0x170F */
-	NAN_WIFI_SUBCMD_DATA_PATH_SEC_INFO,					 /* 0x1710 */
-	NAN_WIFI_SUBCMD_VERSION_INFO,						 /* 0x1711 */
+	NAN_WIFI_SUBCMD_DISABLE,							/* 0x1701 */
+	NAN_WIFI_SUBCMD_REQUEST_PUBLISH,					/* 0x1702 */
+	NAN_WIFI_SUBCMD_REQUEST_SUBSCRIBE,					/* 0x1703 */
+	NAN_WIFI_SUBCMD_CANCEL_PUBLISH,						/* 0x1704 */
+	NAN_WIFI_SUBCMD_CANCEL_SUBSCRIBE,					/* 0x1705 */
+	NAN_WIFI_SUBCMD_TRANSMIT,							/* 0x1706 */
+	NAN_WIFI_SUBCMD_CONFIG,								/* 0x1707 */
+	NAN_WIFI_SUBCMD_TCA,								/* 0x1708 */
+	NAN_WIFI_SUBCMD_STATS,								/* 0x1709 */
+	NAN_WIFI_SUBCMD_GET_CAPABILITIES,					/* 0x170A */
+	NAN_WIFI_SUBCMD_DATA_PATH_IFACE_CREATE,				/* 0x170B */
+	NAN_WIFI_SUBCMD_DATA_PATH_IFACE_DELETE,				/* 0x170C */
+	NAN_WIFI_SUBCMD_DATA_PATH_REQUEST,					/* 0x170D */
+	NAN_WIFI_SUBCMD_DATA_PATH_RESPONSE,					/* 0x170E */
+	NAN_WIFI_SUBCMD_DATA_PATH_END,						/* 0x170F */
+	NAN_WIFI_SUBCMD_DATA_PATH_SEC_INFO,					/* 0x1710 */
+	NAN_WIFI_SUBCMD_VERSION_INFO,						/* 0x1711 */
+	NAN_SUBCMD_ENABLE_MERGE,							/* 0x1712 */
 	APF_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_START,
 	APF_SUBCMD_SET_FILTER,
+	APF_SUBCMD_READ_FILTER,
 	WIFI_SUBCMD_TX_POWER_SCENARIO = ANDROID_NL80211_SUBCMD_TX_POWER_RANGE_START, /*0x1900*/
+
+	WIFI_SUBCMD_THERMAL_MITIGATION = ANDROID_NL80211_SUBCMD_MITIGATION_RANGE_START,
+	DSCP_SUBCMD_SET_TABLE = ANDROID_NL80211_SUBCMD_DSCP_RANGE_START,
+	DSCP_SUBCMD_RESET_TABLE,
+	CHAVOID_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_CHAVOID_RANGE_START,
+
+	WIFI_SUBCMD_GET_OTA_CURRUNT_INFO = ANDROID_NL80211_SUBCMD_OTA_DOWNLOAD_START,
+	WIFI_SUBCMD_OTA_UPDATE,
+	WIFI_SUBCMD_CONFIG_VOIP_MODE = ANDROID_NL80211_SUBCMD_VIOP_MODE_START,
+
+	TWT_SUBCMD_GETCAPABILITY    = ANDROID_NL80211_SUBCMD_TWT_START,
+	TWT_SUBCMD_SETUP_REQUEST,
+	TWT_SUBCMD_TEAR_DOWN_REQUEST,
+	TWT_SUBCMD_INFO_FRAME_REQUEST,
+	TWT_SUBCMD_GETSTATS,
+	TWT_SUBCMD_CLR_STATS,
+	WIFI_SUBCMD_USABLE_CHANNEL = ANDROID_NL80211_SUBCMD_USABLE_CHANNEL_START,
+	WIFI_SUBCMD_TRIGGER_SSR = ANDROID_NL80211_SUBCMD_INIT_DEINIT_RANGE_START,
 	/* Add more sub commands here */
 	VENDOR_SUBCMD_MAX
 };
@@ -389,9 +446,13 @@
 };
 
 enum wifi_rssi_monitor_attr {
+#ifdef ANDROID12_SUPPORT
+	RSSI_MONITOR_ATTRIBUTE_INVALID,
+#endif // endif
 	RSSI_MONITOR_ATTRIBUTE_MAX_RSSI,
 	RSSI_MONITOR_ATTRIBUTE_MIN_RSSI,
-	RSSI_MONITOR_ATTRIBUTE_START
+	RSSI_MONITOR_ATTRIBUTE_START,
+	RSSI_MONITOR_ATTRIBUTE_MAX
 };
 
 enum wifi_sae_key_attr {
@@ -401,6 +462,9 @@
 };
 
 enum debug_attributes {
+#ifdef ANDROID12_SUPPORT
+	DEBUG_ATTRIBUTE_INVALID,
+#endif // endif
 	DEBUG_ATTRIBUTE_GET_DRIVER,
 	DEBUG_ATTRIBUTE_GET_FW,
 	DEBUG_ATTRIBUTE_RING_ID,
@@ -409,16 +473,19 @@
 	DEBUG_ATTRIBUTE_LOG_LEVEL,
 	DEBUG_ATTRIBUTE_LOG_TIME_INTVAL,
 	DEBUG_ATTRIBUTE_LOG_MIN_DATA_SIZE,
-	DEBUG_ATTRIBUTE_DUMP_FILENAME,
 	DEBUG_ATTRIBUTE_FW_DUMP_LEN,
 	DEBUG_ATTRIBUTE_FW_DUMP_DATA,
+	DEBUG_ATTRIBUTE_FW_ERR_CODE,
 	DEBUG_ATTRIBUTE_RING_DATA,
 	DEBUG_ATTRIBUTE_RING_STATUS,
 	DEBUG_ATTRIBUTE_RING_NUM,
 	DEBUG_ATTRIBUTE_DRIVER_DUMP_LEN,
 	DEBUG_ATTRIBUTE_DRIVER_DUMP_DATA,
 	DEBUG_ATTRIBUTE_PKT_FATE_NUM,
-	DEBUG_ATTRIBUTE_PKT_FATE_DATA
+	DEBUG_ATTRIBUTE_PKT_FATE_DATA,
+	DEBUG_ATTRIBUTE_HANG_REASON,
+	/* Add new attributes just above this */
+	DEBUG_ATTRIBUTE_MAX
 };
 
 typedef enum {
@@ -483,12 +550,17 @@
 } EWP_DUMP_CMD_ATTRIBUTE;
 
 enum mkeep_alive_attributes {
+#ifdef ANDROID12_SUPPORT
+	MKEEP_ALIVE_ATTRIBUTE_INVALID,
+#endif // endif
 	MKEEP_ALIVE_ATTRIBUTE_ID,
 	MKEEP_ALIVE_ATTRIBUTE_IP_PKT,
 	MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN,
 	MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR,
 	MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR,
-	MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC
+	MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC,
+	MKEEP_ALIVE_ATTRIBUTE_ETHER_TYPE,
+	MKEEP_ALIVE_ATTRIBUTE_MAX
 };
 
 typedef enum wl_vendor_event {
@@ -537,10 +609,18 @@
 	BRCM_VENDOR_EVENT_PORT_AUTHORIZED       = 36,
 	GOOGLE_FILE_DUMP_EVENT			= 37,
 	BRCM_VENDOR_EVENT_CU			= 38,
-	BRCM_VENDOR_EVENT_WIPS			= 39
+	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
 } wl_vendor_event_t;
 
 enum andr_wifi_attr {
+#ifdef ANDROID12_SUPPORT
+	ANDR_WIFI_ATTRIBUTE_INVALID,
+#endif // endif
 	ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET,
 	ANDR_WIFI_ATTRIBUTE_FEATURE_SET,
 	ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI,
@@ -550,8 +630,13 @@
 	ANDR_WIFI_ATTRIBUTE_TCPACK_SUP_VALUE,
 	ANDR_WIFI_ATTRIBUTE_LATENCY_MODE,
 	ANDR_WIFI_ATTRIBUTE_RANDOM_MAC,
-	ANDR_WIFI_ATTRIBUTE_TX_POWER_SCENARIO
+	ANDR_WIFI_ATTRIBUTE_TX_POWER_SCENARIO,
+	ANDR_WIFI_ATTRIBUTE_THERMAL_MITIGATION,
+	ANDR_WIFI_ATTRIBUTE_THERMAL_COMPLETION_WINDOW,
+	ANDR_WIFI_ATTRIBUTE_VOIP_MODE,
+	ANDR_WIFI_ATTRIBUTE_DTIM_MULTIPLIER,
 	//Add more attributes here
+	ANDR_WIFI_ATTRIBUTE_MAX
 };
 enum apf_attributes {
 	APF_ATTRIBUTE_VERSION,
@@ -591,6 +676,9 @@
 
 #ifdef DHD_WAKE_STATUS
 enum wake_stat_attributes {
+#ifdef ANDROID12_SUPPORT
+	WAKE_STAT_ATTRIBUTE_INVALID,
+#endif // endif
 	WAKE_STAT_ATTRIBUTE_TOTAL_CMD_EVENT,
 	WAKE_STAT_ATTRIBUTE_CMD_EVENT_WAKE,
 	WAKE_STAT_ATTRIBUTE_CMD_EVENT_COUNT,
@@ -610,7 +698,9 @@
 	WAKE_STAT_ATTRIBUTE_RX_ICMP6_NS,
 	WAKE_STAT_ATTRIBUTE_IPV4_RX_MULTICAST_ADD_CNT,
 	WAKE_STAT_ATTRIBUTE_IPV6_RX_MULTICAST_ADD_CNT,
-	WAKE_STAT_ATTRIBUTE_OTHER_RX_MULTICAST_ADD_CNT
+	WAKE_STAT_ATTRIBUTE_OTHER_RX_MULTICAST_ADD_CNT,
+	WAKE_STAT_ATTRIBUTE_RX_MULTICAST_PKT_INFO,
+	WAKE_STAT_ATTRIBUTE_MAX
 };
 
 typedef struct rx_data_cnt_details_t {
@@ -650,6 +740,77 @@
 } WLAN_DRIVER_WAKE_REASON_CNT;
 #endif /* DHD_WAKE_STATUS */
 
+typedef enum {
+	SET_HAL_START_ATTRIBUTE_DEINIT = 0x0001,
+	SET_HAL_START_ATTRIBUTE_PRE_INIT = 0x0002,
+	SET_HAL_START_ATTRIBUTE_EVENT_SOCK_PID = 0x0003,
+	SET_HAL_START_ATTRIBUTE_MAX
+} SET_HAL_START_ATTRIBUTE;
+
+typedef enum {
+    CHAVOID_ATTRIBUTE_INVALID   = 0,
+    CHAVOID_ATTRIBUTE_CNT       = 1,
+    CHAVOID_ATTRIBUTE_CONFIG    = 2,
+    CHAVOID_ATTRIBUTE_BAND      = 3,
+    CHAVOID_ATTRIBUTE_CHANNEL   = 4,
+    CHAVOID_ATTRIBUTE_PWRCAP    = 5,
+    CHAVOID_ATTRIBUTE_MANDATORY = 6,
+    CHAVOID_ATTRIBUTE_MAX
+} CHAVOID_ATTRIBUTE;
+
+typedef enum {
+    USABLECHAN_ATTRIBUTE_INVALID    = 0,
+    USABLECHAN_ATTRIBUTE_BAND       = 1,
+    USABLECHAN_ATTRIBUTE_IFACE      = 2,
+    USABLECHAN_ATTRIBUTE_FILTER     = 3,
+    USABLECHAN_ATTRIBUTE_MAX_SIZE   = 4,
+    USABLECHAN_ATTRIBUTE_SIZE       = 5,
+    USABLECHAN_ATTRIBUTE_CHANNELS   = 6,
+    USABLECHAN_ATTRIBUTE_MAX
+} USABLECHAN_ATTRIBUTE;
+
+typedef enum {
+        /**
+        * Usage:
+        * - This will be sent down for make before break use-case.
+        * - Platform is trying to speculatively connect to a second network and evaluate it without
+        *   disrupting the primary connection.
+        *
+        * Requirements for Firmware:
+        * - Do not reduce the number of tx/rx chains of primary connection.
+        * - If using MCC, should set the MCC duty cycle of the primary connection to be higher than
+        *   the secondary connection (maybe 70/30 split).
+        * - Should pick the best BSSID for the secondary STA (disregard the chip mode)
+        *   independent of the primary STA:
+        * - Don't optimize for DBS vs MCC/SCC
+        * - Should not impact the primary connections bssid selection:
+        * - Don't downgrade chains of the existing primary connection.
+        * - Don't optimize for DBS vs MCC/SCC.
+        */
+        WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY = 0,
+        /**
+        * Usage:
+        * - This will be sent down for any app requested peer to peer connections.
+        * - In this case, both the connections needs to be allocated equal resources.
+        * - For the peer to peer use case, BSSID for the secondary connection will be chosen by the
+        *   framework.
+        *
+        * Requirements for Firmware:
+        * - Can choose MCC or DBS mode depending on the MCC efficiency and HW capability.
+        * - If using MCC, set the MCC duty cycle of the primary connection to be equal to the
+        *   secondary connection.
+        * - Prefer BSSID candidates which will help provide the best "overall" performance for
+        *   both the connections.
+        */
+        WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED = 1
+} wifi_multi_sta_use_case;
+
+typedef enum {
+    MULTISTA_ATTRIBUTE_PRIM_CONN_IFACE,
+    MULTISTA_ATTRIBUTE_USE_CASE,
+    MULTISTA_ATTRIBUTE_MAX
+} MULTISTA_ATTRIBUTE;
+
 #ifdef WL_WIPSEVT
 #define BRCM_VENDOR_WIPS_EVENT_BUF_LEN	128
 typedef enum wl_vendor_wips_attr_type {
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 f8d72d1..43786b4 100644
--- 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,7 +1,7 @@
 /*
  * Linux roam cache
  *
- * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
  *
  * Copyright (C) 1999-2017, Broadcom Corporation
  *
@@ -56,7 +56,7 @@
 static int n_roam_cache = 0;
 static int roam_band = WLC_BAND_AUTO;
 static roam_channel_cache roam_cache[MAX_ROAM_CACHE];
-static uint band2G, band5G, band_bw;
+static uint band2G, band5G, band6G, band_bw;
 
 #ifdef WES_SUPPORT
 static int roamscan_mode = ROAMSCAN_MODE_NORMAL;
@@ -86,11 +86,13 @@
 	} else {
 		band2G = WL_CHANSPEC_BAND_2G;
 		band5G = WL_CHANSPEC_BAND_5G;
+		band6G = WL_CHANSPEC_BAND_6G;
 		band_bw = WL_CHANSPEC_BW_20;
 	}
 #else
 	band2G = WL_CHANSPEC_BAND_2G;
 	band5G = WL_CHANSPEC_BAND_5G;
+	band6G = WL_CHANSPEC_BAND_6G;
 	band_bw = WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE;
 #endif /* D11AC_IOTYPES */
 
@@ -248,7 +250,8 @@
 	channel = wf_chspec_ctlchan(bi->chanspec);
 	WL_DBG(("CHSPEC  = %s, CTL %d\n", wf_chspec_ntoa_ex(bi->chanspec, chanbuf), channel));
 	roam_cache[n_roam_cache].chanspec =
-		(channel <= CH_MAX_2G_CHANNEL ? band2G : band5G) | band_bw | channel;
+		(CHSPEC_IS6G(wl_chspec_driver_to_host(bi->chanspec))?
+		band6G : (channel <= CH_MAX_2G_CHANNEL ? band2G : band5G)) | band_bw | channel;
 	(void)memcpy_s(roam_cache[n_roam_cache].ssid, bi->SSID_len, bi->SSID, bi->SSID_len);
 
 	n_roam_cache++;
@@ -267,7 +270,8 @@
 }
 
 int get_roam_channel_list(int target_chan,
-	chanspec_t *channels, int n_channels, const wlc_ssid_t *ssid, int ioctl_ver)
+	chanspec_t *channels, int n_channels, const wlc_ssid_t *ssid, int ioctl_ver,
+	uint32 center_freq)
 {
 	int i, n = 1;
 	char chanbuf[CHANSPEC_STR_LEN];
@@ -275,7 +279,8 @@
 	/* first index is filled with the given target channel */
 	if (target_chan) {
 		channels[0] = (target_chan & WL_CHANSPEC_CHAN_MASK) |
-			(target_chan <= CH_MAX_2G_CHANNEL ? band2G : band5G) | band_bw;
+			(center_freq > FREQ_START_6G_CHANNEL ?
+			band6G : (target_chan <= CH_MAX_2G_CHANNEL ? band2G : band5G)) | band_bw;
 	} else {
 		/* If target channel is not provided, set the index to 0 */
 		n = 0;
@@ -289,11 +294,15 @@
 			chanspec_t ch = roam_cache[i].chanspec;
 			bool is_2G = ioctl_ver == 1 ? LCHSPEC_IS2G(ch) : CHSPEC_IS2G(ch);
 			bool is_5G = ioctl_ver == 1 ? LCHSPEC_IS5G(ch) : CHSPEC_IS5G(ch);
+			bool is_6G = CHSPEC_IS6G(ch);
 			bool band_match = ((roam_band == WLC_BAND_AUTO) ||
 				((roam_band == WLC_BAND_2G) && is_2G) ||
-				((roam_band == WLC_BAND_5G) && is_5G));
+				((roam_band == WLC_BAND_5G) && is_5G) ||
+				((roam_band == WLC_BAND_6G) && is_6G));
 
 			ch = CHSPEC_CHANNEL(ch) | (is_2G ? band2G : band5G) | band_bw;
+			ch = CHSPEC_CHANNEL(ch) |
+				(is_6G ? band6G : (is_2G ? band2G : band5G)) | band_bw;
 			if (band_match && !is_duplicated_channel(channels, n, ch)) {
 				WL_DBG(("%s: Chanspec = %s\n", __FUNCTION__,
 					wf_chspec_ntoa_ex(ch, chanbuf)));
@@ -313,11 +322,13 @@
 		chanspec_t ch = roam_cache[i].chanspec;
 		bool is_2G = ioctl_ver == 1 ? LCHSPEC_IS2G(ch) : CHSPEC_IS2G(ch);
 		bool is_5G = ioctl_ver == 1 ? LCHSPEC_IS5G(ch) : CHSPEC_IS5G(ch);
+		bool is_6G = CHSPEC_IS6G(ch);
 		bool band_match = ((roam_band == WLC_BAND_AUTO) ||
 			((roam_band == WLC_BAND_2G) && is_2G) ||
-			((roam_band == WLC_BAND_5G) && is_5G));
+			((roam_band == WLC_BAND_5G) && is_5G) ||
+			((roam_band == WLC_BAND_6G) && is_6G));
 
-		ch = CHSPEC_CHANNEL(ch) | (is_2G ? band2G : band5G) | band_bw;
+		ch = CHSPEC_CHANNEL(ch) | (is_6G ? band6G : (is_2G ? band2G : band5G)) | band_bw;
 		if ((roam_cache[i].ssid_len == ssid->SSID_len) &&
 			band_match && !is_duplicated_channel(channels, n, ch) &&
 			(memcmp(roam_cache[i].ssid, ssid->SSID, ssid->SSID_len) == 0)) {
@@ -418,14 +429,17 @@
 		chanspec_t ch = roam_cache[i].chanspec;
 		bool is_2G = ioctl_ver == 1 ? LCHSPEC_IS2G(ch) : CHSPEC_IS2G(ch);
 		bool is_5G = ioctl_ver == 1 ? LCHSPEC_IS5G(ch) : CHSPEC_IS5G(ch);
+		bool is_6G = CHSPEC_IS6G(ch);
 		bool band_match = ((roam_band == WLC_BAND_AUTO) ||
 			((roam_band == WLC_BAND_2G) && is_2G) ||
-			((roam_band == WLC_BAND_5G) && is_5G));
+			((roam_band == WLC_BAND_5G) && is_5G) ||
+			((roam_band == WLC_BAND_6G) && is_6G));
 
 		if ((roam_cache[i].ssid_len == ssid.SSID_len) &&
 			band_match && (memcmp(roam_cache[i].ssid, ssid.SSID, ssid.SSID_len) == 0)) {
 			/* match found, add it */
-			ch = CHSPEC_CHANNEL(ch) | (is_2G ? band2G : band5G) | band_bw;
+			ch = CHSPEC_CHANNEL(ch) |
+				(is_6G ? band6G : (is_2G ? band2G : band5G)) | band_bw;
 			add_roamcache_channel(&channel_list, ch);
 		}
 	}
@@ -464,8 +478,9 @@
 		for (n = 0; n < n_roam_cache; n++) {
 			chanspec_t ch = roam_cache[n].chanspec;
 			bool is_2G = ioctl_ver == 1 ? LCHSPEC_IS2G(ch) : CHSPEC_IS2G(ch);
+			bool is_6G = CHSPEC_IS6G(ch);
 			chanlist_before.channels[n] = CHSPEC_CHANNEL(ch) |
-				(is_2G ? band2G : band5G) | band_bw;
+				(is_6G ? band6G : (is_2G ? band2G : band5G)) | band_bw;
 		}
 	} else {
 		if (band == WLC_BAND_AUTO) {
@@ -484,9 +499,11 @@
 		chanspec_t chspec = chanlist_before.channels[i];
 		bool is_2G = ioctl_ver == 1 ? LCHSPEC_IS2G(chspec) : CHSPEC_IS2G(chspec);
 		bool is_5G = ioctl_ver == 1 ? LCHSPEC_IS5G(chspec) : CHSPEC_IS5G(chspec);
+		bool is_6G = CHSPEC_IS6G(chspec);
 		bool band_match = ((band == WLC_BAND_AUTO) ||
 				((band == WLC_BAND_2G) && is_2G) ||
-				((band == WLC_BAND_5G) && is_5G));
+				((band == WLC_BAND_5G) && is_5G) ||
+				((band == WLC_BAND_6G) && is_6G));
 		if (band_match) {
 			chanlist_after.channels[chanlist_after.n++] = chspec;
 		}