bcmdhd: DHD release for bcm4390, 2024.06.13 Version : 103.10.407.14

Bug: 346697036
Test: under testing in SVT

Change-Id: I8c2e42b0e04f3a3aacd3c5d67907db2acb4e011d
Signed-off-by: Dennis Jeon <[email protected]>
diff --git a/dhd_linux.c b/dhd_linux.c
index e62b30e..2318ef8 100644
--- a/dhd_linux.c
+++ b/dhd_linux.c
@@ -7808,7 +7808,8 @@
 		}
 	} while (ifidx--);
 
-	DHD_ERROR(("no entry found for %s\n", ndev->name));
+	/* if match not found, ndev may be freed. so avoid dereference */
+	DHD_ERROR(("no entry found for ndev ptr\n"));
 	return NULL;
 }
 
@@ -24859,7 +24860,8 @@
 	DHD_PRINT(("%s\n", __FUNCTION__));
 	ifp = dhd_get_ifp_by_ndev(dhdp, ndev);
 	if (ifp == NULL) {
-		DHD_ERROR(("DHD Iface Info corresponding to %s not found\n", ndev->name));
+		/* use ndev addr only for finding ifp, the ndev may be freed already */
+		DHD_ERROR(("DHD Iface Info not found for given ndev\n"));
 		return;
 	}
 
diff --git a/include/epivers.h b/include/epivers.h
index c11e314..025c61e 100644
--- a/include/epivers.h
+++ b/include/epivers.h
@@ -29,27 +29,27 @@
 
 #define EPI_RC_NUMBER		407
 
-#define EPI_INCREMENTAL_NUMBER	11
+#define EPI_INCREMENTAL_NUMBER	14
 
 #define EPI_BUILD_NUMBER	0
 
-#define EPI_VERSION		103, 10, 407, 11
+#define EPI_VERSION		103, 10, 407, 14
 
 #define EPI_VERSION_NUM		0x670a1970
 
-#define EPI_UNIQUE_NUM		0x670a1970b
+#define EPI_UNIQUE_NUM		0x670a1970e
 
 #define EPI_VERSION_DEV		103.10.407
 
 /* Driver Version String, ASCII, 32 chars max */
 #if defined (WLTEST)
-#define EPI_VERSION_STR		"103.10.407.11 (wlan=r1068979 WLTEST)"
+#define EPI_VERSION_STR		"103.10.407.14 (wlan=r1069799 WLTEST)"
 #elif (defined (BCMDBG_ASSERT) && \
 	!defined (BCMDBG_ASSERT_DISABLED) && \
 	!defined (ASSERT_FP_DISABLE))
-#define EPI_VERSION_STR		"103.10.407.11 (wlan=r1068979 ASSRT)"
+#define EPI_VERSION_STR		"103.10.407.14 (wlan=r1069799 ASSRT)"
 #else
-#define EPI_VERSION_STR		"103.10.407.11 (wlan=r1068979)"
+#define EPI_VERSION_STR		"103.10.407.14 (wlan=r1069799)"
 #endif /* BCMINTERNAL */
 
 /* Macros for coex firmware. */
@@ -57,17 +57,17 @@
 
 #define CXFW_MINOR_VERSION	6
 
-#define CXFW_RC_NUMBER		9
+#define CXFW_RC_NUMBER		12
 
 #define CXFW_INCREMENTAL_NUMBER	0
 
-#define CXFW_VERSION		2024, 6, 9, 0
+#define CXFW_VERSION		2024, 6, 12, 0
 
 #define CXFW_VERSION_NUM	0x670a1970
 
-#define CXFW_UNIQUE_NUM		0x670a1970b
+#define CXFW_UNIQUE_NUM		0x670a1970e
 
 /* COEX Firmware Version String, ASCII */
-#define CXFW_VERSION_STR	"2024.06.09 (coex=r1064907)"
+#define CXFW_VERSION_STR	"2024.06.12 (coex=r1064907)"
 
 #endif /* _epivers_h_ */
diff --git a/include/ftm_ioctl.h b/include/ftm_ioctl.h
index 2d62961..37b417a 100644
--- a/include/ftm_ioctl.h
+++ b/include/ftm_ioctl.h
@@ -131,6 +131,12 @@
 #define WL_FTM_SESSION_FLAG_PASSIVE_TB_RANGING	0x0000800000000000llu	/* Passive TB ranging */
 #define WL_FTM_SESSION_FLAG_ONE_WAY		0x0001000000000000llu	/* ONE_WAY RTT */
 #define WL_FTM_SESSION_FLAG_PASSIVE_STA		0x0002000000000000llu	/* Passive STA */
+#define WL_FTM_SESSION_FLAG_DONT_USE_SCAN_CACHE	0x0004000000000000llu	/* Don't use scan cache for
+									 * ranging scan
+									 */
+#define WL_FTM_SESSION_FLAG_DONT_SCAN		0x0008000000000000llu	/* Don't scan when both
+									 * peers are already known.
+									 */
 
 #define WL_FTM_SESSION_FLAG_ALL			0xffffffffffffffffllu
 typedef uint64 wl_ftm_session_flags_t;
@@ -152,7 +158,9 @@
 	| WL_FTM_SESSION_FLAG_AUTO_BURST \
 	| WL_FTM_SESSION_FLAG_NAN_BSS \
 	| WL_FTM_SESSION_FLAG_NO_TSF_SYNC \
-	| WL_FTM_SESSION_FLAG_CONT_ON_BURST_ERR)
+	| WL_FTM_SESSION_FLAG_CONT_ON_BURST_ERR \
+	| WL_FTM_SESSION_FLAG_DONT_USE_SCAN_CACHE \
+	| WL_FTM_SESSION_FLAG_DONT_SCAN)
 
 /* flags relevant to MC sessions */
 #define FTM_MC_CONFIG_MASK \
@@ -427,7 +435,9 @@
 	WL_FTM_TLV_ID_SECURITY_PASSPHRASE	= 1045, /* ftm security passphrase */
 	WL_FTM_TLV_ID_SECURITY_PASSPHRASE_LEN	= 1046, /* ftm security passphrase len */
 	WL_FTM_TLV_ID_SECURITY_CIPHER_TYPE	= 1047, /* ftm security cipher type */
-	WL_FTM_TLV_ID_SECURITY_LTF_REQD		= 1048	/* ftm security, secure ltf needed */
+	WL_FTM_TLV_ID_SECURITY_LTF_REQD		= 1048,	/* ftm security, secure ltf needed */
+
+	WL_FTM_TLV_ID_TX_COREMASK		= 1049	/* tx coremask for ranging frm tx */
 } wl_ftm_tlv_types_t;
 
 enum wl_ftm_wait_reason {
@@ -483,6 +493,10 @@
 	WL_FTM_TEST_MODE_FLAG_BAD_SAC		= 0x00000020u,
 	WL_FTM_TEST_MODE_FLAG_NULL_SAC		= 0x00000040u,
 	WL_FTM_TEST_MODE_FLAG_SKIP_LMR_TX	= 0x00000080u,
+	WL_FTM_TEST_MODE_FLAG_BAD_SLTF_SEQ	= 0x00000100u,
+	/* add new CTT device behavior here */
+	WL_FTM_TEST_MODE_FLAG_WFA_CTT_MASK	= 0x0000FFFFu,
+
 	/* for internal testing purpose */
 	WL_FTM_TEST_MODE_FLAG_TRAP_ON_CSI_TMO	= 0x00010000u,
 	WL_FTM_TEST_MODE_FLAG_NO_TS_IN_LMR	= 0x00020000u
@@ -702,7 +716,9 @@
 	uint16				sample_fmt;	/* format of rtt sample (TLV ID) */
 	chanspec_t			chanspec;	/* ranging chanspec */
 	wl_ftm_ranging_format_bw_t	format_bw;	/* format bw used for ranging */
-	uint8				pad[3];
+	uint8				i2r_sts;	/* initiator to responder spatial stream */
+	uint8				r2i_sts;	/* responder to initiator spatial stream */
+	uint8				pad;
 	uint8				rtt_samples[];	/* optional variable length fields */
 } wl_ftm_az_rtt_result_v2_t;
 
diff --git a/include/wlioctl.h b/include/wlioctl.h
index 64b8a8a..5e215c1 100644
--- a/include/wlioctl.h
+++ b/include/wlioctl.h
@@ -4149,7 +4149,7 @@
 #define OCL_DISABLED_EMLSR		(1u << 16u)  /* Disabled due to EMLSR enabled */
 #define OCL_DISABLED_BTBPHYWAR		(1u << 17u)  /* Disabled during BT eSCO traffic */
 #define OCL_DISABLED_SCCA_MIT		(1u << 18u)  /* Disabled when SCCA enabled, sccatxlbt=1 */
-
+#define OCL_DISABLED_BTMRC_USECASE	(1u << 19u)  /* Disabled when BT has MRC enabled */
 
 /* Bits for hw_status */
 #define OCL_HWCFG			0x01u   /* State of OCL config bit in phy HW */
@@ -10156,12 +10156,14 @@
  * If set - indicates that NAN initialization is successful
  * Bit 30:
  * If set - indicates that NAN MAC cfg creation is successful
- *
+ * Bit 29:
+ * If set - indicates that NAN disc msch registration type is start flex
  * NOTE: These are only ready-only bits for host.
  * All sets to these bits from host are masked off
  */
-#define WL_NAN_PROTO_INIT_DONE		(1u << 31u)
-#define WL_NAN_CFG_CREATE_DONE		(1u << 30u)
+#define WL_NAN_PROTO_INIT_DONE			(1u << 31u)
+#define WL_NAN_CFG_CREATE_DONE			(1u << 30u)
+#define WL_NAN_CTRL_FW_FLEX_REG_FOR_DISC	(1u << 29u)
 
 #define WL_NAN_GET_PROTO_INIT_STATUS(x) \
 		(((x) & WL_NAN_PROTO_INIT_DONE) ? TRUE:FALSE)
@@ -17496,7 +17498,7 @@
 	uint8 opt;
 	uint8 valid;
 	uint8 start;
-	uint8 PAD;
+	uint8 flags;
 	uint32 dur;	/* monitor duration in usec */
 	uint64 ts;	/* timestamp in usec */
 } wlc_dynsar_sts_obs_win_t;
@@ -17690,27 +17692,52 @@
 } dynsar_opt_profile_v1_t;
 
 typedef struct dynsar_opt_profile_v2 {
-	uint32 var_lim; /* variance limit */
-	uint32 var_off; /* hysterysis offset applied to variance while optimized */
-	uint8 pwr_off; /* power boost offset */
-	uint8 mode; /* DSA mode */
+	uint32 var_lim;		/* Variance limit				*/
+	uint32 var_off;		/* Variance Hysterysis while in optimized state */
+	uint8 pwr_off;		/* Power boost to SAR limit			*/
+	uint8 mode;		/* DSA mode					*/
 	/* optimization parameters */
-	uint8 opt_dur;     /* number of mon periods in future to predict optimization */
-	uint8 util_thrhd;  /* Max history utilization before turning off optimization */
-	uint8 util_mean;   /* Mean utilization percentage before turning off optimization */
+	uint8 opt_dur;		/* Tmon periods forecasted when optimized	*/
+	uint8 util_thrhd;	/* Averaged Ux before turning off optimization	*/
+	uint8 util_mean;	/* Mean     Ux before turning off optimization	*/
 	/* failsafe parameters */
-	uint8 fs;          /* historical util percentage to start failsafe */
-	uint8 util_mean_fs; /* Mean utilization to force failsafe */
-	uint8 avg_txdc_fs;   /* mean txdc threshold for failsafe */
-	/* txdc limits */
-	uint8 util_mean_ddc; /* mean utilization threshold to apply avg_txdc_th */
-	uint8 opt_txdc;    /* txdc cap when optimized */
-	uint8 avg_txdc_th;   /* mean txdc threshold for throttling txdc */
-	uint8 opt_txdc_tgt; /* target txdc */
-	uint8 twin; /* Twin in seconds */
+	uint8 fs;          	/* Historical Ux threshold triggering failsafe	*/
+	uint8 util_mean_fs;	/* Mean Ux threshold to trigger failsafe	*/
+	uint8 avg_txdc_fs;	/* Mean TxDC threshold for failsafe for util_mean_fs */
+	/* DDC parameters */
+	uint8 util_mean_ddc;	/* Mean Ux threshold to apply avg_txdc_th	*/
+	uint8 opt_txdc;		/* Static TxDC target limit when DSA is active	*/
+	uint8 avg_txdc_th;	/* Mean TxDC threshold for triggering DDC	*/
+	uint8 opt_txdc_tgt;	/* TxDC target limit when DDC is active		*/
+	uint8 twin;		/* Observation period duration in seconds	*/
 	uint8 pad[3];
 } dynsar_opt_profile_v2_t;
 
+typedef struct dynsar_opt_profile_v3 {
+	uint32 var_lim;		/* Variance limit				*/
+	uint32 var_off;		/* Variance Hysterysis while in optimized state	*/
+	uint8 pwr_off;		/* Power boost to SAR limit			*/
+	uint8 mode;		/* DSA mode					*/
+	/* optimization parameters */
+	uint8 opt_dur;		/* Tmon periods forecasted when not optimized	*/
+	uint8 util_thrhd;	/* Averaged Ux before turning off optimization	*/
+	uint8 util_mean;	/* Mean     Ux before turning off optimization	*/
+	/* failsafe parameters */
+	uint8 fs;          	/* Historical Ux threshold triggering failsafe	*/
+	uint8 util_mean_fs;	/* Mean Ux threshold to trigger failsafe	*/
+	uint8 avg_txdc_fs;	/* Mean TxDC threshold for failsafe for util_mean_fs */
+	/* DDC parameters */
+	uint8 util_mean_ddc;	/* Mean Ux threshold to apply avg_txdc_th	*/
+	uint8 opt_txdc;		/* Static TxDC target limit when DSA is active	*/
+	uint8 avg_txdc_th;	/* Mean TxDC threshold for triggering DDC	*/
+	uint8 opt_txdc_tgt;	/* TxDC target limit when DDC is active		*/
+	uint8 twin;		/* Observation period duration in seconds	*/
+	/* additional parameters */
+	uint8 util_med_opt;	/* Median Ux threshold for optimization		*/
+	uint8 opt_dur_opt;	/* Tmon periods forecasted when optimized	*/
+	uint8 pad;
+} dynsar_opt_profile_v3_t;
+
 typedef struct dynsar_opt_profiles_v1 {
 	uint16 ver;
 	uint16 len;	/* length of this structure */
@@ -17727,6 +17754,21 @@
 	dynsar_opt_profile_v2_t profiles[];
 } dynsar_opt_profiles_v2_t;
 
+typedef struct dynsar_opt_profiles_v3 {
+	uint16 ver;
+	uint16 len;	/* length of this structure */
+	uint16 active;  /* active profile */
+	uint16 num_profiles;  /* number of profiles in variable length below */
+	dynsar_opt_profile_v3_t profiles[];
+} dynsar_opt_profiles_v3_t;
+
+typedef struct dynsar_opt_profiles_hdr {
+	uint16 ver;
+	uint16 len;	/* length of this structure */
+	uint16 active;  /* active profile */
+	uint16 num_profiles;  /* number of profiles in variable length below */
+} dynsar_opt_profiles_hdr_t;
+
 typedef dynsar_opt_profiles_v2_t dynsar_opt_profiles_t;
 
 typedef struct wl_dynsar_ioc {
@@ -17735,16 +17777,17 @@
 	uint8 PAD[4];
 	union { /* var len payload */
 		uint8 cnt;
-		dynsar_cnt_v1_t det;
-		dynsar_cnt_v2_t detv2;
-		dynsar_cnt_v3_t detv3;
-		dynsar_agg_stat_t agg_stat;
-		dynsar_sum_v1_t sum;
-		dynsar_sum_v2_t sumv2;
-		dynsar_status_v3_t statusv3;
-		dynsar_var_info_t var;
+		dynsar_cnt_v1_t		 det;
+		dynsar_cnt_v2_t		 detv2;
+		dynsar_cnt_v3_t		 detv3;
+		dynsar_agg_stat_t	 agg_stat;
+		dynsar_sum_v1_t		 sum;
+		dynsar_sum_v2_t		 sumv2;
+		dynsar_status_v3_t	 statusv3;
+		dynsar_var_info_t	 var;
 		dynsar_opt_profiles_v1_t profiles;
 		dynsar_opt_profiles_v2_t profilesv2;
+		dynsar_opt_profiles_v3_t profilesv3;
 	} data;
 } wl_dynsar_ioc_t;
 
@@ -20544,6 +20587,29 @@
 	WL_FILS_XTLV_PMKID		= 0xb
 };
 
+#define WL_FILS_DISC_IOV_MAJOR_VER_SHIFT 8u
+
+#define WL_FILS_DISC_IOV_MAJOR_VER_1 1u
+#define WL_FILS_DISC_IOV_MINOR_VER_1 1u
+
+#define WL_FILS_DISC_IOV_VERSION_1_1 \
+	((WL_FILS_DISC_IOV_MAJOR_VER_1 \
+	<< WL_FILS_DISC_IOV_MAJOR_VER_SHIFT) | WL_FILS_DISC_IOV_MINOR_VER_1)
+
+enum wl_fils_disc_cmd_ids {
+	WL_FILS_DISC_CMD_VERSION	= 0u,
+	WL_FILS_DISC_CMD_ENABLE		= 1u,
+	WL_FILS_DISC_CMD_TX_PERIOD	= 2u,
+	WL_FILS_DISC_CMD_TX_DURATION	= 3u,
+	WL_FILS_DISC_CMD_LAST
+};
+
+enum wl_fils_disc_xtlv_id {
+	WL_FILS_DISC_XTLV_ENABLE	= 0x1u,
+	WL_FILS_DISC_XTLV_TX_PERIOD	= 0x2u,
+	WL_FILS_DISC_XTLV_TX_DURATION	= 0x3u
+};
+
 #define WL_OCE_IOV_MAJOR_VER_1 1
 #define WL_OCE_IOV_MINOR_VER_1 1
 #define WL_OCE_IOV_MAJOR_VER_SHIFT 8
@@ -26740,7 +26806,7 @@
 	uint8	sr_softrecovery_count;	    /* Critical region recoverable boot count */
 
 	uint32	sr_dbg02;		    /* not populated yet */
-	uint16	sr_dbg03;		    /* not populated yet */
+	uint16	sr_bootstat_bt;		    /* BT FW boot stat */
 	uint16	sr_dbg04;		    /* not populated yet */
 	uint8	sr_phy_crash_rc;	    /* Critical region crash reason code */
 	uint8	sr_phy_crash_boot_count;    /* Boot count when critical region crash happened */
@@ -26796,6 +26862,13 @@
 /* subcommand ids for phy_noise */
 enum wl_phy_noise_cmd_type {
 	WL_PHY_NOISE_CMD_LONG = 0u,	/* get noise profile */
+	WL_PHY_NOISE_CMD_KNOISE = 1u,			/* get knoise profile */
+	WL_PHY_NOISE_CMD_KNOISE_RETRYLIMIT = 2u,	/* get knoise profile */
+	WL_PHY_NOISE_CMD_KNOISE_RETRYTIMEOUT = 3u,	/* get knoise profile */
+	WL_PHY_NOISE_CMD_KNOISE_RETRYLIMIT_SCAN = 4u,	/* get knoise profile */
+	WL_PHY_NOISE_CMD_KNOISE_RETRYTIMEOUT_SCAN = 5u,	/* get knoise profile */
+	WL_PHY_NOISE_CMD_KNOISE_IRQ_EN = 6u,		/* get knoise profile */
+	WL_PHY_NOISE_CMD_KNOISE_BLANKING_EN = 7u,	/* get knoise profile */
 	WL_PHY_NOISE_CMD_LAST
 };
 
@@ -26806,11 +26879,23 @@
 	uint8   PAD[3];
 } wl_phy_noise_long_v1_t;
 
+typedef struct wl_phy_noise_knoise_v1 {
+	int32 noise_dBm;		/* knoise dBm */
+	uint8 hwknoise_retrylimit;
+	uint8 hwknoise_retrylimit_scan;
+	uint8 hwknoise_retrytimeout;
+	uint8 hwknoise_retrytimeout_scan;
+	bool  hwknoise_irq;
+	bool  hwknoise_blanking;
+	uint8 PAD[2];
+} wl_phy_noise_knoise_v1_t;
+
 typedef struct wl_phy_noise_v1 {
 	uint16  subcmd_version;		/* Version of the sub-command */
 	uint16  length;			/* Length of the particular struct being used in union */
 	union {
 		wl_phy_noise_long_v1_t long_v1;
+		wl_phy_noise_knoise_v1_t knoise_v1;
 	} u;
 } wl_phy_noise_v1_t;
 
diff --git a/include/wlioctl_counters.h b/include/wlioctl_counters.h
index 720d1af..2bf2ee9 100644
--- a/include/wlioctl_counters.h
+++ b/include/wlioctl_counters.h
@@ -3810,6 +3810,46 @@
 	uint16 fbaci_nsamples_idx3;	/* number of samples at index3 */
 	uint16 idle2fbc_cnt;		/* count of radio state changes from IDle to FBC */
 	uint16 idle2wlauxrx_cnt;	/* count of radio state changes from IDle to Aux Ded Rx. */
+	uint32 fbcx_ovd_cnt;		/* FBC override cnt */
+	uint32 fbcx_ovd_dur;		/* FBC override duration */
+	uint32 fbcx_bt_forced_fbc_cnt;	/* bt fored fbc cnt */
+	uint32 fbcx_bt_forced_fbc_dur;	/* bt forced fbc_dur */
+	uint32 fbcx_bt_auto_fbc_cnt;	/* bt auto fbc cnt */
+	uint32 fbcx_act_cfg;		/* bt act cfg mask to put bt in fbc */
+	uint8 fbaci_acipwr_cdf_idx_c0_ch0;
+	/* core0, channel0 histogram index of  2% ACI power */
+	uint8 fbaci_acipwr_cdf_idx_c1_ch0;
+	/* core1, channel0 histogram index of  2% ACI power */
+	uint16 fbaci_acipwr_cdf_cnt_c0_ch0;
+	/* core0, channel0 histogram count of ACI power (2%) */
+	uint16 fbaci_acipwr_cdf_cnt_c1_ch0;
+	/* core1, channel0 histogram count of ACI power (2%) */
+	uint8 fbaci_acipwr_cdf_idx_c0_ch1;
+	/* core0, channel1 histogram index of  2% ACI power */
+	uint8 fbaci_acipwr_cdf_idx_c1_ch1;
+	/* core1, channel1 histogram index of  2% ACI power */
+	uint16 fbaci_acipwr_cdf_cnt_c0_ch1;
+	/* core0, channel1 histogram count of ACI power (2%) */
+	uint16 fbaci_acipwr_cdf_cnt_c1_ch1;
+	/* core1, channel1 histogram count of ACI power (2%) */
+	uint8 fbaci_acipwr_cdf_idx_c0_ch2;
+	/* core0, channel2 histogram index of  2% ACI power */
+	uint8 fbaci_acipwr_cdf_idx_c1_ch2;
+	/* core1, channel2 histogram index of  2% ACI power */
+	uint16 fbaci_acipwr_cdf_cnt_c0_ch2;
+	/* core0, channel2 histogram count of ACI power (2%) */
+	uint16 fbaci_acipwr_cdf_cnt_c1_ch2;
+	/* core1, channel2 histogram count of ACI power (2%) */
+	uint8 fbaci_acipwr_cdf_idx_c0_ch3;
+	/* core0, channel3 histogram index of  2% ACI power */
+	uint8 fbaci_acipwr_cdf_idx_c1_ch3;
+	/* core1, channel3 histogram index of  2% ACI power */
+	uint16 fbaci_acipwr_cdf_cnt_c0_ch3;
+	/* core0, channel3 histogram count of ACI power (2%) */
+	uint16 fbaci_acipwr_cdf_cnt_c1_ch3;
+	/* core1, channel3 histogram count of ACI power (2%) */
+	uint32 fbagc_fbc_gain_stuck_cnt;
+	/* fbc gain stuck counter */
 } wlc_btc_stats_v13_t;
 
 #define BTCX_STATS_VER_12 12
diff --git a/include/wlioctl_defs.h b/include/wlioctl_defs.h
index 2f8d03a..13867b8 100644
--- a/include/wlioctl_defs.h
+++ b/include/wlioctl_defs.h
@@ -1485,6 +1485,7 @@
 #define WL_DYNBW_DBG_VAL	0x00000020
 #define WL_RATE_INFO_VAL	0x00000040
 #define WL_RATE_TRACE_VAL	0x00000080
+#define WL_KM_INFO_VAL		0x00000100
 
 /* number of bytes needed to define a proper bit mask for MAC event reporting */
 #define BCMIO_ROUNDUP(x, y)	((((x) + ((y) - 1)) / (y)) * (y))
@@ -3447,6 +3448,7 @@
 #define WL_DBG_CRSH_TYPE_SR_RXIQCAL1			0x51u
 #define WL_DBG_CRSH_TYPE_SR_TEMP0			0x60u
 #define WL_DBG_CRSH_TYPE_SR_TEMP1			0x61u
+#define WL_DBG_CRSH_TYPE_SR_TEMP2			0x62u
 #define WL_DBG_CRSH_TYPE_SR_FULLCAL0			0x70u
 #define WL_DBG_CRSH_TYPE_SR_FULLCAL1			0x71u
 #define WL_DBG_CRSH_TYPE_SR_MPCAL0			0x80u
diff --git a/wl_cfg80211.c b/wl_cfg80211.c
index 217e4f8..1b6236b 100644
--- a/wl_cfg80211.c
+++ b/wl_cfg80211.c
@@ -14851,6 +14851,9 @@
 {
 	s32 ret = BCME_OK;
 	dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub);
+#ifndef BCMSUP_4WAY_HANDSHAKE
+	struct wl_security *sec = wl_read_prof(cfg, as->ndev, WL_PROF_SEC);
+#endif /* BCMSUP_4WAY_HANDSHAKE */
 
 	if (cfg->roam_offload) {
 		/* roam offload enabled, avoid roam events to wake up host */
@@ -14878,14 +14881,20 @@
 
 #if defined(DHD_LOSSLESS_ROAMING) || defined(WLFBT)
 	{
-		struct wl_security *sec = wl_read_prof(cfg,
-				as->ndev, WL_PROF_SEC);
+#ifdef BCMSUP_4WAY_HANDSHAKE
+		wl_bss_roaming_done(cfg, as->ndev, as->event_msg, as->data);
+#else
 		 /* For FT cases roaming done will be called in ROAM/BSSID
 		 * event context and we should avoid here in LINK_UP context
+		 * to ensure key data is all available for external supp
 		 */
 		if (!IS_AKM_SUITE_FT(sec) && !IS_AKM_SUITE_SAE_FT(sec)) {
 			wl_bss_roaming_done(cfg, as->ndev, as->event_msg, as->data);
+		} else {
+			WL_INFORM_MEM(("execute roaming done from WLC_E_BSSID/ROAM for FT AKMs."
+				"wpa_auth:0x%x\n", sec->wpa_auth));
 		}
+#endif /* BCMSUP_4WAY_HANDSHAKE */
 	}
 #endif /* DHD_LOSSLESS_ROAMING || WLFBT */
 
@@ -15511,6 +15520,7 @@
 			 * here only if WLC_E_LINK event is blocked for specific
 			 * security type.
 			 */
+#ifndef BCMSUP_4WAY_HANDSHAKE
 			if (IS_AKM_SUITE_FT(sec) || IS_AKM_SUITE_SAE_FT(sec)) {
 				wl_bss_roaming_done(cfg, ndev, e, data);
 #ifdef BCMDONGLEHOST
@@ -15518,6 +15528,7 @@
 				dhd_dump_mod_pkt_timer(dhdp, PKT_CNT_RSN_ROAM);
 #endif /* BCMDONGLEHOST */
 			}
+#endif /* BCMSUP_4WAY_HANDSHAKE */
 			/* Roam timer is deleted mostly from wl_cfg80211_change_station
 			 * after roaming is finished successfully. We need to delete
 			 * the timer from here only for some security types that aren't
@@ -16990,6 +17001,9 @@
 		WL_INFORM_MEM(("[%s] Report connect result - "
 			"connection succeeded\n", ndev->name));
 
+	} else {
+		WL_INFORM_MEM(("[%s] Report connection failure. status:%d auth_assoc_stat:%d\n",
+			ndev->name, status, sec->auth_assoc_res_status));
 	}
 
 exit:
diff --git a/wl_cfgvendor.c b/wl_cfgvendor.c
index 4747a5c..34f7fcc 100644
--- a/wl_cfgvendor.c
+++ b/wl_cfgvendor.c
@@ -9268,6 +9268,7 @@
 	u8 link_idx, u8 link_id, char **output, uint *total_len)
 {
 	static char iovar_buf[WLC_IOCTL_MAXLEN];
+	static char rate_iovar_buf[WLC_IOCTL_MAXLEN];
 	wifi_rate_stat_v1 *p_wifi_rate_stat_v1 = NULL;
 	wifi_rate_stat *p_wifi_rate_stat = NULL;
 	dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub);
@@ -9284,7 +9285,6 @@
 	chanspec_t chanspec = INVCHANSPEC;
 	bss_peer_list_info_t *peer_list_info;
 	wl_bssload_t *bssload;
-	uint32 rspec = 0;
 
 	COMPAT_STRUCT_IFACE(wifi_link_stat, iface);
 
@@ -9437,18 +9437,26 @@
 	}
 
 	if ((err == BCME_OK) && (peer_list_info && peer_list_info->count > 0)) {
-		err = wldev_link_iovar_getint(inet_ndev, link_idx, "nrate", (int*)&rspec);
+		err = wldev_link_iovar_getbuf(inet_ndev, link_idx, "ratestat", NULL, 0,
+			rate_iovar_buf, WLC_IOCTL_MAXLEN, NULL);
 		if (err != BCME_OK) {
-			WL_ERR(("Error (%d) in getting nrate\n", err));
+			WL_ERR(("failed to fetch the rate_stat: error (%d)\n", err));
+			goto exit;
+		}
+		p_wifi_rate_stat = (wifi_rate_stat *)rate_iovar_buf;
+		if (p_wifi_rate_stat->version != WLC_LINKSTATS_RATESTATS_V1) {
+			err = BCME_VERSION;
 			goto exit;
 		}
 
-		if (WL_CFG_RSPEC_ISEHT(rspec)) {
-			num_rate = NUM_RATE;
-		} else {
-			num_rate = NUM_RATE_NONBE;
+		if (p_wifi_rate_stat->length < sizeof(*p_wifi_rate_stat)) {
+			err = BCME_BADLEN;
+			goto exit;
 		}
-		WL_DBG_MEM(("num_rate %d\n", num_rate));
+
+		num_rate = p_wifi_rate_stat->length/sizeof(*p_wifi_rate_stat);
+		WL_INFORM_MEM(("num_rate %d\n", num_rate));
+
 		COMPAT_ASSIGN_VALUE(iface, peer_info->num_rate, num_rate);
 	}
 
@@ -9472,15 +9480,9 @@
 	COMPAT_MEMCOPY_IFACE(*output, *total_len, wifi_link_stat, iface, wifi_rate_stat_v1);
 
 	if ((err == BCME_OK) && (peer_list_info && peer_list_info->count > 0)) {
-		err = wldev_link_iovar_getbuf(inet_ndev, link_idx, "ratestat", NULL, 0,
-			iovar_buf, WLC_IOCTL_MAXLEN, NULL);
-		if (err != BCME_OK && err != BCME_UNSUPPORTED) {
-			WL_ERR(("error (%d) - size = %zu\n", err, num_rate*sizeof(wifi_rate_stat)));
-			goto exit;
-		}
 		for (i = 0; i < num_rate; i++) {
 			p_wifi_rate_stat =
-				(wifi_rate_stat *)(iovar_buf + i*sizeof(wifi_rate_stat));
+				(wifi_rate_stat *)(rate_iovar_buf + i*sizeof(wifi_rate_stat));
 			p_wifi_rate_stat_v1 = (wifi_rate_stat_v1 *)*output;
 			p_wifi_rate_stat_v1->rate.preamble = p_wifi_rate_stat->rate.preamble;
 			p_wifi_rate_stat_v1->rate.nss = p_wifi_rate_stat->rate.nss;