From b9c36856fa2e05dac6fa15b18a42d8769596e769 Mon Sep 17 00:00:00 2001 From: Bapiraju Alla Date: Mon, 3 Feb 2020 17:19:44 +0530 Subject: [PATCH] qcacld-3.0: Periodically print ARP and DNS stats after STA association Currently no stats were printed related to ARP and DNS frames at STA after initial association or after roaming complete. To print these logs, add INI configuration and a periodic timer to print ARP and DNS stats after initial association or after roaming complete. This is an optional feature controlled by 'WLAN_FEATURE_PERIODIC_STA_STATS' flag. Change-Id: I373632cc35584728c5b556bb28eda1077d51fd9b CRs-Fixed: 2619383 --- Kbuild | 5 + core/hdd/inc/hdd_config.h | 65 ++++++++++ core/hdd/inc/wlan_hdd_cfg.h | 7 ++ core/hdd/inc/wlan_hdd_main.h | 8 ++ core/hdd/inc/wlan_hdd_periodic_sta_stats.h | 114 +++++++++++++++++ core/hdd/src/wlan_hdd_assoc.c | 5 + core/hdd/src/wlan_hdd_main.c | 8 ++ core/hdd/src/wlan_hdd_periodic_sta_stats.c | 139 +++++++++++++++++++++ 8 files changed, 351 insertions(+) create mode 100644 core/hdd/inc/wlan_hdd_periodic_sta_stats.h create mode 100644 core/hdd/src/wlan_hdd_periodic_sta_stats.c diff --git a/Kbuild b/Kbuild index e08db33f8af3..44264c04bf4c 100644 --- a/Kbuild +++ b/Kbuild @@ -84,6 +84,10 @@ HDD_OBJS := $(HDD_SRC_DIR)/wlan_hdd_assoc.o \ $(HDD_SRC_DIR)/wlan_hdd_wmm.o \ $(HDD_SRC_DIR)/wlan_hdd_wowl.o +ifeq ($(CONFIG_WLAN_FEATURE_PERIODIC_STA_STATS), y) +HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_periodic_sta_stats.o +endif + ifeq ($(CONFIG_WLAN_WEXT_SUPPORT_ENABLE), y) HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_wext.o \ $(HDD_SRC_DIR)/wlan_hdd_hostapd_wext.o @@ -2390,6 +2394,7 @@ cppflags-y += -DMSM_PLATFORM endif cppflags-$(CONFIG_WLAN_FEATURE_DP_BUS_BANDWIDTH) += -DWLAN_FEATURE_DP_BUS_BANDWIDTH +cppflags-$(CONFIG_WLAN_FEATURE_PERIODIC_STA_STATS) += -DWLAN_FEATURE_PERIODIC_STA_STATS cppflags-y += -DQCA_SUPPORT_TXRX_LOCAL_PEER_ID diff --git a/core/hdd/inc/hdd_config.h b/core/hdd/inc/hdd_config.h index c5dde815b54e..acb902394a2f 100644 --- a/core/hdd/inc/hdd_config.h +++ b/core/hdd/inc/hdd_config.h @@ -1362,6 +1362,70 @@ struct dhcp_server { CFG_VALUE_OR_DEFAULT, \ "Disable wow feature") +#ifdef WLAN_FEATURE_PERIODIC_STA_STATS +/* + * + * periodic_stats_timer_interval - Print selective stats on this specified + * interval + * + * @Min: 0 + * @Max: 10000 + * Default: 3000 + * + * This ini is used to specify interval in milliseconds for periodic stats + * timer. This timer will print selective stats after expiration of each + * interval. STA starts this periodic timer after initial connection or after + * roaming is successful. This will be restarted for every + * periodic_stats_timer_interval till the periodic_stats_timer_duration expires. + * + * Supported Feature: STA + * + * Usage: Internal + * + * + */ +#define CFG_PERIODIC_STATS_TIMER_INTERVAL CFG_INI_UINT( \ + "periodic_stats_timer_interval", \ + 0, \ + 10000, \ + 3000, \ + CFG_VALUE_OR_DEFAULT, \ + "Periodic stats timer interval") + +/* + * + * periodic_stats_timer_duration - Used as duration for which periodic timer + * should run + * + * @Min: 0 + * @Max: 60000 + * Default: 30000 + * + * This ini is used as duration in milliseconds for which periodic stats timer + * should run. This periodic timer will print selective stats for every + * periodic_stats_timer_interval until this duration is reached. + * + * Supported Feature: STA + * + * Usage: Internal + * + * + */ +#define CFG_PERIODIC_STATS_TIMER_DURATION CFG_INI_UINT( \ + "periodic_stats_timer_duration", \ + 0, \ + 60000, \ + 30000, \ + CFG_VALUE_OR_DEFAULT, \ + "Periodic stats timer duration") + +#define CFG_WLAN_STA_PERIODIC_STATS \ + CFG(CFG_PERIODIC_STATS_TIMER_DURATION) \ + CFG(CFG_PERIODIC_STATS_TIMER_INTERVAL) +#else +#define CFG_WLAN_STA_PERIODIC_STATS +#endif /* WLAN_FEATURE_PERIODIC_STA_STATS */ + /** * enum host_log_level - Debug verbose level imposed by user * @HOST_LOG_LEVEL_NONE: no trace will be logged. @@ -1478,6 +1542,7 @@ enum host_log_level { CFG_VC_MODE_BITMAP_ALL \ CFG_WLAN_AUTO_SHUTDOWN_ALL \ CFG_WLAN_LOGGING_SUPPORT_ALL \ + CFG_WLAN_STA_PERIODIC_STATS \ CFG(CFG_ACTION_OUI_CCKM_1X1) \ CFG(CFG_ACTION_OUI_CONNECT_1X1) \ CFG(CFG_ACTION_OUI_CONNECT_1X1_WITH_1_CHAIN) \ diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index 069356d61d73..9288c980844f 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -244,6 +244,13 @@ struct hdd_config { #endif bool get_roam_chan_from_fw; uint32_t fisa_enable; + +#ifdef WLAN_FEATURE_PERIODIC_STA_STATS + /* Periodicity of logging */ + uint32_t periodic_stats_timer_interval; + /* Duration for which periodic logging should be done */ + uint32_t periodic_stats_timer_duration; +#endif /* WLAN_FEATURE_PERIODIC_STA_STATS */ }; /** diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 5f20ffc8a3e9..72a19c59d34e 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1315,6 +1315,14 @@ struct hdd_adapter { uint32_t motion_det_baseline_value; #endif /* WLAN_FEATURE_MOTION_DETECTION */ enum qca_disconnect_reason_codes last_disconnect_reason; + +#ifdef WLAN_FEATURE_PERIODIC_STA_STATS + /* Indicate whether to display sta periodic stats */ + bool is_sta_periodic_stats_enabled; + uint16_t periodic_stats_timer_count; + uint32_t periodic_stats_timer_counter; + qdf_mutex_t sta_periodic_stats_lock; +#endif /* WLAN_FEATURE_PERIODIC_STA_STATS */ }; #define WLAN_HDD_GET_STATION_CTX_PTR(adapter) (&(adapter)->session.station) diff --git a/core/hdd/inc/wlan_hdd_periodic_sta_stats.h b/core/hdd/inc/wlan_hdd_periodic_sta_stats.h new file mode 100644 index 000000000000..61725404d760 --- /dev/null +++ b/core/hdd/inc/wlan_hdd_periodic_sta_stats.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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_periodic_sta_stats.h + * + * WLAN Host Device Driver periodic STA statistics related implementation + * + */ + +#if !defined(WLAN_HDD_PERIODIC_STA_STATS_H) +#define WLAN_HDD_PERIODIC_STA_STATS_H + +#ifdef WLAN_FEATURE_PERIODIC_STA_STATS +/* + * Used to get device name from the adapter + */ +#define WLAN_HDD_GET_DEV_NAME(adapter) ((adapter)->dev->name) + +/** + * hdd_periodic_sta_stats_config() - Initialize periodic stats configuration + * @config: Pointer to hdd configuration + * @psoc: Pointer to psoc + * + * Return: none + */ +void hdd_periodic_sta_stats_config(struct hdd_config *config, + struct wlan_objmgr_psoc *psoc); + +/** + * hdd_periodic_sta_stats_init() - Initialize periodic stats display flag + * @adapter: Pointer to the station adapter + * + * Return: none + */ +void hdd_periodic_sta_stats_init(struct hdd_adapter *adapter); + +/** + * hdd_periodic_sta_stats_display() - Display periodic stats at STA + * @hdd_ctx: hdd context + * + * Return: none + */ +void hdd_periodic_sta_stats_display(struct hdd_context *hdd_ctx); + +/** + * hdd_periodic_sta_stats_start() - Start displaying periodic stats for STA + * @adapter: Pointer to the station adapter + * + * Return: none + */ +void hdd_periodic_sta_stats_start(struct hdd_adapter *adapter); + +/** + * hdd_periodic_sta_stats_stop() - Stop displaying periodic stats for STA + * @adapter: Pointer to the station adapter + * + * Return: none + */ +void hdd_periodic_sta_stats_stop(struct hdd_adapter *adapter); + +/** + * hdd_periodic_sta_stats_mutex_create() - Create mutex for STA periodic stats + * @adapter: Pointer to the station adapter + * + * Return: none + */ +void hdd_periodic_sta_stats_mutex_create(struct hdd_adapter *adapter); + +/** + * hdd_periodic_sta_stats_mutex_destroy() - Destroy STA periodic stats mutex + * @adapter: Pointer to the station adapter + * + * Return: none + */ +void hdd_periodic_sta_stats_mutex_destroy(struct hdd_adapter *adapter); + +#else +static inline void +hdd_periodic_sta_stats_display(struct hdd_context *hdd_ctx) {} + +static inline void +hdd_periodic_sta_stats_config(struct hdd_config *config, + struct wlan_objmgr_psoc *psoc) {} + +static inline void hdd_periodic_sta_stats_start(struct hdd_adapter *adapter) {} + +static inline void hdd_periodic_sta_stats_stop(struct hdd_adapter *adapter) {} + +static inline void +hdd_periodic_sta_stats_init(struct hdd_adapter *adapter) {} + +static inline void +hdd_periodic_sta_stats_mutex_create(struct hdd_adapter *adapter) {} + +static inline void +hdd_periodic_sta_stats_mutex_destroy(struct hdd_adapter *adapter) {} + +#endif /* end #ifdef WLAN_FEATURE_PERIODIC_STA_STATS */ + +#endif /* end #if !defined(WLAN_HDD_PERIODIC_STA_STATS_H) */ diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 10f7b94d4a67..169f2f3b66cd 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -72,6 +72,7 @@ #include "wlan_blm_ucfg_api.h" #include "wlan_hdd_sta_info.h" #include "wlan_hdd_ftm_time_sync.h" +#include "wlan_hdd_periodic_sta_stats.h" #include #include "wlan_pkt_capture_ucfg_api.h" @@ -1722,6 +1723,8 @@ static QDF_STATUS hdd_dis_connect_handler(struct hdd_adapter *adapter, WLAN_IPA_STA_DISCONNECT, sta_ctx->conn_info.bssid.bytes); + hdd_periodic_sta_stats_stop(adapter); + #ifdef FEATURE_WLAN_AUTO_SHUTDOWN wlan_hdd_auto_shutdown_enable(hdd_ctx, true); #endif @@ -3640,6 +3643,8 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, policy_mgr_check_concurrent_intf_and_restart_sap(hdd_ctx->psoc); } + hdd_periodic_sta_stats_start(adapter); + return QDF_STATUS_SUCCESS; } diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 7aa815c58d66..b07bf368d0be 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -48,6 +48,7 @@ #include "wlan_hdd_ftm.h" #include "wlan_hdd_power.h" #include "wlan_hdd_stats.h" +#include "wlan_hdd_periodic_sta_stats.h" #include "wlan_hdd_scan.h" #include "wlan_policy_mgr_ucfg.h" #include "wlan_osif_priv.h" @@ -5238,6 +5239,7 @@ static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx, hdd_nud_deinit_tracking(adapter); hdd_mic_deinit_work(adapter); qdf_mutex_destroy(&adapter->disconnection_status_lock); + hdd_periodic_sta_stats_mutex_destroy(adapter); hdd_apf_context_destroy(adapter); qdf_spinlock_destroy(&adapter->vdev_lock); hdd_sta_info_deinit(&adapter->sta_info_list); @@ -5896,6 +5898,7 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio adapter->device_mode == QDF_P2P_DEVICE_MODE) hdd_sysfs_create_adapter_root_obj(adapter); qdf_mutex_create(&adapter->disconnection_status_lock); + hdd_periodic_sta_stats_mutex_create(adapter); break; @@ -6028,6 +6031,8 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio if (adapter->device_mode == QDF_STA_MODE) wlan_hdd_debugfs_csr_init(adapter); + hdd_periodic_sta_stats_init(adapter); + return adapter; err_free_netdev: @@ -8808,6 +8813,8 @@ static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx, } hdd_display_periodic_stats(hdd_ctx, (total_pkts > 0) ? true : false); + + hdd_periodic_sta_stats_display(hdd_ctx); } #ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK @@ -10614,6 +10621,7 @@ static void hdd_cfg_params_init(struct hdd_context *hdd_ctx) config->enable_sar_conversion = cfg_get(psoc, CFG_SAR_CONVERSION); config->is_wow_disabled = cfg_get(psoc, CFG_WOW_DISABLE); + hdd_periodic_sta_stats_config(config, psoc); hdd_init_vc_mode_cfg_bitmap(config, psoc); hdd_init_runtime_pm(config, psoc); hdd_init_wlan_auto_shutdown(config, psoc); diff --git a/core/hdd/src/wlan_hdd_periodic_sta_stats.c b/core/hdd/src/wlan_hdd_periodic_sta_stats.c new file mode 100644 index 000000000000..1627f8528a1f --- /dev/null +++ b/core/hdd/src/wlan_hdd_periodic_sta_stats.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * 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_periodic_sta_stats.c + * + * WLAN Host Device Driver periodic STA statistics related implementation + * + */ + +#include "wlan_hdd_main.h" +#include "cfg_ucfg_api.h" +#include "wlan_hdd_periodic_sta_stats.h" + +void hdd_periodic_sta_stats_config(struct hdd_config *config, + struct wlan_objmgr_psoc *psoc) +{ + config->periodic_stats_timer_interval = + cfg_get(psoc, CFG_PERIODIC_STATS_TIMER_INTERVAL); + config->periodic_stats_timer_duration = + cfg_get(psoc, CFG_PERIODIC_STATS_TIMER_DURATION); +} + +void hdd_periodic_sta_stats_init(struct hdd_adapter *adapter) +{ + adapter->is_sta_periodic_stats_enabled = false; +} + +void hdd_periodic_sta_stats_display(struct hdd_context *hdd_ctx) +{ + struct hdd_adapter *adapter; + struct hdd_stats sta_stats; + struct hdd_config *hdd_cfg; + char *dev_name; + bool should_log; + + if (!hdd_ctx) + return; + + hdd_for_each_adapter(hdd_ctx, adapter) { + should_log = false; + + if (adapter->device_mode != QDF_STA_MODE) + continue; + + hdd_cfg = hdd_ctx->config; + qdf_mutex_acquire(&adapter->sta_periodic_stats_lock); + + if (!adapter->is_sta_periodic_stats_enabled) { + qdf_mutex_release(&adapter->sta_periodic_stats_lock); + continue; + } + + adapter->periodic_stats_timer_counter++; + if ((adapter->periodic_stats_timer_counter * + GET_BW_COMPUTE_INTV(hdd_cfg)) >= + hdd_cfg->periodic_stats_timer_interval) { + should_log = true; + + adapter->periodic_stats_timer_count--; + if (adapter->periodic_stats_timer_count == 0) + adapter->is_sta_periodic_stats_enabled = false; + adapter->periodic_stats_timer_counter = 0; + } + qdf_mutex_release(&adapter->sta_periodic_stats_lock); + + if (should_log) { + dev_name = WLAN_HDD_GET_DEV_NAME(adapter); + sta_stats = adapter->hdd_stats; + hdd_nofl_info("%s: Tx ARP requests: %d", dev_name, + sta_stats.hdd_arp_stats.tx_arp_req_count); + hdd_nofl_info("%s: Rx ARP responses: %d", dev_name, + sta_stats.hdd_arp_stats.rx_arp_rsp_count); + hdd_nofl_info("%s: Tx DNS requests: %d", dev_name, + sta_stats.hdd_dns_stats.tx_dns_req_count); + hdd_nofl_info("%s: Rx DNS responses: %d", dev_name, + sta_stats.hdd_dns_stats.rx_dns_rsp_count); + } + } +} + +void hdd_periodic_sta_stats_start(struct hdd_adapter *adapter) +{ + struct hdd_config *hdd_cfg = adapter->hdd_ctx->config; + + if ((adapter->device_mode == QDF_STA_MODE) && + (hdd_cfg->periodic_stats_timer_interval > 0)) { + qdf_mutex_acquire(&adapter->sta_periodic_stats_lock); + + adapter->periodic_stats_timer_count = + hdd_cfg->periodic_stats_timer_duration / + hdd_cfg->periodic_stats_timer_interval; + adapter->periodic_stats_timer_counter = 0; + if (adapter->periodic_stats_timer_count > 0) + adapter->is_sta_periodic_stats_enabled = true; + + qdf_mutex_release(&adapter->sta_periodic_stats_lock); + } +} + +void hdd_periodic_sta_stats_stop(struct hdd_adapter *adapter) +{ + struct hdd_config *hdd_cfg = adapter->hdd_ctx->config; + + if ((adapter->device_mode == QDF_STA_MODE) && + (hdd_cfg->periodic_stats_timer_interval > 0)) { + qdf_mutex_acquire(&adapter->sta_periodic_stats_lock); + + /* Stop the periodic ARP and DNS stats timer */ + adapter->periodic_stats_timer_count = 0; + adapter->is_sta_periodic_stats_enabled = false; + + qdf_mutex_release(&adapter->sta_periodic_stats_lock); + } +} + +void hdd_periodic_sta_stats_mutex_create(struct hdd_adapter *adapter) +{ + qdf_mutex_create(&adapter->sta_periodic_stats_lock); +} + +void hdd_periodic_sta_stats_mutex_destroy(struct hdd_adapter *adapter) +{ + qdf_mutex_destroy(&adapter->sta_periodic_stats_lock); +} +