ath9k: make rate control debugfs stats per station
authorFelix Fietkau <nbd@openwrt.org>
Wed, 13 Oct 2010 14:43:26 +0000 (16:43 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 15 Oct 2010 19:48:44 +0000 (15:48 -0400)
Move them to the same debugfs file that the other rc modules use.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath/ath9k/debug.c
drivers/net/wireless/ath/ath9k/debug.h
drivers/net/wireless/ath/ath9k/rc.c
drivers/net/wireless/ath/ath9k/rc.h

index 74a4570..7f764e3 100644 (file)
@@ -378,95 +378,6 @@ static const struct file_operations fops_interrupt = {
        .owner = THIS_MODULE
 };
 
-void ath_debug_stat_rc(struct ath_softc *sc, int final_rate)
-{
-       struct ath_rc_stats *stats;
-
-       stats = &sc->debug.stats.rcstats[final_rate];
-       stats->success++;
-}
-
-void ath_debug_stat_retries(struct ath_softc *sc, int rix,
-                           int xretries, int retries, u8 per)
-{
-       struct ath_rc_stats *stats = &sc->debug.stats.rcstats[rix];
-
-       stats->xretries += xretries;
-       stats->retries += retries;
-       stats->per = per;
-}
-
-static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
-                               size_t count, loff_t *ppos)
-{
-       struct ath_softc *sc = file->private_data;
-       char *buf;
-       unsigned int len = 0, max;
-       int i = 0;
-       ssize_t retval;
-
-       if (sc->cur_rate_table == NULL)
-               return 0;
-
-       max = 80 + sc->cur_rate_table->rate_cnt * 1024 + 1;
-       buf = kmalloc(max, GFP_KERNEL);
-       if (buf == NULL)
-               return -ENOMEM;
-
-       len += sprintf(buf, "%6s %6s %6s "
-                      "%10s %10s %10s %10s\n",
-                      "HT", "MCS", "Rate",
-                      "Success", "Retries", "XRetries", "PER");
-
-       for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) {
-               u32 ratekbps = sc->cur_rate_table->info[i].ratekbps;
-               struct ath_rc_stats *stats = &sc->debug.stats.rcstats[i];
-               char mcs[5];
-               char htmode[5];
-               int used_mcs = 0, used_htmode = 0;
-
-               if (WLAN_RC_PHY_HT(sc->cur_rate_table->info[i].phy)) {
-                       used_mcs = snprintf(mcs, 5, "%d",
-                               sc->cur_rate_table->info[i].ratecode);
-
-                       if (WLAN_RC_PHY_40(sc->cur_rate_table->info[i].phy))
-                               used_htmode = snprintf(htmode, 5, "HT40");
-                       else if (WLAN_RC_PHY_20(sc->cur_rate_table->info[i].phy))
-                               used_htmode = snprintf(htmode, 5, "HT20");
-                       else
-                               used_htmode = snprintf(htmode, 5, "????");
-               }
-
-               mcs[used_mcs] = '\0';
-               htmode[used_htmode] = '\0';
-
-               len += snprintf(buf + len, max - len,
-                       "%6s %6s %3u.%d: "
-                       "%10u %10u %10u %10u\n",
-                       htmode,
-                       mcs,
-                       ratekbps / 1000,
-                       (ratekbps % 1000) / 100,
-                       stats->success,
-                       stats->retries,
-                       stats->xretries,
-                       stats->per);
-       }
-
-       if (len > max)
-               len = max;
-
-       retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
-       kfree(buf);
-       return retval;
-}
-
-static const struct file_operations fops_rcstat = {
-       .read = read_file_rcstat,
-       .open = ath9k_debugfs_open,
-       .owner = THIS_MODULE
-};
-
 static const char * ath_wiphy_state_str(enum ath_wiphy_state state)
 {
        switch (state) {
@@ -977,10 +888,6 @@ int ath9k_init_debug(struct ath_hw *ah)
                        sc, &fops_interrupt))
                goto err;
 
-       if (!debugfs_create_file("rcstat", S_IRUSR, sc->debug.debugfs_phy,
-                       sc, &fops_rcstat))
-               goto err;
-
        if (!debugfs_create_file("wiphy", S_IRUSR | S_IWUSR,
                        sc->debug.debugfs_phy, sc, &fops_wiphy))
                goto err;
index 822b6f3..bb08232 100644 (file)
@@ -80,13 +80,6 @@ struct ath_interrupt_stats {
        u32 bb_watchdog;
 };
 
-struct ath_rc_stats {
-       u32 success;
-       u32 retries;
-       u32 xretries;
-       u8 per;
-};
-
 /**
  * struct ath_tx_stats - Statistics about TX
  * @tx_pkts_all:  No. of total frames transmitted, including ones that
@@ -160,7 +153,6 @@ struct ath_rx_stats {
 
 struct ath_stats {
        struct ath_interrupt_stats istats;
-       struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
        struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES];
        struct ath_rx_stats rxstats;
 };
@@ -177,12 +169,9 @@ void ath9k_exit_debug(struct ath_hw *ah);
 int ath9k_debug_create_root(void);
 void ath9k_debug_remove_root(void);
 void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
-void ath_debug_stat_rc(struct ath_softc *sc, int final_rate);
 void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
                       struct ath_buf *bf, struct ath_tx_status *ts);
 void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs);
-void ath_debug_stat_retries(struct ath_softc *sc, int rix,
-                           int xretries, int retries, u8 per);
 
 #else
 
@@ -209,11 +198,6 @@ static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
 {
 }
 
-static inline void ath_debug_stat_rc(struct ath_softc *sc,
-                                    int final_rate)
-{
-}
-
 static inline void ath_debug_stat_tx(struct ath_softc *sc,
                                     struct ath_txq *txq,
                                     struct ath_buf *bf,
@@ -226,11 +210,6 @@ static inline void ath_debug_stat_rx(struct ath_softc *sc,
 {
 }
 
-static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix,
-                                         int xretries, int retries, u8 per)
-{
-}
-
 #endif /* CONFIG_ATH9K_DEBUGFS */
 
 #endif /* DEBUG_H */
index abebf24..5db3a12 100644 (file)
@@ -1026,6 +1026,16 @@ static bool ath_rc_update_per(struct ath_softc *sc,
        return state_change;
 }
 
+static void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
+                                  int xretries, int retries, u8 per)
+{
+       struct ath_rc_stats *stats = &rc->rcstats[rix];
+
+       stats->xretries += xretries;
+       stats->retries += retries;
+       stats->per = per;
+}
+
 /* Update PER, RSSI and whatever else that the code thinks it is doing.
    If you can make sense of all this, you really need to go out more. */
 
@@ -1098,7 +1108,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
                ath_rc_priv->per_down_time = now_msec;
        }
 
-       ath_debug_stat_retries(sc, tx_rate, xretries, retries,
+       ath_debug_stat_retries(ath_rc_priv, tx_rate, xretries, retries,
                               ath_rc_priv->per[tx_rate]);
 
 }
@@ -1294,6 +1304,7 @@ static void ath_rc_init(struct ath_softc *sc,
        ath_rc_sort_validrates(rate_table, ath_rc_priv);
        ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4];
        sc->cur_rate_table = rate_table;
+       ath_rc_priv->rate_table = rate_table;
 
        ath_print(common, ATH_DBG_CONFIG,
                  "RC Initialized with capabilities: 0x%x\n",
@@ -1340,6 +1351,15 @@ static bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an,
 /* mac80211 Rate Control callbacks */
 /***********************************/
 
+static void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate)
+{
+       struct ath_rc_stats *stats;
+
+       stats = &rc->rcstats[final_rate];
+       stats->success++;
+}
+
+
 static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
                          struct ieee80211_sta *sta, void *priv_sta,
                          struct sk_buff *skb)
@@ -1419,7 +1439,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
                }
        }
 
-       ath_debug_stat_rc(sc, ath_rc_get_rateindex(sc->cur_rate_table,
+       ath_debug_stat_rc(ath_rc_priv, ath_rc_get_rateindex(sc->cur_rate_table,
                &tx_info->status.rates[final_ts_idx]));
 }
 
@@ -1521,6 +1541,94 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
        }
 }
 
+#ifdef CONFIG_ATH9K_DEBUGFS
+
+static int ath9k_debugfs_open(struct inode *inode, struct file *file)
+{
+       file->private_data = inode->i_private;
+       return 0;
+}
+
+static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
+                               size_t count, loff_t *ppos)
+{
+       struct ath_rate_priv *rc = file->private_data;
+       char *buf;
+       unsigned int len = 0, max;
+       int i = 0;
+       ssize_t retval;
+
+       if (rc->rate_table == NULL)
+               return 0;
+
+       max = 80 + rc->rate_table->rate_cnt * 1024 + 1;
+       buf = kmalloc(max, GFP_KERNEL);
+       if (buf == NULL)
+               return -ENOMEM;
+
+       len += sprintf(buf, "%6s %6s %6s "
+                      "%10s %10s %10s %10s\n",
+                      "HT", "MCS", "Rate",
+                      "Success", "Retries", "XRetries", "PER");
+
+       for (i = 0; i < rc->rate_table->rate_cnt; i++) {
+               u32 ratekbps = rc->rate_table->info[i].ratekbps;
+               struct ath_rc_stats *stats = &rc->rcstats[i];
+               char mcs[5];
+               char htmode[5];
+               int used_mcs = 0, used_htmode = 0;
+
+               if (WLAN_RC_PHY_HT(rc->rate_table->info[i].phy)) {
+                       used_mcs = snprintf(mcs, 5, "%d",
+                               rc->rate_table->info[i].ratecode);
+
+                       if (WLAN_RC_PHY_40(rc->rate_table->info[i].phy))
+                               used_htmode = snprintf(htmode, 5, "HT40");
+                       else if (WLAN_RC_PHY_20(rc->rate_table->info[i].phy))
+                               used_htmode = snprintf(htmode, 5, "HT20");
+                       else
+                               used_htmode = snprintf(htmode, 5, "????");
+               }
+
+               mcs[used_mcs] = '\0';
+               htmode[used_htmode] = '\0';
+
+               len += snprintf(buf + len, max - len,
+                       "%6s %6s %3u.%d: "
+                       "%10u %10u %10u %10u\n",
+                       htmode,
+                       mcs,
+                       ratekbps / 1000,
+                       (ratekbps % 1000) / 100,
+                       stats->success,
+                       stats->retries,
+                       stats->xretries,
+                       stats->per);
+       }
+
+       if (len > max)
+               len = max;
+
+       retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+       kfree(buf);
+       return retval;
+}
+
+static const struct file_operations fops_rcstat = {
+       .read = read_file_rcstat,
+       .open = ath9k_debugfs_open,
+       .owner = THIS_MODULE
+};
+
+static void ath_rate_add_sta_debugfs(void *priv, void *priv_sta,
+                                    struct dentry *dir)
+{
+       struct ath_rate_priv *rc = priv_sta;
+       debugfs_create_file("rc_stats", S_IRUGO, dir, rc, &fops_rcstat);
+}
+
+#endif /* CONFIG_ATH9K_DEBUGFS */
+
 static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
 {
        struct ath_wiphy *aphy = hw->priv;
@@ -1567,6 +1675,9 @@ static struct rate_control_ops ath_rate_ops = {
        .free = ath_rate_free,
        .alloc_sta = ath_rate_alloc_sta,
        .free_sta = ath_rate_free_sta,
+#ifdef CONFIG_ATH9K_DEBUGFS
+       .add_sta_debugfs = ath_rate_add_sta_debugfs,
+#endif
 };
 
 int ath_rate_control_register(void)
index fbb1d33..2f46a22 100644 (file)
@@ -176,6 +176,13 @@ struct ath_rateset {
        u8 rs_rates[ATH_RATE_MAX];
 };
 
+struct ath_rc_stats {
+       u32 success;
+       u32 retries;
+       u32 xretries;
+       u8 per;
+};
+
 /**
  * struct ath_rate_priv - Rate Control priv data
  * @state: RC state
@@ -212,6 +219,10 @@ struct ath_rate_priv {
        struct ath_rateset neg_rates;
        struct ath_rateset neg_ht_rates;
        struct ath_rate_softc *asc;
+       const struct ath_rate_table *rate_table;
+
+       struct dentry *debugfs_rcstats;
+       struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
 };
 
 #define ATH_TX_INFO_FRAME_TYPE_INTERNAL        (1 << 0)