11ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez/*
21ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez * cfg80211 debugfs
31ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez *
41ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez * Copyright 2009	Luis R. Rodriguez <lrodriguez@atheros.com>
51ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez * Copyright 2007	Johannes Berg <johannes@sipsolutions.net>
61ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez *
71ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez * This program is free software; you can redistribute it and/or modify
81ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez * it under the terms of the GNU General Public License version 2 as
91ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez * published by the Free Software Foundation.
101ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez */
111ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez
125a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
131ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez#include "core.h"
141ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez#include "debugfs.h"
151ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez
161ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...)		\
171ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguezstatic ssize_t name## _read(struct file *file, char __user *userbuf,	\
181ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez			    size_t count, loff_t *ppos)			\
191ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez{									\
201ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez	struct wiphy *wiphy= file->private_data;		\
211ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez	char buf[buflen];						\
221ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez	int res;							\
231ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez									\
241ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez	res = scnprintf(buf, buflen, fmt "\n", ##value);		\
251ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez	return simple_read_from_buffer(userbuf, count, ppos, buf, res);	\
261ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez}									\
271ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez									\
281ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguezstatic const struct file_operations name## _ops = {			\
291ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez	.read = name## _read,						\
30234e340582901211f40d8c732afc49f0630ecf05Stephen Boyd	.open = simple_open,						\
312b18ab36cf7e956fb5b5ee12847e94fc66d496f4Arnd Bergmann	.llseek = generic_file_llseek,					\
321ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez};
331ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez
341ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. RodriguezDEBUGFS_READONLY_FILE(rts_threshold, 20, "%d",
351ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez		      wiphy->rts_threshold)
361ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. RodriguezDEBUGFS_READONLY_FILE(fragmentation_threshold, 20, "%d",
371ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez		      wiphy->frag_threshold);
381ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. RodriguezDEBUGFS_READONLY_FILE(short_retry_limit, 20, "%d",
391ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez		      wiphy->retry_short)
401ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. RodriguezDEBUGFS_READONLY_FILE(long_retry_limit, 20, "%d",
411ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez		      wiphy->retry_long);
421ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez
4380a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguezstatic int ht_print_chan(struct ieee80211_channel *chan,
4480a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez			 char *buf, int buf_size, int offset)
4580a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez{
4680a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez	if (WARN_ON(offset > buf_size))
4780a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez		return 0;
4880a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez
4980a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez	if (chan->flags & IEEE80211_CHAN_DISABLED)
50f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller		return scnprintf(buf + offset,
51f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller				 buf_size - offset,
52f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller				 "%d Disabled\n",
53f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller				 chan->center_freq);
5480a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez
55f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller	return scnprintf(buf + offset,
56f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller			 buf_size - offset,
57f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller			 "%d HT40 %c%c\n",
58f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller			 chan->center_freq,
59f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller			 (chan->flags & IEEE80211_CHAN_NO_HT40MINUS) ?
60f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller				' ' : '-',
61f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller			 (chan->flags & IEEE80211_CHAN_NO_HT40PLUS) ?
62f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller				' ' : '+');
6380a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez}
6480a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez
6580a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguezstatic ssize_t ht40allow_map_read(struct file *file,
6680a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez				  char __user *user_buf,
6780a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez				  size_t count, loff_t *ppos)
6880a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez{
6980a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez	struct wiphy *wiphy = file->private_data;
7080a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez	char *buf;
7180a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez	unsigned int offset = 0, buf_size = PAGE_SIZE, i, r;
7280a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez	enum ieee80211_band band;
7380a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez	struct ieee80211_supported_band *sband;
7480a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez
7580a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez	buf = kzalloc(buf_size, GFP_KERNEL);
7680a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez	if (!buf)
7780a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez		return -ENOMEM;
7880a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez
795fe231e873729fa2f57cdc417d5c1f80871e2d7dJohannes Berg	rtnl_lock();
8080a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez
8180a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
8280a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez		sband = wiphy->bands[band];
8380a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez		if (!sband)
8480a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez			continue;
8580a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez		for (i = 0; i < sband->n_channels; i++)
8680a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez			offset += ht_print_chan(&sband->channels[i],
8780a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez						buf, buf_size, offset);
8880a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez	}
8980a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez
905fe231e873729fa2f57cdc417d5c1f80871e2d7dJohannes Berg	rtnl_unlock();
9180a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez
9280a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez	r = simple_read_from_buffer(user_buf, count, ppos, buf, offset);
9380a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez
9480a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez	kfree(buf);
9580a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez
9680a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez	return r;
9780a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez}
9880a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez
9980a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguezstatic const struct file_operations ht40allow_map_ops = {
10080a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez	.read = ht40allow_map_read,
101234e340582901211f40d8c732afc49f0630ecf05Stephen Boyd	.open = simple_open,
1026038f373a3dc1f1c26496e60b6c40b164716f07eArnd Bergmann	.llseek = default_llseek,
10380a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez};
10480a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez
1051ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez#define DEBUGFS_ADD(name)						\
1067bcfaf2f431c09c51fe776fc06638b25d3b421c5Johannes Berg	debugfs_create_file(#name, S_IRUGO, phyd, &rdev->wiphy, &name## _ops);
1071ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez
10879c97e97aed7f760d2826c7daf2d42d8eefe9838Johannes Bergvoid cfg80211_debugfs_rdev_add(struct cfg80211_registered_device *rdev)
1091ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez{
11079c97e97aed7f760d2826c7daf2d42d8eefe9838Johannes Berg	struct dentry *phyd = rdev->wiphy.debugfsdir;
1111ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez
1121ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez	DEBUGFS_ADD(rts_threshold);
1131ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez	DEBUGFS_ADD(fragmentation_threshold);
1141ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez	DEBUGFS_ADD(short_retry_limit);
1151ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez	DEBUGFS_ADD(long_retry_limit);
11680a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez	DEBUGFS_ADD(ht40allow_map);
1171ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez}
118