diff options
author | Felix Fietkau <nbd@openwrt.org> | 2010-05-13 10:48:03 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-06-02 16:12:59 -0400 |
commit | ec8aa669b8393b6789b1954d587c63264af7ff99 (patch) | |
tree | 1a4c43dc718262d1aa6256de2d50b9e03a76c604 /net/mac80211/rc80211_minstrel_ht_debugfs.c | |
parent | b4df47081b67bce9dcb7b84b551588c7402a330a (diff) |
mac80211: add the minstrel_ht rate control algorithm
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/rc80211_minstrel_ht_debugfs.c')
-rw-r--r-- | net/mac80211/rc80211_minstrel_ht_debugfs.c | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/net/mac80211/rc80211_minstrel_ht_debugfs.c b/net/mac80211/rc80211_minstrel_ht_debugfs.c new file mode 100644 index 000000000000..4fb3ccbd8b40 --- /dev/null +++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c | |||
@@ -0,0 +1,120 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Felix Fietkau <nbd@openwrt.org> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | #include <linux/netdevice.h> | ||
9 | #include <linux/types.h> | ||
10 | #include <linux/skbuff.h> | ||
11 | #include <linux/debugfs.h> | ||
12 | #include <linux/ieee80211.h> | ||
13 | #include <net/mac80211.h> | ||
14 | #include "rc80211_minstrel.h" | ||
15 | #include "rc80211_minstrel_ht.h" | ||
16 | |||
17 | extern const struct mcs_group minstrel_mcs_groups[]; | ||
18 | |||
19 | static int | ||
20 | minstrel_ht_stats_open(struct inode *inode, struct file *file) | ||
21 | { | ||
22 | struct minstrel_ht_sta_priv *msp = inode->i_private; | ||
23 | struct minstrel_ht_sta *mi = &msp->ht; | ||
24 | struct minstrel_debugfs_info *ms; | ||
25 | unsigned int i, j, tp, prob, eprob; | ||
26 | char *p; | ||
27 | int ret; | ||
28 | |||
29 | if (!msp->is_ht) { | ||
30 | inode->i_private = &msp->legacy; | ||
31 | ret = minstrel_stats_open(inode, file); | ||
32 | inode->i_private = msp; | ||
33 | return ret; | ||
34 | } | ||
35 | |||
36 | ms = kmalloc(sizeof(*ms) + 8192, GFP_KERNEL); | ||
37 | if (!ms) | ||
38 | return -ENOMEM; | ||
39 | |||
40 | file->private_data = ms; | ||
41 | p = ms->buf; | ||
42 | p += sprintf(p, "type rate throughput ewma prob this prob " | ||
43 | "this succ/attempt success attempts\n"); | ||
44 | for (i = 0; i < MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS; i++) { | ||
45 | char htmode = '2'; | ||
46 | char gimode = 'L'; | ||
47 | |||
48 | if (!mi->groups[i].supported) | ||
49 | continue; | ||
50 | |||
51 | if (minstrel_mcs_groups[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) | ||
52 | htmode = '4'; | ||
53 | if (minstrel_mcs_groups[i].flags & IEEE80211_TX_RC_SHORT_GI) | ||
54 | gimode = 'S'; | ||
55 | |||
56 | for (j = 0; j < MCS_GROUP_RATES; j++) { | ||
57 | struct minstrel_rate_stats *mr = &mi->groups[i].rates[j]; | ||
58 | int idx = i * MCS_GROUP_RATES + j; | ||
59 | |||
60 | if (!(mi->groups[i].supported & BIT(j))) | ||
61 | continue; | ||
62 | |||
63 | p += sprintf(p, "HT%c0/%cGI ", htmode, gimode); | ||
64 | |||
65 | *(p++) = (idx == mi->max_tp_rate) ? 'T' : ' '; | ||
66 | *(p++) = (idx == mi->max_tp_rate2) ? 't' : ' '; | ||
67 | *(p++) = (idx == mi->max_prob_rate) ? 'P' : ' '; | ||
68 | p += sprintf(p, "MCS%-2u", (minstrel_mcs_groups[i].streams - 1) * | ||
69 | MCS_GROUP_RATES + j); | ||
70 | |||
71 | tp = mr->cur_tp / 10; | ||
72 | prob = MINSTREL_TRUNC(mr->cur_prob * 1000); | ||
73 | eprob = MINSTREL_TRUNC(mr->probability * 1000); | ||
74 | |||
75 | p += sprintf(p, " %6u.%1u %6u.%1u %6u.%1u " | ||
76 | "%3u(%3u) %8llu %8llu\n", | ||
77 | tp / 10, tp % 10, | ||
78 | eprob / 10, eprob % 10, | ||
79 | prob / 10, prob % 10, | ||
80 | mr->last_success, | ||
81 | mr->last_attempts, | ||
82 | (unsigned long long)mr->succ_hist, | ||
83 | (unsigned long long)mr->att_hist); | ||
84 | } | ||
85 | } | ||
86 | p += sprintf(p, "\nTotal packet count:: ideal %d " | ||
87 | "lookaround %d\n", | ||
88 | max(0, (int) mi->total_packets - (int) mi->sample_packets), | ||
89 | mi->sample_packets); | ||
90 | p += sprintf(p, "Average A-MPDU length: %d.%d\n", | ||
91 | MINSTREL_TRUNC(mi->avg_ampdu_len), | ||
92 | MINSTREL_TRUNC(mi->avg_ampdu_len * 10) % 10); | ||
93 | ms->len = p - ms->buf; | ||
94 | |||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | static const struct file_operations minstrel_ht_stat_fops = { | ||
99 | .owner = THIS_MODULE, | ||
100 | .open = minstrel_ht_stats_open, | ||
101 | .read = minstrel_stats_read, | ||
102 | .release = minstrel_stats_release, | ||
103 | }; | ||
104 | |||
105 | void | ||
106 | minstrel_ht_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir) | ||
107 | { | ||
108 | struct minstrel_ht_sta_priv *msp = priv_sta; | ||
109 | |||
110 | msp->dbg_stats = debugfs_create_file("rc_stats", S_IRUGO, dir, msp, | ||
111 | &minstrel_ht_stat_fops); | ||
112 | } | ||
113 | |||
114 | void | ||
115 | minstrel_ht_remove_sta_debugfs(void *priv, void *priv_sta) | ||
116 | { | ||
117 | struct minstrel_ht_sta_priv *msp = priv_sta; | ||
118 | |||
119 | debugfs_remove(msp->dbg_stats); | ||
120 | } | ||