Blame view
net/mac80211/rc80211_minstrel_ht_debugfs.c
8.76 KB
d2912cb15 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-only |
ec8aa669b mac80211: add the... |
2 3 |
/* * Copyright (C) 2010 Felix Fietkau <nbd@openwrt.org> |
ec8aa669b mac80211: add the... |
4 5 6 7 8 9 |
*/ #include <linux/netdevice.h> #include <linux/types.h> #include <linux/skbuff.h> #include <linux/debugfs.h> #include <linux/ieee80211.h> |
bc3b2d7fb net: Add export.h... |
10 |
#include <linux/export.h> |
ec8aa669b mac80211: add the... |
11 12 13 |
#include <net/mac80211.h> #include "rc80211_minstrel.h" #include "rc80211_minstrel_ht.h" |
b1c4f6833 mac80211: minstre... |
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
static ssize_t minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos) { struct minstrel_debugfs_info *ms; ms = file->private_data; return simple_read_from_buffer(buf, len, ppos, ms->buf, ms->len); } static int minstrel_stats_release(struct inode *inode, struct file *file) { kfree(file->private_data); return 0; } |
a0497f9f5 mac80211/minstrel... |
29 30 31 |
static char * minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) { |
a0497f9f5 mac80211/minstrel... |
32 |
const struct mcs_group *mg; |
1109dc392 mac80211: minstre... |
33 |
unsigned int j, tp_max, tp_avg, eprob, tx_time; |
a0497f9f5 mac80211/minstrel... |
34 35 |
char htmode = '2'; char gimode = 'L'; |
8ec7886b1 mac80211: minstre... |
36 |
u32 gflags; |
a0497f9f5 mac80211/minstrel... |
37 |
|
41d085835 mac80211: minstre... |
38 |
if (!mi->supported[i]) |
a0497f9f5 mac80211/minstrel... |
39 40 41 |
return p; mg = &minstrel_mcs_groups[i]; |
8ec7886b1 mac80211: minstre... |
42 43 44 |
gflags = mg->flags; if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) |
a0497f9f5 mac80211/minstrel... |
45 |
htmode = '4'; |
8ec7886b1 mac80211: minstre... |
46 |
else if (gflags & IEEE80211_TX_RC_80_MHZ_WIDTH) |
9208247d7 mac80211: minstre... |
47 |
htmode = '8'; |
8ec7886b1 mac80211: minstre... |
48 |
if (gflags & IEEE80211_TX_RC_SHORT_GI) |
a0497f9f5 mac80211/minstrel... |
49 50 51 |
gimode = 'S'; for (j = 0; j < MCS_GROUP_RATES; j++) { |
9134073bc mac80211: improve... |
52 |
struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j]; |
a0497f9f5 mac80211/minstrel... |
53 54 |
static const int bitrates[4] = { 10, 20, 55, 110 }; int idx = i * MCS_GROUP_RATES + j; |
202df504d mac80211: minstre... |
55 |
unsigned int duration; |
a0497f9f5 mac80211/minstrel... |
56 |
|
41d085835 mac80211: minstre... |
57 |
if (!(mi->supported[i] & BIT(j))) |
a0497f9f5 mac80211/minstrel... |
58 |
continue; |
9c00bb721 mac80211: enhance... |
59 60 61 62 63 64 65 66 67 68 69 70 71 |
if (gflags & IEEE80211_TX_RC_MCS) { p += sprintf(p, "HT%c0 ", htmode); p += sprintf(p, "%cGI ", gimode); p += sprintf(p, "%d ", mg->streams); } else if (gflags & IEEE80211_TX_RC_VHT_MCS) { p += sprintf(p, "VHT%c0 ", htmode); p += sprintf(p, "%cGI ", gimode); p += sprintf(p, "%d ", mg->streams); } else { p += sprintf(p, "CCK "); p += sprintf(p, "%cP ", j < 4 ? 'L' : 'S'); p += sprintf(p, "1 "); } |
a0497f9f5 mac80211/minstrel... |
72 |
|
5935839ad mac80211: improve... |
73 74 75 76 |
*(p++) = (idx == mi->max_tp_rate[0]) ? 'A' : ' '; *(p++) = (idx == mi->max_tp_rate[1]) ? 'B' : ' '; *(p++) = (idx == mi->max_tp_rate[2]) ? 'C' : ' '; *(p++) = (idx == mi->max_tp_rate[3]) ? 'D' : ' '; |
a0497f9f5 mac80211/minstrel... |
77 |
*(p++) = (idx == mi->max_prob_rate) ? 'P' : ' '; |
8ec7886b1 mac80211: minstre... |
78 |
if (gflags & IEEE80211_TX_RC_MCS) { |
9c00bb721 mac80211: enhance... |
79 |
p += sprintf(p, " MCS%-2u", (mg->streams - 1) * 8 + j); |
8ec7886b1 mac80211: minstre... |
80 |
} else if (gflags & IEEE80211_TX_RC_VHT_MCS) { |
9c00bb721 mac80211: enhance... |
81 |
p += sprintf(p, " MCS%-1u/%1u", j, mg->streams); |
a0497f9f5 mac80211/minstrel... |
82 |
} else { |
8ec7886b1 mac80211: minstre... |
83 |
int r = bitrates[j % 4]; |
9c00bb721 mac80211: enhance... |
84 |
p += sprintf(p, " %2u.%1uM", r / 10, r % 10); |
a0497f9f5 mac80211/minstrel... |
85 |
} |
9c00bb721 mac80211: enhance... |
86 87 88 |
p += sprintf(p, " %3u ", idx); /* tx_time[rate(i)] in usec */ |
202df504d mac80211: minstre... |
89 90 91 |
duration = mg->duration[j]; duration <<= mg->shift; tx_time = DIV_ROUND_CLOSEST(duration, 1000); |
50e55a8ea mac80211: add max... |
92 |
p += sprintf(p, "%6u ", tx_time); |
9c00bb721 mac80211: enhance... |
93 |
|
50e55a8ea mac80211: add max... |
94 |
tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100)); |
5f63afe02 mac80211: minstre... |
95 96 |
tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_avg); eprob = MINSTREL_TRUNC(mrs->prob_avg * 1000); |
a0497f9f5 mac80211/minstrel... |
97 |
|
506dbf90c mac80211: rc80211... |
98 |
p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u" |
1109dc392 mac80211: minstre... |
99 |
" %3u %3u %-3u " |
5f919abc7 mac80211: add sta... |
100 101 |
"%9llu %-9llu ", |
50e55a8ea mac80211: add max... |
102 |
tp_max / 10, tp_max % 10, |
6a27b2c40 mac80211: restruc... |
103 |
tp_avg / 10, tp_avg % 10, |
a0497f9f5 mac80211/minstrel... |
104 |
eprob / 10, eprob % 10, |
9134073bc mac80211: improve... |
105 106 107 108 109 |
mrs->retry_count, mrs->last_success, mrs->last_attempts, (unsigned long long)mrs->succ_hist, (unsigned long long)mrs->att_hist); |
a0497f9f5 mac80211/minstrel... |
110 111 112 113 |
} return p; } |
ec8aa669b mac80211: add the... |
114 115 116 117 118 119 |
static int minstrel_ht_stats_open(struct inode *inode, struct file *file) { struct minstrel_ht_sta_priv *msp = inode->i_private; struct minstrel_ht_sta *mi = &msp->ht; struct minstrel_debugfs_info *ms; |
a0497f9f5 mac80211/minstrel... |
120 |
unsigned int i; |
ec8aa669b mac80211: add the... |
121 |
int ret; |
2cae0b6a7 mac80211: add new... |
122 |
char *p; |
ec8aa669b mac80211: add the... |
123 124 125 126 127 128 129 |
if (!msp->is_ht) { inode->i_private = &msp->legacy; ret = minstrel_stats_open(inode, file); inode->i_private = msp; return ret; } |
9208247d7 mac80211: minstre... |
130 |
ms = kmalloc(32768, GFP_KERNEL); |
ec8aa669b mac80211: add the... |
131 132 133 134 135 |
if (!ms) return -ENOMEM; file->private_data = ms; p = ms->buf; |
9c00bb721 mac80211: enhance... |
136 137 138 |
p += sprintf(p, " "); |
a0c391b13 mac80211: minstre... |
139 |
p += sprintf(p, |
506dbf90c mac80211: rc80211... |
140 141 |
" best ____________rate__________ ____statistics___ _____last____ ______sum-of________ "); |
a0c391b13 mac80211: minstre... |
142 |
p += sprintf(p, |
506dbf90c mac80211: rc80211... |
143 144 |
"mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob)] [retry|suc|att] [#success | #attempts] "); |
11b2357d5 mac80211: minstre... |
145 |
|
8a0ee4fe1 mac80211: minstre... |
146 147 |
p = minstrel_ht_stats_dump(mi, MINSTREL_CCK_GROUP, p); for (i = 0; i < MINSTREL_CCK_GROUP; i++) |
a0497f9f5 mac80211/minstrel... |
148 |
p = minstrel_ht_stats_dump(mi, i, p); |
9208247d7 mac80211: minstre... |
149 150 |
for (i++; i < ARRAY_SIZE(mi->groups); i++) p = minstrel_ht_stats_dump(mi, i, p); |
ec8aa669b mac80211: add the... |
151 |
|
ec8aa669b mac80211: add the... |
152 153 154 155 156 157 |
p += sprintf(p, " Total packet count:: ideal %d " "lookaround %d ", max(0, (int) mi->total_packets - (int) mi->sample_packets), mi->sample_packets); |
77f7ffdc3 mac80211: minstre... |
158 159 160 161 162 |
if (mi->avg_ampdu_len) p += sprintf(p, "Average # of aggregated frames per A-MPDU: %d.%d ", MINSTREL_TRUNC(mi->avg_ampdu_len), MINSTREL_TRUNC(mi->avg_ampdu_len * 10) % 10); |
ec8aa669b mac80211: add the... |
163 |
ms->len = p - ms->buf; |
9208247d7 mac80211: minstre... |
164 |
WARN_ON(ms->len + sizeof(*ms) > 32768); |
11b2357d5 mac80211: minstre... |
165 |
|
a0572d93c mac80211: disallo... |
166 |
return nonseekable_open(inode, file); |
ec8aa669b mac80211: add the... |
167 168 169 170 171 172 173 |
} static const struct file_operations minstrel_ht_stat_fops = { .owner = THIS_MODULE, .open = minstrel_ht_stats_open, .read = minstrel_stats_read, .release = minstrel_stats_release, |
a0572d93c mac80211: disallo... |
174 |
.llseek = no_llseek, |
ec8aa669b mac80211: add the... |
175 |
}; |
2cae0b6a7 mac80211: add new... |
176 177 178 179 |
static char * minstrel_ht_stats_csv_dump(struct minstrel_ht_sta *mi, int i, char *p) { const struct mcs_group *mg; |
1109dc392 mac80211: minstre... |
180 |
unsigned int j, tp_max, tp_avg, eprob, tx_time; |
2cae0b6a7 mac80211: add new... |
181 182 183 |
char htmode = '2'; char gimode = 'L'; u32 gflags; |
41d085835 mac80211: minstre... |
184 |
if (!mi->supported[i]) |
2cae0b6a7 mac80211: add new... |
185 186 187 188 189 190 191 192 193 194 195 196 197 |
return p; mg = &minstrel_mcs_groups[i]; gflags = mg->flags; if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) htmode = '4'; else if (gflags & IEEE80211_TX_RC_80_MHZ_WIDTH) htmode = '8'; if (gflags & IEEE80211_TX_RC_SHORT_GI) gimode = 'S'; for (j = 0; j < MCS_GROUP_RATES; j++) { |
9134073bc mac80211: improve... |
198 |
struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j]; |
2cae0b6a7 mac80211: add new... |
199 200 |
static const int bitrates[4] = { 10, 20, 55, 110 }; int idx = i * MCS_GROUP_RATES + j; |
202df504d mac80211: minstre... |
201 |
unsigned int duration; |
2cae0b6a7 mac80211: add new... |
202 |
|
41d085835 mac80211: minstre... |
203 |
if (!(mi->supported[i] & BIT(j))) |
2cae0b6a7 mac80211: add new... |
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
continue; if (gflags & IEEE80211_TX_RC_MCS) { p += sprintf(p, "HT%c0,", htmode); p += sprintf(p, "%cGI,", gimode); p += sprintf(p, "%d,", mg->streams); } else if (gflags & IEEE80211_TX_RC_VHT_MCS) { p += sprintf(p, "VHT%c0,", htmode); p += sprintf(p, "%cGI,", gimode); p += sprintf(p, "%d,", mg->streams); } else { p += sprintf(p, "CCK,"); p += sprintf(p, "%cP,", j < 4 ? 'L' : 'S'); p += sprintf(p, "1,"); } p += sprintf(p, "%s" ,((idx == mi->max_tp_rate[0]) ? "A" : "")); p += sprintf(p, "%s" ,((idx == mi->max_tp_rate[1]) ? "B" : "")); p += sprintf(p, "%s" ,((idx == mi->max_tp_rate[2]) ? "C" : "")); p += sprintf(p, "%s" ,((idx == mi->max_tp_rate[3]) ? "D" : "")); p += sprintf(p, "%s" ,((idx == mi->max_prob_rate) ? "P" : "")); if (gflags & IEEE80211_TX_RC_MCS) { p += sprintf(p, ",MCS%-2u,", (mg->streams - 1) * 8 + j); } else if (gflags & IEEE80211_TX_RC_VHT_MCS) { p += sprintf(p, ",MCS%-1u/%1u,", j, mg->streams); } else { int r = bitrates[j % 4]; p += sprintf(p, ",%2u.%1uM,", r / 10, r % 10); } p += sprintf(p, "%u,", idx); |
202df504d mac80211: minstre... |
236 237 238 239 |
duration = mg->duration[j]; duration <<= mg->shift; tx_time = DIV_ROUND_CLOSEST(duration, 1000); |
2cae0b6a7 mac80211: add new... |
240 |
p += sprintf(p, "%u,", tx_time); |
50e55a8ea mac80211: add max... |
241 |
tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100)); |
5f63afe02 mac80211: minstre... |
242 243 |
tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_avg); eprob = MINSTREL_TRUNC(mrs->prob_avg * 1000); |
2cae0b6a7 mac80211: add new... |
244 |
|
506dbf90c mac80211: rc80211... |
245 |
p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u,%u," |
5f919abc7 mac80211: add sta... |
246 |
"%u,%llu,%llu,", |
50e55a8ea mac80211: add max... |
247 |
tp_max / 10, tp_max % 10, |
6a27b2c40 mac80211: restruc... |
248 |
tp_avg / 10, tp_avg % 10, |
2cae0b6a7 mac80211: add new... |
249 |
eprob / 10, eprob % 10, |
9134073bc mac80211: improve... |
250 251 252 253 254 |
mrs->retry_count, mrs->last_success, mrs->last_attempts, (unsigned long long)mrs->succ_hist, (unsigned long long)mrs->att_hist); |
2cae0b6a7 mac80211: add new... |
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 |
p += sprintf(p, "%d,%d,%d.%d ", max(0, (int) mi->total_packets - (int) mi->sample_packets), mi->sample_packets, MINSTREL_TRUNC(mi->avg_ampdu_len), MINSTREL_TRUNC(mi->avg_ampdu_len * 10) % 10); } return p; } static int minstrel_ht_stats_csv_open(struct inode *inode, struct file *file) { struct minstrel_ht_sta_priv *msp = inode->i_private; struct minstrel_ht_sta *mi = &msp->ht; struct minstrel_debugfs_info *ms; unsigned int i; int ret; char *p; if (!msp->is_ht) { inode->i_private = &msp->legacy; ret = minstrel_stats_csv_open(inode, file); inode->i_private = msp; return ret; } ms = kmalloc(32768, GFP_KERNEL); if (!ms) return -ENOMEM; file->private_data = ms; p = ms->buf; p = minstrel_ht_stats_csv_dump(mi, MINSTREL_CCK_GROUP, p); for (i = 0; i < MINSTREL_CCK_GROUP; i++) p = minstrel_ht_stats_csv_dump(mi, i, p); for (i++; i < ARRAY_SIZE(mi->groups); i++) p = minstrel_ht_stats_csv_dump(mi, i, p); ms->len = p - ms->buf; WARN_ON(ms->len + sizeof(*ms) > 32768); return nonseekable_open(inode, file); } static const struct file_operations minstrel_ht_stat_csv_fops = { .owner = THIS_MODULE, .open = minstrel_ht_stats_csv_open, .read = minstrel_stats_read, .release = minstrel_stats_release, .llseek = no_llseek, }; |
ec8aa669b mac80211: add the... |
312 313 314 315 |
void minstrel_ht_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir) { struct minstrel_ht_sta_priv *msp = priv_sta; |
5b5e87314 mac80211: minstre... |
316 317 318 319 |
debugfs_create_file("rc_stats", 0444, dir, msp, &minstrel_ht_stat_fops); debugfs_create_file("rc_stats_csv", 0444, dir, msp, &minstrel_ht_stat_csv_fops); |
ec8aa669b mac80211: add the... |
320 |
} |