wlan: Add BSS status caching

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

Change-Id: I41b74700b161277bc454d8bb8978f4e1e92faea8
CRs-fixed: 2079789
diff --git a/CORE/HDD/inc/wlan_hdd_assoc.h b/CORE/HDD/inc/wlan_hdd_assoc.h
index a474443..0162034 100644
--- a/CORE/HDD/inc/wlan_hdd_assoc.h
+++ b/CORE/HDD/inc/wlan_hdd_assoc.h
@@ -31,6 +31,8 @@
 #if !defined( HDD_CONNECTION_H__ ) 
 #define HDD_CONNECTION_H__
 #include <wlan_hdd_mib.h>
+#include <net/cfg80211.h>
+#include <linux/ieee80211.h>
 #define HDD_MAX_NUM_IBSS_STA ( 32 )
 #ifdef FEATURE_WLAN_TDLS
 #define HDD_MAX_NUM_TDLS_STA ( 8 )
@@ -47,6 +49,57 @@
 /* Timeout in ms for peer info request commpletion */
 #define IBSS_PEER_INFO_REQ_TIMOEUT 1000
 #endif
+
+/**
+ * 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 enum 
 {
    /** Not associated in Infra or participating in an IBSS / Ad-hoc network.*/
@@ -112,7 +165,42 @@
    tANI_U32 dot11Mode;
 
    uint32_t  rate_flags;
-   
+
+   /** channel frequency */
+   uint32_t freq;
+
+   /** txrate structure holds nss & datarate info */
+   struct rate_info txrate;
+
+   /** noise information */
+   int8_t noise;
+
+   /** ht capabilities info */
+   struct ieee80211_ht_cap ht_caps;
+
+   /** vht capabilities info */
+   struct ieee80211_vht_cap vht_caps;
+
+   /** passpoint/hs20 info */
+   tDot11fIEhs20vendor_ie hs20vendor_ie;
+
+   /** conn info params is present or not */
+   struct hdd_conn_flag conn_flag;
+
+   /** ht operation info */
+   struct ieee80211_ht_operation ht_operation;
+
+   /** ht operation info */
+   struct ieee80211_vht_operation vht_operation;
+
+   /** roaming counter */
+   uint32_t roam_count;
+
+   /** rssi info */
+   int8_t signal;
+
+   /** assoc fail reason */
+   int32_t assoc_status_code;
 }connection_info_t;
 /*Forward declaration of Adapter*/
 typedef struct hdd_adapter_s hdd_adapter_t;
diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c
index affc4fe..6a962d4 100644
--- a/CORE/HDD/src/wlan_hdd_assoc.c
+++ b/CORE/HDD/src/wlan_hdd_assoc.c
@@ -266,6 +266,487 @@
 
 }
 
+/**
+ * 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;
+
+    vos_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;
+
+    vos_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;
+
+    vos_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;
+
+    vos_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 = vos_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;
+        vos_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;
+    }
+}
+
 void hdd_connSaveConnectInfo( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, eCsrRoamBssType eBssType )
 {
    hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
@@ -329,6 +810,7 @@
 
           pHddStaCtx->conn_info.rate_flags = pRoamInfo->maxRateFlags;
       }
+      hdd_save_bss_info(pAdapter, pRoamInfo);
    }
 
    // save the connected BssType
@@ -982,6 +1464,53 @@
     return( vosStatus );
 }
 
+/**
+ * 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;
+
+    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"WIFI DATA LOGGER");
+    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"channel: %d",
+              hdd_sta_ctx->conn_info.freq);
+    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"dot11mode: %d",
+              hdd_sta_ctx->conn_info.dot11Mode);
+    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"AKM: %d",
+              hdd_sta_ctx->conn_info.authType);
+    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"ssid: %.*s",
+              hdd_sta_ctx->conn_info.SSID.SSID.length,
+              hdd_sta_ctx->conn_info.SSID.SSID.ssId);
+    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"roam count: %d",
+              hdd_sta_ctx->conn_info.roam_count);
+    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"ant_info: %d",
+              hdd_sta_ctx->conn_info.txrate.nss);
+    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"datarate legacy %d",
+              hdd_sta_ctx->conn_info.txrate.legacy);
+    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_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;
+        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_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;
+        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"vht caps: %x",
+                  *cap_info);
+    }
+    if (hdd_sta_ctx->conn_info.conn_flag.hs20_present)
+        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"hs20 info: %x",
+                  hdd_sta_ctx->conn_info.hs20vendor_ie.release_num);
+    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"signal: %d",
+              hdd_sta_ctx->conn_info.signal);
+    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"noise: %d",
+              hdd_sta_ctx->conn_info.noise);
+}
+
 
 static eHalStatus hdd_DisConnectHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
                                             tANI_U32 roamId, eRoamCmdStatus roamStatus,
@@ -1285,6 +1814,7 @@
 
     //Unblock anyone waiting for disconnect to complete
     complete(&pAdapter->disconnect_comp_var);
+    hdd_print_bss_info(pHddStaCtx);
     return( status );
 }
 
@@ -2054,20 +2584,23 @@
                 wlan_hdd_tdls_reenable(pHddCtx);
             }
 
-            if (pRoamInfo)
+            if (pRoamInfo) {
                 hddLog(VOS_TRACE_LEVEL_ERROR,
                      "%s: send connect failure to nl80211:"
                      " for bssid " MAC_ADDRESS_STR
                      " result:%d and Status:%d reasonCode %d" ,
                      __func__, MAC_ADDR_ARRAY(pRoamInfo->bssid),
                      roamResult, roamStatus, pRoamInfo->reasonCode);
-             else
+                pHddStaCtx->conn_info.assoc_status_code =
+                    pRoamInfo->statusCode;
+             } else {
                  hddLog(VOS_TRACE_LEVEL_ERROR,
                      "%s: connect failed:"
                      " for bssid " MAC_ADDRESS_STR
                      " result:%d and Status:%d" ,
                      __func__, MAC_ADDR_ARRAY(pWextState->req_bssId),
                      roamResult, roamStatus);
+             }
 
             /* inform association failure event to nl80211 */
             if ( eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL == roamResult )
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index b1402b9..64c1826 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -13912,6 +13912,7 @@
     int status = 0;
     hdd_wext_state_t *pWextState;
     hdd_context_t *pHddCtx;
+    hdd_station_ctx_t *hdd_sta_ctx;
     v_U32_t roamId;
     tCsrRoamProfile *pRoamProfile;
     eCsrAuthType RSNAuthType;
@@ -13920,6 +13921,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)
@@ -16160,6 +16162,7 @@
     tANI_U8  MCSRates[SIZE_OF_BASIC_MCS_SET];
     tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
     tANI_U16 maxRate = 0;
+    int8_t snr = 0;
     tANI_U16 myRate;
     tANI_U16 currentRate = 0;
     tANI_U8  maxSpeedMCS = 0;
@@ -16204,6 +16207,9 @@
     rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
 
     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;
     sinfo->filled |= STATION_INFO_SIGNAL;
 
     /*overwrite rate_flags if MAX link-speed need to be reported*/
@@ -16592,6 +16598,8 @@
     sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
     sinfo->filled |= STATION_INFO_RX_PACKETS;
 
+    vos_mem_copy(&pHddStaCtx->conn_info.txrate,
+                 &sinfo->txrate, sizeof(sinfo->txrate));
     if (rate_flags & eHAL_TX_RATE_LEGACY)
         hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
                sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,