diff options
| author | Rajeev Kumar Sirasanagandla <rsirasan@codeaurora.org> | 2018-03-12 08:44:51 +0530 |
|---|---|---|
| committer | nshrivas <nshrivas@codeaurora.org> | 2018-03-19 03:47:54 -0700 |
| commit | cae0cc7ed2f6cebb009d508126fa2508235302e2 (patch) | |
| tree | 766f453a978c9be74d03ed155e92b802c14cd9d7 | |
| parent | ad9a7ba2ceb0a05b3cbe64170fe164db3572c133 (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-- | Kbuild | 1 | ||||
| -rw-r--r-- | core/hdd/inc/wlan_hdd_assoc.h | 4 | ||||
| -rw-r--r-- | core/hdd/inc/wlan_hdd_debugfs_csr.h | 31 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_assoc.c | 21 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_debugfs_connect.c | 384 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_debugfs_csr.c | 17 |
6 files changed, 458 insertions, 0 deletions
@@ -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) |
