Patchwork [v2,4/4] ath9k: Support ethtool getstats api.

login
register
mail settings
Submitter Ben Greear
Date March 16, 2012, 7:59 p.m.
Message ID <1331927952-8706-4-git-send-email-greearb@candelatech.com>
Download mbox | patch
Permalink /patch/147253/
State Not Applicable
Delegated to: David Miller
Headers show

Comments

Ben Greear - March 16, 2012, 7:59 p.m.
From: Ben Greear <greearb@candelatech.com>

This returns many of the values that formerly could
only be obtained from debugfs.  This should be an
improvement when trying to access these counters
programatically.  Currently this support is only
enabled when DEBUGFS is enabled because otherwise
these stats are not accumulated.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---

v2:  Remove phy-err counters that are currently never
     set.  Remove a few other stats that appeared
     useless.

:100644 100644 4a00806... 7261f88... M	drivers/net/wireless/ath/ath9k/main.c
 drivers/net/wireless/ath/ath9k/main.c |  134 +++++++++++++++++++++++++++++++++
 1 files changed, 134 insertions(+), 0 deletions(-)
Ben Hutchings - March 16, 2012, 8:53 p.m.
On Fri, 2012-03-16 at 12:59 -0700, greearb@candelatech.com wrote:
> From: Ben Greear <greearb@candelatech.com>
> 
> This returns many of the values that formerly could
> only be obtained from debugfs.  This should be an
> improvement when trying to access these counters
> programatically.  Currently this support is only
> enabled when DEBUGFS is enabled because otherwise
> these stats are not accumulated.
[...]

Given that ethtool (unlike debugfs) is itself an unconditional feature,
why not make this unconditional?  Is it expensive to accumulate the
stats?

Please at least fix the name.

Ben.
Ben Hutchings - March 16, 2012, 8:57 p.m.
On Fri, 2012-03-16 at 20:53 +0000, Ben Hutchings wrote:
> On Fri, 2012-03-16 at 12:59 -0700, greearb@candelatech.com wrote:
> > From: Ben Greear <greearb@candelatech.com>
> > 
> > This returns many of the values that formerly could
> > only be obtained from debugfs.  This should be an
> > improvement when trying to access these counters
> > programatically.  Currently this support is only
> > enabled when DEBUGFS is enabled because otherwise
> > these stats are not accumulated.
> [...]
> 
> Given that ethtool (unlike debugfs) is itself an unconditional feature,
> why not make this unconditional?  Is it expensive to accumulate the
> stats?
> 
> Please at least fix the name.
                         ^ config option
Ben Greear - March 16, 2012, 9:26 p.m.
On 03/16/2012 01:57 PM, Ben Hutchings wrote:
> On Fri, 2012-03-16 at 20:53 +0000, Ben Hutchings wrote:
>> On Fri, 2012-03-16 at 12:59 -0700, greearb@candelatech.com wrote:
>>> From: Ben Greear<greearb@candelatech.com>
>>>
>>> This returns many of the values that formerly could
>>> only be obtained from debugfs.  This should be an
>>> improvement when trying to access these counters
>>> programatically.  Currently this support is only
>>> enabled when DEBUGFS is enabled because otherwise
>>> these stats are not accumulated.
>> [...]
>>
>> Given that ethtool (unlike debugfs) is itself an unconditional feature,
>> why not make this unconditional?  Is it expensive to accumulate the
>> stats?
>>
>> Please at least fix the name.
>                           ^ config option
>

The ath9k stats are currently only gathered when debugfs is enabled.

I could do some patches in the future to allow stats to always
be gathered regardless of debugfs being enabled, but since
ath9k is used on small form factor systems, there may be some
resistance to enabling that all the time.

Thanks,
Ben
Christian Lamparter - March 16, 2012, 9:38 p.m.
On Friday 16 March 2012 22:26:34 Ben Greear wrote:
> On 03/16/2012 01:57 PM, Ben Hutchings wrote:
> > On Fri, 2012-03-16 at 20:53 +0000, Ben Hutchings wrote:
> >> On Fri, 2012-03-16 at 12:59 -0700, greearb@candelatech.com wrote:
> >>> From: Ben Greear<greearb@candelatech.com>
> >>>
> >>> This returns many of the values that formerly could
> >>> only be obtained from debugfs.  This should be an
> >>> improvement when trying to access these counters
> >>> programatically.  Currently this support is only
> >>> enabled when DEBUGFS is enabled because otherwise
> >>> these stats are not accumulated.
> >> [...]
> >>
> >> Given that ethtool (unlike debugfs) is itself an unconditional feature,
> >> why not make this unconditional?  Is it expensive to accumulate the
> >> stats?
> >>
> >> Please at least fix the name.
> >                           ^ config option
> >
> 
> The ath9k stats are currently only gathered when debugfs is enabled.
> 
> I could do some patches in the future to allow stats to always
> be gathered regardless of debugfs being enabled, but since
> ath9k is used on small form factor systems, there may be some
> resistance to enabling that all the time.
When we are talking about small form factor.
Did you know that OpenWRT has enabled ath9k's debugfs feature by default?
Even the image for my TL-WR841ND [just a 4MiB flash] has it enabled! 
So I don't that's much of a problem. Even more the debugfs bits are
probably smaller than all those initvals [you know, those for the whole
AR5008/AR91XX/AR92XX/AR93XX/AR94XX gang] they have to carry around.
[Yeah, if you use the same rev-chips on your stuff, you could get
away with just one initval... Think of the savings!]

Regards,
	Chr
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 4a00806..7261f88 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2430,6 +2430,134 @@  static int ath9k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
 	return 0;
 }
 
+#ifdef CONFIG_ATH9K_DEBUGFS
+
+/* Ethtool support for get-stats */
+
+#define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO"
+static const char ath9k_gstrings_stats[][ETH_GSTRING_LEN] = {
+	"tx_pkts_nic",
+	"tx_bytes_nic",
+	"rx_pkts_nic",
+	"rx_bytes_nic",
+	AMKSTR(d_tx_pkts),
+	AMKSTR(d_tx_bytes),
+	AMKSTR(d_tx_mpdus_queued),
+	AMKSTR(d_tx_mpdus_completed),
+	AMKSTR(d_tx_mpdu_retries),
+	AMKSTR(d_tx_aggregates),
+	AMKSTR(d_tx_ampdus_queued_hw),
+	AMKSTR(d_tx_ampdus_queued_sw),
+	AMKSTR(d_tx_ampdus_completed),
+	AMKSTR(d_tx_ampdu_retries),
+	AMKSTR(d_tx_ampdu_xretries),
+	AMKSTR(d_tx_fifo_underrun),
+	AMKSTR(d_tx_op_exceeded),
+	AMKSTR(d_tx_timer_expiry),
+	AMKSTR(d_tx_desc_cfg_err),
+	AMKSTR(d_tx_data_underrun),
+	AMKSTR(d_tx_delim_underrun),
+
+	"d_rx_decrypt_crc_err",
+	"d_rx_phy_err",
+	"d_rx_mic_err",
+	"d_rx_pre_delim_crc_err",
+	"d_rx_post_delim_crc_err",
+	"d_rx_decrypt_busy_err",
+
+	"d_rx_phyerr_radar",
+	"d_rx_phyerr_ofdm_timing",
+	"d_rx_phyerr_cck_timing",
+
+};
+#define ATH9K_SSTATS_LEN ARRAY_SIZE(ath9k_gstrings_stats)
+
+static void ath9k_get_et_strings(struct ieee80211_hw *hw,
+				 struct ieee80211_vif *vif,
+				 u32 sset, u8 *data)
+{
+	if (sset == ETH_SS_STATS)
+		memcpy(data, *ath9k_gstrings_stats,
+		       sizeof(ath9k_gstrings_stats));
+}
+
+static int ath9k_get_et_sset_count(struct ieee80211_hw *hw,
+				   struct ieee80211_vif *vif, int sset)
+{
+	if (sset == ETH_SS_STATS)
+		return ATH9K_SSTATS_LEN;
+	return 0;
+}
+
+#define PR_QNUM(_n) (sc->tx.txq_map[_n]->axq_qnum)
+#define AWDATA(elem)							\
+	do {								\
+		data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].elem; \
+		data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].elem; \
+		data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].elem; \
+		data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].elem; \
+	} while (0)
+
+#define AWDATA_RX(elem)						\
+	do {							\
+		data[i++] = sc->debug.stats.rxstats.elem;	\
+	} while (0)
+
+static void ath9k_get_et_stats(struct ieee80211_hw *hw,
+			       struct ieee80211_vif *vif,
+			       struct ethtool_stats *stats, u64 *data)
+{
+	struct ath_softc *sc = hw->priv;
+	int i = 0;
+
+	data[i++] = (sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].tx_pkts_all +
+		     sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].tx_pkts_all +
+		     sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].tx_pkts_all +
+		     sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].tx_pkts_all);
+	data[i++] = (sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].tx_bytes_all +
+		     sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].tx_bytes_all +
+		     sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].tx_bytes_all +
+		     sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].tx_bytes_all);
+	AWDATA_RX(rx_pkts_all);
+	AWDATA_RX(rx_bytes_all);
+
+	AWDATA(tx_pkts_all);
+	AWDATA(tx_bytes_all);
+	AWDATA(queued);
+	AWDATA(completed);
+	AWDATA(xretries);
+	AWDATA(a_aggr);
+	AWDATA(a_queued_hw);
+	AWDATA(a_queued_sw);
+	AWDATA(a_completed);
+	AWDATA(a_retries);
+	AWDATA(a_xretries);
+	AWDATA(fifo_underrun);
+	AWDATA(xtxop);
+	AWDATA(timer_exp);
+	AWDATA(desc_cfg_err);
+	AWDATA(data_underrun);
+	AWDATA(delim_underrun);
+
+	AWDATA_RX(decrypt_crc_err);
+	AWDATA_RX(phy_err);
+	AWDATA_RX(mic_err);
+	AWDATA_RX(pre_delim_crc_err);
+	AWDATA_RX(post_delim_crc_err);
+	AWDATA_RX(decrypt_busy_err);
+
+	AWDATA_RX(phy_err_stats[ATH9K_PHYERR_RADAR]);
+	AWDATA_RX(phy_err_stats[ATH9K_PHYERR_OFDM_TIMING]);
+	AWDATA_RX(phy_err_stats[ATH9K_PHYERR_CCK_TIMING]);
+
+	BUG_ON(i != ATH9K_SSTATS_LEN);
+}
+
+/* End of ethtool get-stats functions */
+
+#endif
+
+
 struct ieee80211_ops ath9k_ops = {
 	.tx 		    = ath9k_tx,
 	.start 		    = ath9k_start,
@@ -2458,4 +2586,10 @@  struct ieee80211_ops ath9k_ops = {
 	.get_stats	    = ath9k_get_stats,
 	.set_antenna	    = ath9k_set_antenna,
 	.get_antenna	    = ath9k_get_antenna,
+
+#ifdef CONFIG_ATH9K_DEBUGFS
+	.get_et_sset_count  = ath9k_get_et_sset_count,
+	.get_et_stats  = ath9k_get_et_stats,
+	.get_et_strings  = ath9k_get_et_strings,
+#endif
 };