qcacld-3.0: Add debugfs support for connect info

Add debugfs entry to get connect info (bssid, ssid, freq etc.,)
for STA interface.

Change-Id: Id5c350dbb4ca9b9f6b203459adee59b2d5e94f67
CRs-Fixed: 2203654
diff --git a/Kbuild b/Kbuild
index 7434f3e..961ee95 100755
--- a/Kbuild
+++ b/Kbuild
@@ -71,6 +71,7 @@
 ifeq ($(CONFIG_WLAN_FEATURE_LINK_LAYER_STATS), y)
 HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_llstat.o
 HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_csr.o
+HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_connect.o
 endif
 endif
 
diff --git a/core/hdd/inc/wlan_hdd_assoc.h b/core/hdd/inc/wlan_hdd_assoc.h
index 6d2aef5..41d9667 100644
--- a/core/hdd/inc/wlan_hdd_assoc.h
+++ b/core/hdd/inc/wlan_hdd_assoc.h
@@ -170,6 +170,9 @@
  * @congestion: holds congestion percentage
  * @last_ssid: holds last ssid
  * @last_auth_type: holds last auth type
+ * @auth_time: last authentication established time
+ * @connect_time: last association established time
+ * @ch_width: channel width of operating channel
  */
 struct hdd_connection_info {
 	eConnectionState connState;
@@ -204,6 +207,9 @@
 	uint32_t cca;
 	tCsrSSIDInfo last_ssid;
 	eCsrAuthType last_auth_type;
+	char auth_time[HDD_TIME_STRING_LEN];
+	char connect_time[HDD_TIME_STRING_LEN];
+	enum phy_ch_width ch_width;
 };
 
 /* Forward declarations */
diff --git a/core/hdd/inc/wlan_hdd_debugfs_csr.h b/core/hdd/inc/wlan_hdd_debugfs_csr.h
index 60a7dbe..9d58f65 100644
--- a/core/hdd/inc/wlan_hdd_debugfs_csr.h
+++ b/core/hdd/inc/wlan_hdd_debugfs_csr.h
@@ -39,6 +39,8 @@
 
 #ifdef WLAN_DEBUGFS
 
+#define DEBUGFS_CONNECT_INFO_BUF_SIZE    (4 * 1024)
+
 /**
  * struct wlan_hdd_debugfs_buffer_info - Debugfs buffer info
  * @length: current length of the debugfs buffer
@@ -84,6 +86,19 @@
 ssize_t
 wlan_hdd_current_time_info_debugfs(uint8_t *buf, ssize_t buf_avail_len);
 
+/**
+ * wlan_hdd_debugfs_update_connect_info() - API to get connect info
+ * into user buffer
+ * @buf: output buffer to hold connect info
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes copied
+ */
+ssize_t
+wlan_hdd_debugfs_update_connect_info(struct hdd_context *hdd_ctx,
+				     struct hdd_adapter *adapter,
+				     uint8_t *buf, ssize_t buf_avail_len);
+
 #else
 /**
  * wlan_hdd_debugfs_csr_init() - Create wifi diagnostic debugfs files
@@ -118,6 +133,22 @@
 	return 0;
 }
 
+/**
+ * wlan_hdd_debugfs_update_connect_info() - API to get connect info
+ * into user buffer
+ * @buf: output buffer to hold connect info
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes copied
+ */
+static inline ssize_t
+wlan_hdd_debugfs_update_connect_info(struct hdd_context *hdd_ctx,
+				     struct hdd_adapter *adapter,
+				     uint8_t *buf, ssize_t buf_avail_len)
+{
+	return 0;
+}
+
 #endif
 
 #endif /* _WLAN_HDD_DEBUGFS_CSR_H */
diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c
index ee99426..bdd2d93 100644
--- a/core/hdd/src/wlan_hdd_assoc.c
+++ b/core/hdd/src/wlan_hdd_assoc.c
@@ -211,7 +211,7 @@
 /**
  * hdd_conn_set_authenticated() - set authentication state
  * @adapter: pointer to the adapter
- * @authState: authentication state
+ * @auth_state: authentication state
  *
  * This function updates the global HDD station context
  * authentication state.
@@ -219,14 +219,26 @@
  * Return: none
  */
 static void
-hdd_conn_set_authenticated(struct hdd_adapter *adapter, uint8_t authState)
+hdd_conn_set_authenticated(struct hdd_adapter *adapter, uint8_t auth_state)
 {
 	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	char *auth_time;
+	uint32_t time_buffer_size;
 
 	/* save the new connection state */
 	hdd_debug("Authenticated state Changed from oldState:%d to State:%d",
-		   sta_ctx->conn_info.uIsAuthenticated, authState);
-	sta_ctx->conn_info.uIsAuthenticated = authState;
+		   sta_ctx->conn_info.uIsAuthenticated, auth_state);
+	sta_ctx->conn_info.uIsAuthenticated = auth_state;
+
+	auth_time = sta_ctx->conn_info.auth_time;
+	time_buffer_size = sizeof(sta_ctx->conn_info.auth_time);
+
+	if (auth_state)
+		qdf_get_time_of_the_day_in_hr_min_sec_usec(auth_time,
+							   time_buffer_size);
+	else
+		qdf_mem_set(auth_time, 0x00, time_buffer_size);
+
 }
 
 /**
@@ -243,6 +255,8 @@
 {
 	struct hdd_station_ctx *hdd_sta_ctx =
 		WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	char *connect_time;
+	uint32_t time_buffer_size;
 
 	/* save the new connection state */
 	hdd_debug("Changed conn state from old:%d to new:%d for dev %s",
@@ -253,6 +267,15 @@
 					 hdd_sta_ctx->conn_info.connState,
 					 conn_state);
 	hdd_sta_ctx->conn_info.connState = conn_state;
+
+	connect_time = hdd_sta_ctx->conn_info.connect_time;
+	time_buffer_size = sizeof(hdd_sta_ctx->conn_info.connect_time);
+	if (conn_state == eConnectionState_Associated)
+		qdf_get_time_of_the_day_in_hr_min_sec_usec(connect_time,
+							   time_buffer_size);
+	else
+		qdf_mem_set(connect_time, 0x00, time_buffer_size);
+
 }
 
 /**
@@ -997,6 +1020,9 @@
 
 			sta_ctx->conn_info.rate_flags =
 				roam_info->chan_info.rate_flags;
+
+			sta_ctx->conn_info.ch_width =
+				roam_info->chan_info.ch_width;
 		}
 		hdd_save_bss_info(adapter, roam_info);
 	}
diff --git a/core/hdd/src/wlan_hdd_debugfs_connect.c b/core/hdd/src/wlan_hdd_debugfs_connect.c
new file mode 100644
index 0000000..107a74b
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_debugfs_connect.c
@@ -0,0 +1,452 @@
+
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: wlan_hdd_debugfs_connect.c
+ *
+ * WLAN Host Device Driver implementation to update
+ * debugfs with connect information
+ */
+
+#include <wlan_hdd_debugfs_csr.h>
+#include <wlan_hdd_main.h>
+#include <cds_sched.h>
+#include <wma_api.h>
+#include "qwlan_version.h"
+#include "wmi_unified_param.h"
+
+/**
+ * wlan_hdd_version_info_debugfs() - Populate driver, FW and HW version
+ * @hdd_ctx: pointer to hdd context
+ * @buf: output buffer to hold version info
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes populated by this function in buffer
+ */
+static ssize_t
+wlan_hdd_version_info_debugfs(struct hdd_context *hdd_ctx, uint8_t *buf,
+			      ssize_t buf_avail_len)
+{
+	uint32_t major_spid = 0, minor_spid = 0, siid = 0, crmid = 0, sub_id;
+	ssize_t length = 0;
+	int ret_val;
+
+	hdd_get_fw_version(hdd_ctx, &major_spid, &minor_spid, &siid, &crmid);
+	sub_id = (hdd_ctx->target_fw_vers_ext & 0xf0000000) >> 28;
+
+	ret_val = scnprintf(buf, buf_avail_len,
+			    "\nVERSION DETAILS\n");
+	if (ret_val <= 0)
+		return length;
+	length += ret_val;
+
+	if (length >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+
+	ret_val = scnprintf(buf + length, buf_avail_len - length,
+			    "Host Driver Version: %s\n"
+			    "Firmware Version: %d.%d.%d.%d.%d\n"
+			    "Hardware Version: %s\n",
+			    QWLAN_VERSIONSTR,
+			    major_spid, minor_spid, siid, crmid, sub_id,
+			    hdd_ctx->target_hw_name);
+	if (ret_val <= 0)
+		return length;
+
+	length += ret_val;
+
+	return length;
+}
+
+/**
+ * wlan_hdd_add_nss_info() - Populate NSS info
+ * @conn_info: station connection information
+ * @buf: output buffer to hold version info
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes populated by this function in buffer
+ */
+static ssize_t
+wlan_hdd_add_nss_info(struct hdd_connection_info *conn_info,
+		      uint8_t *buf, ssize_t buf_avail_len)
+{
+	ssize_t length = 0;
+	int ret_val;
+
+	if (!conn_info->conn_flag.ht_present &&
+	    !conn_info->conn_flag.vht_present)
+		return length;
+
+	ret_val = scnprintf(buf, buf_avail_len,
+			    "nss = %u\n",
+			    conn_info->txrate.nss);
+	if (ret_val <= 0)
+		return length;
+
+	length = ret_val;
+	return length;
+}
+
+/**
+ * wlan_hdd_add_ht_cap_info() - Populate HT info
+ * @conn_info: station connection information
+ * @buf: output buffer to hold version info
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes populated by this function in buffer
+ */
+static ssize_t
+wlan_hdd_add_ht_cap_info(struct hdd_connection_info *conn_info,
+			 uint8_t *buf, ssize_t buf_avail_len)
+{
+	struct ieee80211_ht_cap *ht_caps;
+	ssize_t length = 0;
+	int ret;
+
+	if (!conn_info->conn_flag.ht_present)
+		return length;
+
+	ht_caps = &conn_info->ht_caps;
+	ret = scnprintf(buf, buf_avail_len,
+			"ht_cap_info = %x\n"
+			"ampdu_params_info = %x\n"
+			"extended_ht_cap_info = %x\n"
+			"tx_BF_cap_info = %x\n"
+			"antenna_selection_info = %x\n"
+			"ht_rx_higest = %x\n"
+			"ht_tx_params = %x\n",
+			ht_caps->cap_info,
+			ht_caps->ampdu_params_info,
+			ht_caps->extended_ht_cap_info,
+			ht_caps->tx_BF_cap_info,
+			ht_caps->antenna_selection_info,
+			ht_caps->mcs.rx_highest,
+			ht_caps->mcs.tx_params);
+	if (ret <= 0)
+		return length;
+
+	length = ret;
+	return length;
+}
+
+/**
+ * wlan_hdd_add_vht_cap_info() - Populate VHT info
+ * @conn_info: station connection information
+ * @buf: output buffer to hold version info
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes populated by this function in buffer
+ */
+static ssize_t
+wlan_hdd_add_vht_cap_info(struct hdd_connection_info *conn_info,
+			  uint8_t *buf, ssize_t buf_avail_len)
+{
+	struct ieee80211_vht_cap *vht_caps;
+	ssize_t length = 0;
+	int ret;
+
+	if (!conn_info->conn_flag.vht_present)
+		return length;
+
+	vht_caps = &conn_info->vht_caps;
+	ret = scnprintf(buf, buf_avail_len,
+			"vht_cap_info = %x\n"
+			"rx_mcs_map = %x\n"
+			"rx_highest = %x\n"
+			"tx_mcs_map = %x\n"
+			"tx_highest = %x\n",
+			vht_caps->vht_cap_info,
+			vht_caps->supp_mcs.rx_mcs_map,
+			vht_caps->supp_mcs.rx_highest,
+			vht_caps->supp_mcs.tx_mcs_map,
+			vht_caps->supp_mcs.tx_highest);
+	if (ret <= 0)
+		return length;
+
+	length = ret;
+	return length;
+}
+
+/**
+ * hdd_auth_type_str() - Get string for enum csr auth type
+ * @auth_type: authentication id
+ *
+ * Return: Meaningful string for enum csr auth type
+ */
+static
+uint8_t *hdd_auth_type_str(uint32_t auth_type)
+{
+	switch (auth_type) {
+	case eCSR_AUTH_TYPE_OPEN_SYSTEM:
+		return "OPEN SYSTEM";
+	case eCSR_AUTH_TYPE_SHARED_KEY:
+		return "SHARED KEY";
+	case eCSR_AUTH_TYPE_WPA:
+		return "WPA";
+	case eCSR_AUTH_TYPE_WPA_PSK:
+		return "WPA PSK";
+	case eCSR_AUTH_TYPE_AUTOSWITCH:
+		return "AUTO SWITCH";
+	case eCSR_AUTH_TYPE_WPA_NONE:
+		return "WPA NONE";
+	case eCSR_AUTH_TYPE_RSN:
+		return "RSN";
+	case eCSR_AUTH_TYPE_RSN_PSK:
+		return "RSN PSK";
+	case eCSR_AUTH_TYPE_FT_RSN:
+		return "FT RSN";
+	case eCSR_AUTH_TYPE_FT_RSN_PSK:
+		return "FT RSN PSK";
+	case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
+		return "WAPI WAI CERTIFICATE";
+	case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
+		return "WAPI WAI PSK";
+	case eCSR_AUTH_TYPE_CCKM_WPA:
+		return "CCKM WPA";
+	case eCSR_AUTH_TYPE_CCKM_RSN:
+		return "CCKM RSN";
+	case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
+		return "RSN PSK SHA256";
+	case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
+		return "RSN 8021X SHA256";
+	case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
+		return "NUM OF SUPPORT AUTH TYPE";
+	case eCSR_AUTH_TYPE_FAILED:
+		return "FAILED";
+	case eCSR_AUTH_TYPE_NONE:
+		return "NONE";
+	}
+
+	return "UNKNOWN";
+}
+
+/**
+ * hdd_dot11_mode_str() - Get string for enum csr dot11 mode
+ * @dot11mode: dot11 mode ID
+ *
+ * Return: Meaningful string for enum csr dot11 mode
+ */
+static
+uint8_t *hdd_dot11_mode_str(uint32_t dot11mode)
+{
+	switch (dot11mode) {
+	case eCSR_CFG_DOT11_MODE_11A:
+		return "DOT11 MODE 11A";
+	case eCSR_CFG_DOT11_MODE_11B:
+		return "DOT11 MODE 11B";
+	case eCSR_CFG_DOT11_MODE_11G:
+		return "DOT11 MODE 11G";
+	case eCSR_CFG_DOT11_MODE_11N:
+		return "DOT11 MODE 11N";
+	case eCSR_CFG_DOT11_MODE_11AC:
+		return "DOT11 MODE 11AC";
+	case eCSR_CFG_DOT11_MODE_AUTO:
+		return "DOT11 MODE AUTO";
+	case eCSR_CFG_DOT11_MODE_ABG:
+		return "DOT11 MODE 11ABG";
+	}
+
+	return "UNKNOWN";
+}
+
+/**
+ * hdd_ch_width_str() - Get string for channel width
+ * @ch_width: channel width from connect info
+ *
+ * Return: User readable string for channel width
+ */
+static
+uint8_t *hdd_ch_width_str(enum phy_ch_width ch_width)
+{
+	switch (ch_width) {
+	case CH_WIDTH_20MHZ:
+		return "20MHz";
+	case CH_WIDTH_40MHZ:
+		return "40MHz";
+	case CH_WIDTH_80MHZ:
+		return "80MHz";
+	case CH_WIDTH_160MHZ:
+		return "160MHz";
+	case CH_WIDTH_80P80MHZ:
+		return "(80 + 80)MHz";
+	case CH_WIDTH_5MHZ:
+		return "5MHz";
+	case CH_WIDTH_10MHZ:
+		return "10MHz";
+	case CH_WIDTH_INVALID:
+		/* Fallthrough */
+	case CH_WIDTH_MAX:
+		/* Fallthrough */
+	default:
+		return "UNKNOWN";
+	}
+}
+
+/**
+ * wlan_hdd_connect_info_debugfs() - Populate connect info
+ * @adapter: pointer to sta adapter for which connect info is required
+ * @buf: output buffer to hold version info
+ * @buf_avail_len: available buffer length
+ *
+ * Return: No.of bytes populated by this function in buffer
+ */
+static ssize_t
+wlan_hdd_connect_info_debugfs(struct hdd_adapter *adapter, uint8_t *buf,
+			      ssize_t buf_avail_len)
+{
+	ssize_t length = 0;
+	struct hdd_station_ctx *hdd_sta_ctx;
+	struct hdd_connection_info *conn_info;
+	uint32_t bit_rate;
+	int ret_val;
+
+	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	if (hdd_sta_ctx->conn_info.connState != eConnectionState_Associated) {
+		ret_val = scnprintf(buf, buf_avail_len,
+				    "\nSTA is not connected\n");
+		if (ret_val >= 0)
+			length = ret_val;
+		return length;
+	}
+
+	ret_val = scnprintf(buf, buf_avail_len,
+			    "\nCONNECTION DETAILS\n");
+	if (ret_val <= 0)
+		return length;
+	length += ret_val;
+
+	if (length >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+
+	if (hdd_sta_ctx->hdd_reassoc_scenario) {
+		ret_val = scnprintf(buf + length, buf_avail_len - length,
+				    "Roaming is in progress");
+		if (ret_val <= 0)
+			return length;
+		length += ret_val;
+	}
+
+	conn_info = &hdd_sta_ctx->conn_info;
+	bit_rate = cfg80211_calculate_bitrate(&conn_info->txrate);
+
+	if (length >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+	ret_val = scnprintf(buf + length, buf_avail_len - length,
+			    "ssid = %s\n"
+			    "bssid = " MAC_ADDRESS_STR "\n"
+			    "connect_time = %s\n"
+			    "auth_time = %s\n"
+			    "freq = %u\n"
+			    "ch_width = %s\n"
+			    "signal = %ddBm\n"
+			    "bit_rate = %u\n"
+			    "last_auth_type = %s\n"
+			    "dot11Mode = %s\n",
+			    conn_info->last_ssid.SSID.ssId,
+			    MAC_ADDR_ARRAY(conn_info->bssId.bytes),
+			    conn_info->connect_time,
+			    conn_info->auth_time,
+			    conn_info->freq,
+			    hdd_ch_width_str(conn_info->ch_width),
+			    conn_info->signal,
+			    bit_rate,
+			    hdd_auth_type_str(conn_info->last_auth_type),
+			    hdd_dot11_mode_str(conn_info->dot11Mode));
+
+	if (ret_val <= 0)
+		return length;
+	length += ret_val;
+
+	if (length >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+	length += wlan_hdd_add_nss_info(conn_info, buf + length,
+					buf_avail_len - length);
+
+	if (length >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+
+	length += wlan_hdd_add_ht_cap_info(conn_info, buf + length,
+					   buf_avail_len - length);
+
+	if (length >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+	length += wlan_hdd_add_vht_cap_info(conn_info, buf + length,
+					    buf_avail_len - length);
+	return length;
+}
+
+ssize_t
+wlan_hdd_debugfs_update_connect_info(struct hdd_context *hdd_ctx,
+				     struct hdd_adapter *adapter,
+				     uint8_t *buf, ssize_t buf_avail_len)
+{
+	ssize_t len;
+	int ret_val;
+
+	hdd_enter();
+
+	len = wlan_hdd_current_time_info_debugfs(buf, buf_avail_len);
+	if (len >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+
+	if (adapter->device_mode != QDF_STA_MODE) {
+		ret_val = scnprintf(buf + len, buf_avail_len - len,
+				    "Interface is not operating STA Mode\n");
+		if (ret_val <= 0)
+			return len;
+
+		len += ret_val;
+		return len;
+	}
+
+	if (len >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+	len += wlan_hdd_version_info_debugfs(hdd_ctx, buf + len,
+					     buf_avail_len - len);
+
+	if (len >= buf_avail_len) {
+		hdd_err("No sufficient buf_avail_len");
+		return buf_avail_len;
+	}
+	len += wlan_hdd_connect_info_debugfs(adapter, buf + len,
+					     buf_avail_len - len);
+
+	hdd_exit();
+
+	return len;
+}
diff --git a/core/hdd/src/wlan_hdd_debugfs_csr.c b/core/hdd/src/wlan_hdd_debugfs_csr.c
index eb6f976..9dfc2f4 100644
--- a/core/hdd/src/wlan_hdd_debugfs_csr.c
+++ b/core/hdd/src/wlan_hdd_debugfs_csr.c
@@ -76,6 +76,8 @@
 	switch (id) {
 	case HDD_DEBUFS_FILE_ID_CONNECT_INFO:
 		/* populate connect info */
+		len = wlan_hdd_debugfs_update_connect_info(hdd_ctx, adapter,
+							   buf, buf_avail_len);
 		break;
 	case HDD_DEBUFS_FILE_ID_ROAM_SCAN_STATS_INFO:
 		/* populate roam scan stats info */
@@ -317,10 +319,26 @@
 
 void wlan_hdd_debugfs_csr_init(struct hdd_adapter *adapter)
 {
+	struct hdd_debugfs_file_info *csr;
+	const uint32_t max_len = HDD_DEBUGFS_FILE_NAME_MAX;
+
 	/*
 	 * Create debufs diagnostic files for connect, offload info
 	 * and roam info and store in csr_file member of adapter
 	 */
+
+	csr = &adapter->csr_file[HDD_DEBUFS_FILE_ID_CONNECT_INFO];
+	if (!csr->entry) {
+		strlcpy(csr->name, "connect_info", max_len);
+		csr->id = HDD_DEBUFS_FILE_ID_CONNECT_INFO;
+		csr->buf_max_size = DEBUGFS_CONNECT_INFO_BUF_SIZE;
+		csr->entry = debugfs_create_file(csr->name, 0444,
+						 adapter->debugfs_phy,
+						 csr, &fops_csr_debugfs);
+		if (!csr->entry)
+			hdd_err("Failed to create debugfs file: %s",
+				csr->name);
+	}
 }
 
 void wlan_hdd_debugfs_csr_deinit(struct hdd_adapter *adapter)
diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c
index 06c5935..4689bec 100644
--- a/core/sme/src/csr/csr_api_roam.c
+++ b/core/sme/src/csr/csr_api_roam.c
@@ -7960,6 +7960,8 @@
 			roam_info.chan_info.nss = join_rsp->nss;
 			roam_info.chan_info.rate_flags =
 				join_rsp->max_rate_flags;
+			roam_info.chan_info.ch_width =
+				join_rsp->vht_channel_width;
 #ifdef FEATURE_WLAN_TDLS
 			roam_info.tdls_prohibited = join_rsp->tdls_prohibited;
 			roam_info.tdls_chan_swit_prohibited =
@@ -22181,6 +22183,8 @@
 	roam_info->chan_info.nss = roam_synch_data->join_rsp->nss;
 	roam_info->chan_info.rate_flags =
 		roam_synch_data->join_rsp->max_rate_flags;
+	roam_info->chan_info.ch_width =
+		roam_synch_data->join_rsp->vht_channel_width;
 	csr_roam_fill_tdls_info(mac_ctx, roam_info, roam_synch_data->join_rsp);
 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
 	src_profile = &roam_synch_data->join_rsp->HTProfile;