diff options
author | Felix Fietkau <nbd@openwrt.org> | 2010-10-13 10:43:26 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-10-15 15:48:44 -0400 |
commit | 772d5515635fef5bc7a9d0efee785b58b0181ee5 (patch) | |
tree | ab01946e53486d79b831c83456af71d8ab495b63 /drivers/net | |
parent | 88eac2dad876a58b9c6a4c4805c3fc27b02c048f (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.c | 93 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/debug.h | 21 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/rc.c | 115 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/rc.h | 11 |
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 | ||
381 | void 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 | |||
389 | void 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 | |||
399 | static 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 | |||
464 | static const struct file_operations fops_rcstat = { | ||
465 | .read = read_file_rcstat, | ||
466 | .open = ath9k_debugfs_open, | ||
467 | .owner = THIS_MODULE | ||
468 | }; | ||
469 | |||
470 | static const char * ath_wiphy_state_str(enum ath_wiphy_state state) | 381 | static 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 | ||
83 | struct 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 | ||
161 | struct ath_stats { | 154 | struct 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); | |||
177 | int ath9k_debug_create_root(void); | 169 | int ath9k_debug_create_root(void); |
178 | void ath9k_debug_remove_root(void); | 170 | void ath9k_debug_remove_root(void); |
179 | void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); | 171 | void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); |
180 | void ath_debug_stat_rc(struct ath_softc *sc, int final_rate); | ||
181 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, | 172 | void 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); |
183 | void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs); | 174 | void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs); |
184 | void 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 | ||
212 | static inline void ath_debug_stat_rc(struct ath_softc *sc, | ||
213 | int final_rate) | ||
214 | { | ||
215 | } | ||
216 | |||
217 | static inline void ath_debug_stat_tx(struct ath_softc *sc, | 201 | static 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 | ||
229 | static 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 | ||
1029 | static 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 | ||
1354 | static 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 | |||
1343 | static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, | 1363 | static 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 | |||
1546 | static int ath9k_debugfs_open(struct inode *inode, struct file *file) | ||
1547 | { | ||
1548 | file->private_data = inode->i_private; | ||
1549 | return 0; | ||
1550 | } | ||
1551 | |||
1552 | static 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 | |||
1617 | static const struct file_operations fops_rcstat = { | ||
1618 | .read = read_file_rcstat, | ||
1619 | .open = ath9k_debugfs_open, | ||
1620 | .owner = THIS_MODULE | ||
1621 | }; | ||
1622 | |||
1623 | static 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 | |||
1524 | static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) | 1632 | static 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 | ||
1572 | int ath_rate_control_register(void) | 1683 | int 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 | ||
179 | struct 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) |