2
* Copyright 2003-2005 Devicescape Software, Inc.
3
* Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
4
* Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License version 2 as
8
* published by the Free Software Foundation.
11
#include <linux/debugfs.h>
12
#include <linux/ieee80211.h>
13
#include "ieee80211_i.h"
15
#include "debugfs_sta.h"
20
#define STA_READ(name, buflen, field, format_string) \
21
static ssize_t sta_ ##name## _read(struct file *file, \
22
char __user *userbuf, \
23
size_t count, loff_t *ppos) \
26
struct sta_info *sta = file->private_data; \
28
res = scnprintf(buf, buflen, format_string, sta->field); \
29
return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
31
#define STA_READ_D(name, field) STA_READ(name, 20, field, "%d\n")
32
#define STA_READ_U(name, field) STA_READ(name, 20, field, "%u\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")
36
#define STA_READ_RATE(name, field) \
37
static ssize_t sta_##name##_read(struct file *file, \
38
char __user *userbuf, \
39
size_t count, loff_t *ppos) \
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; \
45
int res = scnprintf(buf, sizeof(buf), "%d\n", \
47
sta->field < mode->num_rates) ? \
48
mode->rates[sta->field].rate : -1); \
49
return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
52
#define STA_OPS(name) \
53
static const struct file_operations sta_ ##name## _ops = { \
54
.read = sta_##name##_read, \
55
.open = mac80211_open_file_generic, \
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, \
65
#define STA_FILE(name, field, format) \
66
STA_READ_##format(name, field) \
69
STA_FILE(aid, aid, D);
70
STA_FILE(key_idx_compression, key_idx_compression, D);
71
STA_FILE(dev, dev->name, S);
72
STA_FILE(vlan_id, vlan_id, D);
73
STA_FILE(rx_packets, rx_packets, LU);
74
STA_FILE(tx_packets, tx_packets, LU);
75
STA_FILE(rx_bytes, rx_bytes, LU);
76
STA_FILE(tx_bytes, tx_bytes, LU);
77
STA_FILE(rx_duplicates, num_duplicates, LU);
78
STA_FILE(rx_fragments, rx_fragments, LU);
79
STA_FILE(rx_dropped, rx_dropped, LU);
80
STA_FILE(tx_fragments, tx_fragments, LU);
81
STA_FILE(tx_filtered, tx_filtered_count, LU);
82
STA_FILE(txrate, txrate, RATE);
83
STA_FILE(last_txrate, last_txrate, RATE);
84
STA_FILE(tx_retry_failed, tx_retry_failed, LU);
85
STA_FILE(tx_retry_count, tx_retry_count, LU);
86
STA_FILE(last_rssi, last_rssi, D);
87
STA_FILE(last_signal, last_signal, D);
88
STA_FILE(last_noise, last_noise, D);
89
STA_FILE(channel_use, channel_use, D);
90
STA_FILE(wep_weak_iv_count, wep_weak_iv_count, D);
92
static ssize_t sta_flags_read(struct file *file, char __user *userbuf,
93
size_t count, loff_t *ppos)
96
struct sta_info *sta = file->private_data;
97
int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s%s",
98
sta->flags & WLAN_STA_AUTH ? "AUTH\n" : "",
99
sta->flags & WLAN_STA_ASSOC ? "ASSOC\n" : "",
100
sta->flags & WLAN_STA_PS ? "PS\n" : "",
101
sta->flags & WLAN_STA_TIM ? "TIM\n" : "",
102
sta->flags & WLAN_STA_PERM ? "PERM\n" : "",
103
sta->flags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "",
104
sta->flags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "",
105
sta->flags & WLAN_STA_WME ? "WME\n" : "",
106
sta->flags & WLAN_STA_HT ? "HT\n" : "",
107
sta->flags & WLAN_STA_WDS ? "WDS\n" : "");
108
return simple_read_from_buffer(userbuf, count, ppos, buf, res);
112
static ssize_t sta_num_ps_buf_frames_read(struct file *file,
113
char __user *userbuf,
114
size_t count, loff_t *ppos)
117
struct sta_info *sta = file->private_data;
118
int res = scnprintf(buf, sizeof(buf), "%u\n",
119
skb_queue_len(&sta->ps_tx_buf));
120
return simple_read_from_buffer(userbuf, count, ppos, buf, res);
122
STA_OPS(num_ps_buf_frames);
124
static ssize_t sta_last_ack_rssi_read(struct file *file, char __user *userbuf,
125
size_t count, loff_t *ppos)
128
struct sta_info *sta = file->private_data;
129
int res = scnprintf(buf, sizeof(buf), "%d %d %d\n",
130
sta->last_ack_rssi[0],
131
sta->last_ack_rssi[1],
132
sta->last_ack_rssi[2]);
133
return simple_read_from_buffer(userbuf, count, ppos, buf, res);
135
STA_OPS(last_ack_rssi);
137
static ssize_t sta_last_ack_ms_read(struct file *file, char __user *userbuf,
138
size_t count, loff_t *ppos)
141
struct sta_info *sta = file->private_data;
142
int res = scnprintf(buf, sizeof(buf), "%d\n",
144
jiffies_to_msecs(jiffies - sta->last_ack) : -1);
145
return simple_read_from_buffer(userbuf, count, ppos, buf, res);
147
STA_OPS(last_ack_ms);
149
static ssize_t sta_inactive_ms_read(struct file *file, char __user *userbuf,
150
size_t count, loff_t *ppos)
153
struct sta_info *sta = file->private_data;
154
int res = scnprintf(buf, sizeof(buf), "%d\n",
155
jiffies_to_msecs(jiffies - sta->last_rx));
156
return simple_read_from_buffer(userbuf, count, ppos, buf, res);
158
STA_OPS(inactive_ms);
160
static ssize_t sta_last_seq_ctrl_read(struct file *file, char __user *userbuf,
161
size_t count, loff_t *ppos)
163
char buf[15*NUM_RX_DATA_QUEUES], *p = buf;
165
struct sta_info *sta = file->private_data;
166
for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
167
p += scnprintf(p, sizeof(buf)+buf-p, "%x ",
168
le16_to_cpu(sta->last_seq_ctrl[i]));
169
p += scnprintf(p, sizeof(buf)+buf-p, "\n");
170
return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
172
STA_OPS(last_seq_ctrl);
174
#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
175
static ssize_t sta_wme_rx_queue_read(struct file *file, char __user *userbuf,
176
size_t count, loff_t *ppos)
178
char buf[15*NUM_RX_DATA_QUEUES], *p = buf;
180
struct sta_info *sta = file->private_data;
181
for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
182
p += scnprintf(p, sizeof(buf)+buf-p, "%u ",
183
sta->wme_rx_queue[i]);
184
p += scnprintf(p, sizeof(buf)+buf-p, "\n");
185
return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
187
STA_OPS(wme_rx_queue);
189
static ssize_t sta_wme_tx_queue_read(struct file *file, char __user *userbuf,
190
size_t count, loff_t *ppos)
192
char buf[15*NUM_TX_DATA_QUEUES], *p = buf;
194
struct sta_info *sta = file->private_data;
195
for (i = 0; i < NUM_TX_DATA_QUEUES; i++)
196
p += scnprintf(p, sizeof(buf)+buf-p, "%u ",
197
sta->wme_tx_queue[i]);
198
p += scnprintf(p, sizeof(buf)+buf-p, "\n");
199
return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
201
STA_OPS(wme_tx_queue);
204
static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
205
size_t count, loff_t *ppos)
207
char buf[768], *p = buf;
209
struct sta_info *sta = file->private_data;
210
p += scnprintf(p, sizeof(buf)+buf-p, "Aggregation state for this STA is:\n");
211
p += scnprintf(p, sizeof(buf)+buf-p, " STA next dialog_token is %d \n TIDs info is: \n TID :",
212
(sta->ht_ba_mlme.dialog_token_allocator + 1));
213
for (i=0;i < STA_TID_NUM;i++)
214
p += scnprintf(p, sizeof(buf)+buf-p, "%5d",i);
216
p += scnprintf(p, sizeof(buf)+buf-p, "\n RX :");
217
for (i=0;i < STA_TID_NUM;i++)
218
p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
219
sta->ht_ba_mlme.tid_agg_info_rx[i].state);
221
p += scnprintf(p, sizeof(buf)+buf-p, "\n DTKN:");
222
for (i=0;i < STA_TID_NUM;i++)
223
p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
224
sta->ht_ba_mlme.tid_agg_info_rx[i].dialog_token);
226
p += scnprintf(p, sizeof(buf)+buf-p, "\n TX :");
227
for (i=0;i < STA_TID_NUM;i++)
228
p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
229
sta->ht_ba_mlme.tid_agg_info_tx[i].state);
231
p += scnprintf(p, sizeof(buf)+buf-p, "\n DTKN:");
232
for (i=0;i < STA_TID_NUM;i++)
233
p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
234
sta->ht_ba_mlme.tid_agg_info_tx[i].dialog_token);
236
p += scnprintf(p, sizeof(buf)+buf-p, "\n SSEQ:");
237
for (i=0;i < STA_TID_NUM;i++)
238
p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
239
sta->ht_ba_mlme.tid_agg_info_tx[i].start_seq_num);
241
p += scnprintf(p, sizeof(buf)+buf-p, "\n");
243
return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
246
static ssize_t sta_agg_status_write(struct file *file,const char __user *user_buf, size_t count, loff_t *ppos)
248
struct sta_info *sta = file->private_data;
249
struct net_device *dev = sta->dev;
250
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
251
struct ieee80211_hw *hw = &local->hw;
253
static int tid_static_tx[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
254
static int tid_static_rx[16]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
258
unsigned int tid_num;
261
memset(buf, 0x00, sizeof(buf));
262
buf_size = min(count, (sizeof(buf)-1));
263
if (copy_from_user(buf, user_buf, buf_size))
266
tid_num = simple_strtoul(buf, &endp, 0);
270
if ((tid_num >= 100) && (tid_num <= 115)) { /* toggle Rx aggregation command */
271
tid_num = tid_num - 100;
272
if(tid_static_rx[tid_num] == 1) {
273
strcpy(state,"off ");
274
ieee80211_sta_stop_rx_BA_session(dev,da,tid_num,0,WLAN_REASON_QSTA_REQUIRE_SETUP);
275
sta->ht_ba_mlme.tid_agg_info_rx[tid_num].buf_size = 0xFF;
276
tid_static_rx[tid_num] = 0;
279
sta->ht_ba_mlme.tid_agg_info_rx[tid_num].buf_size = 0x00;
280
tid_static_rx[tid_num] = 1;
282
printk(KERN_ERR "sta_agg_status_write tried switching tid=%u %s\n",tid_num,state);
284
else if ((tid_num >= 0) && (tid_num <= 15)) { /* toggle Tx aggregation command */
285
if(tid_static_tx[tid_num] == 0) {
287
rs = iwlwifi_ieee80211_start_BA_session(hw, da, tid_num);
289
tid_static_tx[tid_num] = 1;
292
rs = iwlwifi_ieee80211_stop_BA_session(hw, da, tid_num);
293
/* if (rs==0) hack to enable toggeling*/
294
tid_static_tx[tid_num] = 0;
296
printk(KERN_ERR "sta_agg_status_write tried switching tid=%u %s, return=%d\n",tid_num,state,rs);
301
STA_OPS_WR(agg_status);
304
#define DEBUGFS_ADD(name) \
305
sta->debugfs.name = debugfs_create_file(#name, 0444, \
306
sta->debugfs.dir, sta, &sta_ ##name## _ops);
308
#define DEBUGFS_DEL(name) \
309
debugfs_remove(sta->debugfs.name);\
310
sta->debugfs.name = NULL;
313
void ieee80211_sta_debugfs_add(struct sta_info *sta)
316
struct dentry *stations_dir = sta->local->debugfs.stations;
321
sprintf(buf, MAC_FMT, MAC_ARG(sta->addr));
323
sta->debugfs.dir = debugfs_create_dir(buf, stations_dir);
324
if (!sta->debugfs.dir)
328
DEBUGFS_ADD(num_ps_buf_frames);
329
DEBUGFS_ADD(last_ack_rssi);
330
DEBUGFS_ADD(last_ack_ms);
331
DEBUGFS_ADD(inactive_ms);
332
DEBUGFS_ADD(last_seq_ctrl);
333
#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
334
DEBUGFS_ADD(wme_rx_queue);
335
DEBUGFS_ADD(wme_tx_queue);
337
DEBUGFS_ADD(agg_status);
340
void ieee80211_sta_debugfs_remove(struct sta_info *sta)
343
DEBUGFS_DEL(num_ps_buf_frames);
344
DEBUGFS_DEL(last_ack_rssi);
345
DEBUGFS_DEL(last_ack_ms);
346
DEBUGFS_DEL(inactive_ms);
347
DEBUGFS_DEL(last_seq_ctrl);
348
#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
349
DEBUGFS_DEL(wme_rx_queue);
350
DEBUGFS_DEL(wme_tx_queue);
352
DEBUGFS_DEL(agg_status);
354
debugfs_remove(sta->debugfs.dir);
355
sta->debugfs.dir = NULL;