From patchwork Thu Apr 19 18:17:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Greear X-Patchwork-Id: 901426 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=candelatech.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40RnKM16m8z9s1v for ; Fri, 20 Apr 2018 04:17:58 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752966AbeDSSR4 (ORCPT ); Thu, 19 Apr 2018 14:17:56 -0400 Received: from mail2.candelatech.com ([208.74.158.173]:37018 "EHLO mail2.candelatech.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752490AbeDSSRz (ORCPT ); Thu, 19 Apr 2018 14:17:55 -0400 Received: from ben-dt3.candelatech.com (firewall.candelatech.com [50.251.239.81]) by mail2.candelatech.com (Postfix) with ESMTP id 00FDE40B146; Thu, 19 Apr 2018 11:17:52 -0700 (PDT) From: greearb@candelatech.com To: netdev@vger.kernel.org Cc: linux-wireless@vger.kernel.org, ath10k@lists.infradead.org, Ben Greear Subject: [PATCH v2 1/3] ethtool: Support ETHTOOL_GSTATS2 command. Date: Thu, 19 Apr 2018 11:17:41 -0700 Message-Id: <1524161863-30860-1-git-send-email-greearb@candelatech.com> X-Mailer: git-send-email 2.4.11 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Ben Greear This is similar to ETHTOOL_GSTATS, but it allows you to specify flags. These flags can be used by the driver to decrease the amount of stats refreshed. In particular, this helps with ath10k since getting the firmware stats can be slow. Signed-off-by: Ben Greear --- v2: Change flag names to ETHTOOL_GS_NO_REFRESH_FW, ETHTOOL_GS2_REFRESH_ALL. include/linux/ethtool.h | 12 ++++++++++++ include/uapi/linux/ethtool.h | 11 +++++++++++ net/core/ethtool.c | 40 +++++++++++++++++++++++++++++++++++----- 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index ebe4181..c90bc6f6 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -243,6 +243,15 @@ bool ethtool_convert_link_mode_to_legacy_u32(u32 *legacy_u32, * @get_ethtool_stats: Return extended statistics about the device. * This is only useful if the device maintains statistics not * included in &struct rtnl_link_stats64. + * @get_ethtool_stats2: Return extended statistics about the device. + * This is only useful if the device maintains statistics not + * included in &struct rtnl_link_stats64. + * Takes a flags argument: 0 means all (same as get_ethtool_stats), + * 0x1 (ETHTOOL_GS2_NO_REFRESH_FW) means skip refreshing firmware stats. + * Other flags are reserved for now. + * Same number of stats will be returned, but some of them might + * not be as accurate/refreshed. This is to allow not querying + * firmware or other expensive-to-read stats, for instance. * @begin: Function to be called before any other operation. Returns a * negative error code or zero. * @complete: Function to be called after any other operation except @@ -355,6 +364,9 @@ struct ethtool_ops { int (*set_phys_id)(struct net_device *, enum ethtool_phys_id_state); void (*get_ethtool_stats)(struct net_device *, struct ethtool_stats *, u64 *); + void (*get_ethtool_stats2)(struct net_device *dev, + struct ethtool_stats *gstats, u64 *data, + u32 flags); int (*begin)(struct net_device *); void (*complete)(struct net_device *); u32 (*get_priv_flags)(struct net_device *); diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h index 4ca65b5..75c753d 100644 --- a/include/uapi/linux/ethtool.h +++ b/include/uapi/linux/ethtool.h @@ -1396,11 +1396,22 @@ enum ethtool_fec_config_bits { #define ETHTOOL_PHY_STUNABLE 0x0000004f /* Set PHY tunable configuration */ #define ETHTOOL_GFECPARAM 0x00000050 /* Get FEC settings */ #define ETHTOOL_SFECPARAM 0x00000051 /* Set FEC settings */ +#define ETHTOOL_GSTATS2 0x00000052 /* get NIC-specific statistics + * with ability to specify flags. + * See ETHTOOL_GS2* below. + */ /* compatibility with older code */ #define SPARC_ETH_GSET ETHTOOL_GSET #define SPARC_ETH_SSET ETHTOOL_SSET +/* GSTATS2 flags */ +#define ETHTOOL_GS2_REFRESH_ALL (0) /* default is to update all stats */ +#define ETHTOOL_GS2_NO_REFRESH_FW (1<<0) /* Skip refreshing stats that probe + * firmware, and thus are + * slow/expensive. + */ + /* Link mode bit indices */ enum ethtool_link_mode_bit_indices { ETHTOOL_LINK_MODE_10baseT_Half_BIT = 0, diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 03416e6..dd16f15 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -1952,16 +1952,14 @@ static int ethtool_phys_id(struct net_device *dev, void __user *useraddr) return rc; } -static int ethtool_get_stats(struct net_device *dev, void __user *useraddr) +static int _ethtool_get_stats(struct net_device *dev, void __user *useraddr, + u32 flags) { struct ethtool_stats stats; const struct ethtool_ops *ops = dev->ethtool_ops; u64 *data; int ret, n_stats; - if (!ops->get_ethtool_stats || !ops->get_sset_count) - return -EOPNOTSUPP; - n_stats = ops->get_sset_count(dev, ETH_SS_STATS); if (n_stats < 0) return n_stats; @@ -1976,7 +1974,10 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr) if (n_stats && !data) return -ENOMEM; - ops->get_ethtool_stats(dev, &stats, data); + if (flags != ETHTOOL_GS2_REFRESH_ALL) + ops->get_ethtool_stats2(dev, &stats, data, flags); + else + ops->get_ethtool_stats(dev, &stats, data); ret = -EFAULT; if (copy_to_user(useraddr, &stats, sizeof(stats))) @@ -1991,6 +1992,31 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr) return ret; } +static int ethtool_get_stats(struct net_device *dev, void __user *useraddr) +{ + const struct ethtool_ops *ops = dev->ethtool_ops; + + if (!ops->get_ethtool_stats || !ops->get_sset_count) + return -EOPNOTSUPP; + return _ethtool_get_stats(dev, useraddr, ETHTOOL_GS2_REFRESH_ALL); +} + +static int ethtool_get_stats2(struct net_device *dev, void __user *useraddr) +{ + struct ethtool_stats stats; + const struct ethtool_ops *ops = dev->ethtool_ops; + u32 flags = 0; + + if (!ops->get_ethtool_stats2 || !ops->get_sset_count) + return -EOPNOTSUPP; + + if (copy_from_user(&stats, useraddr, sizeof(stats))) + return -EFAULT; + + flags = stats.n_stats; + return _ethtool_get_stats(dev, useraddr, flags); +} + static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr) { struct ethtool_stats stats; @@ -2632,6 +2658,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) case ETHTOOL_GSSET_INFO: case ETHTOOL_GSTRINGS: case ETHTOOL_GSTATS: + case ETHTOOL_GSTATS2: case ETHTOOL_GPHYSTATS: case ETHTOOL_GTSO: case ETHTOOL_GPERMADDR: @@ -2742,6 +2769,9 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) case ETHTOOL_GSTATS: rc = ethtool_get_stats(dev, useraddr); break; + case ETHTOOL_GSTATS2: + rc = ethtool_get_stats2(dev, useraddr); + break; case ETHTOOL_GPERMADDR: rc = ethtool_get_perm_addr(dev, useraddr); break; From patchwork Thu Apr 19 18:17:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Greear X-Patchwork-Id: 901427 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=candelatech.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40RnKR273Vz9s1v for ; Fri, 20 Apr 2018 04:18:03 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753117AbeDSSSA (ORCPT ); Thu, 19 Apr 2018 14:18:00 -0400 Received: from mail2.candelatech.com ([208.74.158.173]:37022 "EHLO mail2.candelatech.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752490AbeDSSR6 (ORCPT ); Thu, 19 Apr 2018 14:17:58 -0400 Received: from ben-dt3.candelatech.com (firewall.candelatech.com [50.251.239.81]) by mail2.candelatech.com (Postfix) with ESMTP id B91A140B24A; Thu, 19 Apr 2018 11:17:55 -0700 (PDT) From: greearb@candelatech.com To: netdev@vger.kernel.org Cc: linux-wireless@vger.kernel.org, ath10k@lists.infradead.org, Ben Greear Subject: [PATCH v2 2/3] mac80211: Add support for ethtool gstats2 API. Date: Thu, 19 Apr 2018 11:17:42 -0700 Message-Id: <1524161863-30860-2-git-send-email-greearb@candelatech.com> X-Mailer: git-send-email 2.4.11 In-Reply-To: <1524161863-30860-1-git-send-email-greearb@candelatech.com> References: <1524161863-30860-1-git-send-email-greearb@candelatech.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Ben Greear This enables users to request fewer stats to be refreshed in cases where firmware does not need to be probed. Signed-off-by: Ben Greear --- v2: No changes. include/net/mac80211.h | 6 ++++++ net/mac80211/driver-ops.h | 9 +++++++-- net/mac80211/ethtool.c | 18 +++++++++++++----- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index d2279b2..4854f33 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -3361,6 +3361,8 @@ enum ieee80211_reconfig_type { * * @get_et_stats: Ethtool API to get a set of u64 stats. * + * @get_et_stats2: Ethtool API to get a set of u64 stats, with flags. + * * @get_et_strings: Ethtool API to get a set of strings to describe stats * and perhaps other supported types of ethtool data-sets. * @@ -3692,6 +3694,10 @@ struct ieee80211_ops { void (*get_et_stats)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ethtool_stats *stats, u64 *data); + void (*get_et_stats2)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ethtool_stats *stats, u64 *data, + u32 flags); void (*get_et_strings)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u32 sset, u8 *data); diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 4d82fe7..519d2db 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -58,10 +58,15 @@ static inline void drv_get_et_strings(struct ieee80211_sub_if_data *sdata, static inline void drv_get_et_stats(struct ieee80211_sub_if_data *sdata, struct ethtool_stats *stats, - u64 *data) + u64 *data, u32 flags) { struct ieee80211_local *local = sdata->local; - if (local->ops->get_et_stats) { + if (local->ops->get_et_stats2) { + trace_drv_get_et_stats(local); + local->ops->get_et_stats2(&local->hw, &sdata->vif, stats, data, + flags); + trace_drv_return_void(local); + } else if (local->ops->get_et_stats) { trace_drv_get_et_stats(local); local->ops->get_et_stats(&local->hw, &sdata->vif, stats, data); trace_drv_return_void(local); diff --git a/net/mac80211/ethtool.c b/net/mac80211/ethtool.c index 9cc986d..b67520e 100644 --- a/net/mac80211/ethtool.c +++ b/net/mac80211/ethtool.c @@ -61,9 +61,9 @@ static int ieee80211_get_sset_count(struct net_device *dev, int sset) return rv; } -static void ieee80211_get_stats(struct net_device *dev, - struct ethtool_stats *stats, - u64 *data) +static void ieee80211_get_stats2(struct net_device *dev, + struct ethtool_stats *stats, + u64 *data, u32 flags) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_chanctx_conf *chanctx_conf; @@ -199,7 +199,14 @@ static void ieee80211_get_stats(struct net_device *dev, if (WARN_ON(i != STA_STATS_LEN)) return; - drv_get_et_stats(sdata, stats, &(data[STA_STATS_LEN])); + drv_get_et_stats(sdata, stats, &data[STA_STATS_LEN], flags); +} + +static void ieee80211_get_stats(struct net_device *dev, + struct ethtool_stats *stats, + u64 *data) +{ + ieee80211_get_stats2(dev, stats, data, 0); } static void ieee80211_get_strings(struct net_device *dev, u32 sset, u8 *data) @@ -211,7 +218,7 @@ static void ieee80211_get_strings(struct net_device *dev, u32 sset, u8 *data) sz_sta_stats = sizeof(ieee80211_gstrings_sta_stats); memcpy(data, ieee80211_gstrings_sta_stats, sz_sta_stats); } - drv_get_et_strings(sdata, sset, &(data[sz_sta_stats])); + drv_get_et_strings(sdata, sset, &data[sz_sta_stats]); } static int ieee80211_get_regs_len(struct net_device *dev) @@ -238,5 +245,6 @@ const struct ethtool_ops ieee80211_ethtool_ops = { .set_ringparam = ieee80211_set_ringparam, .get_strings = ieee80211_get_strings, .get_ethtool_stats = ieee80211_get_stats, + .get_ethtool_stats2 = ieee80211_get_stats2, .get_sset_count = ieee80211_get_sset_count, }; From patchwork Thu Apr 19 18:17:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Greear X-Patchwork-Id: 901428 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=candelatech.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40RnKZ5GrDz9s1v for ; Fri, 20 Apr 2018 04:18:10 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753257AbeDSSSI (ORCPT ); Thu, 19 Apr 2018 14:18:08 -0400 Received: from mail2.candelatech.com ([208.74.158.173]:37034 "EHLO mail2.candelatech.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753038AbeDSSR7 (ORCPT ); Thu, 19 Apr 2018 14:17:59 -0400 Received: from ben-dt3.candelatech.com (firewall.candelatech.com [50.251.239.81]) by mail2.candelatech.com (Postfix) with ESMTP id 3A27C40B2C6; Thu, 19 Apr 2018 11:17:57 -0700 (PDT) From: greearb@candelatech.com To: netdev@vger.kernel.org Cc: linux-wireless@vger.kernel.org, ath10k@lists.infradead.org, Ben Greear Subject: [PATCH v2 3/3] ath10k: Support ethtool gstats2 API. Date: Thu, 19 Apr 2018 11:17:43 -0700 Message-Id: <1524161863-30860-3-git-send-email-greearb@candelatech.com> X-Mailer: git-send-email 2.4.11 In-Reply-To: <1524161863-30860-1-git-send-email-greearb@candelatech.com> References: <1524161863-30860-1-git-send-email-greearb@candelatech.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Ben Greear Skip a firmware stats update when calling code indicates the stats refresh is not needed. Signed-off-by: Ben Greear --- v2: Convert to new flag name, attempt to fix build when there is not DEBUGFS enabled for ath10k. drivers/net/wireless/ath/ath10k/debug.c | 18 +++++++++++++++--- drivers/net/wireless/ath/ath10k/debug.h | 5 +++++ drivers/net/wireless/ath/ath10k/mac.c | 1 + 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index bac832c..235cd04 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -1159,9 +1159,10 @@ int ath10k_debug_get_et_sset_count(struct ieee80211_hw *hw, return 0; } -void ath10k_debug_get_et_stats(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ethtool_stats *stats, u64 *data) +void ath10k_debug_get_et_stats2(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ethtool_stats *stats, u64 *data, + u32 flags) { struct ath10k *ar = hw->priv; static const struct ath10k_fw_stats_pdev zero_stats = {}; @@ -1170,6 +1171,9 @@ void ath10k_debug_get_et_stats(struct ieee80211_hw *hw, mutex_lock(&ar->conf_mutex); + if (flags & ETHTOOL_GS2_NO_REFRESH_FW) + goto skip_query_fw_stats; + if (ar->state == ATH10K_STATE_ON) { ret = ath10k_debug_fw_stats_request(ar); if (ret) { @@ -1180,6 +1184,7 @@ void ath10k_debug_get_et_stats(struct ieee80211_hw *hw, } } +skip_query_fw_stats: pdev_stats = list_first_entry_or_null(&ar->debug.fw_stats.pdevs, struct ath10k_fw_stats_pdev, list); @@ -1244,6 +1249,13 @@ void ath10k_debug_get_et_stats(struct ieee80211_hw *hw, WARN_ON(i != ATH10K_SSTATS_LEN); } +void ath10k_debug_get_et_stats(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ethtool_stats *stats, u64 *data) +{ + ath10k_debug_get_et_stats2(hw, vif, stats, data, 0); +} + static const struct file_operations fops_fw_dbglog = { .read = ath10k_read_fw_dbglog, .write = ath10k_write_fw_dbglog, diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h index 0afca5c..e953dd0 100644 --- a/drivers/net/wireless/ath/ath10k/debug.h +++ b/drivers/net/wireless/ath/ath10k/debug.h @@ -117,6 +117,10 @@ int ath10k_debug_get_et_sset_count(struct ieee80211_hw *hw, void ath10k_debug_get_et_stats(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ethtool_stats *stats, u64 *data); +void ath10k_debug_get_et_stats2(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ethtool_stats *stats, u64 *data, + u32 level); static inline u64 ath10k_debug_get_fw_dbglog_mask(struct ath10k *ar) { @@ -195,6 +199,7 @@ static inline u32 ath10k_debug_get_fw_dbglog_level(struct ath10k *ar) #define ath10k_debug_get_et_strings NULL #define ath10k_debug_get_et_sset_count NULL #define ath10k_debug_get_et_stats NULL +#define ath10k_debug_get_et_stats2 NULL #endif /* CONFIG_ATH10K_DEBUGFS */ #ifdef CONFIG_MAC80211_DEBUGFS diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index bf05a36..27b793c 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -7734,6 +7734,7 @@ static const struct ieee80211_ops ath10k_ops = { .ampdu_action = ath10k_ampdu_action, .get_et_sset_count = ath10k_debug_get_et_sset_count, .get_et_stats = ath10k_debug_get_et_stats, + .get_et_stats2 = ath10k_debug_get_et_stats2, .get_et_strings = ath10k_debug_get_et_strings, .add_chanctx = ath10k_mac_op_add_chanctx, .remove_chanctx = ath10k_mac_op_remove_chanctx,