diff options
author | Sujith <Sujith.Manoharan@atheros.com> | 2009-01-30 04:02:09 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-02-09 15:03:44 -0500 |
commit | 7a7dec656252a5784218a22abf76ad1cdef115d0 (patch) | |
tree | a7496cdb999f27cb80082fd74f9790840f7c9fde /drivers/net/wireless/ath9k/debug.c | |
parent | c89424df441ea8d794682b9c5620d8e8b0315438 (diff) |
ath9k: Add debugfs files for printing TX rate details
Signed-off-by: Sujith <Sujith.Manoharan@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath9k/debug.c')
-rw-r--r-- | drivers/net/wireless/ath9k/debug.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath9k/debug.c b/drivers/net/wireless/ath9k/debug.c index 1680164b4adb..6181e49eecba 100644 --- a/drivers/net/wireless/ath9k/debug.c +++ b/drivers/net/wireless/ath9k/debug.c | |||
@@ -222,6 +222,98 @@ static const struct file_operations fops_interrupt = { | |||
222 | .owner = THIS_MODULE | 222 | .owner = THIS_MODULE |
223 | }; | 223 | }; |
224 | 224 | ||
225 | static void ath_debug_stat_11n_rc(struct ath_softc *sc, struct sk_buff *skb) | ||
226 | { | ||
227 | struct ath_tx_info_priv *tx_info_priv = NULL; | ||
228 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
229 | struct ieee80211_tx_rate *rates = tx_info->status.rates; | ||
230 | int final_ts_idx, idx; | ||
231 | |||
232 | tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | ||
233 | final_ts_idx = tx_info_priv->tx.ts_rateindex; | ||
234 | idx = sc->cur_rate_table->info[rates[final_ts_idx].idx].dot11rate; | ||
235 | |||
236 | sc->sc_debug.stats.n_rcstats[idx].success++; | ||
237 | } | ||
238 | |||
239 | static void ath_debug_stat_legacy_rc(struct ath_softc *sc, struct sk_buff *skb) | ||
240 | { | ||
241 | struct ath_tx_info_priv *tx_info_priv = NULL; | ||
242 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
243 | struct ieee80211_tx_rate *rates = tx_info->status.rates; | ||
244 | int final_ts_idx, idx; | ||
245 | |||
246 | tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | ||
247 | final_ts_idx = tx_info_priv->tx.ts_rateindex; | ||
248 | idx = rates[final_ts_idx].idx; | ||
249 | |||
250 | sc->sc_debug.stats.legacy_rcstats[idx].success++; | ||
251 | } | ||
252 | |||
253 | void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb) | ||
254 | { | ||
255 | if (conf_is_ht(&sc->hw->conf)) | ||
256 | ath_debug_stat_11n_rc(sc, skb); | ||
257 | else | ||
258 | ath_debug_stat_legacy_rc(sc, skb); | ||
259 | } | ||
260 | |||
261 | static ssize_t ath_read_file_stat_11n_rc(struct file *file, | ||
262 | char __user *user_buf, | ||
263 | size_t count, loff_t *ppos) | ||
264 | { | ||
265 | struct ath_softc *sc = file->private_data; | ||
266 | char buf[512]; | ||
267 | unsigned int len = 0; | ||
268 | int i = 0; | ||
269 | |||
270 | len += sprintf(buf, "%7s %13s\n\n", "Rate", "Success"); | ||
271 | |||
272 | for (i = 0; i <= 15; i++) { | ||
273 | len += snprintf(buf + len, sizeof(buf) - len, | ||
274 | "%5s%3d: %8u\n", "MCS", i, | ||
275 | sc->sc_debug.stats.n_rcstats[i].success); | ||
276 | } | ||
277 | |||
278 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
279 | } | ||
280 | |||
281 | static ssize_t ath_read_file_stat_legacy_rc(struct file *file, | ||
282 | char __user *user_buf, | ||
283 | size_t count, loff_t *ppos) | ||
284 | { | ||
285 | struct ath_softc *sc = file->private_data; | ||
286 | char buf[512]; | ||
287 | unsigned int len = 0; | ||
288 | int i = 0; | ||
289 | |||
290 | len += sprintf(buf, "%7s %13s\n\n", "Rate", "Success"); | ||
291 | |||
292 | for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) { | ||
293 | len += snprintf(buf + len, sizeof(buf) - len, "%5u: %12u\n", | ||
294 | sc->cur_rate_table->info[i].ratekbps / 1000, | ||
295 | sc->sc_debug.stats.legacy_rcstats[i].success); | ||
296 | } | ||
297 | |||
298 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
299 | } | ||
300 | |||
301 | static ssize_t read_file_rcstat(struct file *file, char __user *user_buf, | ||
302 | size_t count, loff_t *ppos) | ||
303 | { | ||
304 | struct ath_softc *sc = file->private_data; | ||
305 | |||
306 | if (conf_is_ht(&sc->hw->conf)) | ||
307 | return ath_read_file_stat_11n_rc(file, user_buf, count, ppos); | ||
308 | else | ||
309 | return ath_read_file_stat_legacy_rc(file, user_buf, count ,ppos); | ||
310 | } | ||
311 | |||
312 | static const struct file_operations fops_rcstat = { | ||
313 | .read = read_file_rcstat, | ||
314 | .open = ath9k_debugfs_open, | ||
315 | .owner = THIS_MODULE | ||
316 | }; | ||
225 | 317 | ||
226 | int ath9k_init_debug(struct ath_softc *sc) | 318 | int ath9k_init_debug(struct ath_softc *sc) |
227 | { | 319 | { |
@@ -248,6 +340,13 @@ int ath9k_init_debug(struct ath_softc *sc) | |||
248 | if (!sc->sc_debug.debugfs_interrupt) | 340 | if (!sc->sc_debug.debugfs_interrupt) |
249 | goto err; | 341 | goto err; |
250 | 342 | ||
343 | sc->sc_debug.debugfs_rcstat = debugfs_create_file("rcstat", | ||
344 | S_IRUGO, | ||
345 | sc->sc_debug.debugfs_phy, | ||
346 | sc, &fops_rcstat); | ||
347 | if (!sc->sc_debug.debugfs_rcstat) | ||
348 | goto err; | ||
349 | |||
251 | return 0; | 350 | return 0; |
252 | err: | 351 | err: |
253 | ath9k_exit_debug(sc); | 352 | ath9k_exit_debug(sc); |
@@ -256,6 +355,7 @@ err: | |||
256 | 355 | ||
257 | void ath9k_exit_debug(struct ath_softc *sc) | 356 | void ath9k_exit_debug(struct ath_softc *sc) |
258 | { | 357 | { |
358 | debugfs_remove(sc->sc_debug.debugfs_rcstat); | ||
259 | debugfs_remove(sc->sc_debug.debugfs_interrupt); | 359 | debugfs_remove(sc->sc_debug.debugfs_interrupt); |
260 | debugfs_remove(sc->sc_debug.debugfs_dma); | 360 | debugfs_remove(sc->sc_debug.debugfs_dma); |
261 | debugfs_remove(sc->sc_debug.debugfs_phy); | 361 | debugfs_remove(sc->sc_debug.debugfs_phy); |