qcacld-3.0: Add BSS status caching

Add BSS status caching to get the BSS Information
when disconnect happens.

Change-Id: I41b74700b161277bc454d8bb8978f4e1e92faea8
CRs-Fixed: 1013475
diff --git a/core/cds/inc/cds_api.h b/core/cds/inc/cds_api.h
index 9e9774f..8c3932b 100644
--- a/core/cds/inc/cds_api.h
+++ b/core/cds/inc/cds_api.h
@@ -91,6 +91,32 @@
 enum cds_driver_state cds_get_driver_state(void);
 
 /**
+ * cds_get_u16()- get 16 bit data in little endian
+ * @ptr: buffer that holds data
+ *
+ * Return: uint16_t data in little endian format
+ */
+static inline uint16_t cds_get_u16(uint8_t *ptr)
+{
+	return ((uint16_t) (*(ptr+1) << 8)) |
+		((uint16_t) (*ptr));
+}
+
+/**
+ * cds_get_u32()- get 32 bit data in little endian
+ * @ptr: buffer that holds data
+ *
+ * Return: uint32_t data in little endian format
+ */
+static inline uint32_t cds_get_u32(uint8_t *ptr)
+{
+	return (*(ptr+3) << 24) |
+		(*(ptr+2) << 16) |
+		(*(ptr+1) << 8) |
+		(*(ptr));
+}
+
+/**
  * cds_is_driver_loading() - Is driver load in progress
  *
  * Return: true if driver is loading and false otherwise.
diff --git a/core/hdd/inc/wlan_hdd_assoc.h b/core/hdd/inc/wlan_hdd_assoc.h
index 78f9005..24b2871 100644
--- a/core/hdd/inc/wlan_hdd_assoc.h
+++ b/core/hdd/inc/wlan_hdd_assoc.h
@@ -39,6 +39,8 @@
 #include <wlan_defs.h>
 #include "ol_txrx_ctrl_api.h"
 #include "cdp_txrx_peer_ops.h"
+#include <net/cfg80211.h>
+#include <linux/ieee80211.h>
 
 /* Preprocessor Definitions and Constants */
 #ifdef FEATURE_WLAN_TDLS
@@ -93,6 +95,56 @@
 } ePeerStatus;
 
 /**
+ * struct hdd_conn_flag - connection flags
+ * @ht_present: ht element present or not
+ * @vht_present: vht element present or not
+ * @hs20_present: hs20 element present or not
+ */
+struct hdd_conn_flag {
+	uint8_t ht_present:1;
+	uint8_t vht_present:1;
+	uint8_t hs20_present:1;
+	uint8_t ht_op_present:1;
+	uint8_t vht_op_present:1;
+	uint8_t reserved:3;
+};
+
+/*defines for tx_BF_cap_info */
+#define TX_BF_CAP_INFO_TX_BF			0x00000001
+#define TX_BF_CAP_INFO_RX_STAG_RED_SOUNDING	0x00000002
+#define TX_BF_CAP_INFO_TX_STAG_RED_SOUNDING	0x00000004
+#define TX_BF_CAP_INFO_RX_ZFL			0x00000008
+#define TX_BF_CAP_INFO_TX_ZFL			0x00000010
+#define TX_BF_CAP_INFO_IMP_TX_BF		0x00000020
+#define TX_BF_CAP_INFO_CALIBRATION		0x000000c0
+#define TX_BF_CAP_INFO_CALIBRATION_SHIFT	6
+#define TX_BF_CAP_INFO_EXP_CSIT_BF		0x00000100
+#define TX_BF_CAP_INFO_EXP_UNCOMP_STEER_MAT	0x00000200
+#define TX_BF_CAP_INFO_EXP_BF_CSI_FB		0x00001c00
+#define TX_BF_CAP_INFO_EXP_BF_CSI_FB_SHIFT	10
+#define TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT	0x0000e000
+#define TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT_SHIFT 13
+#define TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB	0x00070000
+#define TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB_SHIFT 16
+#define TX_BF_CAP_INFO_CSI_NUM_BF_ANT		0x00180000
+#define TX_BF_CAP_INFO_CSI_NUM_BF_ANT_SHIFT	18
+#define TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT	0x00600000
+#define TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT_SHIFT 20
+#define TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT	0x01800000
+#define TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT_SHIFT 22
+#define TX_BF_CAP_INFO_RSVD			0xfe000000
+
+/* defines for antenna selection info */
+#define ANTENNA_SEL_INFO			0x01
+#define ANTENNA_SEL_INFO_EXP_CSI_FB_TX		0x02
+#define ANTENNA_SEL_INFO_ANT_ID_FB_TX		0x04
+#define ANTENNA_SEL_INFO_EXP_CSI_FB		0x08
+#define ANTENNA_SEL_INFO_ANT_ID_FB		0x10
+#define ANTENNA_SEL_INFO_RX_AS			0x20
+#define ANTENNA_SEL_INFO_TX_SOUNDING_PPDU	0x40
+#define ANTENNA_SEL_INFO_RSVD			0x80
+
+/**
  * typedef connection_info_t - structure to store connection information
  * @connState: connection state of the NIC
  * @connDot11DesiredBssType: BSS type of the current connection.
@@ -115,6 +167,16 @@
  * @gtk_installed: gtk installed state
  * @nss: number of spatial streams negotiated
  * @rate_flags: rate flags for current connection
+ * @freq: channel frequency
+ * @txrate: txrate structure holds nss & datarate info
+ * @noise: holds noise information
+ * @ht_caps: holds ht capabilities info
+ * @vht_caps: holds vht capabilities info
+ * @hs20vendor_ie: holds passpoint/hs20 info
+ * @hdd_conn_flag: flag conn info params is present or not
+ * @roam_count: roaming counter
+ * @signal: holds rssi info
+ * @assoc_status_code: holds assoc fail reason
  */
 typedef struct connection_info_s {
 	eConnectionState connState;
@@ -135,6 +197,18 @@
 	bool gtk_installed;
 	uint8_t nss;
 	uint32_t rate_flags;
+	uint32_t freq;
+	struct rate_info txrate;
+	int8_t noise;
+	struct ieee80211_ht_cap ht_caps;
+	struct ieee80211_vht_cap vht_caps;
+	struct hdd_conn_flag conn_flag;
+	tDot11fIEhs20vendor_ie hs20vendor_ie;
+	struct ieee80211_ht_operation ht_operation;
+	struct ieee80211_vht_operation vht_operation;
+	uint32_t roam_count;
+	int8_t signal;
+	int32_t assoc_status_code;
 } connection_info_t;
 
 /* Forward declarations */
diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c
index 06cd0c4..103a369 100644
--- a/core/hdd/src/wlan_hdd_assoc.c
+++ b/core/hdd/src/wlan_hdd_assoc.c
@@ -53,6 +53,7 @@
 #include "wlan_hdd_lpass.h"
 #include <cds_sched.h>
 #include "cds_concurrency.h"
+#include <cds_utils.h>
 #include "sme_power_save_api.h"
 #include "ol_txrx_ctrl_api.h"
 #include "ol_txrx_types.h"
@@ -376,6 +377,485 @@
 }
 
 /**
+ * hdd_copy_vht_caps()- copy vht caps info from roam info to
+ *  hdd station context.
+ * @hdd_sta_ctx: pointer to hdd station context
+ * @roam_info: pointer to roam info
+ *
+ * Return: None
+ */
+static void hdd_copy_ht_caps(hdd_station_ctx_t *hdd_sta_ctx,
+				     tCsrRoamInfo *roam_info)
+{
+	tDot11fIEHTCaps *roam_ht_cap = &roam_info->ht_caps;
+	struct ieee80211_ht_cap *hdd_ht_cap = &hdd_sta_ctx->conn_info.ht_caps;
+	uint32_t i, temp_ht_cap;
+
+	qdf_mem_zero(hdd_ht_cap, sizeof(struct ieee80211_ht_cap));
+
+	if (roam_ht_cap->advCodingCap)
+		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_LDPC_CODING;
+	if (roam_ht_cap->supportedChannelWidthSet)
+		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+	temp_ht_cap = roam_ht_cap->mimoPowerSave &
+	    (IEEE80211_HT_CAP_SM_PS >> IEEE80211_HT_CAP_SM_PS_SHIFT);
+	if (temp_ht_cap)
+		hdd_ht_cap->cap_info |=
+			temp_ht_cap << IEEE80211_HT_CAP_SM_PS_SHIFT;
+	if (roam_ht_cap->greenField)
+		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_GRN_FLD;
+	if (roam_ht_cap->shortGI20MHz)
+		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_SGI_20;
+	if (roam_ht_cap->shortGI40MHz)
+		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_SGI_40;
+	if (roam_ht_cap->txSTBC)
+		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_TX_STBC;
+	temp_ht_cap = roam_ht_cap->rxSTBC & (IEEE80211_HT_CAP_RX_STBC >>
+	    IEEE80211_HT_CAP_RX_STBC_SHIFT);
+	if (temp_ht_cap)
+		hdd_ht_cap->cap_info |=
+			temp_ht_cap << IEEE80211_HT_CAP_RX_STBC_SHIFT;
+	if (roam_ht_cap->delayedBA)
+		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_DELAY_BA;
+	if (roam_ht_cap->maximalAMSDUsize)
+		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_MAX_AMSDU;
+	if (roam_ht_cap->dsssCckMode40MHz)
+		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_DSSSCCK40;
+	if (roam_ht_cap->psmp)
+		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_RESERVED;
+	if (roam_ht_cap->stbcControlFrame)
+		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_40MHZ_INTOLERANT;
+	if (roam_ht_cap->lsigTXOPProtection)
+		hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;
+
+	/* 802.11n HT capability AMPDU settings (for ampdu_params_info) */
+	if (roam_ht_cap->maxRxAMPDUFactor)
+		hdd_ht_cap->ampdu_params_info |=
+			IEEE80211_HT_AMPDU_PARM_FACTOR;
+	temp_ht_cap = roam_ht_cap->mpduDensity &
+	    (IEEE80211_HT_AMPDU_PARM_DENSITY >>
+	     IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
+	if (temp_ht_cap)
+		hdd_ht_cap->ampdu_params_info |=
+		temp_ht_cap << IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT;
+
+	/* 802.11n HT extended capabilities masks */
+	if (roam_ht_cap->pco)
+		hdd_ht_cap->extended_ht_cap_info |=
+			IEEE80211_HT_EXT_CAP_PCO;
+	temp_ht_cap = roam_ht_cap->transitionTime &
+	    (IEEE80211_HT_EXT_CAP_PCO_TIME >>
+	    IEEE80211_HT_EXT_CAP_PCO_TIME_SHIFT);
+	if (temp_ht_cap)
+		hdd_ht_cap->extended_ht_cap_info |=
+			temp_ht_cap << IEEE80211_HT_EXT_CAP_PCO_TIME_SHIFT;
+	temp_ht_cap = roam_ht_cap->mcsFeedback &
+	    (IEEE80211_HT_EXT_CAP_MCS_FB >> IEEE80211_HT_EXT_CAP_MCS_FB_SHIFT);
+	if (temp_ht_cap)
+		hdd_ht_cap->extended_ht_cap_info |=
+			temp_ht_cap << IEEE80211_HT_EXT_CAP_MCS_FB_SHIFT;
+
+	/* tx_bf_cap_info capabilities */
+	if (roam_ht_cap->txBF)
+		hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_TX_BF;
+	if (roam_ht_cap->rxStaggeredSounding)
+		hdd_ht_cap->tx_BF_cap_info |=
+			TX_BF_CAP_INFO_RX_STAG_RED_SOUNDING;
+	if (roam_ht_cap->txStaggeredSounding)
+		hdd_ht_cap->tx_BF_cap_info |=
+			TX_BF_CAP_INFO_TX_STAG_RED_SOUNDING;
+	if (roam_ht_cap->rxZLF)
+		hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_RX_ZFL;
+	if (roam_ht_cap->txZLF)
+		hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_TX_ZFL;
+	if (roam_ht_cap->implicitTxBF)
+		hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_IMP_TX_BF;
+	temp_ht_cap = roam_ht_cap->calibration &
+	    (TX_BF_CAP_INFO_CALIBRATION >> TX_BF_CAP_INFO_CALIBRATION_SHIFT);
+	if (temp_ht_cap)
+		hdd_ht_cap->tx_BF_cap_info |=
+			temp_ht_cap << TX_BF_CAP_INFO_CALIBRATION_SHIFT;
+	if (roam_ht_cap->explicitCSITxBF)
+		hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_EXP_CSIT_BF;
+	if (roam_ht_cap->explicitUncompressedSteeringMatrix)
+		hdd_ht_cap->tx_BF_cap_info |=
+			TX_BF_CAP_INFO_EXP_UNCOMP_STEER_MAT;
+	temp_ht_cap = roam_ht_cap->explicitBFCSIFeedback &
+	    (TX_BF_CAP_INFO_EXP_BF_CSI_FB >>
+	     TX_BF_CAP_INFO_EXP_BF_CSI_FB_SHIFT);
+	if (temp_ht_cap)
+		hdd_ht_cap->tx_BF_cap_info |=
+			temp_ht_cap << TX_BF_CAP_INFO_EXP_BF_CSI_FB_SHIFT;
+	temp_ht_cap =
+	    roam_ht_cap->explicitUncompressedSteeringMatrixFeedback &
+	    (TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT >>
+	     TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT_SHIFT);
+	if (temp_ht_cap)
+		hdd_ht_cap->tx_BF_cap_info |=
+			temp_ht_cap <<
+			TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT_SHIFT;
+	temp_ht_cap =
+	    roam_ht_cap->explicitCompressedSteeringMatrixFeedback &
+	    (TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB >>
+	     TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB_SHIFT);
+	if (temp_ht_cap)
+		hdd_ht_cap->tx_BF_cap_info |=
+			temp_ht_cap <<
+				TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB_SHIFT;
+	temp_ht_cap = roam_ht_cap->csiNumBFAntennae &
+	    (TX_BF_CAP_INFO_CSI_NUM_BF_ANT >>
+	     TX_BF_CAP_INFO_CSI_NUM_BF_ANT_SHIFT);
+	if (temp_ht_cap)
+		hdd_ht_cap->tx_BF_cap_info |=
+			temp_ht_cap << TX_BF_CAP_INFO_CSI_NUM_BF_ANT_SHIFT;
+	temp_ht_cap = roam_ht_cap->uncompressedSteeringMatrixBFAntennae &
+	    (TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT >>
+	     TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT_SHIFT);
+	if (temp_ht_cap)
+		hdd_ht_cap->tx_BF_cap_info |=
+			temp_ht_cap <<
+				TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT_SHIFT;
+	temp_ht_cap = roam_ht_cap->compressedSteeringMatrixBFAntennae &
+	    (TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT >>
+	     TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT_SHIFT);
+	if (temp_ht_cap)
+		hdd_ht_cap->tx_BF_cap_info |=
+			temp_ht_cap <<
+				TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT_SHIFT;
+
+	/* antenna selection */
+	if (roam_ht_cap->antennaSelection)
+		hdd_ht_cap->antenna_selection_info |= ANTENNA_SEL_INFO;
+	if (roam_ht_cap->explicitCSIFeedbackTx)
+		hdd_ht_cap->antenna_selection_info |=
+			ANTENNA_SEL_INFO_EXP_CSI_FB_TX;
+	if (roam_ht_cap->antennaIndicesFeedbackTx)
+		hdd_ht_cap->antenna_selection_info |=
+			ANTENNA_SEL_INFO_ANT_ID_FB_TX;
+	if (roam_ht_cap->explicitCSIFeedback)
+		hdd_ht_cap->antenna_selection_info |=
+			ANTENNA_SEL_INFO_EXP_CSI_FB;
+	if (roam_ht_cap->antennaIndicesFeedback)
+		hdd_ht_cap->antenna_selection_info |=
+			ANTENNA_SEL_INFO_ANT_ID_FB;
+	if (roam_ht_cap->rxAS)
+		hdd_ht_cap->antenna_selection_info |=
+			ANTENNA_SEL_INFO_RX_AS;
+	if (roam_ht_cap->txSoundingPPDUs)
+		hdd_ht_cap->antenna_selection_info |=
+			ANTENNA_SEL_INFO_TX_SOUNDING_PPDU;
+
+	/* mcs data rate */
+	for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; ++i)
+		hdd_ht_cap->mcs.rx_mask[i] =
+			roam_ht_cap->supportedMCSSet[i];
+		hdd_ht_cap->mcs.rx_highest =
+			((short) (roam_ht_cap->supportedMCSSet[11]) << 8) |
+			((short) (roam_ht_cap->supportedMCSSet[10]));
+		hdd_ht_cap->mcs.tx_params =
+			roam_ht_cap->supportedMCSSet[12];
+}
+
+#define VHT_CAP_MAX_MPDU_LENGTH_MASK 0x00000003
+#define VHT_CAP_SUPP_CHAN_WIDTH_MASK_SHIFT 2
+#define VHT_CAP_RXSTBC_MASK_SHIFT 8
+#define VHT_CAP_BEAMFORMEE_STS_SHIFT 13
+#define VHT_CAP_BEAMFORMEE_STS_MASK \
+	(0x0000e000 >> VHT_CAP_BEAMFORMEE_STS_SHIFT)
+#define VHT_CAP_SOUNDING_DIMENSIONS_SHIFT 16
+#define VHT_CAP_SOUNDING_DIMENSIONS_MASK \
+	(0x00070000 >> VHT_CAP_SOUNDING_DIMENSIONS_SHIFT)
+#define VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK_SHIFT 23
+#define VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK \
+	(0x03800000 >> VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK_SHIFT)
+#define VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB_SHIFT 26
+
+/**
+ * hdd_copy_ht_caps()- copy ht caps info from roam info to
+ *  hdd station context.
+ * @hdd_sta_ctx: pointer to hdd station context
+ * @roam_info: pointer to roam info
+ *
+ * Return: None
+ */
+static void hdd_copy_vht_caps(hdd_station_ctx_t *hdd_sta_ctx,
+				     tCsrRoamInfo *roam_info)
+{
+	tDot11fIEVHTCaps *roam_vht_cap = &roam_info->vht_caps;
+	struct ieee80211_vht_cap *hdd_vht_cap =
+		&hdd_sta_ctx->conn_info.vht_caps;
+	uint32_t temp_vht_cap;
+
+	qdf_mem_zero(hdd_vht_cap, sizeof(struct ieee80211_vht_cap));
+
+	temp_vht_cap = roam_vht_cap->maxMPDULen & VHT_CAP_MAX_MPDU_LENGTH_MASK;
+	hdd_vht_cap->vht_cap_info |= temp_vht_cap;
+	temp_vht_cap = roam_vht_cap->supportedChannelWidthSet &
+		(IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK >>
+			VHT_CAP_SUPP_CHAN_WIDTH_MASK_SHIFT);
+	if (temp_vht_cap)
+		if (roam_vht_cap->supportedChannelWidthSet &
+		    (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ >>
+			VHT_CAP_SUPP_CHAN_WIDTH_MASK_SHIFT))
+			hdd_vht_cap->vht_cap_info |=
+				temp_vht_cap <<
+				IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
+		if (roam_vht_cap->supportedChannelWidthSet &
+		    (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ >>
+			VHT_CAP_SUPP_CHAN_WIDTH_MASK_SHIFT))
+			hdd_vht_cap->vht_cap_info |=
+			temp_vht_cap <<
+			IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
+	if (roam_vht_cap->ldpcCodingCap)
+		hdd_vht_cap->vht_cap_info |= IEEE80211_VHT_CAP_RXLDPC;
+	if (roam_vht_cap->shortGI80MHz)
+		hdd_vht_cap->vht_cap_info |= IEEE80211_VHT_CAP_SHORT_GI_80;
+	if (roam_vht_cap->shortGI160and80plus80MHz)
+		hdd_vht_cap->vht_cap_info |= IEEE80211_VHT_CAP_SHORT_GI_160;
+	if (roam_vht_cap->txSTBC)
+		hdd_vht_cap->vht_cap_info |= IEEE80211_VHT_CAP_TXSTBC;
+	temp_vht_cap = roam_vht_cap->rxSTBC & (IEEE80211_VHT_CAP_RXSTBC_MASK >>
+		VHT_CAP_RXSTBC_MASK_SHIFT);
+	if (temp_vht_cap)
+		hdd_vht_cap->vht_cap_info |=
+			temp_vht_cap << VHT_CAP_RXSTBC_MASK_SHIFT;
+	if (roam_vht_cap->suBeamFormerCap)
+		hdd_vht_cap->vht_cap_info |=
+			IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
+	if (roam_vht_cap->suBeamformeeCap)
+		hdd_vht_cap->vht_cap_info |=
+			IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
+	temp_vht_cap = roam_vht_cap->csnofBeamformerAntSup &
+			(VHT_CAP_BEAMFORMEE_STS_MASK);
+	if (temp_vht_cap)
+		hdd_vht_cap->vht_cap_info |=
+			temp_vht_cap << VHT_CAP_BEAMFORMEE_STS_SHIFT;
+	temp_vht_cap = roam_vht_cap->numSoundingDim &
+			(VHT_CAP_SOUNDING_DIMENSIONS_MASK);
+	if (temp_vht_cap)
+		hdd_vht_cap->vht_cap_info |=
+			temp_vht_cap << VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
+	if (roam_vht_cap->muBeamformerCap)
+		hdd_vht_cap->vht_cap_info |=
+			IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
+	if (roam_vht_cap->muBeamformeeCap)
+		hdd_vht_cap->vht_cap_info |=
+			IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
+	if (roam_vht_cap->vhtTXOPPS)
+		hdd_vht_cap->vht_cap_info |=
+			IEEE80211_VHT_CAP_VHT_TXOP_PS;
+	if (roam_vht_cap->htcVHTCap)
+		hdd_vht_cap->vht_cap_info |=
+			IEEE80211_VHT_CAP_HTC_VHT;
+	temp_vht_cap = roam_vht_cap->maxAMPDULenExp &
+			(VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK);
+	if (temp_vht_cap)
+		hdd_vht_cap->vht_cap_info |=
+			temp_vht_cap <<
+			VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK_SHIFT;
+	temp_vht_cap = roam_vht_cap->vhtLinkAdaptCap &
+		(IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB >>
+		 VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB_SHIFT);
+	if (temp_vht_cap)
+		hdd_vht_cap->vht_cap_info |= temp_vht_cap <<
+			VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB_SHIFT;
+	if (roam_vht_cap->rxAntPattern)
+		hdd_vht_cap->vht_cap_info |=
+			IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN;
+	if (roam_vht_cap->txAntPattern)
+		hdd_vht_cap->vht_cap_info |=
+			IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
+	hdd_vht_cap->supp_mcs.rx_mcs_map = roam_vht_cap->rxMCSMap;
+	hdd_vht_cap->supp_mcs.rx_highest =
+		((uint16_t)roam_vht_cap->rxHighSupDataRate);
+	hdd_vht_cap->supp_mcs.tx_mcs_map = roam_vht_cap->txMCSMap;
+	hdd_vht_cap->supp_mcs.tx_highest =
+		((uint16_t)roam_vht_cap->txSupDataRate);
+}
+
+/* ht param */
+#define HT_PARAM_CONTROLLED_ACCESS_ONLY 0x10
+#define HT_PARAM_SERVICE_INT_GRAN 0xe0
+#define HT_PARAM_SERVICE_INT_GRAN_SHIFT 5
+
+/* operatinon mode */
+#define HT_OP_MODE_TX_BURST_LIMIT 0x0008
+
+/* stbc_param */
+#define HT_STBC_PARAM_MCS 0x007f
+
+/**
+ * hdd_copy_ht_operation()- copy HT operation element from roam info to
+ *  hdd station context.
+ * @hdd_sta_ctx: pointer to hdd station context
+ * @roam_info: pointer to roam info
+ *
+ * Return: None
+ */
+static void hdd_copy_ht_operation(hdd_station_ctx_t *hdd_sta_ctx,
+					    tCsrRoamInfo *roam_info)
+{
+	tDot11fIEHTInfo *roam_ht_ops = &roam_info->ht_operation;
+	struct ieee80211_ht_operation *hdd_ht_ops =
+		&hdd_sta_ctx->conn_info.ht_operation;
+	uint32_t i, temp_ht_ops;
+
+	qdf_mem_zero(hdd_ht_ops, sizeof(struct ieee80211_ht_operation));
+
+	hdd_ht_ops->primary_chan = roam_ht_ops->primaryChannel;
+
+	/* HT_PARAMS */
+	temp_ht_ops = roam_ht_ops->secondaryChannelOffset &
+		IEEE80211_HT_PARAM_CHA_SEC_OFFSET;
+	if (temp_ht_ops)
+		hdd_ht_ops->ht_param |= temp_ht_ops;
+	else
+		hdd_ht_ops->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE;
+	if (roam_ht_ops->recommendedTxWidthSet)
+		hdd_ht_ops->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY;
+	if (roam_ht_ops->rifsMode)
+		hdd_ht_ops->ht_param |= IEEE80211_HT_PARAM_RIFS_MODE;
+	if (roam_ht_ops->controlledAccessOnly)
+		hdd_ht_ops->ht_param |= HT_PARAM_CONTROLLED_ACCESS_ONLY;
+	temp_ht_ops = roam_ht_ops->serviceIntervalGranularity &
+		(HT_PARAM_SERVICE_INT_GRAN >> HT_PARAM_SERVICE_INT_GRAN_SHIFT);
+	if (temp_ht_ops)
+		hdd_ht_ops->ht_param |= temp_ht_ops <<
+			HT_PARAM_SERVICE_INT_GRAN_SHIFT;
+
+	/* operation mode */
+	temp_ht_ops = roam_ht_ops->opMode &
+			IEEE80211_HT_OP_MODE_PROTECTION;
+	switch (temp_ht_ops) {
+	case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
+		hdd_ht_ops->operation_mode |=
+			IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER;
+		break;
+	case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
+		hdd_ht_ops->operation_mode |=
+			IEEE80211_HT_OP_MODE_PROTECTION_20MHZ;
+		break;
+	case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
+		hdd_ht_ops->operation_mode |=
+			IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED;
+		break;
+	case IEEE80211_HT_OP_MODE_PROTECTION_NONE:
+	default:
+		hdd_ht_ops->operation_mode |=
+			IEEE80211_HT_OP_MODE_PROTECTION_NONE;
+	}
+	if (roam_ht_ops->nonGFDevicesPresent)
+		hdd_ht_ops->operation_mode |=
+			IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT;
+	if (roam_ht_ops->transmitBurstLimit)
+		hdd_ht_ops->operation_mode |=
+			HT_OP_MODE_TX_BURST_LIMIT;
+	if (roam_ht_ops->obssNonHTStaPresent)
+		hdd_ht_ops->operation_mode |=
+			IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT;
+
+	/* stbc_param */
+	temp_ht_ops = roam_ht_ops->basicSTBCMCS &
+			HT_STBC_PARAM_MCS;
+	if (temp_ht_ops)
+		hdd_ht_ops->stbc_param |= temp_ht_ops;
+	if (roam_ht_ops->dualCTSProtection)
+		hdd_ht_ops->stbc_param |=
+			IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT;
+	if (roam_ht_ops->secondaryBeacon)
+		hdd_ht_ops->stbc_param |=
+			IEEE80211_HT_STBC_PARAM_STBC_BEACON;
+	if (roam_ht_ops->lsigTXOPProtectionFullSupport)
+		hdd_ht_ops->stbc_param |=
+			IEEE80211_HT_STBC_PARAM_LSIG_TXOP_FULLPROT;
+	if (roam_ht_ops->pcoActive)
+		hdd_ht_ops->stbc_param |=
+			IEEE80211_HT_STBC_PARAM_PCO_ACTIVE;
+	if (roam_ht_ops->pcoPhase)
+		hdd_ht_ops->stbc_param |=
+			IEEE80211_HT_STBC_PARAM_PCO_PHASE;
+
+	/* basic MCs set */
+	for (i = 0; i < 16; ++i)
+		hdd_ht_ops->basic_set[i] =
+			roam_ht_ops->basicMCSSet[i];
+}
+
+/**
+ * hdd_copy_vht_operation()- copy VHT operations element from roam info to
+ *  hdd station context.
+ * @hdd_sta_ctx: pointer to hdd station context
+ * @roam_info: pointer to roam info
+ *
+ * Return: None
+ */
+static void hdd_copy_vht_operation(hdd_station_ctx_t *hdd_sta_ctx,
+					      tCsrRoamInfo *roam_info)
+{
+	tDot11fIEVHTOperation *roam_vht_ops = &roam_info->vht_operation;
+	struct ieee80211_vht_operation *hdd_vht_ops =
+		&hdd_sta_ctx->conn_info.vht_operation;
+
+	qdf_mem_zero(hdd_vht_ops, sizeof(struct ieee80211_vht_operation));
+
+	hdd_vht_ops->chan_width = roam_vht_ops->chanWidth;
+	hdd_vht_ops->center_freq_seg1_idx = roam_vht_ops->chanCenterFreqSeg1;
+	hdd_vht_ops->center_freq_seg2_idx = roam_vht_ops->chanCenterFreqSeg2;
+	hdd_vht_ops->basic_mcs_set = roam_vht_ops->basicMCSSet;
+}
+
+
+/**
+ * hdd_save_bss_info() - save connection info in hdd sta ctx
+ * @adapter: Pointer to adapter
+ * @roam_info: pointer to roam info
+ *
+ * Return: None
+ */
+static void hdd_save_bss_info(hdd_adapter_t *adapter,
+						tCsrRoamInfo *roam_info)
+{
+	hdd_station_ctx_t *hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	hdd_sta_ctx->conn_info.freq = cds_chan_to_freq(
+		hdd_sta_ctx->conn_info.operationChannel);
+	if (roam_info->vht_caps.present) {
+		hdd_sta_ctx->conn_info.conn_flag.vht_present = true;
+		hdd_copy_vht_caps(hdd_sta_ctx, roam_info);
+	} else {
+		hdd_sta_ctx->conn_info.conn_flag.vht_present = false;
+	}
+	if (roam_info->ht_caps.present) {
+		hdd_sta_ctx->conn_info.conn_flag.ht_present = true;
+		hdd_copy_ht_caps(hdd_sta_ctx, roam_info);
+	} else {
+		hdd_sta_ctx->conn_info.conn_flag.ht_present = false;
+	}
+	if (roam_info->reassoc)
+		hdd_sta_ctx->conn_info.roam_count++;
+	if (roam_info->hs20vendor_ie.present) {
+		hdd_sta_ctx->conn_info.conn_flag.hs20_present = true;
+		qdf_mem_copy(&hdd_sta_ctx->conn_info.hs20vendor_ie,
+			     &roam_info->hs20vendor_ie,
+			     sizeof(roam_info->hs20vendor_ie));
+	} else {
+		hdd_sta_ctx->conn_info.conn_flag.hs20_present = false;
+	}
+	if (roam_info->ht_operation.present) {
+		hdd_sta_ctx->conn_info.conn_flag.ht_op_present = true;
+		hdd_copy_ht_operation(hdd_sta_ctx, roam_info);
+	} else {
+		hdd_sta_ctx->conn_info.conn_flag.ht_op_present = false;
+	}
+	if (roam_info->vht_operation.present) {
+		hdd_sta_ctx->conn_info.conn_flag.vht_op_present = true;
+		hdd_copy_vht_operation(hdd_sta_ctx, roam_info);
+	} else {
+		hdd_sta_ctx->conn_info.conn_flag.vht_op_present = false;
+	}
+}
+
+/**
  * hdd_conn_save_connect_info() - save current connection information
  * @pAdapter: pointer to adapter
  * @pRoamInfo: pointer to roam info
@@ -459,6 +939,7 @@
 			pHddStaCtx->conn_info.rate_flags =
 				pRoamInfo->chan_info.rate_flags;
 		}
+		hdd_save_bss_info(pAdapter, pRoamInfo);
 	}
 	/* save the connected BssType */
 	hdd_conn_save_connected_bss_type(pHddStaCtx, eBssType);
@@ -1014,6 +1495,51 @@
 }
 
 /**
+ * hdd_print_bss_info() - print bss info
+ * @hdd_sta_ctx: pointer to hdd station context
+ *
+ * Return: None
+ */
+void hdd_print_bss_info(hdd_station_ctx_t *hdd_sta_ctx)
+{
+	uint32_t *cap_info;
+
+	hdd_info("WIFI DATA LOGGER");
+	hdd_info("channel: %d",
+		 hdd_sta_ctx->conn_info.freq);
+	hdd_info("dot11mode: %d",
+		 hdd_sta_ctx->conn_info.dot11Mode);
+	hdd_info("AKM: %d",
+		 hdd_sta_ctx->conn_info.authType);
+	hdd_info("ssid: %.*s",
+		 hdd_sta_ctx->conn_info.SSID.SSID.length,
+		 hdd_sta_ctx->conn_info.SSID.SSID.ssId);
+	hdd_info("roam count: %d",
+		 hdd_sta_ctx->conn_info.roam_count);
+	hdd_info("ant_info: %d",
+		 hdd_sta_ctx->conn_info.txrate.nss);
+	hdd_info("datarate legacy %d",
+		 hdd_sta_ctx->conn_info.txrate.legacy);
+	hdd_info("datarate mcs: %d",
+		 hdd_sta_ctx->conn_info.txrate.mcs);
+	if (hdd_sta_ctx->conn_info.conn_flag.ht_present) {
+		cap_info = (uint32_t *)&hdd_sta_ctx->conn_info.ht_caps;
+		hdd_info("ht caps: %x", *cap_info);
+	}
+	if (hdd_sta_ctx->conn_info.conn_flag.vht_present) {
+		cap_info = (uint32_t *)&hdd_sta_ctx->conn_info.vht_caps;
+		hdd_info("vht caps: %x", *cap_info);
+	}
+	if (hdd_sta_ctx->conn_info.conn_flag.hs20_present)
+		hdd_info("hs20 info: %x",
+			 hdd_sta_ctx->conn_info.hs20vendor_ie.release_num);
+	hdd_info("signal: %d",
+		 hdd_sta_ctx->conn_info.signal);
+	hdd_info("noise: %d",
+		 hdd_sta_ctx->conn_info.noise);
+}
+
+/**
  * hdd_dis_connect_handler() - disconnect event handler
  * @pAdapter: pointer to adapter
  * @pRoamInfo: pointer to roam info
@@ -1220,6 +1746,7 @@
 	}
 	/* Unblock anyone waiting for disconnect to complete */
 	complete(&pAdapter->disconnect_comp_var);
+	hdd_print_bss_info(pHddStaCtx);
 	return status;
 }
 
@@ -2287,7 +2814,7 @@
 		 */
 		if (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus
 		    && !hddDisconInProgress) {
-			if (pRoamInfo)
+			if (pRoamInfo) {
 				hddLog(LOGE,
 				       FL("send connect failure to nl80211: for bssid "
 				       MAC_ADDRESS_STR
@@ -2295,6 +2822,9 @@
 				       MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
 				       roamResult, roamStatus,
 				       pRoamInfo->reasonCode);
+				pHddStaCtx->conn_info.assoc_status_code =
+					pRoamInfo->statusCode;
+			}
 			else
 				hddLog(LOGE,
 				       FL("connect failed: for bssid "
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index e27a1a3..d6b5046 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -8905,6 +8905,7 @@
 	int status = 0;
 	hdd_wext_state_t *pWextState;
 	hdd_context_t *pHddCtx;
+	hdd_station_ctx_t *hdd_sta_ctx;
 	uint32_t roamId;
 	tCsrRoamProfile *pRoamProfile;
 	eCsrAuthType RSNAuthType;
@@ -8914,6 +8915,7 @@
 
 	pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
 	pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
 
 	status = wlan_hdd_validate_context(pHddCtx);
 	if (status)
@@ -8925,6 +8927,8 @@
 	}
 
 	pRoamProfile = &pWextState->roamProfile;
+	qdf_mem_zero(&hdd_sta_ctx->conn_info,
+		     sizeof(hdd_sta_ctx->conn_info));
 
 	if (pRoamProfile) {
 		hdd_station_ctx_t *pHddStaCtx;
diff --git a/core/hdd/src/wlan_hdd_stats.c b/core/hdd/src/wlan_hdd_stats.c
index 52643cc..c91d516 100644
--- a/core/hdd/src/wlan_hdd_stats.c
+++ b/core/hdd/src/wlan_hdd_stats.c
@@ -1657,6 +1657,7 @@
 	uint8_t MCSRates[SIZE_OF_BASIC_MCS_SET];
 	uint32_t MCSLeng = SIZE_OF_BASIC_MCS_SET;
 	uint16_t maxRate = 0;
+	int8_t snr = 0;
 	uint16_t myRate;
 	uint16_t currentRate = 0;
 	uint8_t maxSpeedMCS = 0;
@@ -1697,6 +1698,11 @@
 		return status;
 
 	wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
+	wlan_hdd_get_snr(pAdapter, &snr);
+	pHddStaCtx->conn_info.signal = sinfo->signal;
+	pHddStaCtx->conn_info.noise =
+		pHddStaCtx->conn_info.signal - snr;
+
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS)
 	sinfo->filled |= STATION_INFO_SIGNAL;
 #else
@@ -2110,6 +2116,9 @@
 	sinfo->rx_bytes = pAdapter->stats.rx_bytes;
 	sinfo->rx_packets = pAdapter->stats.rx_packets;
 
+	qdf_mem_copy(&pHddStaCtx->conn_info.txrate,
+		     &sinfo->txrate, sizeof(sinfo->txrate));
+
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS)
 	sinfo->filled |= STATION_INFO_TX_BITRATE |
 			 STATION_INFO_TX_BYTES   |
diff --git a/core/mac/inc/ani_global.h b/core/mac/inc/ani_global.h
index 8807263..cd786ea 100644
--- a/core/mac/inc/ani_global.h
+++ b/core/mac/inc/ani_global.h
@@ -28,12 +28,6 @@
 #ifndef _ANIGLOBAL_H
 #define _ANIGLOBAL_H
 
-/* Take care to avoid redefinition of this type, if it is */
-/* already defined in "halWmmApi.h" */
-#if !defined(_HALMAC_WMM_API_H)
-typedef struct sAniSirGlobal *tpAniSirGlobal;
-#endif
-
 #include "qdf_types.h"
 #include "sir_common.h"
 #include "ani_system_defs.h"
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index 2105505..a7e85ef 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -38,6 +38,13 @@
 #ifndef __SIR_API_H
 #define __SIR_API_H
 
+
+/* Take care to avoid redefinition of this type, if it is */
+/* already defined in "halWmmApi.h" */
+#if !defined(_HALMAC_WMM_API_H)
+typedef struct sAniSirGlobal *tpAniSirGlobal;
+#endif
+
 #include "qdf_types.h"
 #include "cds_reg_service.h"
 #include "cds_regdomain.h"
@@ -47,6 +54,7 @@
 #include "sir_params.h"
 #include "cds_regdomain.h"
 #include "wmi_unified_param.h"
+#include <dot11f.h>
 
 #define OFFSET_OF(structType, fldName)   (&((structType *)0)->fldName)
 
@@ -1163,6 +1171,11 @@
 	tSirSmeHTProfile HTProfile;
 #endif
 	bool supported_nss_1x1;
+	tDot11fIEHTCaps ht_caps;
+	tDot11fIEVHTCaps vht_caps;
+	tDot11fIEHTInfo ht_operation;
+	tDot11fIEVHTOperation vht_operation;
+	tDot11fIEhs20vendor_ie hs20vendor_ie;
 	uint8_t frames[1];
 } tSirSmeJoinRsp, *tpSirSmeJoinRsp;
 
diff --git a/core/mac/src/pe/include/lim_session.h b/core/mac/src/pe/include/lim_session.h
index 8f3f118..aeb7d5f 100644
--- a/core/mac/src/pe/include/lim_session.h
+++ b/core/mac/src/pe/include/lim_session.h
@@ -479,6 +479,10 @@
 	/* Supported NSS is intersection of self and peer NSS */
 	bool supported_nss_1x1;
 	bool is_ext_caps_present;
+	tDot11fIEHTCaps ht_caps;
+	tDot11fIEVHTCaps vht_caps;
+	tDot11fIEHTInfo ht_operation;
+	tDot11fIEVHTOperation vht_operation;
 } tPESession, *tpPESession;
 
 /*-------------------------------------------------------------------------
diff --git a/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c b/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c
index c6d9d70..573a288 100644
--- a/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c
+++ b/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c
@@ -973,6 +973,12 @@
 		ie_len,
 		beacon);
 
+	session_entry->vht_caps = beacon->VHTCaps;
+	session_entry->ht_caps = beacon->HTCaps;
+	session_entry->hs20vendor_ie = beacon->hs20vendor_ie;
+	session_entry->ht_operation = beacon->HTInfo;
+	session_entry->vht_operation = beacon->VHTOperation;
+
 	if (mac_ctx->lim.gLimProtectionControl !=
 		WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
 		lim_decide_sta_protection_on_assoc(mac_ctx, beacon,
diff --git a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
index eab9439..9f6413f 100644
--- a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
+++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
@@ -388,6 +388,24 @@
 #endif
 	}
 }
+
+/**
+ * lim_add_bss_info() - copy data from session entry to join rsp
+ * @session_entry: PE Session Info
+ * @sme_join_rsp: Join response buffer to be filled up
+ *
+ * Return: None
+ */
+void lim_add_bss_info(tpPESession session_entry,
+					tpSirSmeJoinRsp sme_join_rsp)
+{
+	sme_join_rsp->hs20vendor_ie = session_entry->hs20vendor_ie;
+	sme_join_rsp->vht_caps = session_entry->vht_caps;
+	sme_join_rsp->ht_caps = session_entry->ht_caps;
+	sme_join_rsp->ht_operation = session_entry->ht_operation;
+	sme_join_rsp->vht_operation = session_entry->vht_operation;
+}
+
 /**
  * lim_send_sme_join_reassoc_rsp() - Send Response to Upper Layers
  * @mac_ctx:            Pointer to Global MAC structure
@@ -489,7 +507,7 @@
 #ifdef FEATURE_WLAN_ESE
 		sme_join_rsp->tspecIeLen = 0;
 #endif
-
+		lim_add_bss_info(session_entry, sme_join_rsp);
 		lim_handle_join_rsp_status(mac_ctx, session_entry, result_code,
 			sme_join_rsp);
 
diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h
index de7d011..266e5a0 100644
--- a/core/sme/inc/csr_api.h
+++ b/core/sme/inc/csr_api.h
@@ -1393,6 +1393,12 @@
 		struct ndi_delete_rsp ndi_delete_params;
 	} ndp;
 #endif
+	tDot11fIEHTCaps ht_caps;
+	tDot11fIEVHTCaps vht_caps;
+	tDot11fIEhs20vendor_ie hs20vendor_ie;
+	tDot11fIEVHTOperation vht_operation;
+	tDot11fIEHTInfo ht_operation;
+	bool reassoc;
 } tCsrRoamInfo;
 
 typedef struct tagCsrFreqScanInfo {
diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c
index a6e6cb8..6b1628c 100644
--- a/core/sme/src/csr/csr_api_roam.c
+++ b/core/sme/src/csr/csr_api_roam.c
@@ -6509,10 +6509,13 @@
 	session = CSR_GET_SESSION(mac_ctx, session_id);
 
 	conn_profile = &session->connectedProfile;
-	if (eCsrReassocSuccess == res)
+	if (eCsrReassocSuccess == res) {
+		roam_info.reassoc = true;
 		ind_qos = SME_QOS_CSR_REASSOC_COMPLETE;
-	else
+	} else {
+		roam_info.reassoc = false;
 		ind_qos = SME_QOS_CSR_ASSOC_COMPLETE;
+	}
 	sms_log(mac_ctx, LOGW, FL("receives association indication"));
 	qdf_mem_set(&roam_info, sizeof(roam_info), 0);
 	/* always free the memory here */
@@ -6760,6 +6763,11 @@
 				csr_roam_copy_ht_profile(dst_profile,
 						src_profile);
 #endif
+			roam_info.vht_caps = join_rsp->vht_caps;
+			roam_info.ht_caps = join_rsp->ht_caps;
+			roam_info.hs20vendor_ie = join_rsp->hs20vendor_ie;
+			roam_info.ht_operation = join_rsp->ht_operation;
+			roam_info.vht_operation = join_rsp->vht_operation;
 		} else {
 			if (cmd->u.roamCmd.fReassoc) {
 				roam_info.fReassocReq =
@@ -6774,7 +6782,6 @@
 					session->connectedInfo.pbFrames;
 			}
 		}
-
 		/*
 		 * Update the staId from the previous connected profile info
 		 * as the reassociation is triggred at SME/HDD