Blame view

net/mac80211/debugfs_netdev.c 20.5 KB
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
1
2
3
4
5
6
7
8
9
10
11
12
  /*
   * Copyright (c) 2006	Jiri Benc <jbenc@suse.cz>
   * Copyright 2007	Johannes Berg <johannes@sipsolutions.net>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
   */
  
  #include <linux/kernel.h>
  #include <linux/device.h>
  #include <linux/if.h>
28656a111   Johannes Berg   mac80211: use mac...
13
  #include <linux/if_ether.h>
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
14
15
16
  #include <linux/interrupt.h>
  #include <linux/netdevice.h>
  #include <linux/rtnetlink.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
17
  #include <linux/slab.h>
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
18
19
20
21
  #include <linux/notifier.h>
  #include <net/mac80211.h>
  #include <net/cfg80211.h>
  #include "ieee80211_i.h"
2c8dccc77   Johannes Berg   mac80211: rename ...
22
  #include "rate.h"
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
23
24
  #include "debugfs.h"
  #include "debugfs_netdev.h"
37a41b4af   Eliad Peller   mac80211: add iee...
25
  #include "driver-ops.h"
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
26
27
28
29
30
31
32
33
34
35
36
  
  static ssize_t ieee80211_if_read(
  	struct ieee80211_sub_if_data *sdata,
  	char __user *userbuf,
  	size_t count, loff_t *ppos,
  	ssize_t (*format)(const struct ieee80211_sub_if_data *, char *, int))
  {
  	char buf[70];
  	ssize_t ret = -EINVAL;
  
  	read_lock(&dev_base_lock);
73bb3e4a7   Luis Carlos Cobo   mac80211: fix dea...
37
  	if (sdata->dev->reg_state == NETREG_REGISTERED)
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
38
  		ret = (*format)(sdata, buf, sizeof(buf));
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
39
  	read_unlock(&dev_base_lock);
73bb3e4a7   Luis Carlos Cobo   mac80211: fix dea...
40

681d11904   Jouni Malinen   mac80211: Add tes...
41
  	if (ret >= 0)
73bb3e4a7   Luis Carlos Cobo   mac80211: fix dea...
42
  		ret = simple_read_from_buffer(userbuf, count, ppos, buf, ret);
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
43
44
  	return ret;
  }
0f78231bf   Johannes Berg   mac80211: enable ...
45
46
47
48
49
50
  static ssize_t ieee80211_if_write(
  	struct ieee80211_sub_if_data *sdata,
  	const char __user *userbuf,
  	size_t count, loff_t *ppos,
  	ssize_t (*write)(struct ieee80211_sub_if_data *, const char *, int))
  {
ada577c12   Eliad Peller   mac80211: add NUL...
51
  	char buf[64];
51f5f8ca4   Eric Dumazet   mac80211: Fix mem...
52
  	ssize_t ret;
0f78231bf   Johannes Berg   mac80211: enable ...
53

ada577c12   Eliad Peller   mac80211: add NUL...
54
55
  	if (count >= sizeof(buf))
  		return -E2BIG;
0f78231bf   Johannes Berg   mac80211: enable ...
56
57
  
  	if (copy_from_user(buf, userbuf, count))
ada577c12   Eliad Peller   mac80211: add NUL...
58
59
  		return -EFAULT;
  	buf[count] = '\0';
0f78231bf   Johannes Berg   mac80211: enable ...
60

51f5f8ca4   Eric Dumazet   mac80211: Fix mem...
61
  	ret = -ENODEV;
0f78231bf   Johannes Berg   mac80211: enable ...
62
63
64
65
66
67
68
  	rtnl_lock();
  	if (sdata->dev->reg_state == NETREG_REGISTERED)
  		ret = (*write)(sdata, buf, count);
  	rtnl_unlock();
  
  	return ret;
  }
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
69
70
71
72
73
74
75
76
77
78
79
80
81
  #define IEEE80211_IF_FMT(name, field, format_string)			\
  static ssize_t ieee80211_if_fmt_##name(					\
  	const struct ieee80211_sub_if_data *sdata, char *buf,		\
  	int buflen)							\
  {									\
  	return scnprintf(buf, buflen, format_string, sdata->field);	\
  }
  #define IEEE80211_IF_FMT_DEC(name, field)				\
  		IEEE80211_IF_FMT(name, field, "%d
  ")
  #define IEEE80211_IF_FMT_HEX(name, field)				\
  		IEEE80211_IF_FMT(name, field, "%#x
  ")
4914b3bb7   Ben Greear   mac80211: Add sda...
82
83
84
  #define IEEE80211_IF_FMT_LHEX(name, field)				\
  		IEEE80211_IF_FMT(name, field, "%#lx
  ")
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
85
86
87
  #define IEEE80211_IF_FMT_SIZE(name, field)				\
  		IEEE80211_IF_FMT(name, field, "%zd
  ")
19468413e   Simon Wunderlich   mac80211: add sup...
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
  #define IEEE80211_IF_FMT_HEXARRAY(name, field)				\
  static ssize_t ieee80211_if_fmt_##name(					\
  	const struct ieee80211_sub_if_data *sdata,			\
  	char *buf, int buflen)						\
  {									\
  	char *p = buf;							\
  	int i;								\
  	for (i = 0; i < sizeof(sdata->field); i++) {			\
  		p += scnprintf(p, buflen + buf - p, "%.2x ",		\
  				 sdata->field[i]);			\
  	}								\
  	p += scnprintf(p, buflen + buf - p, "
  ");			\
  	return p - buf;							\
  }
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
103
104
105
106
107
108
109
110
111
112
113
114
115
116
  #define IEEE80211_IF_FMT_ATOMIC(name, field)				\
  static ssize_t ieee80211_if_fmt_##name(					\
  	const struct ieee80211_sub_if_data *sdata,			\
  	char *buf, int buflen)						\
  {									\
  	return scnprintf(buf, buflen, "%d
  ", atomic_read(&sdata->field));\
  }
  
  #define IEEE80211_IF_FMT_MAC(name, field)				\
  static ssize_t ieee80211_if_fmt_##name(					\
  	const struct ieee80211_sub_if_data *sdata, char *buf,		\
  	int buflen)							\
  {									\
0c68ae260   Johannes Berg   mac80211: convert...
117
118
  	return scnprintf(buf, buflen, "%pM
  ", sdata->field);		\
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
119
  }
17e4ec147   Jouni Malinen   mac80211: Track B...
120
121
122
123
124
125
126
127
  #define IEEE80211_IF_FMT_DEC_DIV_16(name, field)			\
  static ssize_t ieee80211_if_fmt_##name(					\
  	const struct ieee80211_sub_if_data *sdata,			\
  	char *buf, int buflen)						\
  {									\
  	return scnprintf(buf, buflen, "%d
  ", sdata->field / 16);	\
  }
78e443e4c   Ben Greear   mac80211: add bea...
128
129
130
131
132
133
134
135
136
  #define IEEE80211_IF_FMT_JIFFIES_TO_MS(name, field)			\
  static ssize_t ieee80211_if_fmt_##name(					\
  	const struct ieee80211_sub_if_data *sdata,			\
  	char *buf, int buflen)						\
  {									\
  	return scnprintf(buf, buflen, "%d
  ",				\
  			 jiffies_to_msecs(sdata->field));		\
  }
0f78231bf   Johannes Berg   mac80211: enable ...
137
  #define __IEEE80211_IF_FILE(name, _write)				\
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
138
139
140
141
142
143
144
145
146
147
  static ssize_t ieee80211_if_read_##name(struct file *file,		\
  					char __user *userbuf,		\
  					size_t count, loff_t *ppos)	\
  {									\
  	return ieee80211_if_read(file->private_data,			\
  				 userbuf, count, ppos,			\
  				 ieee80211_if_fmt_##name);		\
  }									\
  static const struct file_operations name##_ops = {			\
  	.read = ieee80211_if_read_##name,				\
0f78231bf   Johannes Berg   mac80211: enable ...
148
  	.write = (_write),						\
234e34058   Stephen Boyd   simple_open: auto...
149
  	.open = simple_open,						\
2b18ab36c   Arnd Bergmann   net/wireless: use...
150
  	.llseek = generic_file_llseek,					\
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
151
  }
0f78231bf   Johannes Berg   mac80211: enable ...
152
153
154
155
156
157
158
159
160
  #define __IEEE80211_IF_FILE_W(name)					\
  static ssize_t ieee80211_if_write_##name(struct file *file,		\
  					 const char __user *userbuf,	\
  					 size_t count, loff_t *ppos)	\
  {									\
  	return ieee80211_if_write(file->private_data, userbuf, count,	\
  				  ppos, ieee80211_if_parse_##name);	\
  }									\
  __IEEE80211_IF_FILE(name, ieee80211_if_write_##name)
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
161
162
  #define IEEE80211_IF_FILE(name, field, format)				\
  		IEEE80211_IF_FMT_##format(name, field)			\
0f78231bf   Johannes Berg   mac80211: enable ...
163
  		__IEEE80211_IF_FILE(name, NULL)
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
164
165
  
  /* common attributes */
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
166
  IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC);
37eb0b164   Jouni Malinen   cfg80211/mac80211...
167
168
169
170
  IEEE80211_IF_FILE(rc_rateidx_mask_2ghz, rc_rateidx_mask[IEEE80211_BAND_2GHZ],
  		  HEX);
  IEEE80211_IF_FILE(rc_rateidx_mask_5ghz, rc_rateidx_mask[IEEE80211_BAND_5GHZ],
  		  HEX);
19468413e   Simon Wunderlich   mac80211: add sup...
171
172
173
174
  IEEE80211_IF_FILE(rc_rateidx_mcs_mask_2ghz,
  		  rc_rateidx_mcs_mask[IEEE80211_BAND_2GHZ], HEXARRAY);
  IEEE80211_IF_FILE(rc_rateidx_mcs_mask_5ghz,
  		  rc_rateidx_mcs_mask[IEEE80211_BAND_5GHZ], HEXARRAY);
4914b3bb7   Ben Greear   mac80211: Add sda...
175
176
  IEEE80211_IF_FILE(flags, flags, HEX);
  IEEE80211_IF_FILE(state, state, LHEX);
1ea6f9c0d   Johannes Berg   mac80211: handle ...
177
178
179
  IEEE80211_IF_FILE(txpower, vif.bss_conf.txpower, DEC);
  IEEE80211_IF_FILE(ap_power_level, ap_power_level, DEC);
  IEEE80211_IF_FILE(user_power_level, user_power_level, DEC);
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
180

08643315e   Johannes Berg   mac80211: add deb...
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
  static ssize_t
  ieee80211_if_fmt_hw_queues(const struct ieee80211_sub_if_data *sdata,
  			   char *buf, int buflen)
  {
  	int len;
  
  	len = scnprintf(buf, buflen, "AC queues: VO:%d VI:%d BE:%d BK:%d
  ",
  			sdata->vif.hw_queue[IEEE80211_AC_VO],
  			sdata->vif.hw_queue[IEEE80211_AC_VI],
  			sdata->vif.hw_queue[IEEE80211_AC_BE],
  			sdata->vif.hw_queue[IEEE80211_AC_BK]);
  
  	if (sdata->vif.type == NL80211_IFTYPE_AP)
  		len += scnprintf(buf + len, buflen - len, "cab queue: %d
  ",
  				 sdata->vif.cab_queue);
  
  	return len;
  }
  __IEEE80211_IF_FILE(hw_queues, NULL);
469002983   Johannes Berg   mac80211: split I...
202
  /* STA attributes */
469002983   Johannes Berg   mac80211: split I...
203
  IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC);
469002983   Johannes Berg   mac80211: split I...
204
  IEEE80211_IF_FILE(aid, u.mgd.aid, DEC);
17e4ec147   Jouni Malinen   mac80211: Track B...
205
206
  IEEE80211_IF_FILE(last_beacon, u.mgd.last_beacon_signal, DEC);
  IEEE80211_IF_FILE(ave_beacon, u.mgd.ave_beacon_signal, DEC_DIV_16);
78e443e4c   Ben Greear   mac80211: add bea...
207
  IEEE80211_IF_FILE(beacon_timeout, u.mgd.beacon_timeout, JIFFIES_TO_MS);
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
208

0f78231bf   Johannes Berg   mac80211: enable ...
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
  static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata,
  			      enum ieee80211_smps_mode smps_mode)
  {
  	struct ieee80211_local *local = sdata->local;
  	int err;
  
  	if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_STATIC_SMPS) &&
  	    smps_mode == IEEE80211_SMPS_STATIC)
  		return -EINVAL;
  
  	/* auto should be dynamic if in PS mode */
  	if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS) &&
  	    (smps_mode == IEEE80211_SMPS_DYNAMIC ||
  	     smps_mode == IEEE80211_SMPS_AUTOMATIC))
  		return -EINVAL;
  
  	/* supported only on managed interfaces for now */
  	if (sdata->vif.type != NL80211_IFTYPE_STATION)
  		return -EOPNOTSUPP;
243e6df4e   Johannes Berg   mac80211: fix SMP...
228
  	mutex_lock(&sdata->u.mgd.mtx);
0f78231bf   Johannes Berg   mac80211: enable ...
229
  	err = __ieee80211_request_smps(sdata, smps_mode);
243e6df4e   Johannes Berg   mac80211: fix SMP...
230
  	mutex_unlock(&sdata->u.mgd.mtx);
0f78231bf   Johannes Berg   mac80211: enable ...
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
  
  	return err;
  }
  
  static const char *smps_modes[IEEE80211_SMPS_NUM_MODES] = {
  	[IEEE80211_SMPS_AUTOMATIC] = "auto",
  	[IEEE80211_SMPS_OFF] = "off",
  	[IEEE80211_SMPS_STATIC] = "static",
  	[IEEE80211_SMPS_DYNAMIC] = "dynamic",
  };
  
  static ssize_t ieee80211_if_fmt_smps(const struct ieee80211_sub_if_data *sdata,
  				     char *buf, int buflen)
  {
  	if (sdata->vif.type != NL80211_IFTYPE_STATION)
  		return -EOPNOTSUPP;
  
  	return snprintf(buf, buflen, "request: %s
  used: %s
  ",
  			smps_modes[sdata->u.mgd.req_smps],
04ecd2578   Johannes Berg   mac80211: track n...
252
  			smps_modes[sdata->smps_mode]);
0f78231bf   Johannes Berg   mac80211: enable ...
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
  }
  
  static ssize_t ieee80211_if_parse_smps(struct ieee80211_sub_if_data *sdata,
  				       const char *buf, int buflen)
  {
  	enum ieee80211_smps_mode mode;
  
  	for (mode = 0; mode < IEEE80211_SMPS_NUM_MODES; mode++) {
  		if (strncmp(buf, smps_modes[mode], buflen) == 0) {
  			int err = ieee80211_set_smps(sdata, mode);
  			if (!err)
  				return buflen;
  			return err;
  		}
  	}
  
  	return -EINVAL;
  }
  
  __IEEE80211_IF_FILE_W(smps);
681d11904   Jouni Malinen   mac80211: Add tes...
273
274
275
276
277
  static ssize_t ieee80211_if_fmt_tkip_mic_test(
  	const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
  {
  	return -EOPNOTSUPP;
  }
681d11904   Jouni Malinen   mac80211: Add tes...
278
279
280
281
282
283
284
285
  static ssize_t ieee80211_if_parse_tkip_mic_test(
  	struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
  {
  	struct ieee80211_local *local = sdata->local;
  	u8 addr[ETH_ALEN];
  	struct sk_buff *skb;
  	struct ieee80211_hdr *hdr;
  	__le16 fc;
28656a111   Johannes Berg   mac80211: use mac...
286
  	if (!mac_pton(buf, addr))
681d11904   Jouni Malinen   mac80211: Add tes...
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
  		return -EINVAL;
  
  	if (!ieee80211_sdata_running(sdata))
  		return -ENOTCONN;
  
  	skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24 + 100);
  	if (!skb)
  		return -ENOMEM;
  	skb_reserve(skb, local->hw.extra_tx_headroom);
  
  	hdr = (struct ieee80211_hdr *) skb_put(skb, 24);
  	memset(hdr, 0, 24);
  	fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA);
  
  	switch (sdata->vif.type) {
  	case NL80211_IFTYPE_AP:
  		fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
  		/* DA BSSID SA */
  		memcpy(hdr->addr1, addr, ETH_ALEN);
  		memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
  		memcpy(hdr->addr3, sdata->vif.addr, ETH_ALEN);
  		break;
  	case NL80211_IFTYPE_STATION:
  		fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
  		/* BSSID SA DA */
41c97a203   Johannes Berg   mac80211: fix rac...
312
313
314
  		mutex_lock(&sdata->u.mgd.mtx);
  		if (!sdata->u.mgd.associated) {
  			mutex_unlock(&sdata->u.mgd.mtx);
681d11904   Jouni Malinen   mac80211: Add tes...
315
316
317
  			dev_kfree_skb(skb);
  			return -ENOTCONN;
  		}
41c97a203   Johannes Berg   mac80211: fix rac...
318
  		memcpy(hdr->addr1, sdata->u.mgd.associated->bssid, ETH_ALEN);
681d11904   Jouni Malinen   mac80211: Add tes...
319
320
  		memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
  		memcpy(hdr->addr3, addr, ETH_ALEN);
41c97a203   Johannes Berg   mac80211: fix rac...
321
  		mutex_unlock(&sdata->u.mgd.mtx);
681d11904   Jouni Malinen   mac80211: Add tes...
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
  		break;
  	default:
  		dev_kfree_skb(skb);
  		return -EOPNOTSUPP;
  	}
  	hdr->frame_control = fc;
  
  	/*
  	 * Add some length to the test frame to make it look bit more valid.
  	 * The exact contents does not matter since the recipient is required
  	 * to drop this because of the Michael MIC failure.
  	 */
  	memset(skb_put(skb, 50), 0, 50);
  
  	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_TKIP_MIC_FAILURE;
  
  	ieee80211_tx_skb(sdata, skb);
  
  	return buflen;
  }
  
  __IEEE80211_IF_FILE_W(tkip_mic_test);
dc41e4d47   Eliad Peller   mac80211: make ua...
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
  static ssize_t ieee80211_if_fmt_uapsd_queues(
  	const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
  {
  	const struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
  
  	return snprintf(buf, buflen, "0x%x
  ", ifmgd->uapsd_queues);
  }
  
  static ssize_t ieee80211_if_parse_uapsd_queues(
  	struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
  {
  	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
  	u8 val;
  	int ret;
  
  	ret = kstrtou8(buf, 0, &val);
  	if (ret)
  		return ret;
  
  	if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
  		return -ERANGE;
  
  	ifmgd->uapsd_queues = val;
  
  	return buflen;
  }
  __IEEE80211_IF_FILE_W(uapsd_queues);
  
  static ssize_t ieee80211_if_fmt_uapsd_max_sp_len(
  	const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
  {
  	const struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
  
  	return snprintf(buf, buflen, "0x%x
  ", ifmgd->uapsd_max_sp_len);
  }
  
  static ssize_t ieee80211_if_parse_uapsd_max_sp_len(
  	struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
  {
  	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
  	unsigned long val;
  	int ret;
  
  	ret = kstrtoul(buf, 0, &val);
  	if (ret)
  		return -EINVAL;
  
  	if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
  		return -ERANGE;
  
  	ifmgd->uapsd_max_sp_len = val;
  
  	return buflen;
  }
  __IEEE80211_IF_FILE_W(uapsd_max_sp_len);
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
401
  /* AP attributes */
030ef8f8a   Felix Fietkau   mac80211: rename ...
402
  IEEE80211_IF_FILE(num_mcast_sta, u.ap.num_mcast_sta, ATOMIC);
d012a6051   Marco Porsch   mac80211: make cl...
403
404
  IEEE80211_IF_FILE(num_sta_ps, u.ap.ps.num_sta_ps, ATOMIC);
  IEEE80211_IF_FILE(dtim_count, u.ap.ps.dtim_count, DEC);
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
405
406
407
408
409
410
  
  static ssize_t ieee80211_if_fmt_num_buffered_multicast(
  	const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
  {
  	return scnprintf(buf, buflen, "%u
  ",
d012a6051   Marco Porsch   mac80211: make cl...
411
  			 skb_queue_len(&sdata->u.ap.ps.bc_buf));
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
412
  }
0f78231bf   Johannes Berg   mac80211: enable ...
413
  __IEEE80211_IF_FILE(num_buffered_multicast, NULL);
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
414

37a41b4af   Eliad Peller   mac80211: add iee...
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
  /* IBSS attributes */
  static ssize_t ieee80211_if_fmt_tsf(
  	const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
  {
  	struct ieee80211_local *local = sdata->local;
  	u64 tsf;
  
  	tsf = drv_get_tsf(local, (struct ieee80211_sub_if_data *)sdata);
  
  	return scnprintf(buf, buflen, "0x%016llx
  ", (unsigned long long) tsf);
  }
  
  static ssize_t ieee80211_if_parse_tsf(
  	struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
  {
  	struct ieee80211_local *local = sdata->local;
  	unsigned long long tsf;
  	int ret;
9bdd3a6bf   Javier Cardona   mac80211: Allow t...
434
  	int tsf_is_delta = 0;
37a41b4af   Eliad Peller   mac80211: add iee...
435
436
437
438
439
440
441
442
  
  	if (strncmp(buf, "reset", 5) == 0) {
  		if (local->ops->reset_tsf) {
  			drv_reset_tsf(local, sdata);
  			wiphy_info(local->hw.wiphy, "debugfs reset TSF
  ");
  		}
  	} else {
9bdd3a6bf   Javier Cardona   mac80211: Allow t...
443
444
445
446
447
448
449
450
451
  		if (buflen > 10 && buf[1] == '=') {
  			if (buf[0] == '+')
  				tsf_is_delta = 1;
  			else if (buf[0] == '-')
  				tsf_is_delta = -1;
  			else
  				return -EINVAL;
  			buf += 2;
  		}
37a41b4af   Eliad Peller   mac80211: add iee...
452
453
  		ret = kstrtoull(buf, 10, &tsf);
  		if (ret < 0)
6fc1da9b4   Johannes Berg   mac80211: use kst...
454
  			return ret;
9bdd3a6bf   Javier Cardona   mac80211: Allow t...
455
456
  		if (tsf_is_delta)
  			tsf = drv_get_tsf(local, sdata) + tsf_is_delta * tsf;
37a41b4af   Eliad Peller   mac80211: add iee...
457
458
459
460
461
462
463
464
465
466
467
  		if (local->ops->set_tsf) {
  			drv_set_tsf(local, sdata, tsf);
  			wiphy_info(local->hw.wiphy,
  				   "debugfs set TSF to %#018llx
  ", tsf);
  		}
  	}
  
  	return buflen;
  }
  __IEEE80211_IF_FILE_W(tsf);
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
468
469
  /* WDS attributes */
  IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC);
9f42f6070   Luis Carlos Cobo   mac80211: mesh st...
470
471
  #ifdef CONFIG_MAC80211_MESH
  /* Mesh stats attributes */
c8a61a7d3   Daniel Walker   mac80211: New sta...
472
473
  IEEE80211_IF_FILE(fwded_mcast, u.mesh.mshstats.fwded_mcast, DEC);
  IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC);
472dbc45d   Johannes Berg   mac80211: split o...
474
475
  IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC);
  IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC);
cfee66b0f   Javier Cardona   mac80211: Stop fo...
476
  IEEE80211_IF_FILE(dropped_frames_congestion,
a4f606ea7   Chun-Yeow Yeoh   {nl,cfg,mac}80211...
477
  		  u.mesh.mshstats.dropped_frames_congestion, DEC);
9f42f6070   Luis Carlos Cobo   mac80211: mesh st...
478
  IEEE80211_IF_FILE(dropped_frames_no_route,
a4f606ea7   Chun-Yeow Yeoh   {nl,cfg,mac}80211...
479
  		  u.mesh.mshstats.dropped_frames_no_route, DEC);
1258d9761   Ashok Nagarajan   mac80211: move ou...
480
  IEEE80211_IF_FILE(estab_plinks, u.mesh.estab_plinks, ATOMIC);
9f42f6070   Luis Carlos Cobo   mac80211: mesh st...
481
482
  
  /* Mesh parameters */
36ff382d0   Johannes Berg   mac80211: remove ...
483
  IEEE80211_IF_FILE(dot11MeshMaxRetries,
a4f606ea7   Chun-Yeow Yeoh   {nl,cfg,mac}80211...
484
  		  u.mesh.mshcfg.dot11MeshMaxRetries, DEC);
36ff382d0   Johannes Berg   mac80211: remove ...
485
  IEEE80211_IF_FILE(dot11MeshRetryTimeout,
a4f606ea7   Chun-Yeow Yeoh   {nl,cfg,mac}80211...
486
  		  u.mesh.mshcfg.dot11MeshRetryTimeout, DEC);
36ff382d0   Johannes Berg   mac80211: remove ...
487
  IEEE80211_IF_FILE(dot11MeshConfirmTimeout,
a4f606ea7   Chun-Yeow Yeoh   {nl,cfg,mac}80211...
488
  		  u.mesh.mshcfg.dot11MeshConfirmTimeout, DEC);
36ff382d0   Johannes Berg   mac80211: remove ...
489
  IEEE80211_IF_FILE(dot11MeshHoldingTimeout,
a4f606ea7   Chun-Yeow Yeoh   {nl,cfg,mac}80211...
490
  		  u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC);
36ff382d0   Johannes Berg   mac80211: remove ...
491
  IEEE80211_IF_FILE(dot11MeshTTL, u.mesh.mshcfg.dot11MeshTTL, DEC);
45904f216   Javier Cardona   nl80211/mac80211:...
492
  IEEE80211_IF_FILE(element_ttl, u.mesh.mshcfg.element_ttl, DEC);
36ff382d0   Johannes Berg   mac80211: remove ...
493
494
  IEEE80211_IF_FILE(auto_open_plinks, u.mesh.mshcfg.auto_open_plinks, DEC);
  IEEE80211_IF_FILE(dot11MeshMaxPeerLinks,
a4f606ea7   Chun-Yeow Yeoh   {nl,cfg,mac}80211...
495
  		  u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC);
36ff382d0   Johannes Berg   mac80211: remove ...
496
  IEEE80211_IF_FILE(dot11MeshHWMPactivePathTimeout,
a4f606ea7   Chun-Yeow Yeoh   {nl,cfg,mac}80211...
497
  		  u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC);
36ff382d0   Johannes Berg   mac80211: remove ...
498
  IEEE80211_IF_FILE(dot11MeshHWMPpreqMinInterval,
a4f606ea7   Chun-Yeow Yeoh   {nl,cfg,mac}80211...
499
  		  u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC);
dca7e9430   Thomas Pedersen   {nl,cfg,mac}80211...
500
  IEEE80211_IF_FILE(dot11MeshHWMPperrMinInterval,
a4f606ea7   Chun-Yeow Yeoh   {nl,cfg,mac}80211...
501
  		  u.mesh.mshcfg.dot11MeshHWMPperrMinInterval, DEC);
36ff382d0   Johannes Berg   mac80211: remove ...
502
  IEEE80211_IF_FILE(dot11MeshHWMPnetDiameterTraversalTime,
a4f606ea7   Chun-Yeow Yeoh   {nl,cfg,mac}80211...
503
  		  u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC);
36ff382d0   Johannes Berg   mac80211: remove ...
504
  IEEE80211_IF_FILE(dot11MeshHWMPmaxPREQretries,
a4f606ea7   Chun-Yeow Yeoh   {nl,cfg,mac}80211...
505
  		  u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries, DEC);
36ff382d0   Johannes Berg   mac80211: remove ...
506
  IEEE80211_IF_FILE(path_refresh_time,
a4f606ea7   Chun-Yeow Yeoh   {nl,cfg,mac}80211...
507
  		  u.mesh.mshcfg.path_refresh_time, DEC);
36ff382d0   Johannes Berg   mac80211: remove ...
508
  IEEE80211_IF_FILE(min_discovery_timeout,
a4f606ea7   Chun-Yeow Yeoh   {nl,cfg,mac}80211...
509
  		  u.mesh.mshcfg.min_discovery_timeout, DEC);
63c5723bc   Rui Paulo   mac80211: add nl8...
510
  IEEE80211_IF_FILE(dot11MeshHWMPRootMode,
a4f606ea7   Chun-Yeow Yeoh   {nl,cfg,mac}80211...
511
  		  u.mesh.mshcfg.dot11MeshHWMPRootMode, DEC);
16dd7267f   Javier Cardona   {nl,cfg,mac}80211...
512
  IEEE80211_IF_FILE(dot11MeshGateAnnouncementProtocol,
a4f606ea7   Chun-Yeow Yeoh   {nl,cfg,mac}80211...
513
  		  u.mesh.mshcfg.dot11MeshGateAnnouncementProtocol, DEC);
0507e159a   Javier Cardona   {nl,cfg,mac}80211...
514
  IEEE80211_IF_FILE(dot11MeshHWMPRannInterval,
a4f606ea7   Chun-Yeow Yeoh   {nl,cfg,mac}80211...
515
  		  u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC);
94f906564   Chun-Yeow Yeoh   {nl,cfg,mac}80211...
516
  IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC);
553351378   Ashok Nagarajan   {nl,cfg,mac}80211...
517
  IEEE80211_IF_FILE(rssi_threshold, u.mesh.mshcfg.rssi_threshold, DEC);
4416f5d2a   Ashok Nagarajan   mac80211: Add deb...
518
  IEEE80211_IF_FILE(ht_opmode, u.mesh.mshcfg.ht_opmode, DEC);
ac1073a61   Chun-Yeow Yeoh   {nl,cfg,mac}80211...
519
520
521
522
  IEEE80211_IF_FILE(dot11MeshHWMPactivePathToRootTimeout,
  		  u.mesh.mshcfg.dot11MeshHWMPactivePathToRootTimeout, DEC);
  IEEE80211_IF_FILE(dot11MeshHWMProotInterval,
  		  u.mesh.mshcfg.dot11MeshHWMProotInterval, DEC);
728b19e5f   Chun-Yeow Yeoh   {nl,cfg,mac}80211...
523
524
  IEEE80211_IF_FILE(dot11MeshHWMPconfirmationInterval,
  		  u.mesh.mshcfg.dot11MeshHWMPconfirmationInterval, DEC);
3f52b7e32   Marco Porsch   mac80211: mesh po...
525
526
527
  IEEE80211_IF_FILE(power_mode, u.mesh.mshcfg.power_mode, DEC);
  IEEE80211_IF_FILE(dot11MeshAwakeWindowDuration,
  		  u.mesh.mshcfg.dot11MeshAwakeWindowDuration, DEC);
9f42f6070   Luis Carlos Cobo   mac80211: mesh st...
528
  #endif
0f78231bf   Johannes Berg   mac80211: enable ...
529
  #define DEBUGFS_ADD_MODE(name, mode) \
ddbfe860a   Stanislaw Gruszka   mac80211: move sd...
530
  	debugfs_create_file(#name, mode, sdata->vif.debugfs_dir, \
0f78231bf   Johannes Berg   mac80211: enable ...
531
  			    sdata, &name##_ops);
fcb2c9e10   Felix Fietkau   mac80211: reduce ...
532
533
534
  #define DEBUGFS_ADD(name) DEBUGFS_ADD_MODE(name, 0400)
  
  static void add_common_files(struct ieee80211_sub_if_data *sdata)
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
535
  {
2d46d7c12   Johannes Berg   mac80211: remove ...
536
537
538
  	DEBUGFS_ADD(drop_unencrypted);
  	DEBUGFS_ADD(rc_rateidx_mask_2ghz);
  	DEBUGFS_ADD(rc_rateidx_mask_5ghz);
19468413e   Simon Wunderlich   mac80211: add sup...
539
540
  	DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz);
  	DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz);
08643315e   Johannes Berg   mac80211: add deb...
541
  	DEBUGFS_ADD(hw_queues);
fcb2c9e10   Felix Fietkau   mac80211: reduce ...
542
  }
3e122be08   Johannes Berg   mac80211: make ma...
543

fcb2c9e10   Felix Fietkau   mac80211: reduce ...
544
545
  static void add_sta_files(struct ieee80211_sub_if_data *sdata)
  {
2d46d7c12   Johannes Berg   mac80211: remove ...
546
547
  	DEBUGFS_ADD(bssid);
  	DEBUGFS_ADD(aid);
17e4ec147   Jouni Malinen   mac80211: Track B...
548
549
  	DEBUGFS_ADD(last_beacon);
  	DEBUGFS_ADD(ave_beacon);
78e443e4c   Ben Greear   mac80211: add bea...
550
  	DEBUGFS_ADD(beacon_timeout);
0f78231bf   Johannes Berg   mac80211: enable ...
551
  	DEBUGFS_ADD_MODE(smps, 0600);
681d11904   Jouni Malinen   mac80211: Add tes...
552
  	DEBUGFS_ADD_MODE(tkip_mic_test, 0200);
dc41e4d47   Eliad Peller   mac80211: make ua...
553
554
  	DEBUGFS_ADD_MODE(uapsd_queues, 0600);
  	DEBUGFS_ADD_MODE(uapsd_max_sp_len, 0600);
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
555
556
557
558
  }
  
  static void add_ap_files(struct ieee80211_sub_if_data *sdata)
  {
030ef8f8a   Felix Fietkau   mac80211: rename ...
559
  	DEBUGFS_ADD(num_mcast_sta);
2d46d7c12   Johannes Berg   mac80211: remove ...
560
561
562
  	DEBUGFS_ADD(num_sta_ps);
  	DEBUGFS_ADD(dtim_count);
  	DEBUGFS_ADD(num_buffered_multicast);
681d11904   Jouni Malinen   mac80211: Add tes...
563
  	DEBUGFS_ADD_MODE(tkip_mic_test, 0200);
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
564
  }
37a41b4af   Eliad Peller   mac80211: add iee...
565
566
567
568
  static void add_ibss_files(struct ieee80211_sub_if_data *sdata)
  {
  	DEBUGFS_ADD_MODE(tsf, 0600);
  }
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
569
570
  static void add_wds_files(struct ieee80211_sub_if_data *sdata)
  {
2d46d7c12   Johannes Berg   mac80211: remove ...
571
  	DEBUGFS_ADD(peer);
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
572
  }
9f42f6070   Luis Carlos Cobo   mac80211: mesh st...
573
  #ifdef CONFIG_MAC80211_MESH
9f42f6070   Luis Carlos Cobo   mac80211: mesh st...
574

12ce8ba3e   Javier Cardona   mac80211: Modify ...
575
576
577
578
  static void add_mesh_files(struct ieee80211_sub_if_data *sdata)
  {
  	DEBUGFS_ADD_MODE(tsf, 0600);
  }
9f42f6070   Luis Carlos Cobo   mac80211: mesh st...
579
580
  static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
  {
7bcfaf2f4   Johannes Berg   cfg80211/mac80211...
581
  	struct dentry *dir = debugfs_create_dir("mesh_stats",
ddbfe860a   Stanislaw Gruszka   mac80211: move sd...
582
  						sdata->vif.debugfs_dir);
7bcfaf2f4   Johannes Berg   cfg80211/mac80211...
583
584
  #define MESHSTATS_ADD(name)\
  	debugfs_create_file(#name, 0400, dir, sdata, &name##_ops);
c8a61a7d3   Daniel Walker   mac80211: New sta...
585
586
  	MESHSTATS_ADD(fwded_mcast);
  	MESHSTATS_ADD(fwded_unicast);
9f42f6070   Luis Carlos Cobo   mac80211: mesh st...
587
588
589
  	MESHSTATS_ADD(fwded_frames);
  	MESHSTATS_ADD(dropped_frames_ttl);
  	MESHSTATS_ADD(dropped_frames_no_route);
cfee66b0f   Javier Cardona   mac80211: Stop fo...
590
  	MESHSTATS_ADD(dropped_frames_congestion);
9f42f6070   Luis Carlos Cobo   mac80211: mesh st...
591
  	MESHSTATS_ADD(estab_plinks);
7bcfaf2f4   Johannes Berg   cfg80211/mac80211...
592
  #undef MESHSTATS_ADD
9f42f6070   Luis Carlos Cobo   mac80211: mesh st...
593
  }
9f42f6070   Luis Carlos Cobo   mac80211: mesh st...
594
595
  static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
  {
7bcfaf2f4   Johannes Berg   cfg80211/mac80211...
596
  	struct dentry *dir = debugfs_create_dir("mesh_config",
ddbfe860a   Stanislaw Gruszka   mac80211: move sd...
597
  						sdata->vif.debugfs_dir);
7bcfaf2f4   Johannes Berg   cfg80211/mac80211...
598
599
600
  
  #define MESHPARAMS_ADD(name) \
  	debugfs_create_file(#name, 0600, dir, sdata, &name##_ops);
9f42f6070   Luis Carlos Cobo   mac80211: mesh st...
601
602
603
604
605
  	MESHPARAMS_ADD(dot11MeshMaxRetries);
  	MESHPARAMS_ADD(dot11MeshRetryTimeout);
  	MESHPARAMS_ADD(dot11MeshConfirmTimeout);
  	MESHPARAMS_ADD(dot11MeshHoldingTimeout);
  	MESHPARAMS_ADD(dot11MeshTTL);
45904f216   Javier Cardona   nl80211/mac80211:...
606
  	MESHPARAMS_ADD(element_ttl);
9f42f6070   Luis Carlos Cobo   mac80211: mesh st...
607
608
609
610
  	MESHPARAMS_ADD(auto_open_plinks);
  	MESHPARAMS_ADD(dot11MeshMaxPeerLinks);
  	MESHPARAMS_ADD(dot11MeshHWMPactivePathTimeout);
  	MESHPARAMS_ADD(dot11MeshHWMPpreqMinInterval);
dca7e9430   Thomas Pedersen   {nl,cfg,mac}80211...
611
  	MESHPARAMS_ADD(dot11MeshHWMPperrMinInterval);
9f42f6070   Luis Carlos Cobo   mac80211: mesh st...
612
613
614
615
  	MESHPARAMS_ADD(dot11MeshHWMPnetDiameterTraversalTime);
  	MESHPARAMS_ADD(dot11MeshHWMPmaxPREQretries);
  	MESHPARAMS_ADD(path_refresh_time);
  	MESHPARAMS_ADD(min_discovery_timeout);
699403dbd   Javier Cardona   {nl,mac}80211: ad...
616
  	MESHPARAMS_ADD(dot11MeshHWMPRootMode);
0507e159a   Javier Cardona   {nl,cfg,mac}80211...
617
  	MESHPARAMS_ADD(dot11MeshHWMPRannInterval);
8c06e8c08   Chun-Yeow Yeoh   mac80211: Add mis...
618
  	MESHPARAMS_ADD(dot11MeshForwarding);
16dd7267f   Javier Cardona   {nl,cfg,mac}80211...
619
  	MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol);
553351378   Ashok Nagarajan   {nl,cfg,mac}80211...
620
  	MESHPARAMS_ADD(rssi_threshold);
4416f5d2a   Ashok Nagarajan   mac80211: Add deb...
621
  	MESHPARAMS_ADD(ht_opmode);
ac1073a61   Chun-Yeow Yeoh   {nl,cfg,mac}80211...
622
623
  	MESHPARAMS_ADD(dot11MeshHWMPactivePathToRootTimeout);
  	MESHPARAMS_ADD(dot11MeshHWMProotInterval);
728b19e5f   Chun-Yeow Yeoh   {nl,cfg,mac}80211...
624
  	MESHPARAMS_ADD(dot11MeshHWMPconfirmationInterval);
3f52b7e32   Marco Porsch   mac80211: mesh po...
625
626
  	MESHPARAMS_ADD(power_mode);
  	MESHPARAMS_ADD(dot11MeshAwakeWindowDuration);
7bcfaf2f4   Johannes Berg   cfg80211/mac80211...
627
  #undef MESHPARAMS_ADD
9f42f6070   Luis Carlos Cobo   mac80211: mesh st...
628
629
  }
  #endif
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
630
631
  static void add_files(struct ieee80211_sub_if_data *sdata)
  {
ddbfe860a   Stanislaw Gruszka   mac80211: move sd...
632
  	if (!sdata->vif.debugfs_dir)
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
633
  		return;
fcb2c9e10   Felix Fietkau   mac80211: reduce ...
634
635
  	DEBUGFS_ADD(flags);
  	DEBUGFS_ADD(state);
1ea6f9c0d   Johannes Berg   mac80211: handle ...
636
637
638
  	DEBUGFS_ADD(txpower);
  	DEBUGFS_ADD(user_power_level);
  	DEBUGFS_ADD(ap_power_level);
fcb2c9e10   Felix Fietkau   mac80211: reduce ...
639
640
641
  
  	if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
  		add_common_files(sdata);
51fb61e76   Johannes Berg   mac80211: move in...
642
  	switch (sdata->vif.type) {
05c914fe3   Johannes Berg   mac80211: use nl8...
643
  	case NL80211_IFTYPE_MESH_POINT:
9f42f6070   Luis Carlos Cobo   mac80211: mesh st...
644
  #ifdef CONFIG_MAC80211_MESH
12ce8ba3e   Javier Cardona   mac80211: Modify ...
645
  		add_mesh_files(sdata);
9f42f6070   Luis Carlos Cobo   mac80211: mesh st...
646
647
648
  		add_mesh_stats(sdata);
  		add_mesh_config(sdata);
  #endif
472dbc45d   Johannes Berg   mac80211: split o...
649
  		break;
05c914fe3   Johannes Berg   mac80211: use nl8...
650
  	case NL80211_IFTYPE_STATION:
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
651
652
  		add_sta_files(sdata);
  		break;
469002983   Johannes Berg   mac80211: split I...
653
  	case NL80211_IFTYPE_ADHOC:
37a41b4af   Eliad Peller   mac80211: add iee...
654
  		add_ibss_files(sdata);
469002983   Johannes Berg   mac80211: split I...
655
  		break;
05c914fe3   Johannes Berg   mac80211: use nl8...
656
  	case NL80211_IFTYPE_AP:
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
657
658
  		add_ap_files(sdata);
  		break;
05c914fe3   Johannes Berg   mac80211: use nl8...
659
  	case NL80211_IFTYPE_WDS:
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
660
661
  		add_wds_files(sdata);
  		break;
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
662
663
664
665
  	default:
  		break;
  	}
  }
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
666
667
668
  void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata)
  {
  	char buf[10+IFNAMSIZ];
47846c9b0   Johannes Berg   mac80211: reduce ...
669
  	sprintf(buf, "netdev:%s", sdata->name);
ddbfe860a   Stanislaw Gruszka   mac80211: move sd...
670
  	sdata->vif.debugfs_dir = debugfs_create_dir(buf,
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
671
  		sdata->local->hw.wiphy->debugfsdir);
ddbfe860a   Stanislaw Gruszka   mac80211: move sd...
672
  	if (sdata->vif.debugfs_dir)
295bafb47   Ben Greear   mac80211: Support...
673
  		sdata->debugfs.subdir_stations = debugfs_create_dir("stations",
ddbfe860a   Stanislaw Gruszka   mac80211: move sd...
674
  			sdata->vif.debugfs_dir);
75636525f   Johannes Berg   mac80211: revamp ...
675
  	add_files(sdata);
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
676
677
678
679
  }
  
  void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata)
  {
ddbfe860a   Stanislaw Gruszka   mac80211: move sd...
680
  	if (!sdata->vif.debugfs_dir)
7bcfaf2f4   Johannes Berg   cfg80211/mac80211...
681
  		return;
ddbfe860a   Stanislaw Gruszka   mac80211: move sd...
682
683
  	debugfs_remove_recursive(sdata->vif.debugfs_dir);
  	sdata->vif.debugfs_dir = NULL;
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
684
  }
47846c9b0   Johannes Berg   mac80211: reduce ...
685
  void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata)
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
686
  {
7c8081eb8   Johannes Berg   [PATCH] mac80211:...
687
  	struct dentry *dir;
47846c9b0   Johannes Berg   mac80211: reduce ...
688
  	char buf[10 + IFNAMSIZ];
3e122be08   Johannes Berg   mac80211: make ma...
689

ddbfe860a   Stanislaw Gruszka   mac80211: move sd...
690
  	dir = sdata->vif.debugfs_dir;
c74e90a9e   Johannes Berg   mac80211: fix deb...
691
692
  
  	if (!dir)
47846c9b0   Johannes Berg   mac80211: reduce ...
693
  		return;
c74e90a9e   Johannes Berg   mac80211: fix deb...
694

47846c9b0   Johannes Berg   mac80211: reduce ...
695
  	sprintf(buf, "netdev:%s", sdata->name);
7c8081eb8   Johannes Berg   [PATCH] mac80211:...
696
  	if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf))
bdcbd8e0e   Johannes Berg   mac80211: clean u...
697
698
699
700
  		sdata_err(sdata,
  			  "debugfs: failed to rename debugfs dir to %s
  ",
  			  buf);
e9f207f0f   Jiri Benc   [MAC80211]: Add d...
701
  }