All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/10] Wireless patches for wireless-testing
@ 2012-04-11 17:52 greearb
  2012-04-11 17:52 ` [PATCH 01/10] cfg80211: Add framework to support ethtool stats greearb
                   ` (10 more replies)
  0 siblings, 11 replies; 28+ messages in thread
From: greearb @ 2012-04-11 17:52 UTC (permalink / raw)
  To: linux-wireless; +Cc: netdev, Ben Greear

From: Ben Greear <greearb@candelatech.com>

Support Ethtool stats for Wireless, including in-depth
stats for ath9k, and add some additional ath9k stats
to debugfs.  Support scanning on-channel.

The basic ethtool patches are little changed from previous
posted patches.  The others are tweaked at least some, and
some have not been posted before at all.

Ben Greear (10):
  cfg80211: Add framework to support ethtool stats.
  mac80211: Support getting sta_info stats via ethtool.
  mac80211: Framework to get wifi-driver stats via ethtool.
  ath9k: Support ethtool getstats api.
  mac80211: Add more ethtools stats: survey, rates, etc
  mac80211: Add sta_state to ethtool stats.
  ath9k: Add tx-failed counter.
  mac80211: Support on-channel scan option.
  ath9k: Add more recv stats.
  ath9k: Gather and report IRQ sync_cause errors.

 drivers/net/wireless/ath/ath9k/ar9002_mac.c |    1 +
 drivers/net/wireless/ath/ath9k/ar9003_mac.c |    2 +
 drivers/net/wireless/ath/ath9k/debug.c      |  167 ++++++++++++++-------------
 drivers/net/wireless/ath/ath9k/debug.h      |   43 +++++++
 drivers/net/wireless/ath/ath9k/hw.c         |   49 ++++++++
 drivers/net/wireless/ath/ath9k/hw.h         |    6 +
 drivers/net/wireless/ath/ath9k/main.c       |  135 +++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/recv.c       |   35 ++++--
 include/net/cfg80211.h                      |   17 +++
 include/net/mac80211.h                      |   17 +++
 net/mac80211/cfg.c                          |  160 +++++++++++++++++++++++++
 net/mac80211/driver-ops.h                   |   37 ++++++
 net/mac80211/driver-trace.h                 |   15 +++
 net/mac80211/ieee80211_i.h                  |    3 +
 net/mac80211/main.c                         |    4 +-
 net/mac80211/rx.c                           |    2 +
 net/mac80211/scan.c                         |   92 +++++++++++-----
 net/wireless/ethtool.c                      |   29 +++++
 18 files changed, 695 insertions(+), 119 deletions(-)

-- 
1.7.3.4


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 01/10] cfg80211: Add framework to support ethtool stats.
  2012-04-11 17:52 [PATCH 00/10] Wireless patches for wireless-testing greearb
@ 2012-04-11 17:52 ` greearb
  2012-04-11 17:52 ` [PATCH 02/10] mac80211: Support getting sta_info stats via ethtool greearb
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 28+ messages in thread
From: greearb @ 2012-04-11 17:52 UTC (permalink / raw)
  To: linux-wireless; +Cc: netdev, Ben Greear

From: Ben Greear <greearb@candelatech.com>

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 ae3a3bb... 8bf68f3... M	include/net/cfg80211.h
:100644 100644 9bde4d1... 7eecdf4... M	net/wireless/ethtool.c
 include/net/cfg80211.h |   17 +++++++++++++++++
 net/wireless/ethtool.c |   29 +++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+), 0 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ae3a3bb..8bf68f3 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1511,6 +1511,16 @@ struct cfg80211_gtk_rekey_data {
  *	later passes to cfg80211_probe_status().
  *
  * @set_noack_map: Set the NoAck Map for the TIDs.
+ *
+ * @get_et_sset_count:  Ethtool API to get string-set count.
+ *	See @ethtool_ops.get_sset_count
+ *
+ * @get_et_stats:  Ethtool API to get a set of u64 stats.
+ *	See @ethtool_ops.get_ethtool_stats
+ *
+ * @get_et_strings:  Ethtool API to get a set of strings to describe stats
+ *	and perhaps other supported types of ethtool data-sets.
+ *	See @ethtool_ops.get_strings
  */
 struct cfg80211_ops {
 	int	(*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -1707,6 +1717,13 @@ struct cfg80211_ops {
 				  u16 noack_map);
 
 	struct ieee80211_channel *(*get_channel)(struct wiphy *wiphy);
+
+	int	(*get_et_sset_count)(struct wiphy *wiphy,
+				     struct net_device *dev, int sset);
+	void	(*get_et_stats)(struct wiphy *wiphy, struct net_device *dev,
+				struct ethtool_stats *stats, u64 *data);
+	void	(*get_et_strings)(struct wiphy *wiphy, struct net_device *dev,
+				  u32 sset, u8 *data);
 };
 
 /*
diff --git a/net/wireless/ethtool.c b/net/wireless/ethtool.c
index 9bde4d1..7eecdf4 100644
--- a/net/wireless/ethtool.c
+++ b/net/wireless/ethtool.c
@@ -68,6 +68,32 @@ static int cfg80211_set_ringparam(struct net_device *dev,
 	return -ENOTSUPP;
 }
 
+static int cfg80211_get_sset_count(struct net_device *dev, int sset)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	if (rdev->ops->get_et_sset_count)
+		return rdev->ops->get_et_sset_count(wdev->wiphy, dev, sset);
+	return -EOPNOTSUPP;
+}
+
+static void cfg80211_get_stats(struct net_device *dev,
+			       struct ethtool_stats *stats, u64 *data)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	if (rdev->ops->get_et_stats)
+		rdev->ops->get_et_stats(wdev->wiphy, dev, stats, data);
+}
+
+static void cfg80211_get_strings(struct net_device *dev, u32 sset, u8 *data)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	if (rdev->ops->get_et_strings)
+		rdev->ops->get_et_strings(wdev->wiphy, dev, sset, data);
+}
+
 const struct ethtool_ops cfg80211_ethtool_ops = {
 	.get_drvinfo = cfg80211_get_drvinfo,
 	.get_regs_len = cfg80211_get_regs_len,
@@ -75,4 +101,7 @@ const struct ethtool_ops cfg80211_ethtool_ops = {
 	.get_link = ethtool_op_get_link,
 	.get_ringparam = cfg80211_get_ringparam,
 	.set_ringparam = cfg80211_set_ringparam,
+	.get_strings = cfg80211_get_strings,
+	.get_ethtool_stats = cfg80211_get_stats,
+	.get_sset_count = cfg80211_get_sset_count,
 };
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 02/10] mac80211: Support getting sta_info stats via ethtool.
  2012-04-11 17:52 [PATCH 00/10] Wireless patches for wireless-testing greearb
  2012-04-11 17:52 ` [PATCH 01/10] cfg80211: Add framework to support ethtool stats greearb
@ 2012-04-11 17:52 ` greearb
  2012-04-11 17:52 ` [PATCH 03/10] mac80211: Framework to get wifi-driver " greearb
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 28+ messages in thread
From: greearb @ 2012-04-11 17:52 UTC (permalink / raw)
  To: linux-wireless; +Cc: netdev, Ben Greear

From: Ben Greear <greearb@candelatech.com>

This lets ethtool print out stats related to stations
connected to the interface.  Does not yet get stats
from the underlying driver.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 83e08dc... d008666... M	net/mac80211/cfg.c
 net/mac80211/cfg.c |   71 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 71 insertions(+), 0 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 83e08dc..d008666 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -112,6 +112,74 @@ static int ieee80211_set_noack_map(struct wiphy *wiphy,
 	return 0;
 }
 
+static const char ieee80211_gstrings_sta_stats[][ETH_GSTRING_LEN] = {
+	"rx_packets", "rx_bytes", "wep_weak_iv_count",
+	"rx_duplicates", "rx_fragments", "rx_dropped",
+	"tx_packets", "tx_bytes", "tx_fragments",
+	"tx_filtered", "tx_retry_failed", "tx_retries",
+	"beacon_loss"
+};
+#define STA_STATS_LEN	ARRAY_SIZE(ieee80211_gstrings_sta_stats)
+
+static int ieee80211_get_et_sset_count(struct wiphy *wiphy,
+				       struct net_device *dev,
+				       int sset)
+{
+	if (sset == ETH_SS_STATS)
+		return STA_STATS_LEN;
+
+	return -EOPNOTSUPP;
+}
+
+static void ieee80211_get_et_stats(struct wiphy *wiphy,
+				   struct net_device *dev,
+				   struct ethtool_stats *stats,
+				   u64 *data)
+{
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	struct sta_info *sta;
+	struct ieee80211_local *local = sdata->local;
+
+	memset(data, 0, sizeof(u64) * STA_STATS_LEN);
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(sta, &local->sta_list, list) {
+		int i = 0;
+
+		/* Make sure this station belongs to the proper dev */
+		if (sta->sdata->dev != dev)
+			continue;
+
+		data[i++] += sta->rx_packets;
+		data[i++] += sta->rx_bytes;
+		data[i++] += sta->wep_weak_iv_count;
+		data[i++] += sta->num_duplicates;
+		data[i++] += sta->rx_fragments;
+		data[i++] += sta->rx_dropped;
+
+		data[i++] += sta->tx_packets;
+		data[i++] += sta->tx_bytes;
+		data[i++] += sta->tx_fragments;
+		data[i++] += sta->tx_filtered_count;
+		data[i++] += sta->tx_retry_failed;
+		data[i++] += sta->tx_retry_count;
+		data[i++] += sta->beacon_loss_count;
+		BUG_ON(i != STA_STATS_LEN);
+	}
+	rcu_read_unlock();
+}
+
+static void ieee80211_get_et_strings(struct wiphy *wiphy,
+				     struct net_device *dev,
+				     u32 sset, u8 *data)
+{
+	if (sset == ETH_SS_STATS) {
+		int sz_sta_stats = sizeof(ieee80211_gstrings_sta_stats);
+		memcpy(data, *ieee80211_gstrings_sta_stats, sz_sta_stats);
+	}
+}
+
+
 static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
 			     u8 key_idx, bool pairwise, const u8 *mac_addr,
 			     struct key_params *params)
@@ -2749,4 +2817,7 @@ struct cfg80211_ops mac80211_config_ops = {
 	.probe_client = ieee80211_probe_client,
 	.get_channel = ieee80211_wiphy_get_channel,
 	.set_noack_map = ieee80211_set_noack_map,
+	.get_et_sset_count = ieee80211_get_et_sset_count,
+	.get_et_stats = ieee80211_get_et_stats,
+	.get_et_strings = ieee80211_get_et_strings,
 };
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 03/10] mac80211: Framework to get wifi-driver stats via ethtool.
  2012-04-11 17:52 [PATCH 00/10] Wireless patches for wireless-testing greearb
  2012-04-11 17:52 ` [PATCH 01/10] cfg80211: Add framework to support ethtool stats greearb
  2012-04-11 17:52 ` [PATCH 02/10] mac80211: Support getting sta_info stats via ethtool greearb
@ 2012-04-11 17:52 ` greearb
  2012-04-11 17:52 ` [PATCH 04/10] ath9k: Support ethtool getstats api greearb
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 28+ messages in thread
From: greearb @ 2012-04-11 17:52 UTC (permalink / raw)
  To: linux-wireless; +Cc: netdev, Ben Greear

From: Ben Greear <greearb@candelatech.com>

This adds hooks to call into the driver to get additional
stats for the ethtool API.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 ed55d89... b6822f9... M	include/net/mac80211.h
:100644 100644 d008666... ea2e995... M	net/mac80211/cfg.c
:100644 100644 8ad40f6... 047d8fe... M	net/mac80211/driver-ops.h
:100644 100644 d1f017a... 2722f8c... M	net/mac80211/driver-trace.h
 include/net/mac80211.h      |   17 +++++++++++++++++
 net/mac80211/cfg.c          |   19 ++++++++++++++++---
 net/mac80211/driver-ops.h   |   37 +++++++++++++++++++++++++++++++++++++
 net/mac80211/driver-trace.h |   15 +++++++++++++++
 4 files changed, 85 insertions(+), 3 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index ed55d89..b6822f9 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2146,6 +2146,14 @@ enum ieee80211_rate_control_changed {
  *	The @tids parameter is a bitmap and tells the driver which TIDs the
  *	frames will be on; it will at most have two bits set.
  *	This callback must be atomic.
+ *
+ * @get_et_sset_count:  Ethtool API to get string-set count.
+ *
+ * @get_et_stats:  Ethtool API to get a set of u64 stats.
+ *
+ * @get_et_strings:  Ethtool API to get a set of strings to describe stats
+ *	and perhaps other supported types of ethtool data-sets.
+ *
  */
 struct ieee80211_ops {
 	void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb);
@@ -2275,6 +2283,15 @@ struct ieee80211_ops {
 					u16 tids, int num_frames,
 					enum ieee80211_frame_release_type reason,
 					bool more_data);
+
+	int	(*get_et_sset_count)(struct ieee80211_hw *hw,
+				     struct ieee80211_vif *vif, int sset);
+	void	(*get_et_stats)(struct ieee80211_hw *hw,
+				struct ieee80211_vif *vif,
+				struct ethtool_stats *stats, u64 *data);
+	void	(*get_et_strings)(struct ieee80211_hw *hw,
+				  struct ieee80211_vif *vif,
+				  u32 sset, u8 *data);
 };
 
 /**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index d008666..ea2e995 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -125,10 +125,17 @@ static int ieee80211_get_et_sset_count(struct wiphy *wiphy,
 				       struct net_device *dev,
 				       int sset)
 {
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	int rv = 0;
+
 	if (sset == ETH_SS_STATS)
-		return STA_STATS_LEN;
+		rv += STA_STATS_LEN;
 
-	return -EOPNOTSUPP;
+	rv += drv_get_et_sset_count(sdata, sset);
+
+	if (rv == 0)
+		return -EOPNOTSUPP;
+	return rv;
 }
 
 static void ieee80211_get_et_stats(struct wiphy *wiphy,
@@ -167,16 +174,22 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy,
 		BUG_ON(i != STA_STATS_LEN);
 	}
 	rcu_read_unlock();
+
+	drv_get_et_stats(sdata, stats, &(data[STA_STATS_LEN]));
 }
 
 static void ieee80211_get_et_strings(struct wiphy *wiphy,
 				     struct net_device *dev,
 				     u32 sset, u8 *data)
 {
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	int sz_sta_stats = 0;
+
 	if (sset == ETH_SS_STATS) {
-		int sz_sta_stats = sizeof(ieee80211_gstrings_sta_stats);
+		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]));
 }
 
 
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 8ad40f6..047d8fe 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -35,6 +35,43 @@ static inline void drv_tx_frags(struct ieee80211_local *local,
 	local->ops->tx_frags(&local->hw, vif, sta, skbs);
 }
 
+static inline void drv_get_et_strings(struct ieee80211_sub_if_data *sdata,
+				      u32 sset, u8 *data)
+{
+	struct ieee80211_local *local = sdata->local;
+	if (local->ops->get_et_strings) {
+		trace_drv_get_et_strings(local, sset);
+		local->ops->get_et_strings(&local->hw, &sdata->vif, sset, data);
+		trace_drv_return_void(local);
+	}
+}
+
+static inline void drv_get_et_stats(struct ieee80211_sub_if_data *sdata,
+				    struct ethtool_stats *stats,
+				    u64 *data)
+{
+	struct ieee80211_local *local = sdata->local;
+	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);
+	}
+}
+
+static inline int drv_get_et_sset_count(struct ieee80211_sub_if_data *sdata,
+					int sset)
+{
+	struct ieee80211_local *local = sdata->local;
+	int rv = 0;
+	if (local->ops->get_et_sset_count) {
+		trace_drv_get_et_sset_count(local, sset);
+		rv = local->ops->get_et_sset_count(&local->hw, &sdata->vif,
+						   sset);
+		trace_drv_return_int(local, rv);
+	}
+	return rv;
+}
+
 static inline int drv_start(struct ieee80211_local *local)
 {
 	int ret;
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index d1f017a..2722f8c 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -161,6 +161,21 @@ DEFINE_EVENT(local_only_evt, drv_start,
 	TP_ARGS(local)
 );
 
+DEFINE_EVENT(local_u32_evt, drv_get_et_strings,
+	     TP_PROTO(struct ieee80211_local *local, u32 sset),
+	     TP_ARGS(local, sset)
+);
+
+DEFINE_EVENT(local_u32_evt, drv_get_et_sset_count,
+	     TP_PROTO(struct ieee80211_local *local, u32 sset),
+	     TP_ARGS(local, sset)
+);
+
+DEFINE_EVENT(local_only_evt, drv_get_et_stats,
+	     TP_PROTO(struct ieee80211_local *local),
+	     TP_ARGS(local)
+);
+
 DEFINE_EVENT(local_only_evt, drv_suspend,
 	TP_PROTO(struct ieee80211_local *local),
 	TP_ARGS(local)
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 04/10] ath9k: Support ethtool getstats api.
  2012-04-11 17:52 [PATCH 00/10] Wireless patches for wireless-testing greearb
                   ` (2 preceding siblings ...)
  2012-04-11 17:52 ` [PATCH 03/10] mac80211: Framework to get wifi-driver " greearb
@ 2012-04-11 17:52 ` greearb
  2012-04-11 17:52   ` greearb-my8/4N5VtI7c+919tysfdA
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 28+ messages in thread
From: greearb @ 2012-04-11 17:52 UTC (permalink / raw)
  To: linux-wireless; +Cc: netdev, Ben Greear

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>
---
:100644 100644 ba5af8e... 39f8f7c... M	drivers/net/wireless/ath/ath9k/main.c
 drivers/net/wireless/ath/ath9k/main.c |  134 +++++++++++++++++++++++++++++++++
 1 files changed, 134 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index ba5af8e..39f8f7c 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2404,6 +2404,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_xretries),
+	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,
@@ -2432,4 +2560,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
 };
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 05/10] mac80211: Add more ethtools stats: survey, rates, etc
@ 2012-04-11 17:52   ` greearb-my8/4N5VtI7c+919tysfdA
  0 siblings, 0 replies; 28+ messages in thread
From: greearb @ 2012-04-11 17:52 UTC (permalink / raw)
  To: linux-wireless; +Cc: netdev, Ben Greear

From: Ben Greear <greearb@candelatech.com>

The signal and noise are forced to be positive since ethtool
deals in unsigned 64-bit values and this number should be human
readable.  This gives easy access to some of the data formerly
exposed in the deprecated /proc/net/wireless file.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 ea2e995... bbaf564... M	net/mac80211/cfg.c
 net/mac80211/cfg.c |  156 ++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 115 insertions(+), 41 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index ea2e995..bbaf564 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -19,6 +19,7 @@
 #include "cfg.h"
 #include "rate.h"
 #include "mesh.h"
+#include "../wireless/core.h"
 
 static struct net_device *ieee80211_add_iface(struct wiphy *wiphy, char *name,
 					      enum nl80211_iftype type,
@@ -117,7 +118,9 @@ static const char ieee80211_gstrings_sta_stats[][ETH_GSTRING_LEN] = {
 	"rx_duplicates", "rx_fragments", "rx_dropped",
 	"tx_packets", "tx_bytes", "tx_fragments",
 	"tx_filtered", "tx_retry_failed", "tx_retries",
-	"beacon_loss"
+	"beacon_loss", "txrate", "rxrate", "signal",
+	"channel", "noise", "ch_time", "ch_time_busy",
+	"ch_time_ext_busy", "ch_time_rx", "ch_time_tx"
 };
 #define STA_STATS_LEN	ARRAY_SIZE(ieee80211_gstrings_sta_stats)
 
@@ -138,46 +141,6 @@ static int ieee80211_get_et_sset_count(struct wiphy *wiphy,
 	return rv;
 }
 
-static void ieee80211_get_et_stats(struct wiphy *wiphy,
-				   struct net_device *dev,
-				   struct ethtool_stats *stats,
-				   u64 *data)
-{
-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-	struct sta_info *sta;
-	struct ieee80211_local *local = sdata->local;
-
-	memset(data, 0, sizeof(u64) * STA_STATS_LEN);
-
-	rcu_read_lock();
-	list_for_each_entry_rcu(sta, &local->sta_list, list) {
-		int i = 0;
-
-		/* Make sure this station belongs to the proper dev */
-		if (sta->sdata->dev != dev)
-			continue;
-
-		data[i++] += sta->rx_packets;
-		data[i++] += sta->rx_bytes;
-		data[i++] += sta->wep_weak_iv_count;
-		data[i++] += sta->num_duplicates;
-		data[i++] += sta->rx_fragments;
-		data[i++] += sta->rx_dropped;
-
-		data[i++] += sta->tx_packets;
-		data[i++] += sta->tx_bytes;
-		data[i++] += sta->tx_fragments;
-		data[i++] += sta->tx_filtered_count;
-		data[i++] += sta->tx_retry_failed;
-		data[i++] += sta->tx_retry_count;
-		data[i++] += sta->beacon_loss_count;
-		BUG_ON(i != STA_STATS_LEN);
-	}
-	rcu_read_unlock();
-
-	drv_get_et_stats(sdata, stats, &(data[STA_STATS_LEN]));
-}
-
 static void ieee80211_get_et_strings(struct wiphy *wiphy,
 				     struct net_device *dev,
 				     u32 sset, u8 *data)
@@ -531,6 +494,117 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
 		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
 }
 
+static void ieee80211_get_et_stats(struct wiphy *wiphy,
+				   struct net_device *dev,
+				   struct ethtool_stats *stats,
+				   u64 *data)
+{
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	struct sta_info *sta;
+	struct ieee80211_local *local = sdata->local;
+	struct station_info sinfo;
+	struct survey_info survey;
+	bool do_once = true;
+	int i;
+#define STA_STATS_SURVEY_LEN 7
+
+	memset(data, 0, sizeof(u64) * STA_STATS_LEN);
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(sta, &local->sta_list, list) {
+		i = 0;
+
+		/* Make sure this station belongs to the proper dev */
+		if (sta->sdata->dev != dev)
+			continue;
+
+		data[i++] += sta->rx_packets;
+		data[i++] += sta->rx_bytes;
+		data[i++] += sta->wep_weak_iv_count;
+		data[i++] += sta->num_duplicates;
+		data[i++] += sta->rx_fragments;
+		data[i++] += sta->rx_dropped;
+
+		data[i++] += sta->tx_packets;
+		data[i++] += sta->tx_bytes;
+		data[i++] += sta->tx_fragments;
+		data[i++] += sta->tx_filtered_count;
+		data[i++] += sta->tx_retry_failed;
+		data[i++] += sta->tx_retry_count;
+		data[i++] += sta->beacon_loss_count;
+
+		if (!do_once) {
+			i += 3;
+			goto after_once;
+		}
+
+		do_once = false;
+		sinfo.filled = 0;
+		sta_set_sinfo(sta, &sinfo);
+
+		if (sinfo.filled | STATION_INFO_TX_BITRATE)
+			data[i] = 100000 *
+				cfg80211_calculate_bitrate(&sinfo.txrate);
+		i++;
+		if (sinfo.filled | STATION_INFO_RX_BITRATE)
+			data[i] = 100000 *
+				cfg80211_calculate_bitrate(&sinfo.rxrate);
+		i++;
+
+		if (sinfo.filled | STATION_INFO_SIGNAL_AVG)
+			data[i] = abs(sinfo.signal_avg);
+		i++;
+
+after_once:
+		if (WARN_ON(i != (STA_STATS_LEN - STA_STATS_SURVEY_LEN))) {
+			rcu_read_unlock();
+			return;
+		}
+	}
+
+	i = STA_STATS_LEN - STA_STATS_SURVEY_LEN;
+	/* Get survey stats for current channel only */
+	survey.filled = 0;
+	if (drv_get_survey(local, 0, &survey) != 0) {
+		survey.filled = 0;
+		data[i++] = 0;
+	} else {
+		data[i++] = survey.channel->center_freq;
+	}
+
+	if (survey.filled & SURVEY_INFO_NOISE_DBM)
+		data[i++] = abs(survey.noise);
+	else
+		data[i++] = -1LL;
+	if (survey.filled & SURVEY_INFO_CHANNEL_TIME)
+		data[i++] = survey.channel_time;
+	else
+		data[i++] = -1LL;
+	if (survey.filled & SURVEY_INFO_CHANNEL_TIME_BUSY)
+		data[i++] = survey.channel_time_busy;
+	else
+		data[i++] = -1LL;
+	if (survey.filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY)
+		data[i++] = survey.channel_time_ext_busy;
+	else
+		data[i++] = -1LL;
+	if (survey.filled & SURVEY_INFO_CHANNEL_TIME_RX)
+		data[i++] = survey.channel_time_rx;
+	else
+		data[i++] = -1LL;
+	if (survey.filled & SURVEY_INFO_CHANNEL_TIME_TX)
+		data[i++] = survey.channel_time_tx;
+	else
+		data[i++] = -1LL;
+
+	if (WARN_ON(i != STA_STATS_LEN)) {
+		rcu_read_unlock();
+		return;
+	}
+
+	drv_get_et_stats(sdata, stats, &(data[STA_STATS_LEN]));
+}
+
 
 static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
 				 int idx, u8 *mac, struct station_info *sinfo)
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 05/10] mac80211: Add more ethtools stats: survey, rates, etc
@ 2012-04-11 17:52   ` greearb-my8/4N5VtI7c+919tysfdA
  0 siblings, 0 replies; 28+ messages in thread
From: greearb-my8/4N5VtI7c+919tysfdA @ 2012-04-11 17:52 UTC (permalink / raw)
  To: linux-wireless-u79uwXL29TY76Z2rM5mHXA
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Ben Greear

From: Ben Greear <greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org>

The signal and noise are forced to be positive since ethtool
deals in unsigned 64-bit values and this number should be human
readable.  This gives easy access to some of the data formerly
exposed in the deprecated /proc/net/wireless file.

Signed-off-by: Ben Greear <greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org>
---
:100644 100644 ea2e995... bbaf564... M	net/mac80211/cfg.c
 net/mac80211/cfg.c |  156 ++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 115 insertions(+), 41 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index ea2e995..bbaf564 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -19,6 +19,7 @@
 #include "cfg.h"
 #include "rate.h"
 #include "mesh.h"
+#include "../wireless/core.h"
 
 static struct net_device *ieee80211_add_iface(struct wiphy *wiphy, char *name,
 					      enum nl80211_iftype type,
@@ -117,7 +118,9 @@ static const char ieee80211_gstrings_sta_stats[][ETH_GSTRING_LEN] = {
 	"rx_duplicates", "rx_fragments", "rx_dropped",
 	"tx_packets", "tx_bytes", "tx_fragments",
 	"tx_filtered", "tx_retry_failed", "tx_retries",
-	"beacon_loss"
+	"beacon_loss", "txrate", "rxrate", "signal",
+	"channel", "noise", "ch_time", "ch_time_busy",
+	"ch_time_ext_busy", "ch_time_rx", "ch_time_tx"
 };
 #define STA_STATS_LEN	ARRAY_SIZE(ieee80211_gstrings_sta_stats)
 
@@ -138,46 +141,6 @@ static int ieee80211_get_et_sset_count(struct wiphy *wiphy,
 	return rv;
 }
 
-static void ieee80211_get_et_stats(struct wiphy *wiphy,
-				   struct net_device *dev,
-				   struct ethtool_stats *stats,
-				   u64 *data)
-{
-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-	struct sta_info *sta;
-	struct ieee80211_local *local = sdata->local;
-
-	memset(data, 0, sizeof(u64) * STA_STATS_LEN);
-
-	rcu_read_lock();
-	list_for_each_entry_rcu(sta, &local->sta_list, list) {
-		int i = 0;
-
-		/* Make sure this station belongs to the proper dev */
-		if (sta->sdata->dev != dev)
-			continue;
-
-		data[i++] += sta->rx_packets;
-		data[i++] += sta->rx_bytes;
-		data[i++] += sta->wep_weak_iv_count;
-		data[i++] += sta->num_duplicates;
-		data[i++] += sta->rx_fragments;
-		data[i++] += sta->rx_dropped;
-
-		data[i++] += sta->tx_packets;
-		data[i++] += sta->tx_bytes;
-		data[i++] += sta->tx_fragments;
-		data[i++] += sta->tx_filtered_count;
-		data[i++] += sta->tx_retry_failed;
-		data[i++] += sta->tx_retry_count;
-		data[i++] += sta->beacon_loss_count;
-		BUG_ON(i != STA_STATS_LEN);
-	}
-	rcu_read_unlock();
-
-	drv_get_et_stats(sdata, stats, &(data[STA_STATS_LEN]));
-}
-
 static void ieee80211_get_et_strings(struct wiphy *wiphy,
 				     struct net_device *dev,
 				     u32 sset, u8 *data)
@@ -531,6 +494,117 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
 		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
 }
 
+static void ieee80211_get_et_stats(struct wiphy *wiphy,
+				   struct net_device *dev,
+				   struct ethtool_stats *stats,
+				   u64 *data)
+{
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	struct sta_info *sta;
+	struct ieee80211_local *local = sdata->local;
+	struct station_info sinfo;
+	struct survey_info survey;
+	bool do_once = true;
+	int i;
+#define STA_STATS_SURVEY_LEN 7
+
+	memset(data, 0, sizeof(u64) * STA_STATS_LEN);
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(sta, &local->sta_list, list) {
+		i = 0;
+
+		/* Make sure this station belongs to the proper dev */
+		if (sta->sdata->dev != dev)
+			continue;
+
+		data[i++] += sta->rx_packets;
+		data[i++] += sta->rx_bytes;
+		data[i++] += sta->wep_weak_iv_count;
+		data[i++] += sta->num_duplicates;
+		data[i++] += sta->rx_fragments;
+		data[i++] += sta->rx_dropped;
+
+		data[i++] += sta->tx_packets;
+		data[i++] += sta->tx_bytes;
+		data[i++] += sta->tx_fragments;
+		data[i++] += sta->tx_filtered_count;
+		data[i++] += sta->tx_retry_failed;
+		data[i++] += sta->tx_retry_count;
+		data[i++] += sta->beacon_loss_count;
+
+		if (!do_once) {
+			i += 3;
+			goto after_once;
+		}
+
+		do_once = false;
+		sinfo.filled = 0;
+		sta_set_sinfo(sta, &sinfo);
+
+		if (sinfo.filled | STATION_INFO_TX_BITRATE)
+			data[i] = 100000 *
+				cfg80211_calculate_bitrate(&sinfo.txrate);
+		i++;
+		if (sinfo.filled | STATION_INFO_RX_BITRATE)
+			data[i] = 100000 *
+				cfg80211_calculate_bitrate(&sinfo.rxrate);
+		i++;
+
+		if (sinfo.filled | STATION_INFO_SIGNAL_AVG)
+			data[i] = abs(sinfo.signal_avg);
+		i++;
+
+after_once:
+		if (WARN_ON(i != (STA_STATS_LEN - STA_STATS_SURVEY_LEN))) {
+			rcu_read_unlock();
+			return;
+		}
+	}
+
+	i = STA_STATS_LEN - STA_STATS_SURVEY_LEN;
+	/* Get survey stats for current channel only */
+	survey.filled = 0;
+	if (drv_get_survey(local, 0, &survey) != 0) {
+		survey.filled = 0;
+		data[i++] = 0;
+	} else {
+		data[i++] = survey.channel->center_freq;
+	}
+
+	if (survey.filled & SURVEY_INFO_NOISE_DBM)
+		data[i++] = abs(survey.noise);
+	else
+		data[i++] = -1LL;
+	if (survey.filled & SURVEY_INFO_CHANNEL_TIME)
+		data[i++] = survey.channel_time;
+	else
+		data[i++] = -1LL;
+	if (survey.filled & SURVEY_INFO_CHANNEL_TIME_BUSY)
+		data[i++] = survey.channel_time_busy;
+	else
+		data[i++] = -1LL;
+	if (survey.filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY)
+		data[i++] = survey.channel_time_ext_busy;
+	else
+		data[i++] = -1LL;
+	if (survey.filled & SURVEY_INFO_CHANNEL_TIME_RX)
+		data[i++] = survey.channel_time_rx;
+	else
+		data[i++] = -1LL;
+	if (survey.filled & SURVEY_INFO_CHANNEL_TIME_TX)
+		data[i++] = survey.channel_time_tx;
+	else
+		data[i++] = -1LL;
+
+	if (WARN_ON(i != STA_STATS_LEN)) {
+		rcu_read_unlock();
+		return;
+	}
+
+	drv_get_et_stats(sdata, stats, &(data[STA_STATS_LEN]));
+}
+
 
 static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
 				 int idx, u8 *mac, struct station_info *sinfo)
-- 
1.7.3.4

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 06/10] mac80211: Add sta_state to ethtool stats.
@ 2012-04-11 17:52   ` greearb-my8/4N5VtI7c+919tysfdA
  0 siblings, 0 replies; 28+ messages in thread
From: greearb @ 2012-04-11 17:52 UTC (permalink / raw)
  To: linux-wireless; +Cc: netdev, Ben Greear

From: Ben Greear <greearb@candelatech.com>

Helps to know how the station is doing in it's association
attempt.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 bbaf564... a63834d... M	net/mac80211/cfg.c
 net/mac80211/cfg.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index bbaf564..a63834d 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -118,7 +118,7 @@ static const char ieee80211_gstrings_sta_stats[][ETH_GSTRING_LEN] = {
 	"rx_duplicates", "rx_fragments", "rx_dropped",
 	"tx_packets", "tx_bytes", "tx_fragments",
 	"tx_filtered", "tx_retry_failed", "tx_retries",
-	"beacon_loss", "txrate", "rxrate", "signal",
+	"beacon_loss", "sta_state", "txrate", "rxrate", "signal",
 	"channel", "noise", "ch_time", "ch_time_busy",
 	"ch_time_ext_busy", "ch_time_rx", "ch_time_tx"
 };
@@ -534,10 +534,12 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy,
 		data[i++] += sta->beacon_loss_count;
 
 		if (!do_once) {
-			i += 3;
+			i += 4;
 			goto after_once;
 		}
 
+		data[i++] = sta->sta_state;
+
 		do_once = false;
 		sinfo.filled = 0;
 		sta_set_sinfo(sta, &sinfo);
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 06/10] mac80211: Add sta_state to ethtool stats.
@ 2012-04-11 17:52   ` greearb-my8/4N5VtI7c+919tysfdA
  0 siblings, 0 replies; 28+ messages in thread
From: greearb-my8/4N5VtI7c+919tysfdA @ 2012-04-11 17:52 UTC (permalink / raw)
  To: linux-wireless-u79uwXL29TY76Z2rM5mHXA
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Ben Greear

From: Ben Greear <greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org>

Helps to know how the station is doing in it's association
attempt.

Signed-off-by: Ben Greear <greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org>
---
:100644 100644 bbaf564... a63834d... M	net/mac80211/cfg.c
 net/mac80211/cfg.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index bbaf564..a63834d 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -118,7 +118,7 @@ static const char ieee80211_gstrings_sta_stats[][ETH_GSTRING_LEN] = {
 	"rx_duplicates", "rx_fragments", "rx_dropped",
 	"tx_packets", "tx_bytes", "tx_fragments",
 	"tx_filtered", "tx_retry_failed", "tx_retries",
-	"beacon_loss", "txrate", "rxrate", "signal",
+	"beacon_loss", "sta_state", "txrate", "rxrate", "signal",
 	"channel", "noise", "ch_time", "ch_time_busy",
 	"ch_time_ext_busy", "ch_time_rx", "ch_time_tx"
 };
@@ -534,10 +534,12 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy,
 		data[i++] += sta->beacon_loss_count;
 
 		if (!do_once) {
-			i += 3;
+			i += 4;
 			goto after_once;
 		}
 
+		data[i++] = sta->sta_state;
+
 		do_once = false;
 		sinfo.filled = 0;
 		sta_set_sinfo(sta, &sinfo);
-- 
1.7.3.4

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 07/10] ath9k: Add tx-failed counter.
  2012-04-11 17:52 [PATCH 00/10] Wireless patches for wireless-testing greearb
                   ` (5 preceding siblings ...)
  2012-04-11 17:52   ` greearb-my8/4N5VtI7c+919tysfdA
@ 2012-04-11 17:52 ` greearb
  2012-04-11 17:52   ` greearb-my8/4N5VtI7c+919tysfdA
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 28+ messages in thread
From: greearb @ 2012-04-11 17:52 UTC (permalink / raw)
  To: linux-wireless; +Cc: netdev, Ben Greear

From: Ben Greear <greearb@candelatech.com>

This counts any failure during getting packets into
the DMA buffers, including out-of-memory, etc.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 ff47b32... 186efc5... M	drivers/net/wireless/ath/ath9k/debug.c
:100644 100644 2d47f74... fe2b487... M	drivers/net/wireless/ath/ath9k/debug.h
:100644 100644 39f8f7c... c18290a... M	drivers/net/wireless/ath/ath9k/main.c
 drivers/net/wireless/ath/ath9k/debug.c |    1 +
 drivers/net/wireless/ath/ath9k/debug.h |    2 ++
 drivers/net/wireless/ath/ath9k/main.c  |    1 +
 3 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index ff47b32..186efc5 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -524,6 +524,7 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
 	PR("hw-put-tx-buf:   ", puttxbuf);
 	PR("hw-tx-start:     ", txstart);
 	PR("hw-tx-proc-desc: ", txprocdesc);
+	PR("TX-Failed:       ", txfailed);
 	len += snprintf(buf + len, size - len,
 			"%s%11p%11p%10p%10p\n", "txq-memory-address:",
 			sc->tx.txq_map[WME_AC_BE],
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 2d47f74..fe2b487 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -113,6 +113,7 @@ struct ath_interrupt_stats {
  * @puttxbuf: Number of times hardware was given txbuf to write.
  * @txstart:  Number of times hardware was told to start tx.
  * @txprocdesc:  Number of times tx descriptor was processed
+ * @txfailed:  Out-of-memory or other errors in xmit path.
  */
 struct ath_tx_stats {
 	u32 tx_pkts_all;
@@ -135,6 +136,7 @@ struct ath_tx_stats {
 	u32 puttxbuf;
 	u32 txstart;
 	u32 txprocdesc;
+	u32 txfailed;
 };
 
 /**
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 39f8f7c..c18290a 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1150,6 +1150,7 @@ static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 
 	if (ath_tx_start(hw, skb, &txctl) != 0) {
 		ath_dbg(common, XMIT, "TX failed\n");
+		TX_STAT_INC(txctl.txq->axq_qnum, txfailed);
 		goto exit;
 	}
 
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 08/10] mac80211: Support on-channel scan option.
@ 2012-04-11 17:52   ` greearb-my8/4N5VtI7c+919tysfdA
  0 siblings, 0 replies; 28+ messages in thread
From: greearb @ 2012-04-11 17:52 UTC (permalink / raw)
  To: linux-wireless; +Cc: netdev, Ben Greear

From: Ben Greear <greearb@candelatech.com>

This based on an idea posted by Stanislaw Gruszka,
though I accept full blame for the implementation!

This is compile-tested only at this point.

The idea is to let users scan on the current operating
channel without interrupting normal traffic more than
absolutely necessary (changing power level might reset
some hardware, for instance).

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 ea9623c... 82da2c9... M	net/mac80211/ieee80211_i.h
:100644 100644 d019f0d... dff9c22... M	net/mac80211/main.c
:100644 100644 54a0491... dd2fbec... M	net/mac80211/rx.c
:100644 100644 c70e176... 5c7a332... M	net/mac80211/scan.c
 net/mac80211/ieee80211_i.h |    3 +
 net/mac80211/main.c        |    4 +-
 net/mac80211/rx.c          |    2 +
 net/mac80211/scan.c        |   92 +++++++++++++++++++++++++++++++-------------
 4 files changed, 73 insertions(+), 28 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ea9623c..82da2c9 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -803,6 +803,8 @@ struct tpt_led_trigger {
  *	well be on the operating channel
  * @SCAN_HW_SCANNING: The hardware is scanning for us, we have no way to
  *	determine if we are on the operating channel or not
+ * @SCAN_ONCHANNEL_SCANNING:  Do a software scan on only the current operating
+ *	channel. This should not interrupt normal traffic.
  * @SCAN_COMPLETED: Set for our scan work function when the driver reported
  *	that the scan completed.
  * @SCAN_ABORTED: Set for our scan work function when the driver reported
@@ -811,6 +813,7 @@ struct tpt_led_trigger {
 enum {
 	SCAN_SW_SCANNING,
 	SCAN_HW_SCANNING,
+	SCAN_ONCHANNEL_SCANNING,
 	SCAN_COMPLETED,
 	SCAN_ABORTED,
 };
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index d019f0d..dff9c22 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -47,7 +47,8 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
 	if (atomic_read(&local->iff_allmultis))
 		new_flags |= FIF_ALLMULTI;
 
-	if (local->monitors || test_bit(SCAN_SW_SCANNING, &local->scanning))
+	if (local->monitors || test_bit(SCAN_SW_SCANNING, &local->scanning) ||
+	    test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning))
 		new_flags |= FIF_BCN_PRBRESP_PROMISC;
 
 	if (local->fif_probe_req || local->probe_req_reg)
@@ -148,6 +149,7 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
 	}
 
 	if (test_bit(SCAN_SW_SCANNING, &local->scanning) ||
+	    test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) ||
 	    test_bit(SCAN_HW_SCANNING, &local->scanning))
 		power = chan->max_power;
 	else
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 54a0491..dd2fbec 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -425,6 +425,7 @@ ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
 
 	if (test_bit(SCAN_HW_SCANNING, &local->scanning) ||
 	    test_bit(SCAN_SW_SCANNING, &local->scanning) ||
+	    test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) ||
 	    local->sched_scanning)
 		return ieee80211_scan_rx(rx->sdata, skb);
 
@@ -2915,6 +2916,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
 		local->dot11ReceivedFragmentCount++;
 
 	if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) ||
+		     test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) ||
 		     test_bit(SCAN_SW_SCANNING, &local->scanning)))
 		status->rx_flags |= IEEE80211_RX_IN_SCAN;
 
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index c70e176..5c7a332 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -387,6 +387,29 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
 	return 0;
 }
 
+static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
+					    unsigned long *next_delay)
+{
+	int i;
+	struct ieee80211_sub_if_data *sdata = local->scan_sdata;
+	enum ieee80211_band band = local->hw.conf.channel->band;
+
+	for (i = 0; i < local->scan_req->n_ssids; i++)
+		ieee80211_send_probe_req(
+			sdata, NULL,
+			local->scan_req->ssids[i].ssid,
+			local->scan_req->ssids[i].ssid_len,
+			local->scan_req->ie, local->scan_req->ie_len,
+			local->scan_req->rates[band], false,
+			local->scan_req->no_cck);
+
+	/*
+	 * After sending probe requests, wait for probe responses
+	 * on the channel.
+	 */
+	*next_delay = IEEE80211_CHANNEL_TIME;
+	local->next_scan_state = SCAN_DECISION;
+}
 
 static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
 				  struct cfg80211_scan_request *req)
@@ -438,10 +461,43 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
 	local->scan_req = req;
 	local->scan_sdata = sdata;
 
-	if (local->ops->hw_scan)
+	if (local->ops->hw_scan) {
 		__set_bit(SCAN_HW_SCANNING, &local->scanning);
-	else
-		__set_bit(SCAN_SW_SCANNING, &local->scanning);
+	} else {
+		/* If we are scanning only on the current channel, then
+		 * we do not need to stop normal activities
+		 */
+		if ((req->n_channels == 1) &&
+		    (req->channels[0]->center_freq ==
+		     local->hw.conf.channel->center_freq)) {
+			unsigned long next_delay;
+			__set_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning);
+			ieee80211_recalc_idle(local);
+			/* accept probe-responses */
+			ieee80211_configure_filter(local);
+			/* We need to set power level to max for scanning. */
+			ieee80211_hw_config(local, 0);
+
+			if ((req->channels[0]->flags &
+			     IEEE80211_CHAN_PASSIVE_SCAN) ||
+			    !local->scan_req->n_ssids) {
+				next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
+			} else {
+				ieee80211_scan_state_send_probe(local,
+								&next_delay);
+				next_delay = IEEE80211_CHANNEL_TIME;
+			}
+
+			/* Now, just wait a bit and we are all done! */
+			ieee80211_queue_delayed_work(&local->hw,
+						     &local->scan_work,
+						     next_delay);
+			return 0;
+		}
+		else {
+			__set_bit(SCAN_SW_SCANNING, &local->scanning);
+		}
+	}
 
 	ieee80211_recalc_idle(local);
 
@@ -598,30 +654,6 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
 	local->next_scan_state = SCAN_SEND_PROBE;
 }
 
-static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
-					    unsigned long *next_delay)
-{
-	int i;
-	struct ieee80211_sub_if_data *sdata = local->scan_sdata;
-	enum ieee80211_band band = local->hw.conf.channel->band;
-
-	for (i = 0; i < local->scan_req->n_ssids; i++)
-		ieee80211_send_probe_req(
-			sdata, NULL,
-			local->scan_req->ssids[i].ssid,
-			local->scan_req->ssids[i].ssid_len,
-			local->scan_req->ie, local->scan_req->ie_len,
-			local->scan_req->rates[band], false,
-			local->scan_req->no_cck);
-
-	/*
-	 * After sending probe requests, wait for probe responses
-	 * on the channel.
-	 */
-	*next_delay = IEEE80211_CHANNEL_TIME;
-	local->next_scan_state = SCAN_DECISION;
-}
-
 static void ieee80211_scan_state_suspend(struct ieee80211_local *local,
 					 unsigned long *next_delay)
 {
@@ -672,6 +704,12 @@ void ieee80211_scan_work(struct work_struct *work)
 
 	sdata = local->scan_sdata;
 
+	/* When scanning on-channel, the first-callback means completeed. */
+	if (test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning)) {
+		aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning);
+		goto out_complete;
+	}
+
 	if (test_and_clear_bit(SCAN_COMPLETED, &local->scanning)) {
 		aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning);
 		goto out_complete;
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 08/10] mac80211: Support on-channel scan option.
@ 2012-04-11 17:52   ` greearb-my8/4N5VtI7c+919tysfdA
  0 siblings, 0 replies; 28+ messages in thread
From: greearb-my8/4N5VtI7c+919tysfdA @ 2012-04-11 17:52 UTC (permalink / raw)
  To: linux-wireless-u79uwXL29TY76Z2rM5mHXA
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Ben Greear

From: Ben Greear <greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org>

This based on an idea posted by Stanislaw Gruszka,
though I accept full blame for the implementation!

This is compile-tested only at this point.

The idea is to let users scan on the current operating
channel without interrupting normal traffic more than
absolutely necessary (changing power level might reset
some hardware, for instance).

Signed-off-by: Ben Greear <greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org>
---
:100644 100644 ea9623c... 82da2c9... M	net/mac80211/ieee80211_i.h
:100644 100644 d019f0d... dff9c22... M	net/mac80211/main.c
:100644 100644 54a0491... dd2fbec... M	net/mac80211/rx.c
:100644 100644 c70e176... 5c7a332... M	net/mac80211/scan.c
 net/mac80211/ieee80211_i.h |    3 +
 net/mac80211/main.c        |    4 +-
 net/mac80211/rx.c          |    2 +
 net/mac80211/scan.c        |   92 +++++++++++++++++++++++++++++++-------------
 4 files changed, 73 insertions(+), 28 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ea9623c..82da2c9 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -803,6 +803,8 @@ struct tpt_led_trigger {
  *	well be on the operating channel
  * @SCAN_HW_SCANNING: The hardware is scanning for us, we have no way to
  *	determine if we are on the operating channel or not
+ * @SCAN_ONCHANNEL_SCANNING:  Do a software scan on only the current operating
+ *	channel. This should not interrupt normal traffic.
  * @SCAN_COMPLETED: Set for our scan work function when the driver reported
  *	that the scan completed.
  * @SCAN_ABORTED: Set for our scan work function when the driver reported
@@ -811,6 +813,7 @@ struct tpt_led_trigger {
 enum {
 	SCAN_SW_SCANNING,
 	SCAN_HW_SCANNING,
+	SCAN_ONCHANNEL_SCANNING,
 	SCAN_COMPLETED,
 	SCAN_ABORTED,
 };
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index d019f0d..dff9c22 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -47,7 +47,8 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
 	if (atomic_read(&local->iff_allmultis))
 		new_flags |= FIF_ALLMULTI;
 
-	if (local->monitors || test_bit(SCAN_SW_SCANNING, &local->scanning))
+	if (local->monitors || test_bit(SCAN_SW_SCANNING, &local->scanning) ||
+	    test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning))
 		new_flags |= FIF_BCN_PRBRESP_PROMISC;
 
 	if (local->fif_probe_req || local->probe_req_reg)
@@ -148,6 +149,7 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
 	}
 
 	if (test_bit(SCAN_SW_SCANNING, &local->scanning) ||
+	    test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) ||
 	    test_bit(SCAN_HW_SCANNING, &local->scanning))
 		power = chan->max_power;
 	else
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 54a0491..dd2fbec 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -425,6 +425,7 @@ ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
 
 	if (test_bit(SCAN_HW_SCANNING, &local->scanning) ||
 	    test_bit(SCAN_SW_SCANNING, &local->scanning) ||
+	    test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) ||
 	    local->sched_scanning)
 		return ieee80211_scan_rx(rx->sdata, skb);
 
@@ -2915,6 +2916,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
 		local->dot11ReceivedFragmentCount++;
 
 	if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) ||
+		     test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) ||
 		     test_bit(SCAN_SW_SCANNING, &local->scanning)))
 		status->rx_flags |= IEEE80211_RX_IN_SCAN;
 
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index c70e176..5c7a332 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -387,6 +387,29 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
 	return 0;
 }
 
+static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
+					    unsigned long *next_delay)
+{
+	int i;
+	struct ieee80211_sub_if_data *sdata = local->scan_sdata;
+	enum ieee80211_band band = local->hw.conf.channel->band;
+
+	for (i = 0; i < local->scan_req->n_ssids; i++)
+		ieee80211_send_probe_req(
+			sdata, NULL,
+			local->scan_req->ssids[i].ssid,
+			local->scan_req->ssids[i].ssid_len,
+			local->scan_req->ie, local->scan_req->ie_len,
+			local->scan_req->rates[band], false,
+			local->scan_req->no_cck);
+
+	/*
+	 * After sending probe requests, wait for probe responses
+	 * on the channel.
+	 */
+	*next_delay = IEEE80211_CHANNEL_TIME;
+	local->next_scan_state = SCAN_DECISION;
+}
 
 static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
 				  struct cfg80211_scan_request *req)
@@ -438,10 +461,43 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
 	local->scan_req = req;
 	local->scan_sdata = sdata;
 
-	if (local->ops->hw_scan)
+	if (local->ops->hw_scan) {
 		__set_bit(SCAN_HW_SCANNING, &local->scanning);
-	else
-		__set_bit(SCAN_SW_SCANNING, &local->scanning);
+	} else {
+		/* If we are scanning only on the current channel, then
+		 * we do not need to stop normal activities
+		 */
+		if ((req->n_channels == 1) &&
+		    (req->channels[0]->center_freq ==
+		     local->hw.conf.channel->center_freq)) {
+			unsigned long next_delay;
+			__set_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning);
+			ieee80211_recalc_idle(local);
+			/* accept probe-responses */
+			ieee80211_configure_filter(local);
+			/* We need to set power level to max for scanning. */
+			ieee80211_hw_config(local, 0);
+
+			if ((req->channels[0]->flags &
+			     IEEE80211_CHAN_PASSIVE_SCAN) ||
+			    !local->scan_req->n_ssids) {
+				next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
+			} else {
+				ieee80211_scan_state_send_probe(local,
+								&next_delay);
+				next_delay = IEEE80211_CHANNEL_TIME;
+			}
+
+			/* Now, just wait a bit and we are all done! */
+			ieee80211_queue_delayed_work(&local->hw,
+						     &local->scan_work,
+						     next_delay);
+			return 0;
+		}
+		else {
+			__set_bit(SCAN_SW_SCANNING, &local->scanning);
+		}
+	}
 
 	ieee80211_recalc_idle(local);
 
@@ -598,30 +654,6 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
 	local->next_scan_state = SCAN_SEND_PROBE;
 }
 
-static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
-					    unsigned long *next_delay)
-{
-	int i;
-	struct ieee80211_sub_if_data *sdata = local->scan_sdata;
-	enum ieee80211_band band = local->hw.conf.channel->band;
-
-	for (i = 0; i < local->scan_req->n_ssids; i++)
-		ieee80211_send_probe_req(
-			sdata, NULL,
-			local->scan_req->ssids[i].ssid,
-			local->scan_req->ssids[i].ssid_len,
-			local->scan_req->ie, local->scan_req->ie_len,
-			local->scan_req->rates[band], false,
-			local->scan_req->no_cck);
-
-	/*
-	 * After sending probe requests, wait for probe responses
-	 * on the channel.
-	 */
-	*next_delay = IEEE80211_CHANNEL_TIME;
-	local->next_scan_state = SCAN_DECISION;
-}

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 09/10] ath9k: Add more recv stats.
@ 2012-04-11 17:52   ` greearb-my8/4N5VtI7c+919tysfdA
  0 siblings, 0 replies; 28+ messages in thread
From: greearb @ 2012-04-11 17:52 UTC (permalink / raw)
  To: linux-wireless; +Cc: netdev, Ben Greear

From: Ben Greear <greearb@candelatech.com>

This adds counters in various places that can drop packets on
rx without otherwise incrementing a counter.  It also counts
some non-error cases, such as becons and fragments received.

Should help with figuring out where packets are (and are not)
dropped.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 186efc5... 189ac7f... M	drivers/net/wireless/ath/ath9k/debug.c
:100644 100644 fe2b487... 17f6cc2... M	drivers/net/wireless/ath/ath9k/debug.h
:100644 100644 8588017... 301ef3e... M	drivers/net/wireless/ath/ath9k/recv.c
 drivers/net/wireless/ath/ath9k/debug.c |   53 ++++++++++++++------------------
 drivers/net/wireless/ath/ath9k/debug.h |   18 +++++++++++
 drivers/net/wireless/ath/ath9k/recv.c  |   35 +++++++++++++++-----
 3 files changed, 67 insertions(+), 39 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 186efc5..189ac7f 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -881,36 +881,27 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
 	len += snprintf(buf + len, size - len, "%22s : %10u\n", s, \
 			sc->debug.stats.rxstats.phy_err_stats[p]);
 
+#define RXS_ERR(s, e)				\
+	len += snprintf(buf + len, size - len,	\
+			"%22s : %10u\n", s, \
+			sc->debug.stats.rxstats.e);
+
 	struct ath_softc *sc = file->private_data;
 	char *buf;
-	unsigned int len = 0, size = 1600;
+	unsigned int len = 0, size = 3000;
 	ssize_t retval = 0;
 
 	buf = kzalloc(size, GFP_KERNEL);
 	if (buf == NULL)
 		return -ENOMEM;
 
-	len += snprintf(buf + len, size - len,
-			"%22s : %10u\n", "CRC ERR",
-			sc->debug.stats.rxstats.crc_err);
-	len += snprintf(buf + len, size - len,
-			"%22s : %10u\n", "DECRYPT CRC ERR",
-			sc->debug.stats.rxstats.decrypt_crc_err);
-	len += snprintf(buf + len, size - len,
-			"%22s : %10u\n", "PHY ERR",
-			sc->debug.stats.rxstats.phy_err);
-	len += snprintf(buf + len, size - len,
-			"%22s : %10u\n", "MIC ERR",
-			sc->debug.stats.rxstats.mic_err);
-	len += snprintf(buf + len, size - len,
-			"%22s : %10u\n", "PRE-DELIM CRC ERR",
-			sc->debug.stats.rxstats.pre_delim_crc_err);
-	len += snprintf(buf + len, size - len,
-			"%22s : %10u\n", "POST-DELIM CRC ERR",
-			sc->debug.stats.rxstats.post_delim_crc_err);
-	len += snprintf(buf + len, size - len,
-			"%22s : %10u\n", "DECRYPT BUSY ERR",
-			sc->debug.stats.rxstats.decrypt_busy_err);
+	RXS_ERR("CRC ERR", crc_err);
+	RXS_ERR("DECRYPT CRC ERR", decrypt_crc_err);
+	RXS_ERR("PHY ERR", phy_err);
+	RXS_ERR("MIC ERR", mic_err);
+	RXS_ERR("PRE-DELIM CRC ERR", pre_delim_crc_err);
+	RXS_ERR("POST-DELIM CRC ERR", post_delim_crc_err);
+	RXS_ERR("DECRYPT BUSY ERR", decrypt_busy_err);
 
 	PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN);
 	PHY_ERR("TIMING ERR", ATH9K_PHYERR_TIMING);
@@ -939,12 +930,16 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
 	PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
 	PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL);
 
-	len += snprintf(buf + len, size - len,
-			"%22s : %10u\n", "RX-Pkts-All",
-			sc->debug.stats.rxstats.rx_pkts_all);
-	len += snprintf(buf + len, size - len,
-			"%22s : %10u\n", "RX-Bytes-All",
-			sc->debug.stats.rxstats.rx_bytes_all);
+	RXS_ERR("DECRYPT BUSY ERR", decrypt_busy_err);
+	RXS_ERR("RX-LENGTH-ERR", rx_len_err);
+	RXS_ERR("RX-OOM-ERR", rx_oom_err);
+	RXS_ERR("RX-RATE-ERR", rx_rate_err);
+	RXS_ERR("RX-DROP-RXFLUSH", rx_drop_rxflush);
+	RXS_ERR("RX-TOO-MANY-FRAGS", rx_too_many_frags_err);
+	RXS_ERR("RX-Pkts-All", rx_pkts_all);
+	RXS_ERR("RX-Bytes-All", rx_bytes_all);
+	RXS_ERR("RX-Beacons", rx_beacons);
+	RXS_ERR("RX-Frags", rx_frags);
 
 	if (len > size)
 		len = size;
@@ -959,7 +954,6 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
 
 void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
 {
-#define RX_STAT_INC(c) sc->debug.stats.rxstats.c++
 #define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++
 #define RX_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].rs\
 			[sc->debug.rsidx].c)
@@ -1005,7 +999,6 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
 
 #endif
 
-#undef RX_STAT_INC
 #undef RX_PHY_ERR_INC
 #undef RX_SAMP_DBG
 }
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index fe2b487..17f6cc2 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -139,6 +139,8 @@ struct ath_tx_stats {
 	u32 txfailed;
 };
 
+#define RX_STAT_INC(c) (sc->debug.stats.rxstats.c++)
+
 /**
  * struct ath_rx_stats - RX Statistics
  * @rx_pkts_all:  No. of total frames received, including ones that
@@ -155,6 +157,13 @@ struct ath_tx_stats {
  * @post_delim_crc_err: Post-Frame delimiter CRC error detections
  * @decrypt_busy_err: Decryption interruptions counter
  * @phy_err_stats: Individual PHY error statistics
+ * @rx_len_err:  No. of frames discarded due to bad length.
+ * @rx_oom_err:  No. of frames dropped due to OOM issues.
+ * @rx_rate_err:  No. of frames dropped due to rate errors.
+ * @rx_too_many_frags_err:  Frames dropped due to too-many-frags received.
+ * @rx_drop_rxflush: No. of frames dropped due to RX-FLUSH.
+ * @rx_beacons:  No. of beacons received.
+ * @rx_frags:  No. of rx-fragements received.
  */
 struct ath_rx_stats {
 	u32 rx_pkts_all;
@@ -167,6 +176,13 @@ struct ath_rx_stats {
 	u32 post_delim_crc_err;
 	u32 decrypt_busy_err;
 	u32 phy_err_stats[ATH9K_PHYERR_MAX];
+	u32 rx_len_err;
+	u32 rx_oom_err;
+	u32 rx_rate_err;
+	u32 rx_too_many_frags_err;
+	u32 rx_drop_rxflush;
+	u32 rx_beacons;
+	u32 rx_frags;
 };
 
 enum ath_reset_type {
@@ -250,6 +266,8 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs);
 
 #else
 
+#define RX_STAT_INC(c) /* NOP */
+
 static inline int ath9k_init_debug(struct ath_hw *ah)
 {
 	return 0;
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 8588017..301ef3e 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -824,15 +824,20 @@ static bool ath9k_rx_accept(struct ath_common *common,
 	if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID)
 		rx_stats->rs_status &= ~ATH9K_RXERR_KEYMISS;
 
-	if (!rx_stats->rs_datalen)
+	if (!rx_stats->rs_datalen) {
+		RX_STAT_INC(rx_len_err);
 		return false;
+	}
+
         /*
          * rs_status follows rs_datalen so if rs_datalen is too large
          * we can take a hint that hardware corrupted it, so ignore
          * those frames.
          */
-	if (rx_stats->rs_datalen > (common->rx_bufsize - rx_status_len))
+	if (rx_stats->rs_datalen > (common->rx_bufsize - rx_status_len)) {
+		RX_STAT_INC(rx_len_err);
 		return false;
+	}
 
 	/* Only use error bits from the last fragment */
 	if (rx_stats->rs_more)
@@ -902,6 +907,7 @@ static int ath9k_process_rate(struct ath_common *common,
 	struct ieee80211_supported_band *sband;
 	enum ieee80211_band band;
 	unsigned int i = 0;
+	struct ath_softc *sc = (struct ath_softc *) common->priv;
 
 	band = hw->conf.channel->band;
 	sband = hw->wiphy->bands[band];
@@ -936,7 +942,7 @@ static int ath9k_process_rate(struct ath_common *common,
 	ath_dbg(common, ANY,
 		"unsupported hw bitrate detected 0x%02x using 1 Mbit\n",
 		rx_stats->rs_rate);
-
+	RX_STAT_INC(rx_rate_err);
 	return -EINVAL;
 }
 
@@ -1823,10 +1829,14 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
 
 		hdr = (struct ieee80211_hdr *) (hdr_skb->data + rx_status_len);
 		rxs = IEEE80211_SKB_RXCB(hdr_skb);
-		if (ieee80211_is_beacon(hdr->frame_control) &&
-		    !is_zero_ether_addr(common->curbssid) &&
-		    !compare_ether_addr(hdr->addr3, common->curbssid))
-			rs.is_mybeacon = true;
+		if (ieee80211_is_beacon(hdr->frame_control)) {
+			RX_STAT_INC(rx_beacons);
+			if (!is_zero_ether_addr(common->curbssid) &&
+			    !compare_ether_addr(hdr->addr3, common->curbssid))
+				rs.is_mybeacon = true;
+			else
+				rs.is_mybeacon = false;
+		}
 		else
 			rs.is_mybeacon = false;
 
@@ -1836,8 +1846,10 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
 		 * If we're asked to flush receive queue, directly
 		 * chain it back at the queue without processing it.
 		 */
-		if (sc->sc_flags & SC_OP_RXFLUSH)
+		if (sc->sc_flags & SC_OP_RXFLUSH) {
+			RX_STAT_INC(rx_drop_rxflush);
 			goto requeue_drop_frag;
+		}
 
 		memset(rxs, 0, sizeof(struct ieee80211_rx_status));
 
@@ -1867,8 +1879,10 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
 		 * tell hardware it can give us a new frame using the old
 		 * skb and put it at the tail of the sc->rx.rxbuf list for
 		 * processing. */
-		if (!requeue_skb)
+		if (!requeue_skb) {
+			RX_STAT_INC(rx_oom_err);
 			goto requeue_drop_frag;
+		}
 
 		/* Unmap the frame */
 		dma_unmap_single(sc->dev, bf->bf_buf_addr,
@@ -1899,6 +1913,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
 		}
 
 		if (rs.rs_more) {
+			RX_STAT_INC(rx_frags);
 			/*
 			 * rs_more indicates chained descriptors which can be
 			 * used to link buffers together for a sort of
@@ -1908,6 +1923,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
 				/* too many fragments - cannot handle frame */
 				dev_kfree_skb_any(sc->rx.frag);
 				dev_kfree_skb_any(skb);
+				RX_STAT_INC(rx_too_many_frags_err);
 				skb = NULL;
 			}
 			sc->rx.frag = skb;
@@ -1919,6 +1935,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
 
 			if (pskb_expand_head(hdr_skb, 0, space, GFP_ATOMIC) < 0) {
 				dev_kfree_skb(skb);
+				RX_STAT_INC(rx_oom_err);
 				goto requeue_drop_frag;
 			}
 
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 09/10] ath9k: Add more recv stats.
@ 2012-04-11 17:52   ` greearb-my8/4N5VtI7c+919tysfdA
  0 siblings, 0 replies; 28+ messages in thread
From: greearb-my8/4N5VtI7c+919tysfdA @ 2012-04-11 17:52 UTC (permalink / raw)
  To: linux-wireless-u79uwXL29TY76Z2rM5mHXA
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Ben Greear

From: Ben Greear <greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org>

This adds counters in various places that can drop packets on
rx without otherwise incrementing a counter.  It also counts
some non-error cases, such as becons and fragments received.

Should help with figuring out where packets are (and are not)
dropped.

Signed-off-by: Ben Greear <greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org>
---
:100644 100644 186efc5... 189ac7f... M	drivers/net/wireless/ath/ath9k/debug.c
:100644 100644 fe2b487... 17f6cc2... M	drivers/net/wireless/ath/ath9k/debug.h
:100644 100644 8588017... 301ef3e... M	drivers/net/wireless/ath/ath9k/recv.c
 drivers/net/wireless/ath/ath9k/debug.c |   53 ++++++++++++++------------------
 drivers/net/wireless/ath/ath9k/debug.h |   18 +++++++++++
 drivers/net/wireless/ath/ath9k/recv.c  |   35 +++++++++++++++-----
 3 files changed, 67 insertions(+), 39 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 186efc5..189ac7f 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -881,36 +881,27 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
 	len += snprintf(buf + len, size - len, "%22s : %10u\n", s, \
 			sc->debug.stats.rxstats.phy_err_stats[p]);
 
+#define RXS_ERR(s, e)				\
+	len += snprintf(buf + len, size - len,	\
+			"%22s : %10u\n", s, \
+			sc->debug.stats.rxstats.e);
+
 	struct ath_softc *sc = file->private_data;
 	char *buf;
-	unsigned int len = 0, size = 1600;
+	unsigned int len = 0, size = 3000;
 	ssize_t retval = 0;
 
 	buf = kzalloc(size, GFP_KERNEL);
 	if (buf == NULL)
 		return -ENOMEM;
 
-	len += snprintf(buf + len, size - len,
-			"%22s : %10u\n", "CRC ERR",
-			sc->debug.stats.rxstats.crc_err);
-	len += snprintf(buf + len, size - len,
-			"%22s : %10u\n", "DECRYPT CRC ERR",
-			sc->debug.stats.rxstats.decrypt_crc_err);
-	len += snprintf(buf + len, size - len,
-			"%22s : %10u\n", "PHY ERR",
-			sc->debug.stats.rxstats.phy_err);
-	len += snprintf(buf + len, size - len,
-			"%22s : %10u\n", "MIC ERR",
-			sc->debug.stats.rxstats.mic_err);
-	len += snprintf(buf + len, size - len,
-			"%22s : %10u\n", "PRE-DELIM CRC ERR",
-			sc->debug.stats.rxstats.pre_delim_crc_err);
-	len += snprintf(buf + len, size - len,
-			"%22s : %10u\n", "POST-DELIM CRC ERR",
-			sc->debug.stats.rxstats.post_delim_crc_err);
-	len += snprintf(buf + len, size - len,
-			"%22s : %10u\n", "DECRYPT BUSY ERR",
-			sc->debug.stats.rxstats.decrypt_busy_err);
+	RXS_ERR("CRC ERR", crc_err);
+	RXS_ERR("DECRYPT CRC ERR", decrypt_crc_err);
+	RXS_ERR("PHY ERR", phy_err);
+	RXS_ERR("MIC ERR", mic_err);
+	RXS_ERR("PRE-DELIM CRC ERR", pre_delim_crc_err);
+	RXS_ERR("POST-DELIM CRC ERR", post_delim_crc_err);
+	RXS_ERR("DECRYPT BUSY ERR", decrypt_busy_err);
 
 	PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN);
 	PHY_ERR("TIMING ERR", ATH9K_PHYERR_TIMING);
@@ -939,12 +930,16 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
 	PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
 	PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL);
 
-	len += snprintf(buf + len, size - len,
-			"%22s : %10u\n", "RX-Pkts-All",
-			sc->debug.stats.rxstats.rx_pkts_all);
-	len += snprintf(buf + len, size - len,
-			"%22s : %10u\n", "RX-Bytes-All",
-			sc->debug.stats.rxstats.rx_bytes_all);
+	RXS_ERR("DECRYPT BUSY ERR", decrypt_busy_err);
+	RXS_ERR("RX-LENGTH-ERR", rx_len_err);
+	RXS_ERR("RX-OOM-ERR", rx_oom_err);
+	RXS_ERR("RX-RATE-ERR", rx_rate_err);
+	RXS_ERR("RX-DROP-RXFLUSH", rx_drop_rxflush);
+	RXS_ERR("RX-TOO-MANY-FRAGS", rx_too_many_frags_err);
+	RXS_ERR("RX-Pkts-All", rx_pkts_all);
+	RXS_ERR("RX-Bytes-All", rx_bytes_all);
+	RXS_ERR("RX-Beacons", rx_beacons);
+	RXS_ERR("RX-Frags", rx_frags);
 
 	if (len > size)
 		len = size;
@@ -959,7 +954,6 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
 
 void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
 {
-#define RX_STAT_INC(c) sc->debug.stats.rxstats.c++
 #define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++
 #define RX_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].rs\
 			[sc->debug.rsidx].c)
@@ -1005,7 +999,6 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
 
 #endif
 
-#undef RX_STAT_INC
 #undef RX_PHY_ERR_INC
 #undef RX_SAMP_DBG
 }
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index fe2b487..17f6cc2 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -139,6 +139,8 @@ struct ath_tx_stats {
 	u32 txfailed;
 };
 
+#define RX_STAT_INC(c) (sc->debug.stats.rxstats.c++)
+
 /**
  * struct ath_rx_stats - RX Statistics
  * @rx_pkts_all:  No. of total frames received, including ones that
@@ -155,6 +157,13 @@ struct ath_tx_stats {
  * @post_delim_crc_err: Post-Frame delimiter CRC error detections
  * @decrypt_busy_err: Decryption interruptions counter
  * @phy_err_stats: Individual PHY error statistics
+ * @rx_len_err:  No. of frames discarded due to bad length.
+ * @rx_oom_err:  No. of frames dropped due to OOM issues.
+ * @rx_rate_err:  No. of frames dropped due to rate errors.
+ * @rx_too_many_frags_err:  Frames dropped due to too-many-frags received.
+ * @rx_drop_rxflush: No. of frames dropped due to RX-FLUSH.
+ * @rx_beacons:  No. of beacons received.
+ * @rx_frags:  No. of rx-fragements received.
  */
 struct ath_rx_stats {
 	u32 rx_pkts_all;
@@ -167,6 +176,13 @@ struct ath_rx_stats {
 	u32 post_delim_crc_err;
 	u32 decrypt_busy_err;
 	u32 phy_err_stats[ATH9K_PHYERR_MAX];
+	u32 rx_len_err;
+	u32 rx_oom_err;
+	u32 rx_rate_err;
+	u32 rx_too_many_frags_err;
+	u32 rx_drop_rxflush;
+	u32 rx_beacons;
+	u32 rx_frags;
 };
 
 enum ath_reset_type {
@@ -250,6 +266,8 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs);
 
 #else
 
+#define RX_STAT_INC(c) /* NOP */
+
 static inline int ath9k_init_debug(struct ath_hw *ah)
 {
 	return 0;
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 8588017..301ef3e 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -824,15 +824,20 @@ static bool ath9k_rx_accept(struct ath_common *common,
 	if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID)
 		rx_stats->rs_status &= ~ATH9K_RXERR_KEYMISS;
 
-	if (!rx_stats->rs_datalen)
+	if (!rx_stats->rs_datalen) {
+		RX_STAT_INC(rx_len_err);
 		return false;
+	}
+
         /*
          * rs_status follows rs_datalen so if rs_datalen is too large
          * we can take a hint that hardware corrupted it, so ignore
          * those frames.
          */
-	if (rx_stats->rs_datalen > (common->rx_bufsize - rx_status_len))
+	if (rx_stats->rs_datalen > (common->rx_bufsize - rx_status_len)) {
+		RX_STAT_INC(rx_len_err);
 		return false;
+	}
 
 	/* Only use error bits from the last fragment */
 	if (rx_stats->rs_more)
@@ -902,6 +907,7 @@ static int ath9k_process_rate(struct ath_common *common,
 	struct ieee80211_supported_band *sband;
 	enum ieee80211_band band;
 	unsigned int i = 0;
+	struct ath_softc *sc = (struct ath_softc *) common->priv;
 
 	band = hw->conf.channel->band;
 	sband = hw->wiphy->bands[band];
@@ -936,7 +942,7 @@ static int ath9k_process_rate(struct ath_common *common,
 	ath_dbg(common, ANY,
 		"unsupported hw bitrate detected 0x%02x using 1 Mbit\n",
 		rx_stats->rs_rate);
-
+	RX_STAT_INC(rx_rate_err);
 	return -EINVAL;
 }
 
@@ -1823,10 +1829,14 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
 
 		hdr = (struct ieee80211_hdr *) (hdr_skb->data + rx_status_len);
 		rxs = IEEE80211_SKB_RXCB(hdr_skb);
-		if (ieee80211_is_beacon(hdr->frame_control) &&
-		    !is_zero_ether_addr(common->curbssid) &&
-		    !compare_ether_addr(hdr->addr3, common->curbssid))
-			rs.is_mybeacon = true;
+		if (ieee80211_is_beacon(hdr->frame_control)) {
+			RX_STAT_INC(rx_beacons);
+			if (!is_zero_ether_addr(common->curbssid) &&
+			    !compare_ether_addr(hdr->addr3, common->curbssid))
+				rs.is_mybeacon = true;
+			else
+				rs.is_mybeacon = false;
+		}
 		else
 			rs.is_mybeacon = false;
 
@@ -1836,8 +1846,10 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
 		 * If we're asked to flush receive queue, directly
 		 * chain it back at the queue without processing it.
 		 */
-		if (sc->sc_flags & SC_OP_RXFLUSH)
+		if (sc->sc_flags & SC_OP_RXFLUSH) {
+			RX_STAT_INC(rx_drop_rxflush);
 			goto requeue_drop_frag;
+		}
 
 		memset(rxs, 0, sizeof(struct ieee80211_rx_status));
 
@@ -1867,8 +1879,10 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
 		 * tell hardware it can give us a new frame using the old
 		 * skb and put it at the tail of the sc->rx.rxbuf list for
 		 * processing. */
-		if (!requeue_skb)
+		if (!requeue_skb) {
+			RX_STAT_INC(rx_oom_err);
 			goto requeue_drop_frag;
+		}
 
 		/* Unmap the frame */
 		dma_unmap_single(sc->dev, bf->bf_buf_addr,
@@ -1899,6 +1913,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
 		}
 
 		if (rs.rs_more) {
+			RX_STAT_INC(rx_frags);
 			/*
 			 * rs_more indicates chained descriptors which can be
 			 * used to link buffers together for a sort of
@@ -1908,6 +1923,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
 				/* too many fragments - cannot handle frame */
 				dev_kfree_skb_any(sc->rx.frag);
 				dev_kfree_skb_any(skb);
+				RX_STAT_INC(rx_too_many_frags_err);
 				skb = NULL;
 			}
 			sc->rx.frag = skb;
@@ -1919,6 +1935,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
 
 			if (pskb_expand_head(hdr_skb, 0, space, GFP_ATOMIC) < 0) {
 				dev_kfree_skb(skb);
+				RX_STAT_INC(rx_oom_err);
 				goto requeue_drop_frag;
 			}
 
-- 
1.7.3.4

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 10/10] ath9k: Gather and report IRQ sync_cause errors.
  2012-04-11 17:52 [PATCH 00/10] Wireless patches for wireless-testing greearb
                   ` (8 preceding siblings ...)
  2012-04-11 17:52   ` greearb-my8/4N5VtI7c+919tysfdA
@ 2012-04-11 17:52 ` greearb
  2012-04-12  3:39   ` Johannes Berg
  10 siblings, 0 replies; 28+ messages in thread
From: greearb @ 2012-04-11 17:52 UTC (permalink / raw)
  To: linux-wireless; +Cc: netdev, Ben Greear

From: Ben Greear <greearb@candelatech.com>

Report all defined sync_cause errors in debugfs
to aid with debugging.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 aa2abaf... 8d78253... M	drivers/net/wireless/ath/ath9k/ar9002_mac.c
:100644 100644 a66a13b... d9e0824... M	drivers/net/wireless/ath/ath9k/ar9003_mac.c
:100644 100644 189ac7f... 1bd7204... M	drivers/net/wireless/ath/ath9k/debug.c
:100644 100644 17f6cc2... c34da09... M	drivers/net/wireless/ath/ath9k/debug.h
:100644 100644 d1345a8... 61b2157... M	drivers/net/wireless/ath/ath9k/hw.c
:100644 100644 aa1680a... fba99ef... M	drivers/net/wireless/ath/ath9k/hw.h
 drivers/net/wireless/ath/ath9k/ar9002_mac.c |    1 +
 drivers/net/wireless/ath/ath9k/ar9003_mac.c |    2 +
 drivers/net/wireless/ath/ath9k/debug.c      |  113 ++++++++++++++------------
 drivers/net/wireless/ath/ath9k/debug.h      |   23 ++++++
 drivers/net/wireless/ath/ath9k/hw.c         |   49 ++++++++++++
 drivers/net/wireless/ath/ath9k/hw.h         |    6 ++
 6 files changed, 142 insertions(+), 52 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
index aa2abaf..8d78253 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
@@ -136,6 +136,7 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
 	}
 
 	if (sync_cause) {
+		ath9k_debug_sync_cause(common, sync_cause);
 		fatal_int =
 			(sync_cause &
 			 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index a66a13b..d9e0824 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -306,6 +306,8 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
 		ar9003_mci_get_isr(ah, masked);
 
 	if (sync_cause) {
+		ath9k_debug_sync_cause(common, sync_cause);
+
 		if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
 			REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
 			REG_WRITE(ah, AR_RC, 0);
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 189ac7f..1bd7204 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -380,63 +380,72 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
 				   size_t count, loff_t *ppos)
 {
 	struct ath_softc *sc = file->private_data;
-	char buf[512];
 	unsigned int len = 0;
+	int rv;
+	int mxlen = 4000;
+	char *buf = kmalloc(mxlen, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+#define PR_IS(a, s)							\
+	len += snprintf(buf + len, mxlen - len,				\
+			"%21s: %10u\n", a, sc->debug.stats.istats.s);
 
 	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
-		len += snprintf(buf + len, sizeof(buf) - len,
-			"%8s: %10u\n", "RXLP", sc->debug.stats.istats.rxlp);
-		len += snprintf(buf + len, sizeof(buf) - len,
-			"%8s: %10u\n", "RXHP", sc->debug.stats.istats.rxhp);
-		len += snprintf(buf + len, sizeof(buf) - len,
-			"%8s: %10u\n", "WATCHDOG",
-			sc->debug.stats.istats.bb_watchdog);
+		PR_IS("RXLP", rxlp);
+		PR_IS("RXHP", rxhp);
+		PR_IS("WATHDOG", bb_watchdog);
 	} else {
-		len += snprintf(buf + len, sizeof(buf) - len,
-			"%8s: %10u\n", "RX", sc->debug.stats.istats.rxok);
+		PR_IS("RX", rxok);
 	}
-	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "RXEOL", sc->debug.stats.istats.rxeol);
-	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "RXORN", sc->debug.stats.istats.rxorn);
-	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "TX", sc->debug.stats.istats.txok);
-	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "TXURN", sc->debug.stats.istats.txurn);
-	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "MIB", sc->debug.stats.istats.mib);
-	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "RXPHY", sc->debug.stats.istats.rxphyerr);
-	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "RXKCM", sc->debug.stats.istats.rx_keycache_miss);
-	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "SWBA", sc->debug.stats.istats.swba);
-	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "BMISS", sc->debug.stats.istats.bmiss);
-	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "BNR", sc->debug.stats.istats.bnr);
-	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "CST", sc->debug.stats.istats.cst);
-	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "GTT", sc->debug.stats.istats.gtt);
-	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "TIM", sc->debug.stats.istats.tim);
-	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "CABEND", sc->debug.stats.istats.cabend);
-	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "DTIMSYNC", sc->debug.stats.istats.dtimsync);
-	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "DTIM", sc->debug.stats.istats.dtim);
-	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "TSFOOR", sc->debug.stats.istats.tsfoor);
-	len += snprintf(buf + len, sizeof(buf) - len,
-		"%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total);
-
-
-	if (len > sizeof(buf))
-		len = sizeof(buf);
-
-	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+	PR_IS("RXEOL", rxeol);
+	PR_IS("RXORN", rxorn);
+	PR_IS("TX", txok);
+	PR_IS("TXURN", txurn);
+	PR_IS("MIB", mib);
+	PR_IS("RXPHY", rxphyerr);
+	PR_IS("RXKCM", rx_keycache_miss);
+	PR_IS("SWBA", swba);
+	PR_IS("BMISS", bmiss);
+	PR_IS("BNR", bnr);
+	PR_IS("CST", cst);
+	PR_IS("GTT", gtt);
+	PR_IS("TIM", tim);
+	PR_IS("CABEND", cabend);
+	PR_IS("DTIMSYNC", dtimsync);
+	PR_IS("DTIM", dtim);
+	PR_IS("TSFOOR", tsfoor);
+	PR_IS("TOTAL", total);
+
+	len += snprintf(buf + len, mxlen - len,
+			"SYNC_CAUSE stats:\n");
+
+	PR_IS("Sync-All", sync_cause_all);
+	PR_IS("RTC-IRQ", sync_rtc_irq);
+	PR_IS("MAC-IRQ", sync_mac_irq);
+	PR_IS("EEPROM-Illegal-Access", eeprom_illegal_access);
+	PR_IS("APB-Timeout", apb_timeout);
+	PR_IS("PCI-Mode-Conflict", pci_mode_conflict);
+	PR_IS("HOST1-Fatal", host1_fatal);
+	PR_IS("HOST1-Perr", host1_perr);
+	PR_IS("TRCV-FIFO-Perr", trcv_fifo_perr);
+	PR_IS("RADM-CPL-EP", radm_cpl_ep);
+	PR_IS("RADM-CPL-DLLP-Abort", radm_cpl_dllp_abort);
+	PR_IS("RADM-CPL-TLP-Abort", radm_cpl_tlp_abort);
+	PR_IS("RADM-CPL-ECRC-Err", radm_cpl_ecrc_err);
+	PR_IS("RADM-CPL-Timeout", radm_cpl_timeout);
+	PR_IS("Local-Bus-Timeout", local_timeout);
+	PR_IS("PM-Access", pm_access);
+	PR_IS("MAC-Awake", mac_awake);
+	PR_IS("MAC-Asleep", mac_asleep);
+	PR_IS("MAC-Sleep-Access", mac_sleep_access);
+
+	if (len > mxlen)
+		len = mxlen;
+
+	rv = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+	kfree(buf);
+	return rv;
 }
 
 static const struct file_operations fops_interrupt = {
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 17f6cc2..c34da09 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -60,6 +60,7 @@ struct ath_buf;
  * @tsfoor: TSF out of range, indicates that the corrected TSF received
  * from a beacon differs from the PCU's internal TSF by more than a
  * (programmable) threshold
+ * @local_timeout: Internal bus timeout.
  */
 struct ath_interrupt_stats {
 	u32 total;
@@ -85,8 +86,30 @@ struct ath_interrupt_stats {
 	u32 dtim;
 	u32 bb_watchdog;
 	u32 tsfoor;
+
+	/* Sync-cause stats */
+	u32 sync_cause_all;
+	u32 sync_rtc_irq;
+	u32 sync_mac_irq;
+	u32 eeprom_illegal_access;
+	u32 apb_timeout;
+	u32 pci_mode_conflict;
+	u32 host1_fatal;
+	u32 host1_perr;
+	u32 trcv_fifo_perr;
+	u32 radm_cpl_ep;
+	u32 radm_cpl_dllp_abort;
+	u32 radm_cpl_tlp_abort;
+	u32 radm_cpl_ecrc_err;
+	u32 radm_cpl_timeout;
+	u32 local_timeout;
+	u32 pm_access;
+	u32 mac_awake;
+	u32 mac_asleep;
+	u32 mac_sleep_access;
 };
 
+
 /**
  * struct ath_tx_stats - Statistics about TX
  * @tx_pkts_all:  No. of total frames transmitted, including ones that
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index d1345a8..61b2157 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -24,6 +24,8 @@
 #include "rc.h"
 #include "ar9003_mac.h"
 #include "ar9003_mci.h"
+#include "debug.h"
+#include "ath9k.h"
 
 static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
 
@@ -83,6 +85,53 @@ static void ath9k_hw_ani_cache_ini_regs(struct ath_hw *ah)
 /* Helper Functions */
 /********************/
 
+#ifdef CONFIG_ATH9K_DEBUGFS
+
+void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause)
+{
+	struct ath_softc *sc = common->priv;
+	if (sync_cause)
+		sc->debug.stats.istats.sync_cause_all++;
+	if (sync_cause & AR_INTR_SYNC_RTC_IRQ)
+		sc->debug.stats.istats.sync_rtc_irq++;
+	if (sync_cause & AR_INTR_SYNC_MAC_IRQ)
+		sc->debug.stats.istats.sync_mac_irq++;
+	if (sync_cause & AR_INTR_SYNC_EEPROM_ILLEGAL_ACCESS)
+		sc->debug.stats.istats.eeprom_illegal_access++;
+	if (sync_cause & AR_INTR_SYNC_APB_TIMEOUT)
+		sc->debug.stats.istats.apb_timeout++;
+	if (sync_cause & AR_INTR_SYNC_PCI_MODE_CONFLICT)
+		sc->debug.stats.istats.pci_mode_conflict++;
+	if (sync_cause & AR_INTR_SYNC_HOST1_FATAL)
+		sc->debug.stats.istats.host1_fatal++;
+	if (sync_cause & AR_INTR_SYNC_HOST1_PERR)
+		sc->debug.stats.istats.host1_perr++;
+	if (sync_cause & AR_INTR_SYNC_TRCV_FIFO_PERR)
+		sc->debug.stats.istats.trcv_fifo_perr++;
+	if (sync_cause & AR_INTR_SYNC_RADM_CPL_EP)
+		sc->debug.stats.istats.radm_cpl_ep++;
+	if (sync_cause & AR_INTR_SYNC_RADM_CPL_DLLP_ABORT)
+		sc->debug.stats.istats.radm_cpl_dllp_abort++;
+	if (sync_cause & AR_INTR_SYNC_RADM_CPL_TLP_ABORT)
+		sc->debug.stats.istats.radm_cpl_tlp_abort++;
+	if (sync_cause & AR_INTR_SYNC_RADM_CPL_ECRC_ERR)
+		sc->debug.stats.istats.radm_cpl_ecrc_err++;
+	if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT)
+		sc->debug.stats.istats.radm_cpl_timeout++;
+	if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT)
+		sc->debug.stats.istats.local_timeout++;
+	if (sync_cause & AR_INTR_SYNC_PM_ACCESS)
+		sc->debug.stats.istats.pm_access++;
+	if (sync_cause & AR_INTR_SYNC_MAC_AWAKE)
+		sc->debug.stats.istats.mac_awake++;
+	if (sync_cause & AR_INTR_SYNC_MAC_ASLEEP)
+		sc->debug.stats.istats.mac_asleep++;
+	if (sync_cause & AR_INTR_SYNC_MAC_SLEEP_ACCESS)
+		sc->debug.stats.istats.mac_sleep_access++;
+}
+#endif
+
+
 static void ath9k_hw_set_clockrate(struct ath_hw *ah)
 {
 	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index aa1680a..fba99ef 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -965,6 +965,12 @@ bool ath9k_hw_check_alive(struct ath_hw *ah);
 
 bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
 
+#ifdef CONFIG_ATH9K_DEBUGFS
+void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause);
+#else
+static void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause) {}
+#endif
+
 /* Generic hw timer primitives */
 struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
 					  void (*trigger)(void *),
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH 05/10] mac80211: Add more ethtools stats: survey, rates, etc
@ 2012-04-11 18:01     ` Ben Greear
  0 siblings, 0 replies; 28+ messages in thread
From: Ben Greear @ 2012-04-11 18:01 UTC (permalink / raw)
  To: greearb; +Cc: linux-wireless, netdev

On 04/11/2012 10:52 AM, greearb@candelatech.com wrote:
> From: Ben Greear<greearb@candelatech.com>
>
> The signal and noise are forced to be positive since ethtool
> deals in unsigned 64-bit values and this number should be human
> readable.  This gives easy access to some of the data formerly
> exposed in the deprecated /proc/net/wireless file.

> +	if (WARN_ON(i != STA_STATS_LEN)) {
> +		rcu_read_unlock();
> +		return;
> +	}
> +
> +	drv_get_et_stats(sdata, stats,&(data[STA_STATS_LEN]));
> +}
> +

Ahh crap, I missed an rcu_read_unlock here...will fix this
and whatever else folks suggest and repost..but don't apply
this patch as is!

Thanks,
Ben

-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 05/10] mac80211: Add more ethtools stats: survey, rates, etc
@ 2012-04-11 18:01     ` Ben Greear
  0 siblings, 0 replies; 28+ messages in thread
From: Ben Greear @ 2012-04-11 18:01 UTC (permalink / raw)
  To: greearb-my8/4N5VtI7c+919tysfdA
  Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA

On 04/11/2012 10:52 AM, greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org wrote:
> From: Ben Greear<greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org>
>
> The signal and noise are forced to be positive since ethtool
> deals in unsigned 64-bit values and this number should be human
> readable.  This gives easy access to some of the data formerly
> exposed in the deprecated /proc/net/wireless file.

> +	if (WARN_ON(i != STA_STATS_LEN)) {
> +		rcu_read_unlock();
> +		return;
> +	}
> +
> +	drv_get_et_stats(sdata, stats,&(data[STA_STATS_LEN]));
> +}
> +

Ahh crap, I missed an rcu_read_unlock here...will fix this
and whatever else folks suggest and repost..but don't apply
this patch as is!

Thanks,
Ben

-- 
Ben Greear <greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org>
Candela Technologies Inc  http://www.candelatech.com

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 00/10] Wireless patches for wireless-testing
@ 2012-04-12  3:39   ` Johannes Berg
  0 siblings, 0 replies; 28+ messages in thread
From: Johannes Berg @ 2012-04-12  3:39 UTC (permalink / raw)
  To: greearb; +Cc: linux-wireless, netdev

On Wed, 2012-04-11 at 10:52 -0700, greearb@candelatech.com wrote:
> From: Ben Greear <greearb@candelatech.com>
> 
> Support Ethtool stats for Wireless, including in-depth
> stats for ath9k, and add some additional ath9k stats
> to debugfs.  Support scanning on-channel.

Please don't mix two completely different things in a single series of
patches. I almost skipped this completely since I already saw the
ethtool stuff and don't care about ath9k stats, but clearly I need to
look at the scan thing ...

johannes


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 00/10] Wireless patches for wireless-testing
@ 2012-04-12  3:39   ` Johannes Berg
  0 siblings, 0 replies; 28+ messages in thread
From: Johannes Berg @ 2012-04-12  3:39 UTC (permalink / raw)
  To: greearb-my8/4N5VtI7c+919tysfdA
  Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA

On Wed, 2012-04-11 at 10:52 -0700, greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org wrote:
> From: Ben Greear <greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org>
> 
> Support Ethtool stats for Wireless, including in-depth
> stats for ath9k, and add some additional ath9k stats
> to debugfs.  Support scanning on-channel.

Please don't mix two completely different things in a single series of
patches. I almost skipped this completely since I already saw the
ethtool stuff and don't care about ath9k stats, but clearly I need to
look at the scan thing ...

johannes

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 08/10] mac80211: Support on-channel scan option.
  2012-04-11 17:52   ` greearb-my8/4N5VtI7c+919tysfdA
  (?)
@ 2012-04-12  3:45   ` Johannes Berg
  2012-04-12 15:03     ` Ben Greear
  -1 siblings, 1 reply; 28+ messages in thread
From: Johannes Berg @ 2012-04-12  3:45 UTC (permalink / raw)
  To: greearb; +Cc: linux-wireless, netdev

On Wed, 2012-04-11 at 10:52 -0700, greearb@candelatech.com wrote:

>  static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
>  				  struct cfg80211_scan_request *req)
> @@ -438,10 +461,43 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
>  	local->scan_req = req;
>  	local->scan_sdata = sdata;
>  
> -	if (local->ops->hw_scan)
> +	if (local->ops->hw_scan) {
>  		__set_bit(SCAN_HW_SCANNING, &local->scanning);
> -	else
> -		__set_bit(SCAN_SW_SCANNING, &local->scanning);
> +	} else {
> +		/* If we are scanning only on the current channel, then
> +		 * we do not need to stop normal activities
> +		 */
> +		if ((req->n_channels == 1) &&
> +		    (req->channels[0]->center_freq ==
> +		     local->hw.conf.channel->center_freq)) {

how about "else if {", then the indentation isn't so deep and you can
have much nicer code in the entire block :)

> +			unsigned long next_delay;

please add a blank line after variable declarations.

> +		}
> +		else {

please read the coding style documentation

> @@ -672,6 +704,12 @@ void ieee80211_scan_work(struct work_struct *work)
>  
>  	sdata = local->scan_sdata;
>  
> +	/* When scanning on-channel, the first-callback means completeed. */

typo "completed"

> +	if (test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning)) {
> +		aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning);
> +		goto out_complete;
> +	}

how does the onchannel bit get cleared?

Shouldn't you be calling pre/post scan hooks?


I'm a bit divided over this. On the one hand, it seems like a mildly
useful optimisation, on the other though it adds a bunch of complexity
for multi-channel we've been thinking about... Not that we want to
support multi-channel with SW scan anyway, but still.

johannes


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 05/10] mac80211: Add more ethtools stats: survey, rates, etc
@ 2012-04-12  3:46     ` Johannes Berg
  0 siblings, 0 replies; 28+ messages in thread
From: Johannes Berg @ 2012-04-12  3:46 UTC (permalink / raw)
  To: greearb; +Cc: linux-wireless, netdev

On Wed, 2012-04-11 at 10:52 -0700, greearb@candelatech.com wrote:

> --- a/net/mac80211/cfg.c
> +++ b/net/mac80211/cfg.c
> @@ -19,6 +19,7 @@
>  #include "cfg.h"
>  #include "rate.h"
>  #include "mesh.h"
> +#include "../wireless/core.h"

NACK. Don't do that.

johannes


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 05/10] mac80211: Add more ethtools stats: survey, rates, etc
@ 2012-04-12  3:46     ` Johannes Berg
  0 siblings, 0 replies; 28+ messages in thread
From: Johannes Berg @ 2012-04-12  3:46 UTC (permalink / raw)
  To: greearb-my8/4N5VtI7c+919tysfdA
  Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA

On Wed, 2012-04-11 at 10:52 -0700, greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org wrote:

> --- a/net/mac80211/cfg.c
> +++ b/net/mac80211/cfg.c
> @@ -19,6 +19,7 @@
>  #include "cfg.h"
>  #include "rate.h"
>  #include "mesh.h"
> +#include "../wireless/core.h"

NACK. Don't do that.

johannes

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 06/10] mac80211: Add sta_state to ethtool stats.
  2012-04-11 17:52   ` greearb-my8/4N5VtI7c+919tysfdA
  (?)
@ 2012-04-12  3:49   ` Johannes Berg
  2012-04-12 14:48     ` Ben Greear
  -1 siblings, 1 reply; 28+ messages in thread
From: Johannes Berg @ 2012-04-12  3:49 UTC (permalink / raw)
  To: greearb; +Cc: linux-wireless, netdev

On Wed, 2012-04-11 at 10:52 -0700, greearb@candelatech.com wrote:
> From: Ben Greear <greearb@candelatech.com>
> 
> Helps to know how the station is doing in it's association
> attempt.
> 
> Signed-off-by: Ben Greear <greearb@candelatech.com>
> ---
> :100644 100644 bbaf564... a63834d... M	net/mac80211/cfg.c
>  net/mac80211/cfg.c |    6 ++++--
>  1 files changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
> index bbaf564..a63834d 100644
> --- a/net/mac80211/cfg.c
> +++ b/net/mac80211/cfg.c
> @@ -118,7 +118,7 @@ static const char ieee80211_gstrings_sta_stats[][ETH_GSTRING_LEN] = {
>  	"rx_duplicates", "rx_fragments", "rx_dropped",
>  	"tx_packets", "tx_bytes", "tx_fragments",
>  	"tx_filtered", "tx_retry_failed", "tx_retries",
> -	"beacon_loss", "txrate", "rxrate", "signal",
> +	"beacon_loss", "sta_state", "txrate", "rxrate", "signal",
>  	"channel", "noise", "ch_time", "ch_time_busy",
>  	"ch_time_ext_busy", "ch_time_rx", "ch_time_tx"
>  };
> @@ -534,10 +534,12 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy,
>  		data[i++] += sta->beacon_loss_count;
>  
>  		if (!do_once) {
> -			i += 3;
> +			i += 4;
>  			goto after_once;
>  		}
>  
> +		data[i++] = sta->sta_state;
> +

Gee, I wish it was easier to tell if you were adding it to the right
spot in the list ... any way that could be made easier?

johannes


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 06/10] mac80211: Add sta_state to ethtool stats.
  2012-04-12  3:49   ` Johannes Berg
@ 2012-04-12 14:48     ` Ben Greear
  0 siblings, 0 replies; 28+ messages in thread
From: Ben Greear @ 2012-04-12 14:48 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, netdev

On 04/11/2012 08:49 PM, Johannes Berg wrote:
> On Wed, 2012-04-11 at 10:52 -0700, greearb@candelatech.com wrote:
>> From: Ben Greear<greearb@candelatech.com>
>>
>> Helps to know how the station is doing in it's association
>> attempt.
>>
>> Signed-off-by: Ben Greear<greearb@candelatech.com>
>> ---
>> :100644 100644 bbaf564... a63834d... M	net/mac80211/cfg.c
>>   net/mac80211/cfg.c |    6 ++++--
>>   1 files changed, 4 insertions(+), 2 deletions(-)
>>
>> diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
>> index bbaf564..a63834d 100644
>> --- a/net/mac80211/cfg.c
>> +++ b/net/mac80211/cfg.c
>> @@ -118,7 +118,7 @@ static const char ieee80211_gstrings_sta_stats[][ETH_GSTRING_LEN] = {
>>   	"rx_duplicates", "rx_fragments", "rx_dropped",
>>   	"tx_packets", "tx_bytes", "tx_fragments",
>>   	"tx_filtered", "tx_retry_failed", "tx_retries",
>> -	"beacon_loss", "txrate", "rxrate", "signal",
>> +	"beacon_loss", "sta_state", "txrate", "rxrate", "signal",
>>   	"channel", "noise", "ch_time", "ch_time_busy",
>>   	"ch_time_ext_busy", "ch_time_rx", "ch_time_tx"
>>   };
>> @@ -534,10 +534,12 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy,
>>   		data[i++] += sta->beacon_loss_count;
>>
>>   		if (!do_once) {
>> -			i += 3;
>> +			i += 4;
>>   			goto after_once;
>>   		}
>>
>> +		data[i++] = sta->sta_state;
>> +
>
> Gee, I wish it was easier to tell if you were adding it to the right
> spot in the list ... any way that could be made easier?

It would be nice, but I haven't thought of an easy way to do this,
and I haven't noticed any other drivers
that found a way.

I *could* add a lot of #defines and do something like: data[STA_STATE_IDX] = sta->state,
and maybe create the strings array at run-time using macros to map string to
an idx define instead of have a static array of char*.  But, I'm not sure if
it's worth the effort.

Thanks,
Ben

>
> johannes


-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 05/10] mac80211: Add more ethtools stats: survey, rates, etc
@ 2012-04-12 14:50       ` Ben Greear
  0 siblings, 0 replies; 28+ messages in thread
From: Ben Greear @ 2012-04-12 14:50 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, netdev

On 04/11/2012 08:46 PM, Johannes Berg wrote:
> On Wed, 2012-04-11 at 10:52 -0700, greearb@candelatech.com wrote:
>
>> --- a/net/mac80211/cfg.c
>> +++ b/net/mac80211/cfg.c
>> @@ -19,6 +19,7 @@
>>   #include "cfg.h"
>>   #include "rate.h"
>>   #include "mesh.h"
>> +#include "../wireless/core.h"
>
> NACK. Don't do that.

So, move the pertinent header stuff to linux/include/ieee80211.h ??

Thanks,
Ben

>
> johannes


-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 05/10] mac80211: Add more ethtools stats: survey, rates, etc
@ 2012-04-12 14:50       ` Ben Greear
  0 siblings, 0 replies; 28+ messages in thread
From: Ben Greear @ 2012-04-12 14:50 UTC (permalink / raw)
  To: Johannes Berg
  Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA

On 04/11/2012 08:46 PM, Johannes Berg wrote:
> On Wed, 2012-04-11 at 10:52 -0700, greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org wrote:
>
>> --- a/net/mac80211/cfg.c
>> +++ b/net/mac80211/cfg.c
>> @@ -19,6 +19,7 @@
>>   #include "cfg.h"
>>   #include "rate.h"
>>   #include "mesh.h"
>> +#include "../wireless/core.h"
>
> NACK. Don't do that.

So, move the pertinent header stuff to linux/include/ieee80211.h ??

Thanks,
Ben

>
> johannes


-- 
Ben Greear <greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org>
Candela Technologies Inc  http://www.candelatech.com

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 08/10] mac80211: Support on-channel scan option.
  2012-04-12  3:45   ` Johannes Berg
@ 2012-04-12 15:03     ` Ben Greear
  0 siblings, 0 replies; 28+ messages in thread
From: Ben Greear @ 2012-04-12 15:03 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, netdev

On 04/11/2012 08:45 PM, Johannes Berg wrote:
> On Wed, 2012-04-11 at 10:52 -0700, greearb@candelatech.com wrote:
>
>>   static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
>>   				  struct cfg80211_scan_request *req)
>> @@ -438,10 +461,43 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
>>   	local->scan_req = req;
>>   	local->scan_sdata = sdata;
>>
>> -	if (local->ops->hw_scan)
>> +	if (local->ops->hw_scan) {
>>   		__set_bit(SCAN_HW_SCANNING,&local->scanning);
>> -	else
>> -		__set_bit(SCAN_SW_SCANNING,&local->scanning);
>> +	} else {
>> +		/* If we are scanning only on the current channel, then
>> +		 * we do not need to stop normal activities
>> +		 */
>> +		if ((req->n_channels == 1)&&
>> +		    (req->channels[0]->center_freq ==
>> +		     local->hw.conf.channel->center_freq)) {
>
> how about "else if {", then the indentation isn't so deep and you can
> have much nicer code in the entire block :)
>
>> +			unsigned long next_delay;
>
> please add a blank line after variable declarations.
>
>> +		}
>> +		else {
>
> please read the coding style documentation
>
>> @@ -672,6 +704,12 @@ void ieee80211_scan_work(struct work_struct *work)
>>
>>   	sdata = local->scan_sdata;
>>
>> +	/* When scanning on-channel, the first-callback means completeed. */
>
> typo "completed"

Ok, will fix all of that.


>> +	if (test_bit(SCAN_ONCHANNEL_SCANNING,&local->scanning)) {
>> +		aborted = test_and_clear_bit(SCAN_ABORTED,&local->scanning);
>> +		goto out_complete;
>> +	}
>
> how does the onchannel bit get cleared?

__ieee80211_scan_completed sets local->scanning to 0, and it
will WARN_ON if local->scanning is NOT zero when entering
the method, so I don't think I should clear it earlier.

> Shouldn't you be calling pre/post scan hooks?

Probably so...I'll add that.  Doesn't look like ath9k uses
it, but maybe some other NIC does need it.

> I'm a bit divided over this. On the one hand, it seems like a mildly
> useful optimisation, on the other though it adds a bunch of complexity
> for multi-channel we've been thinking about... Not that we want to
> support multi-channel with SW scan anyway, but still.

It's just an optimization...maybe just add a check and do a regular scan
if multi-channel is active if it's difficult to just make it work with
multi-channel?

Thanks,
Ben

>
> johannes


-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 05/10] mac80211: Add more ethtools stats: survey, rates, etc
  2012-04-12  3:46     ` Johannes Berg
  (?)
  (?)
@ 2012-04-12 15:23     ` Ben Greear
  -1 siblings, 0 replies; 28+ messages in thread
From: Ben Greear @ 2012-04-12 15:23 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, netdev

On 04/11/2012 08:46 PM, Johannes Berg wrote:
> On Wed, 2012-04-11 at 10:52 -0700, greearb@candelatech.com wrote:
>
>> --- a/net/mac80211/cfg.c
>> +++ b/net/mac80211/cfg.c
>> @@ -19,6 +19,7 @@
>>   #include "cfg.h"
>>   #include "rate.h"
>>   #include "mesh.h"
>> +#include "../wireless/core.h"
>
> NACK. Don't do that.

Looks like whatever I needed has already been moved somewhere
proper...I can just delete that line and it compiles fine.

Thanks,
Ben

>
> johannes


-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com


^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2012-04-12 15:23 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-11 17:52 [PATCH 00/10] Wireless patches for wireless-testing greearb
2012-04-11 17:52 ` [PATCH 01/10] cfg80211: Add framework to support ethtool stats greearb
2012-04-11 17:52 ` [PATCH 02/10] mac80211: Support getting sta_info stats via ethtool greearb
2012-04-11 17:52 ` [PATCH 03/10] mac80211: Framework to get wifi-driver " greearb
2012-04-11 17:52 ` [PATCH 04/10] ath9k: Support ethtool getstats api greearb
2012-04-11 17:52 ` [PATCH 05/10] mac80211: Add more ethtools stats: survey, rates, etc greearb
2012-04-11 17:52   ` greearb-my8/4N5VtI7c+919tysfdA
2012-04-11 18:01   ` Ben Greear
2012-04-11 18:01     ` Ben Greear
2012-04-12  3:46   ` Johannes Berg
2012-04-12  3:46     ` Johannes Berg
2012-04-12 14:50     ` Ben Greear
2012-04-12 14:50       ` Ben Greear
2012-04-12 15:23     ` Ben Greear
2012-04-11 17:52 ` [PATCH 06/10] mac80211: Add sta_state to ethtool stats greearb
2012-04-11 17:52   ` greearb-my8/4N5VtI7c+919tysfdA
2012-04-12  3:49   ` Johannes Berg
2012-04-12 14:48     ` Ben Greear
2012-04-11 17:52 ` [PATCH 07/10] ath9k: Add tx-failed counter greearb
2012-04-11 17:52 ` [PATCH 08/10] mac80211: Support on-channel scan option greearb
2012-04-11 17:52   ` greearb-my8/4N5VtI7c+919tysfdA
2012-04-12  3:45   ` Johannes Berg
2012-04-12 15:03     ` Ben Greear
2012-04-11 17:52 ` [PATCH 09/10] ath9k: Add more recv stats greearb
2012-04-11 17:52   ` greearb-my8/4N5VtI7c+919tysfdA
2012-04-11 17:52 ` [PATCH 10/10] ath9k: Gather and report IRQ sync_cause errors greearb
2012-04-12  3:39 ` [PATCH 00/10] Wireless patches for wireless-testing Johannes Berg
2012-04-12  3:39   ` Johannes Berg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.