diff options
-rw-r--r-- | net/mac80211/debugfs_sta.c | 116 | ||||
-rw-r--r-- | net/mac80211/sta_info.h | 1 |
2 files changed, 117 insertions, 0 deletions
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 8f5944c53d4e..df25abf63137 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
@@ -55,6 +55,13 @@ static const struct file_operations sta_ ##name## _ops = { \ | |||
55 | .open = mac80211_open_file_generic, \ | 55 | .open = mac80211_open_file_generic, \ |
56 | } | 56 | } |
57 | 57 | ||
58 | #define STA_OPS_WR(name) \ | ||
59 | static const struct file_operations sta_ ##name## _ops = { \ | ||
60 | .read = sta_##name##_read, \ | ||
61 | .write = sta_##name##_write, \ | ||
62 | .open = mac80211_open_file_generic, \ | ||
63 | } | ||
64 | |||
58 | #define STA_FILE(name, field, format) \ | 65 | #define STA_FILE(name, field, format) \ |
59 | STA_READ_##format(name, field) \ | 66 | STA_READ_##format(name, field) \ |
60 | STA_OPS(name) | 67 | STA_OPS(name) |
@@ -191,6 +198,113 @@ static ssize_t sta_wme_tx_queue_read(struct file *file, char __user *userbuf, | |||
191 | STA_OPS(wme_tx_queue); | 198 | STA_OPS(wme_tx_queue); |
192 | #endif | 199 | #endif |
193 | 200 | ||
201 | static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, | ||
202 | size_t count, loff_t *ppos) | ||
203 | { | ||
204 | char buf[768], *p = buf; | ||
205 | int i; | ||
206 | struct sta_info *sta = file->private_data; | ||
207 | p += scnprintf(p, sizeof(buf)+buf-p, "Agg state for STA is:\n"); | ||
208 | p += scnprintf(p, sizeof(buf)+buf-p, " STA next dialog_token is %d \n " | ||
209 | "TIDs info is: \n TID :", | ||
210 | (sta->ampdu_mlme.dialog_token_allocator + 1)); | ||
211 | for (i = 0; i < STA_TID_NUM; i++) | ||
212 | p += scnprintf(p, sizeof(buf)+buf-p, "%5d", i); | ||
213 | |||
214 | p += scnprintf(p, sizeof(buf)+buf-p, "\n RX :"); | ||
215 | for (i = 0; i < STA_TID_NUM; i++) | ||
216 | p += scnprintf(p, sizeof(buf)+buf-p, "%5d", | ||
217 | sta->ampdu_mlme.tid_rx[i].state); | ||
218 | |||
219 | p += scnprintf(p, sizeof(buf)+buf-p, "\n DTKN:"); | ||
220 | for (i = 0; i < STA_TID_NUM; i++) | ||
221 | p += scnprintf(p, sizeof(buf)+buf-p, "%5d", | ||
222 | sta->ampdu_mlme.tid_rx[i].dialog_token); | ||
223 | |||
224 | p += scnprintf(p, sizeof(buf)+buf-p, "\n TX :"); | ||
225 | for (i = 0; i < STA_TID_NUM; i++) | ||
226 | p += scnprintf(p, sizeof(buf)+buf-p, "%5d", | ||
227 | sta->ampdu_mlme.tid_tx[i].state); | ||
228 | |||
229 | p += scnprintf(p, sizeof(buf)+buf-p, "\n DTKN:"); | ||
230 | for (i = 0; i < STA_TID_NUM; i++) | ||
231 | p += scnprintf(p, sizeof(buf)+buf-p, "%5d", | ||
232 | sta->ampdu_mlme.tid_tx[i].dialog_token); | ||
233 | |||
234 | p += scnprintf(p, sizeof(buf)+buf-p, "\n SSN :"); | ||
235 | for (i = 0; i < STA_TID_NUM; i++) | ||
236 | p += scnprintf(p, sizeof(buf)+buf-p, "%5d", | ||
237 | sta->ampdu_mlme.tid_tx[i].ssn); | ||
238 | |||
239 | p += scnprintf(p, sizeof(buf)+buf-p, "\n"); | ||
240 | |||
241 | return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); | ||
242 | } | ||
243 | |||
244 | static ssize_t sta_agg_status_write(struct file *file, | ||
245 | const char __user *user_buf, size_t count, loff_t *ppos) | ||
246 | { | ||
247 | struct sta_info *sta = file->private_data; | ||
248 | struct net_device *dev = sta->dev; | ||
249 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
250 | struct ieee80211_hw *hw = &local->hw; | ||
251 | u8 *da = sta->addr; | ||
252 | static int tid_static_tx[16] = {0, 0, 0, 0, 0, 0, 0, 0, | ||
253 | 0, 0, 0, 0, 0, 0, 0, 0}; | ||
254 | static int tid_static_rx[16] = {1, 1, 1, 1, 1, 1, 1, 1, | ||
255 | 1, 1, 1, 1, 1, 1, 1, 1}; | ||
256 | char *endp; | ||
257 | char buf[32]; | ||
258 | int buf_size, rs; | ||
259 | unsigned int tid_num; | ||
260 | char state[4]; | ||
261 | |||
262 | memset(buf, 0x00, sizeof(buf)); | ||
263 | buf_size = min(count, (sizeof(buf)-1)); | ||
264 | if (copy_from_user(buf, user_buf, buf_size)) | ||
265 | return -EFAULT; | ||
266 | |||
267 | tid_num = simple_strtoul(buf, &endp, 0); | ||
268 | if (endp == buf) | ||
269 | return -EINVAL; | ||
270 | |||
271 | if ((tid_num >= 100) && (tid_num <= 115)) { | ||
272 | /* toggle Rx aggregation command */ | ||
273 | tid_num = tid_num - 100; | ||
274 | if (tid_static_rx[tid_num] == 1) { | ||
275 | strcpy(state, "off "); | ||
276 | ieee80211_sta_stop_rx_ba_session(dev, da, tid_num, 0, | ||
277 | WLAN_REASON_QSTA_REQUIRE_SETUP); | ||
278 | sta->ampdu_mlme.tid_rx[tid_num].buf_size = 0xFF; | ||
279 | tid_static_rx[tid_num] = 0; | ||
280 | } else { | ||
281 | strcpy(state, "on "); | ||
282 | sta->ampdu_mlme.tid_rx[tid_num].buf_size = 0x00; | ||
283 | tid_static_rx[tid_num] = 1; | ||
284 | } | ||
285 | printk(KERN_DEBUG "debugfs - try switching tid %u %s\n", | ||
286 | tid_num, state); | ||
287 | } else if ((tid_num >= 0) && (tid_num <= 15)) { | ||
288 | /* toggle Tx aggregation command */ | ||
289 | if (tid_static_tx[tid_num] == 0) { | ||
290 | strcpy(state, "on "); | ||
291 | rs = ieee80211_start_tx_ba_session(hw, da, tid_num); | ||
292 | if (rs == 0) | ||
293 | tid_static_tx[tid_num] = 1; | ||
294 | } else { | ||
295 | strcpy(state, "off"); | ||
296 | rs = ieee80211_stop_tx_ba_session(hw, da, tid_num, 1); | ||
297 | if (rs == 0) | ||
298 | tid_static_tx[tid_num] = 0; | ||
299 | } | ||
300 | printk(KERN_DEBUG "debugfs - switching tid %u %s, return=%d\n", | ||
301 | tid_num, state, rs); | ||
302 | } | ||
303 | |||
304 | return count; | ||
305 | } | ||
306 | STA_OPS_WR(agg_status); | ||
307 | |||
194 | #define DEBUGFS_ADD(name) \ | 308 | #define DEBUGFS_ADD(name) \ |
195 | sta->debugfs.name = debugfs_create_file(#name, 0444, \ | 309 | sta->debugfs.name = debugfs_create_file(#name, 0444, \ |
196 | sta->debugfs.dir, sta, &sta_ ##name## _ops); | 310 | sta->debugfs.dir, sta, &sta_ ##name## _ops); |
@@ -224,6 +338,7 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta) | |||
224 | DEBUGFS_ADD(wme_rx_queue); | 338 | DEBUGFS_ADD(wme_rx_queue); |
225 | DEBUGFS_ADD(wme_tx_queue); | 339 | DEBUGFS_ADD(wme_tx_queue); |
226 | #endif | 340 | #endif |
341 | DEBUGFS_ADD(agg_status); | ||
227 | } | 342 | } |
228 | 343 | ||
229 | void ieee80211_sta_debugfs_remove(struct sta_info *sta) | 344 | void ieee80211_sta_debugfs_remove(struct sta_info *sta) |
@@ -238,6 +353,7 @@ void ieee80211_sta_debugfs_remove(struct sta_info *sta) | |||
238 | DEBUGFS_DEL(wme_rx_queue); | 353 | DEBUGFS_DEL(wme_rx_queue); |
239 | DEBUGFS_DEL(wme_tx_queue); | 354 | DEBUGFS_DEL(wme_tx_queue); |
240 | #endif | 355 | #endif |
356 | DEBUGFS_DEL(agg_status); | ||
241 | 357 | ||
242 | debugfs_remove(sta->debugfs.dir); | 358 | debugfs_remove(sta->debugfs.dir); |
243 | sta->debugfs.dir = NULL; | 359 | sta->debugfs.dir = NULL; |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 48a620a4e1a6..75573dc79d7a 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -192,6 +192,7 @@ struct sta_info { | |||
192 | struct dentry *wme_rx_queue; | 192 | struct dentry *wme_rx_queue; |
193 | struct dentry *wme_tx_queue; | 193 | struct dentry *wme_tx_queue; |
194 | #endif | 194 | #endif |
195 | struct dentry *agg_status; | ||
195 | } debugfs; | 196 | } debugfs; |
196 | #endif | 197 | #endif |
197 | }; | 198 | }; |