aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2010-10-13 10:43:26 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-10-15 15:48:44 -0400
commit772d5515635fef5bc7a9d0efee785b58b0181ee5 (patch)
treeab01946e53486d79b831c83456af71d8ab495b63 /drivers/net
parent88eac2dad876a58b9c6a4c4805c3fc27b02c048f (diff)
ath9k: make rate control debugfs stats per station
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>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c93
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h21
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c115
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.h11
4 files changed, 124 insertions, 116 deletions
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 74a4570dc87f..7f764e3d1c0a 100644
--- 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_interrupt = {
378 .owner = THIS_MODULE 378 .owner = THIS_MODULE
379}; 379};
380 380
381void ath_debug_stat_rc(struct ath_softc *sc, int final_rate)
382{
383 struct ath_rc_stats *stats;
384
385 stats = &sc->debug.stats.rcstats[final_rate];
386 stats->success++;
387}
388
389void ath_debug_stat_retries(struct ath_softc *sc, int rix,
390 int xretries, int retries, u8 per)
391{
392 struct ath_rc_stats *stats = &sc->debug.stats.rcstats[rix];
393
394 stats->xretries += xretries;
395 stats->retries += retries;
396 stats->per = per;
397}
398
399static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
400 size_t count, loff_t *ppos)
401{
402 struct ath_softc *sc = file->private_data;
403 char *buf;
404 unsigned int len = 0, max;
405 int i = 0;
406 ssize_t retval;
407
408 if (sc->cur_rate_table == NULL)
409 return 0;
410
411 max = 80 + sc->cur_rate_table->rate_cnt * 1024 + 1;
412 buf = kmalloc(max, GFP_KERNEL);
413 if (buf == NULL)
414 return -ENOMEM;
415
416 len += sprintf(buf, "%6s %6s %6s "
417 "%10s %10s %10s %10s\n",
418 "HT", "MCS", "Rate",
419 "Success", "Retries", "XRetries", "PER");
420
421 for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) {
422 u32 ratekbps = sc->cur_rate_table->info[i].ratekbps;
423 struct ath_rc_stats *stats = &sc->debug.stats.rcstats[i];
424 char mcs[5];
425 char htmode[5];
426 int used_mcs = 0, used_htmode = 0;
427
428 if (WLAN_RC_PHY_HT(sc->cur_rate_table->info[i].phy)) {
429 used_mcs = snprintf(mcs, 5, "%d",
430 sc->cur_rate_table->info[i].ratecode);
431
432 if (WLAN_RC_PHY_40(sc->cur_rate_table->info[i].phy))
433 used_htmode = snprintf(htmode, 5, "HT40");
434 else if (WLAN_RC_PHY_20(sc->cur_rate_table->info[i].phy))
435 used_htmode = snprintf(htmode, 5, "HT20");
436 else
437 used_htmode = snprintf(htmode, 5, "????");
438 }
439
440 mcs[used_mcs] = '\0';
441 htmode[used_htmode] = '\0';
442
443 len += snprintf(buf + len, max - len,
444 "%6s %6s %3u.%d: "
445 "%10u %10u %10u %10u\n",
446 htmode,
447 mcs,
448 ratekbps / 1000,
449 (ratekbps % 1000) / 100,
450 stats->success,
451 stats->retries,
452 stats->xretries,
453 stats->per);
454 }
455
456 if (len > max)
457 len = max;
458
459 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
460 kfree(buf);
461 return retval;
462}
463
464static const struct file_operations fops_rcstat = {
465 .read = read_file_rcstat,
466 .open = ath9k_debugfs_open,
467 .owner = THIS_MODULE
468};
469
470static const char * ath_wiphy_state_str(enum ath_wiphy_state state) 381static const char * ath_wiphy_state_str(enum ath_wiphy_state state)
471{ 382{
472 switch (state) { 383 switch (state) {
@@ -977,10 +888,6 @@ int ath9k_init_debug(struct ath_hw *ah)
977 sc, &fops_interrupt)) 888 sc, &fops_interrupt))
978 goto err; 889 goto err;
979 890
980 if (!debugfs_create_file("rcstat", S_IRUSR, sc->debug.debugfs_phy,
981 sc, &fops_rcstat))
982 goto err;
983
984 if (!debugfs_create_file("wiphy", S_IRUSR | S_IWUSR, 891 if (!debugfs_create_file("wiphy", S_IRUSR | S_IWUSR,
985 sc->debug.debugfs_phy, sc, &fops_wiphy)) 892 sc->debug.debugfs_phy, sc, &fops_wiphy))
986 goto err; 893 goto err;
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 822b6f3f23c5..bb0823242ba0 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -80,13 +80,6 @@ struct ath_interrupt_stats {
80 u32 bb_watchdog; 80 u32 bb_watchdog;
81}; 81};
82 82
83struct ath_rc_stats {
84 u32 success;
85 u32 retries;
86 u32 xretries;
87 u8 per;
88};
89
90/** 83/**
91 * struct ath_tx_stats - Statistics about TX 84 * struct ath_tx_stats - Statistics about TX
92 * @tx_pkts_all: No. of total frames transmitted, including ones that 85 * @tx_pkts_all: No. of total frames transmitted, including ones that
@@ -160,7 +153,6 @@ struct ath_rx_stats {
160 153
161struct ath_stats { 154struct ath_stats {
162 struct ath_interrupt_stats istats; 155 struct ath_interrupt_stats istats;
163 struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
164 struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES]; 156 struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES];
165 struct ath_rx_stats rxstats; 157 struct ath_rx_stats rxstats;
166}; 158};
@@ -177,12 +169,9 @@ void ath9k_exit_debug(struct ath_hw *ah);
177int ath9k_debug_create_root(void); 169int ath9k_debug_create_root(void);
178void ath9k_debug_remove_root(void); 170void ath9k_debug_remove_root(void);
179void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); 171void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
180void ath_debug_stat_rc(struct ath_softc *sc, int final_rate);
181void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, 172void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
182 struct ath_buf *bf, struct ath_tx_status *ts); 173 struct ath_buf *bf, struct ath_tx_status *ts);
183void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs); 174void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs);
184void ath_debug_stat_retries(struct ath_softc *sc, int rix,
185 int xretries, int retries, u8 per);
186 175
187#else 176#else
188 177
@@ -209,11 +198,6 @@ static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
209{ 198{
210} 199}
211 200
212static inline void ath_debug_stat_rc(struct ath_softc *sc,
213 int final_rate)
214{
215}
216
217static inline void ath_debug_stat_tx(struct ath_softc *sc, 201static inline void ath_debug_stat_tx(struct ath_softc *sc,
218 struct ath_txq *txq, 202 struct ath_txq *txq,
219 struct ath_buf *bf, 203 struct ath_buf *bf,
@@ -226,11 +210,6 @@ static inline void ath_debug_stat_rx(struct ath_softc *sc,
226{ 210{
227} 211}
228 212
229static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix,
230 int xretries, int retries, u8 per)
231{
232}
233
234#endif /* CONFIG_ATH9K_DEBUGFS */ 213#endif /* CONFIG_ATH9K_DEBUGFS */
235 214
236#endif /* DEBUG_H */ 215#endif /* DEBUG_H */
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index abebf2466a13..5db3a12356ec 100644
--- 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_softc *sc,
1026 return state_change; 1026 return state_change;
1027} 1027}
1028 1028
1029static void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
1030 int xretries, int retries, u8 per)
1031{
1032 struct ath_rc_stats *stats = &rc->rcstats[rix];
1033
1034 stats->xretries += xretries;
1035 stats->retries += retries;
1036 stats->per = per;
1037}
1038
1029/* Update PER, RSSI and whatever else that the code thinks it is doing. 1039/* Update PER, RSSI and whatever else that the code thinks it is doing.
1030 If you can make sense of all this, you really need to go out more. */ 1040 If you can make sense of all this, you really need to go out more. */
1031 1041
@@ -1098,7 +1108,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1098 ath_rc_priv->per_down_time = now_msec; 1108 ath_rc_priv->per_down_time = now_msec;
1099 } 1109 }
1100 1110
1101 ath_debug_stat_retries(sc, tx_rate, xretries, retries, 1111 ath_debug_stat_retries(ath_rc_priv, tx_rate, xretries, retries,
1102 ath_rc_priv->per[tx_rate]); 1112 ath_rc_priv->per[tx_rate]);
1103 1113
1104} 1114}
@@ -1294,6 +1304,7 @@ static void ath_rc_init(struct ath_softc *sc,
1294 ath_rc_sort_validrates(rate_table, ath_rc_priv); 1304 ath_rc_sort_validrates(rate_table, ath_rc_priv);
1295 ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4]; 1305 ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4];
1296 sc->cur_rate_table = rate_table; 1306 sc->cur_rate_table = rate_table;
1307 ath_rc_priv->rate_table = rate_table;
1297 1308
1298 ath_print(common, ATH_DBG_CONFIG, 1309 ath_print(common, ATH_DBG_CONFIG,
1299 "RC Initialized with capabilities: 0x%x\n", 1310 "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,
1340/* mac80211 Rate Control callbacks */ 1351/* mac80211 Rate Control callbacks */
1341/***********************************/ 1352/***********************************/
1342 1353
1354static void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate)
1355{
1356 struct ath_rc_stats *stats;
1357
1358 stats = &rc->rcstats[final_rate];
1359 stats->success++;
1360}
1361
1362
1343static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, 1363static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1344 struct ieee80211_sta *sta, void *priv_sta, 1364 struct ieee80211_sta *sta, void *priv_sta,
1345 struct sk_buff *skb) 1365 struct sk_buff *skb)
@@ -1419,7 +1439,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1419 } 1439 }
1420 } 1440 }
1421 1441
1422 ath_debug_stat_rc(sc, ath_rc_get_rateindex(sc->cur_rate_table, 1442 ath_debug_stat_rc(ath_rc_priv, ath_rc_get_rateindex(sc->cur_rate_table,
1423 &tx_info->status.rates[final_ts_idx])); 1443 &tx_info->status.rates[final_ts_idx]));
1424} 1444}
1425 1445
@@ -1521,6 +1541,94 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
1521 } 1541 }
1522} 1542}
1523 1543
1544#ifdef CONFIG_ATH9K_DEBUGFS
1545
1546static int ath9k_debugfs_open(struct inode *inode, struct file *file)
1547{
1548 file->private_data = inode->i_private;
1549 return 0;
1550}
1551
1552static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
1553 size_t count, loff_t *ppos)
1554{
1555 struct ath_rate_priv *rc = file->private_data;
1556 char *buf;
1557 unsigned int len = 0, max;
1558 int i = 0;
1559 ssize_t retval;
1560
1561 if (rc->rate_table == NULL)
1562 return 0;
1563
1564 max = 80 + rc->rate_table->rate_cnt * 1024 + 1;
1565 buf = kmalloc(max, GFP_KERNEL);
1566 if (buf == NULL)
1567 return -ENOMEM;
1568
1569 len += sprintf(buf, "%6s %6s %6s "
1570 "%10s %10s %10s %10s\n",
1571 "HT", "MCS", "Rate",
1572 "Success", "Retries", "XRetries", "PER");
1573
1574 for (i = 0; i < rc->rate_table->rate_cnt; i++) {
1575 u32 ratekbps = rc->rate_table->info[i].ratekbps;
1576 struct ath_rc_stats *stats = &rc->rcstats[i];
1577 char mcs[5];
1578 char htmode[5];
1579 int used_mcs = 0, used_htmode = 0;
1580
1581 if (WLAN_RC_PHY_HT(rc->rate_table->info[i].phy)) {
1582 used_mcs = snprintf(mcs, 5, "%d",
1583 rc->rate_table->info[i].ratecode);
1584
1585 if (WLAN_RC_PHY_40(rc->rate_table->info[i].phy))
1586 used_htmode = snprintf(htmode, 5, "HT40");
1587 else if (WLAN_RC_PHY_20(rc->rate_table->info[i].phy))
1588 used_htmode = snprintf(htmode, 5, "HT20");
1589 else
1590 used_htmode = snprintf(htmode, 5, "????");
1591 }
1592
1593 mcs[used_mcs] = '\0';
1594 htmode[used_htmode] = '\0';
1595
1596 len += snprintf(buf + len, max - len,
1597 "%6s %6s %3u.%d: "
1598 "%10u %10u %10u %10u\n",
1599 htmode,
1600 mcs,
1601 ratekbps / 1000,
1602 (ratekbps % 1000) / 100,
1603 stats->success,
1604 stats->retries,
1605 stats->xretries,
1606 stats->per);
1607 }
1608
1609 if (len > max)
1610 len = max;
1611
1612 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1613 kfree(buf);
1614 return retval;
1615}
1616
1617static const struct file_operations fops_rcstat = {
1618 .read = read_file_rcstat,
1619 .open = ath9k_debugfs_open,
1620 .owner = THIS_MODULE
1621};
1622
1623static void ath_rate_add_sta_debugfs(void *priv, void *priv_sta,
1624 struct dentry *dir)
1625{
1626 struct ath_rate_priv *rc = priv_sta;
1627 debugfs_create_file("rc_stats", S_IRUGO, dir, rc, &fops_rcstat);
1628}
1629
1630#endif /* CONFIG_ATH9K_DEBUGFS */
1631
1524static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) 1632static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
1525{ 1633{
1526 struct ath_wiphy *aphy = hw->priv; 1634 struct ath_wiphy *aphy = hw->priv;
@@ -1567,6 +1675,9 @@ static struct rate_control_ops ath_rate_ops = {
1567 .free = ath_rate_free, 1675 .free = ath_rate_free,
1568 .alloc_sta = ath_rate_alloc_sta, 1676 .alloc_sta = ath_rate_alloc_sta,
1569 .free_sta = ath_rate_free_sta, 1677 .free_sta = ath_rate_free_sta,
1678#ifdef CONFIG_ATH9K_DEBUGFS
1679 .add_sta_debugfs = ath_rate_add_sta_debugfs,
1680#endif
1570}; 1681};
1571 1682
1572int ath_rate_control_register(void) 1683int ath_rate_control_register(void)
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
index fbb1d33ee4b7..2f46a2266ba1 100644
--- a/drivers/net/wireless/ath/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -176,6 +176,13 @@ struct ath_rateset {
176 u8 rs_rates[ATH_RATE_MAX]; 176 u8 rs_rates[ATH_RATE_MAX];
177}; 177};
178 178
179struct ath_rc_stats {
180 u32 success;
181 u32 retries;
182 u32 xretries;
183 u8 per;
184};
185
179/** 186/**
180 * struct ath_rate_priv - Rate Control priv data 187 * struct ath_rate_priv - Rate Control priv data
181 * @state: RC state 188 * @state: RC state
@@ -212,6 +219,10 @@ struct ath_rate_priv {
212 struct ath_rateset neg_rates; 219 struct ath_rateset neg_rates;
213 struct ath_rateset neg_ht_rates; 220 struct ath_rateset neg_ht_rates;
214 struct ath_rate_softc *asc; 221 struct ath_rate_softc *asc;
222 const struct ath_rate_table *rate_table;
223
224 struct dentry *debugfs_rcstats;
225 struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
215}; 226};
216 227
217#define ATH_TX_INFO_FRAME_TYPE_INTERNAL (1 << 0) 228#define ATH_TX_INFO_FRAME_TYPE_INTERNAL (1 << 0)