diff options
Diffstat (limited to 'net/mac80211/debugfs_sta.c')
-rw-r--r-- | net/mac80211/debugfs_sta.c | 181 |
1 files changed, 127 insertions, 54 deletions
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 8f5944c53d4e..6d47a1d31b37 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
@@ -33,25 +33,16 @@ static ssize_t sta_ ##name## _read(struct file *file, \ | |||
33 | #define STA_READ_LU(name, field) STA_READ(name, 20, field, "%lu\n") | 33 | #define STA_READ_LU(name, field) STA_READ(name, 20, field, "%lu\n") |
34 | #define STA_READ_S(name, field) STA_READ(name, 20, field, "%s\n") | 34 | #define STA_READ_S(name, field) STA_READ(name, 20, field, "%s\n") |
35 | 35 | ||
36 | #define STA_READ_RATE(name, field) \ | 36 | #define STA_OPS(name) \ |
37 | static ssize_t sta_##name##_read(struct file *file, \ | 37 | static const struct file_operations sta_ ##name## _ops = { \ |
38 | char __user *userbuf, \ | 38 | .read = sta_##name##_read, \ |
39 | size_t count, loff_t *ppos) \ | 39 | .open = mac80211_open_file_generic, \ |
40 | { \ | ||
41 | struct sta_info *sta = file->private_data; \ | ||
42 | struct ieee80211_local *local = wdev_priv(sta->dev->ieee80211_ptr);\ | ||
43 | struct ieee80211_hw_mode *mode = local->oper_hw_mode; \ | ||
44 | char buf[20]; \ | ||
45 | int res = scnprintf(buf, sizeof(buf), "%d\n", \ | ||
46 | (sta->field >= 0 && \ | ||
47 | sta->field < mode->num_rates) ? \ | ||
48 | mode->rates[sta->field].rate : -1); \ | ||
49 | return simple_read_from_buffer(userbuf, count, ppos, buf, res); \ | ||
50 | } | 40 | } |
51 | 41 | ||
52 | #define STA_OPS(name) \ | 42 | #define STA_OPS_WR(name) \ |
53 | static const struct file_operations sta_ ##name## _ops = { \ | 43 | static const struct file_operations sta_ ##name## _ops = { \ |
54 | .read = sta_##name##_read, \ | 44 | .read = sta_##name##_read, \ |
45 | .write = sta_##name##_write, \ | ||
55 | .open = mac80211_open_file_generic, \ | 46 | .open = mac80211_open_file_generic, \ |
56 | } | 47 | } |
57 | 48 | ||
@@ -60,7 +51,7 @@ static const struct file_operations sta_ ##name## _ops = { \ | |||
60 | STA_OPS(name) | 51 | STA_OPS(name) |
61 | 52 | ||
62 | STA_FILE(aid, aid, D); | 53 | STA_FILE(aid, aid, D); |
63 | STA_FILE(dev, dev->name, S); | 54 | STA_FILE(dev, sdata->dev->name, S); |
64 | STA_FILE(rx_packets, rx_packets, LU); | 55 | STA_FILE(rx_packets, rx_packets, LU); |
65 | STA_FILE(tx_packets, tx_packets, LU); | 56 | STA_FILE(tx_packets, tx_packets, LU); |
66 | STA_FILE(rx_bytes, rx_bytes, LU); | 57 | STA_FILE(rx_bytes, rx_bytes, LU); |
@@ -70,27 +61,23 @@ STA_FILE(rx_fragments, rx_fragments, LU); | |||
70 | STA_FILE(rx_dropped, rx_dropped, LU); | 61 | STA_FILE(rx_dropped, rx_dropped, LU); |
71 | STA_FILE(tx_fragments, tx_fragments, LU); | 62 | STA_FILE(tx_fragments, tx_fragments, LU); |
72 | STA_FILE(tx_filtered, tx_filtered_count, LU); | 63 | STA_FILE(tx_filtered, tx_filtered_count, LU); |
73 | STA_FILE(txrate, txrate, RATE); | ||
74 | STA_FILE(last_txrate, last_txrate, RATE); | ||
75 | STA_FILE(tx_retry_failed, tx_retry_failed, LU); | 64 | STA_FILE(tx_retry_failed, tx_retry_failed, LU); |
76 | STA_FILE(tx_retry_count, tx_retry_count, LU); | 65 | STA_FILE(tx_retry_count, tx_retry_count, LU); |
77 | STA_FILE(last_rssi, last_rssi, D); | 66 | STA_FILE(last_rssi, last_rssi, D); |
78 | STA_FILE(last_signal, last_signal, D); | 67 | STA_FILE(last_signal, last_signal, D); |
79 | STA_FILE(last_noise, last_noise, D); | 68 | STA_FILE(last_noise, last_noise, D); |
80 | STA_FILE(channel_use, channel_use, D); | 69 | STA_FILE(channel_use, channel_use, D); |
81 | STA_FILE(wep_weak_iv_count, wep_weak_iv_count, D); | 70 | STA_FILE(wep_weak_iv_count, wep_weak_iv_count, LU); |
82 | 71 | ||
83 | static ssize_t sta_flags_read(struct file *file, char __user *userbuf, | 72 | static ssize_t sta_flags_read(struct file *file, char __user *userbuf, |
84 | size_t count, loff_t *ppos) | 73 | size_t count, loff_t *ppos) |
85 | { | 74 | { |
86 | char buf[100]; | 75 | char buf[100]; |
87 | struct sta_info *sta = file->private_data; | 76 | struct sta_info *sta = file->private_data; |
88 | int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s", | 77 | int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s", |
89 | sta->flags & WLAN_STA_AUTH ? "AUTH\n" : "", | 78 | sta->flags & WLAN_STA_AUTH ? "AUTH\n" : "", |
90 | sta->flags & WLAN_STA_ASSOC ? "ASSOC\n" : "", | 79 | sta->flags & WLAN_STA_ASSOC ? "ASSOC\n" : "", |
91 | sta->flags & WLAN_STA_PS ? "PS\n" : "", | 80 | sta->flags & WLAN_STA_PS ? "PS\n" : "", |
92 | sta->flags & WLAN_STA_TIM ? "TIM\n" : "", | ||
93 | sta->flags & WLAN_STA_PERM ? "PERM\n" : "", | ||
94 | sta->flags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "", | 81 | sta->flags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "", |
95 | sta->flags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "", | 82 | sta->flags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "", |
96 | sta->flags & WLAN_STA_WME ? "WME\n" : "", | 83 | sta->flags & WLAN_STA_WME ? "WME\n" : "", |
@@ -111,31 +98,6 @@ static ssize_t sta_num_ps_buf_frames_read(struct file *file, | |||
111 | } | 98 | } |
112 | STA_OPS(num_ps_buf_frames); | 99 | STA_OPS(num_ps_buf_frames); |
113 | 100 | ||
114 | static ssize_t sta_last_ack_rssi_read(struct file *file, char __user *userbuf, | ||
115 | size_t count, loff_t *ppos) | ||
116 | { | ||
117 | char buf[100]; | ||
118 | struct sta_info *sta = file->private_data; | ||
119 | int res = scnprintf(buf, sizeof(buf), "%d %d %d\n", | ||
120 | sta->last_ack_rssi[0], | ||
121 | sta->last_ack_rssi[1], | ||
122 | sta->last_ack_rssi[2]); | ||
123 | return simple_read_from_buffer(userbuf, count, ppos, buf, res); | ||
124 | } | ||
125 | STA_OPS(last_ack_rssi); | ||
126 | |||
127 | static ssize_t sta_last_ack_ms_read(struct file *file, char __user *userbuf, | ||
128 | size_t count, loff_t *ppos) | ||
129 | { | ||
130 | char buf[20]; | ||
131 | struct sta_info *sta = file->private_data; | ||
132 | int res = scnprintf(buf, sizeof(buf), "%d\n", | ||
133 | sta->last_ack ? | ||
134 | jiffies_to_msecs(jiffies - sta->last_ack) : -1); | ||
135 | return simple_read_from_buffer(userbuf, count, ppos, buf, res); | ||
136 | } | ||
137 | STA_OPS(last_ack_ms); | ||
138 | |||
139 | static ssize_t sta_inactive_ms_read(struct file *file, char __user *userbuf, | 101 | static ssize_t sta_inactive_ms_read(struct file *file, char __user *userbuf, |
140 | size_t count, loff_t *ppos) | 102 | size_t count, loff_t *ppos) |
141 | { | 103 | { |
@@ -191,8 +153,120 @@ static ssize_t sta_wme_tx_queue_read(struct file *file, char __user *userbuf, | |||
191 | STA_OPS(wme_tx_queue); | 153 | STA_OPS(wme_tx_queue); |
192 | #endif | 154 | #endif |
193 | 155 | ||
156 | static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, | ||
157 | size_t count, loff_t *ppos) | ||
158 | { | ||
159 | char buf[768], *p = buf; | ||
160 | int i; | ||
161 | struct sta_info *sta = file->private_data; | ||
162 | p += scnprintf(p, sizeof(buf)+buf-p, "Agg state for STA is:\n"); | ||
163 | p += scnprintf(p, sizeof(buf)+buf-p, " STA next dialog_token is %d \n " | ||
164 | "TIDs info is: \n TID :", | ||
165 | (sta->ampdu_mlme.dialog_token_allocator + 1)); | ||
166 | for (i = 0; i < STA_TID_NUM; i++) | ||
167 | p += scnprintf(p, sizeof(buf)+buf-p, "%5d", i); | ||
168 | |||
169 | p += scnprintf(p, sizeof(buf)+buf-p, "\n RX :"); | ||
170 | for (i = 0; i < STA_TID_NUM; i++) | ||
171 | p += scnprintf(p, sizeof(buf)+buf-p, "%5d", | ||
172 | sta->ampdu_mlme.tid_state_rx[i]); | ||
173 | |||
174 | p += scnprintf(p, sizeof(buf)+buf-p, "\n DTKN:"); | ||
175 | for (i = 0; i < STA_TID_NUM; i++) | ||
176 | p += scnprintf(p, sizeof(buf)+buf-p, "%5d", | ||
177 | sta->ampdu_mlme.tid_state_rx[i]? | ||
178 | sta->ampdu_mlme.tid_rx[i]->dialog_token : 0); | ||
179 | |||
180 | p += scnprintf(p, sizeof(buf)+buf-p, "\n TX :"); | ||
181 | for (i = 0; i < STA_TID_NUM; i++) | ||
182 | p += scnprintf(p, sizeof(buf)+buf-p, "%5d", | ||
183 | sta->ampdu_mlme.tid_state_tx[i]); | ||
184 | |||
185 | p += scnprintf(p, sizeof(buf)+buf-p, "\n DTKN:"); | ||
186 | for (i = 0; i < STA_TID_NUM; i++) | ||
187 | p += scnprintf(p, sizeof(buf)+buf-p, "%5d", | ||
188 | sta->ampdu_mlme.tid_state_tx[i]? | ||
189 | sta->ampdu_mlme.tid_tx[i]->dialog_token : 0); | ||
190 | |||
191 | p += scnprintf(p, sizeof(buf)+buf-p, "\n SSN :"); | ||
192 | for (i = 0; i < STA_TID_NUM; i++) | ||
193 | p += scnprintf(p, sizeof(buf)+buf-p, "%5d", | ||
194 | sta->ampdu_mlme.tid_state_tx[i]? | ||
195 | sta->ampdu_mlme.tid_tx[i]->ssn : 0); | ||
196 | |||
197 | p += scnprintf(p, sizeof(buf)+buf-p, "\n"); | ||
198 | |||
199 | return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); | ||
200 | } | ||
201 | |||
202 | static ssize_t sta_agg_status_write(struct file *file, | ||
203 | const char __user *user_buf, size_t count, loff_t *ppos) | ||
204 | { | ||
205 | struct sta_info *sta = file->private_data; | ||
206 | struct net_device *dev = sta->sdata->dev; | ||
207 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
208 | struct ieee80211_hw *hw = &local->hw; | ||
209 | u8 *da = sta->addr; | ||
210 | static int tid_static_tx[16] = {0, 0, 0, 0, 0, 0, 0, 0, | ||
211 | 0, 0, 0, 0, 0, 0, 0, 0}; | ||
212 | static int tid_static_rx[16] = {1, 1, 1, 1, 1, 1, 1, 1, | ||
213 | 1, 1, 1, 1, 1, 1, 1, 1}; | ||
214 | char *endp; | ||
215 | char buf[32]; | ||
216 | int buf_size, rs; | ||
217 | unsigned int tid_num; | ||
218 | char state[4]; | ||
219 | |||
220 | memset(buf, 0x00, sizeof(buf)); | ||
221 | buf_size = min(count, (sizeof(buf)-1)); | ||
222 | if (copy_from_user(buf, user_buf, buf_size)) | ||
223 | return -EFAULT; | ||
224 | |||
225 | tid_num = simple_strtoul(buf, &endp, 0); | ||
226 | if (endp == buf) | ||
227 | return -EINVAL; | ||
228 | |||
229 | if ((tid_num >= 100) && (tid_num <= 115)) { | ||
230 | /* toggle Rx aggregation command */ | ||
231 | tid_num = tid_num - 100; | ||
232 | if (tid_static_rx[tid_num] == 1) { | ||
233 | strcpy(state, "off "); | ||
234 | ieee80211_sta_stop_rx_ba_session(dev, da, tid_num, 0, | ||
235 | WLAN_REASON_QSTA_REQUIRE_SETUP); | ||
236 | sta->ampdu_mlme.tid_state_rx[tid_num] |= | ||
237 | HT_AGG_STATE_DEBUGFS_CTL; | ||
238 | tid_static_rx[tid_num] = 0; | ||
239 | } else { | ||
240 | strcpy(state, "on "); | ||
241 | sta->ampdu_mlme.tid_state_rx[tid_num] &= | ||
242 | ~HT_AGG_STATE_DEBUGFS_CTL; | ||
243 | tid_static_rx[tid_num] = 1; | ||
244 | } | ||
245 | printk(KERN_DEBUG "debugfs - try switching tid %u %s\n", | ||
246 | tid_num, state); | ||
247 | } else if ((tid_num >= 0) && (tid_num <= 15)) { | ||
248 | /* toggle Tx aggregation command */ | ||
249 | if (tid_static_tx[tid_num] == 0) { | ||
250 | strcpy(state, "on "); | ||
251 | rs = ieee80211_start_tx_ba_session(hw, da, tid_num); | ||
252 | if (rs == 0) | ||
253 | tid_static_tx[tid_num] = 1; | ||
254 | } else { | ||
255 | strcpy(state, "off"); | ||
256 | rs = ieee80211_stop_tx_ba_session(hw, da, tid_num, 1); | ||
257 | if (rs == 0) | ||
258 | tid_static_tx[tid_num] = 0; | ||
259 | } | ||
260 | printk(KERN_DEBUG "debugfs - switching tid %u %s, return=%d\n", | ||
261 | tid_num, state, rs); | ||
262 | } | ||
263 | |||
264 | return count; | ||
265 | } | ||
266 | STA_OPS_WR(agg_status); | ||
267 | |||
194 | #define DEBUGFS_ADD(name) \ | 268 | #define DEBUGFS_ADD(name) \ |
195 | sta->debugfs.name = debugfs_create_file(#name, 0444, \ | 269 | sta->debugfs.name = debugfs_create_file(#name, 0400, \ |
196 | sta->debugfs.dir, sta, &sta_ ##name## _ops); | 270 | sta->debugfs.dir, sta, &sta_ ##name## _ops); |
197 | 271 | ||
198 | #define DEBUGFS_DEL(name) \ | 272 | #define DEBUGFS_DEL(name) \ |
@@ -203,12 +277,13 @@ STA_OPS(wme_tx_queue); | |||
203 | void ieee80211_sta_debugfs_add(struct sta_info *sta) | 277 | void ieee80211_sta_debugfs_add(struct sta_info *sta) |
204 | { | 278 | { |
205 | struct dentry *stations_dir = sta->local->debugfs.stations; | 279 | struct dentry *stations_dir = sta->local->debugfs.stations; |
206 | DECLARE_MAC_BUF(mac); | 280 | DECLARE_MAC_BUF(mbuf); |
281 | u8 *mac; | ||
207 | 282 | ||
208 | if (!stations_dir) | 283 | if (!stations_dir) |
209 | return; | 284 | return; |
210 | 285 | ||
211 | print_mac(mac, sta->addr); | 286 | mac = print_mac(mbuf, sta->addr); |
212 | 287 | ||
213 | sta->debugfs.dir = debugfs_create_dir(mac, stations_dir); | 288 | sta->debugfs.dir = debugfs_create_dir(mac, stations_dir); |
214 | if (!sta->debugfs.dir) | 289 | if (!sta->debugfs.dir) |
@@ -216,28 +291,26 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta) | |||
216 | 291 | ||
217 | DEBUGFS_ADD(flags); | 292 | DEBUGFS_ADD(flags); |
218 | DEBUGFS_ADD(num_ps_buf_frames); | 293 | DEBUGFS_ADD(num_ps_buf_frames); |
219 | DEBUGFS_ADD(last_ack_rssi); | ||
220 | DEBUGFS_ADD(last_ack_ms); | ||
221 | DEBUGFS_ADD(inactive_ms); | 294 | DEBUGFS_ADD(inactive_ms); |
222 | DEBUGFS_ADD(last_seq_ctrl); | 295 | DEBUGFS_ADD(last_seq_ctrl); |
223 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS | 296 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS |
224 | DEBUGFS_ADD(wme_rx_queue); | 297 | DEBUGFS_ADD(wme_rx_queue); |
225 | DEBUGFS_ADD(wme_tx_queue); | 298 | DEBUGFS_ADD(wme_tx_queue); |
226 | #endif | 299 | #endif |
300 | DEBUGFS_ADD(agg_status); | ||
227 | } | 301 | } |
228 | 302 | ||
229 | void ieee80211_sta_debugfs_remove(struct sta_info *sta) | 303 | void ieee80211_sta_debugfs_remove(struct sta_info *sta) |
230 | { | 304 | { |
231 | DEBUGFS_DEL(flags); | 305 | DEBUGFS_DEL(flags); |
232 | DEBUGFS_DEL(num_ps_buf_frames); | 306 | DEBUGFS_DEL(num_ps_buf_frames); |
233 | DEBUGFS_DEL(last_ack_rssi); | ||
234 | DEBUGFS_DEL(last_ack_ms); | ||
235 | DEBUGFS_DEL(inactive_ms); | 307 | DEBUGFS_DEL(inactive_ms); |
236 | DEBUGFS_DEL(last_seq_ctrl); | 308 | DEBUGFS_DEL(last_seq_ctrl); |
237 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS | 309 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS |
238 | DEBUGFS_DEL(wme_rx_queue); | 310 | DEBUGFS_DEL(wme_rx_queue); |
239 | DEBUGFS_DEL(wme_tx_queue); | 311 | DEBUGFS_DEL(wme_tx_queue); |
240 | #endif | 312 | #endif |
313 | DEBUGFS_DEL(agg_status); | ||
241 | 314 | ||
242 | debugfs_remove(sta->debugfs.dir); | 315 | debugfs_remove(sta->debugfs.dir); |
243 | sta->debugfs.dir = NULL; | 316 | sta->debugfs.dir = NULL; |