summaryrefslogtreecommitdiff
path: root/package/mac80211/patches/540-ath9k_rc_debugfs.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/mac80211/patches/540-ath9k_rc_debugfs.patch')
-rw-r--r--package/mac80211/patches/540-ath9k_rc_debugfs.patch363
1 files changed, 363 insertions, 0 deletions
diff --git a/package/mac80211/patches/540-ath9k_rc_debugfs.patch b/package/mac80211/patches/540-ath9k_rc_debugfs.patch
new file mode 100644
index 0000000000..4e413f88d1
--- /dev/null
+++ b/package/mac80211/patches/540-ath9k_rc_debugfs.patch
@@ -0,0 +1,363 @@
+--- a/drivers/net/wireless/ath/ath9k/debug.c
++++ b/drivers/net/wireless/ath/ath9k/debug.c
+@@ -378,95 +378,6 @@ static const struct file_operations fops
+ .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) {
+@@ -1024,10 +935,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;
+--- a/drivers/net/wireless/ath/ath9k/debug.h
++++ b/drivers/net/wireless/ath/ath9k/debug.h
+@@ -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_interr
+ {
+ }
+
+-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(str
+ {
+ }
+
+-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 */
+--- a/drivers/net/wireless/ath/ath9k/rc.c
++++ b/drivers/net/wireless/ath/ath9k/rc.c
+@@ -1026,6 +1026,16 @@ static bool ath_rc_update_per(struct ath
+ 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_
+ 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
+ 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
+ /* 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, st
+ }
+ }
+
+- 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,
+ }
+ }
+
++#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_
+ .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)
+--- a/drivers/net/wireless/ath/ath9k/rc.h
++++ b/drivers/net/wireless/ath/ath9k/rc.h
+@@ -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)