summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRajeev Kumar Sirasanagandla <rsirasan@codeaurora.org>2018-03-12 08:44:51 +0530
committernshrivas <nshrivas@codeaurora.org>2018-03-19 03:47:54 -0700
commitcae0cc7ed2f6cebb009d508126fa2508235302e2 (patch)
tree766f453a978c9be74d03ed155e92b802c14cd9d7
parentad9a7ba2ceb0a05b3cbe64170fe164db3572c133 (diff)
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
-rw-r--r--Kbuild1
-rw-r--r--core/hdd/inc/wlan_hdd_assoc.h4
-rw-r--r--core/hdd/inc/wlan_hdd_debugfs_csr.h31
-rw-r--r--core/hdd/src/wlan_hdd_assoc.c21
-rw-r--r--core/hdd/src/wlan_hdd_debugfs_connect.c384
-rw-r--r--core/hdd/src/wlan_hdd_debugfs_csr.c17
6 files changed, 458 insertions, 0 deletions
diff --git a/Kbuild b/Kbuild
index 6e516ca0e490..37f756e75fe0 100644
--- a/Kbuild
+++ b/Kbuild
@@ -464,6 +464,7 @@ ifeq ($(CONFIG_WLAN_DEBUGFS), y)
HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs.o
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
ifeq ($(CONFIG_WLAN_FEATURE_DSRC), y)
diff --git a/core/hdd/inc/wlan_hdd_assoc.h b/core/hdd/inc/wlan_hdd_assoc.h
index 0505964a160e..2e5248a6029b 100644
--- a/core/hdd/inc/wlan_hdd_assoc.h
+++ b/core/hdd/inc/wlan_hdd_assoc.h
@@ -179,6 +179,8 @@ struct hdd_conn_flag {
* @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
*/
typedef struct connection_info_s {
eConnectionState connState;
@@ -213,6 +215,8 @@ typedef struct connection_info_s {
uint32_t cca;
tCsrSSIDInfo last_ssid;
eCsrAuthType last_auth_type;
+ char auth_time[HDD_TIME_STRING_LEN];
+ char connect_time[HDD_TIME_STRING_LEN];
} connection_info_t;
/* Forward declarations */
diff --git a/core/hdd/inc/wlan_hdd_debugfs_csr.h b/core/hdd/inc/wlan_hdd_debugfs_csr.h
index 751a650c288a..89de04c3b023 100644
--- a/core/hdd/inc/wlan_hdd_debugfs_csr.h
+++ b/core/hdd/inc/wlan_hdd_debugfs_csr.h
@@ -37,6 +37,8 @@
#include <wlan_hdd_includes.h>
+#define DEBUGFS_CONNECT_INFO_BUF_SIZE (4 * 1024)
+
/**
* struct wlan_hdd_debugfs_buffer_info - Debugfs buffer info
* @length: current length of the debugfs buffer
@@ -83,6 +85,19 @@ void wlan_hdd_debugfs_csr_deinit(hdd_adapter_t *adapter);
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(hdd_context_t *hdd_ctx,
+ hdd_adapter_t *adapter,
+ uint8_t *buf, ssize_t buf_avail_len);
+
#else
/**
* wlan_hdd_debugfs_csr_init() - Create wifi diagnostic debugfs files
@@ -117,6 +132,22 @@ wlan_hdd_current_time_info_debugfs(uint8_t *buf, ssize_t buf_avail_len)
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(hdd_context_t *hdd_ctx,
+ hdd_adapter_t *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 8f3ea5bd65f7..e7bf180cb1fb 100644
--- a/core/hdd/src/wlan_hdd_assoc.c
+++ b/core/hdd/src/wlan_hdd_assoc.c
@@ -154,12 +154,23 @@ hdd_conn_set_authenticated(hdd_adapter_t *pAdapter, uint8_t authState)
{
hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+ char *auth_time;
+ uint32_t time_buffer_size;
/* save the new connection state */
hdd_debug("Authenticated state Changed from oldState:%d to State:%d",
pHddStaCtx->conn_info.uIsAuthenticated, authState);
pHddStaCtx->conn_info.uIsAuthenticated = authState;
+ auth_time = pHddStaCtx->conn_info.auth_time;
+ time_buffer_size = sizeof(pHddStaCtx->conn_info.auth_time);
+
+ if (authState)
+ 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);
+
/* Check is pending ROC request or not when auth state changed */
schedule_delayed_work(&pHddCtx->roc_req_work, 0);
}
@@ -178,6 +189,8 @@ void hdd_conn_set_connection_state(hdd_adapter_t *adapter,
{
hdd_station_ctx_t *hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+ char *connect_time;
+ uint32_t time_buffer_size;
/* save the new connection state */
hdd_debug("%pS Changed conn state from old:%d to new:%d for dev %s",
@@ -189,6 +202,14 @@ void hdd_conn_set_connection_state(hdd_adapter_t *adapter,
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);
+
if (conn_state != eConnectionState_NdiConnected)
schedule_delayed_work(&hdd_ctx->roc_req_work, 0);
}
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 000000000000..cf6c8ff02c91
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_debugfs_connect.c
@@ -0,0 +1,384 @@
+
+/*
+ * 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"
+#include "wlan_hdd_request_manager.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(hdd_context_t *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_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(connection_info_t *conn_info,
+ uint8_t *buf, ssize_t buf_avail_len)
+{
+ struct ieee80211_ht_cap *ht_caps;
+ ssize_t length = 0;
+ int ret_val;
+
+ if (!conn_info->conn_flag.ht_present)
+ return length;
+
+ ht_caps = &conn_info->ht_caps;
+ ret_val = 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_val <= 0)
+ return length;
+
+ length = ret_val;
+ 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(connection_info_t *conn_info,
+ uint8_t *buf, ssize_t buf_avail_len)
+{
+ struct ieee80211_vht_cap *vht_caps;
+ ssize_t length = 0;
+ int ret_val;
+
+ if (!conn_info->conn_flag.vht_present)
+ return length;
+
+ vht_caps = &conn_info->vht_caps;
+ ret_val = 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_val <= 0)
+ return length;
+
+ length = ret_val;
+ 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";
+}
+
+/**
+ * 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(hdd_adapter_t *adapter, uint8_t *buf,
+ ssize_t buf_avail_len)
+{
+ ssize_t length = 0;
+ hdd_station_ctx_t *hdd_sta_ctx;
+ connection_info_t *conn_info;
+ uint32_t bit_rate, bit_rate_compat;
+ 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_ReassocScenario) {
+ 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);
+ bit_rate_compat = bit_rate < (1UL << 16) ? bit_rate : 0;
+
+ 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"
+ "noise = %ddBm\n"
+ "signal = %ddBm\n"
+ "bit_rate = %u\n"
+ "bit_rate_compat = %u\n"
+ "nss = %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,
+ (conn_info->noise + 100),
+ (conn_info->signal + 100),
+ bit_rate,
+ bit_rate_compat,
+ conn_info->txrate.nss,
+ 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_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(hdd_context_t *hdd_ctx,
+ hdd_adapter_t *adapter,
+ uint8_t *buf, ssize_t buf_avail_len)
+{
+ ssize_t len;
+ int ret_val;
+
+ 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);
+
+ return len;
+}
diff --git a/core/hdd/src/wlan_hdd_debugfs_csr.c b/core/hdd/src/wlan_hdd_debugfs_csr.c
index 41906df10e0e..15c046d94e4c 100644
--- a/core/hdd/src/wlan_hdd_debugfs_csr.c
+++ b/core/hdd/src/wlan_hdd_debugfs_csr.c
@@ -74,6 +74,8 @@ wlan_hdd_debugfs_update_csr(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter,
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 */
@@ -293,10 +295,25 @@ static const struct file_operations fops_csr_debugfs = {
void wlan_hdd_debugfs_csr_init(hdd_adapter_t *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 connect_info debugfs file");
+ }
}
void wlan_hdd_debugfs_csr_deinit(hdd_adapter_t *adapter)