[go: nahoru, domu]

1c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez/*
2c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez * Intel Wireless WiMAX Connection 2400m
3c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez * Debugfs interfaces to manipulate driver and device information
4c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez *
5c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez *
6c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez * Copyright (C) 2007 Intel Corporation <linux-wimax@intel.com>
7c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
8c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez *
9c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez * This program is free software; you can redistribute it and/or
10c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez * modify it under the terms of the GNU General Public License version
11c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez * 2 as published by the Free Software Foundation.
12c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez *
13c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez * This program is distributed in the hope that it will be useful,
14c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez * but WITHOUT ANY WARRANTY; without even the implied warranty of
15c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez * GNU General Public License for more details.
17c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez *
18c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez * You should have received a copy of the GNU General Public License
19c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez * along with this program; if not, write to the Free Software
20c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez * 02110-1301, USA.
22c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez */
23c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
24c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez#include <linux/debugfs.h>
25c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez#include <linux/netdevice.h>
26c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez#include <linux/etherdevice.h>
27c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez#include <linux/spinlock.h>
28c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez#include <linux/device.h>
29ee40fa0656a730491765545ff7550f3c1ceb0fbcPaul Gortmaker#include <linux/export.h>
30c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez#include "i2400m.h"
31c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
32c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
33c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez#define D_SUBMODULE debugfs
34c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez#include "debug-levels.h"
35c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
36c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezstatic
37c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezint debugfs_netdev_queue_stopped_get(void *data, u64 *val)
38c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez{
39c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	struct i2400m *i2400m = data;
40c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	*val = netif_queue_stopped(i2400m->wimax_dev.net_dev);
41c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	return 0;
42c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez}
43c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-GonzalezDEFINE_SIMPLE_ATTRIBUTE(fops_netdev_queue_stopped,
44c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez			debugfs_netdev_queue_stopped_get,
45c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez			NULL, "%llu\n");
46c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
47c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
48c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezstatic
49c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezstruct dentry *debugfs_create_netdev_queue_stopped(
50c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	const char *name, struct dentry *parent, struct i2400m *i2400m)
51c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez{
52c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	return debugfs_create_file(name, 0400, parent, i2400m,
53c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez				   &fops_netdev_queue_stopped);
54c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez}
55c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
56c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez/*
57c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez * We don't allow partial reads of this file, as then the reader would
58c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez * get weirdly confused data as it is updated.
59c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez *
60c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez * So or you read it all or nothing; if you try to read with an offset
61c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez * != 0, we consider you are done reading.
62c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez */
63c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezstatic
64c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezssize_t i2400m_rx_stats_read(struct file *filp, char __user *buffer,
65c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez			     size_t count, loff_t *ppos)
66c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez{
67c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	struct i2400m *i2400m = filp->private_data;
68c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	char buf[128];
69c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	unsigned long flags;
70c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
71c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	if (*ppos != 0)
72c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		return 0;
73c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	if (count < sizeof(buf))
74c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		return -ENOSPC;
75c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	spin_lock_irqsave(&i2400m->rx_lock, flags);
76c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	snprintf(buf, sizeof(buf), "%u %u %u %u %u %u %u\n",
77c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		 i2400m->rx_pl_num, i2400m->rx_pl_min,
78c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		 i2400m->rx_pl_max, i2400m->rx_num,
79c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		 i2400m->rx_size_acc,
80c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		 i2400m->rx_size_min, i2400m->rx_size_max);
81c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	spin_unlock_irqrestore(&i2400m->rx_lock, flags);
82c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	return simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf));
83c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez}
84c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
85c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
86c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez/* Any write clears the stats */
87c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezstatic
88c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezssize_t i2400m_rx_stats_write(struct file *filp, const char __user *buffer,
89c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez			      size_t count, loff_t *ppos)
90c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez{
91c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	struct i2400m *i2400m = filp->private_data;
92c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	unsigned long flags;
93c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
94c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	spin_lock_irqsave(&i2400m->rx_lock, flags);
95c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	i2400m->rx_pl_num = 0;
96c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	i2400m->rx_pl_max = 0;
97c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	i2400m->rx_pl_min = UINT_MAX;
98c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	i2400m->rx_num = 0;
99c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	i2400m->rx_size_acc = 0;
100c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	i2400m->rx_size_min = UINT_MAX;
101c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	i2400m->rx_size_max = 0;
102c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	spin_unlock_irqrestore(&i2400m->rx_lock, flags);
103c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	return count;
104c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez}
105c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
106c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezstatic
107c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezconst struct file_operations i2400m_rx_stats_fops = {
108c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	.owner =	THIS_MODULE,
109234e340582901211f40d8c732afc49f0630ecf05Stephen Boyd	.open =		simple_open,
110c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	.read =		i2400m_rx_stats_read,
111c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	.write =	i2400m_rx_stats_write,
1126038f373a3dc1f1c26496e60b6c40b164716f07eArnd Bergmann	.llseek =	default_llseek,
113c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez};
114c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
115c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
116c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez/* See i2400m_rx_stats_read() */
117c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezstatic
118c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezssize_t i2400m_tx_stats_read(struct file *filp, char __user *buffer,
119c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez			     size_t count, loff_t *ppos)
120c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez{
121c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	struct i2400m *i2400m = filp->private_data;
122c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	char buf[128];
123c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	unsigned long flags;
124c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
125c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	if (*ppos != 0)
126c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		return 0;
127c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	if (count < sizeof(buf))
128c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		return -ENOSPC;
129c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	spin_lock_irqsave(&i2400m->tx_lock, flags);
130c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	snprintf(buf, sizeof(buf), "%u %u %u %u %u %u %u\n",
131c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		 i2400m->tx_pl_num, i2400m->tx_pl_min,
132c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		 i2400m->tx_pl_max, i2400m->tx_num,
133c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		 i2400m->tx_size_acc,
134c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		 i2400m->tx_size_min, i2400m->tx_size_max);
135c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	spin_unlock_irqrestore(&i2400m->tx_lock, flags);
136c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	return simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf));
137c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez}
138c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
139c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez/* Any write clears the stats */
140c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezstatic
141c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezssize_t i2400m_tx_stats_write(struct file *filp, const char __user *buffer,
142c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez			      size_t count, loff_t *ppos)
143c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez{
144c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	struct i2400m *i2400m = filp->private_data;
145c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	unsigned long flags;
146c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
147c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	spin_lock_irqsave(&i2400m->tx_lock, flags);
148c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	i2400m->tx_pl_num = 0;
149c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	i2400m->tx_pl_max = 0;
150c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	i2400m->tx_pl_min = UINT_MAX;
151c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	i2400m->tx_num = 0;
152c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	i2400m->tx_size_acc = 0;
153c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	i2400m->tx_size_min = UINT_MAX;
154c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	i2400m->tx_size_max = 0;
155c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	spin_unlock_irqrestore(&i2400m->tx_lock, flags);
156c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	return count;
157c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez}
158c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
159c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezstatic
160c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezconst struct file_operations i2400m_tx_stats_fops = {
161c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	.owner =	THIS_MODULE,
162234e340582901211f40d8c732afc49f0630ecf05Stephen Boyd	.open =		simple_open,
163c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	.read =		i2400m_tx_stats_read,
164c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	.write =	i2400m_tx_stats_write,
1656038f373a3dc1f1c26496e60b6c40b164716f07eArnd Bergmann	.llseek =	default_llseek,
166c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez};
167c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
168c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
169c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez/* Write 1 to ask the device to go into suspend */
170c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezstatic
171c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezint debugfs_i2400m_suspend_set(void *data, u64 val)
172c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez{
173c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	int result;
174c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	struct i2400m *i2400m = data;
175c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	result = i2400m_cmd_enter_powersave(i2400m);
176c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	if (result >= 0)
177c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		result = 0;
178c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	return result;
179c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez}
180c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-GonzalezDEFINE_SIMPLE_ATTRIBUTE(fops_i2400m_suspend,
181c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez			NULL, debugfs_i2400m_suspend_set,
182c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez			"%llu\n");
183c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
184c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezstatic
185c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezstruct dentry *debugfs_create_i2400m_suspend(
186c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	const char *name, struct dentry *parent, struct i2400m *i2400m)
187c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez{
188c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	return debugfs_create_file(name, 0200, parent, i2400m,
189c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez				   &fops_i2400m_suspend);
190c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez}
191c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
192c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
193c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez/*
194c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez * Reset the device
195c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez *
196c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez * Write 0 to ask the device to soft reset, 1 to cold reset, 2 to bus
197c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez * reset (as defined by enum i2400m_reset_type).
198c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez */
199c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezstatic
200c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezint debugfs_i2400m_reset_set(void *data, u64 val)
201c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez{
202c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	int result;
203c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	struct i2400m *i2400m = data;
204c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	enum i2400m_reset_type rt = val;
205c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	switch(rt) {
206c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	case I2400M_RT_WARM:
207c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	case I2400M_RT_COLD:
208c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	case I2400M_RT_BUS:
209c931ceeb780560ff652a8f9875f88778439ee87eInaky Perez-Gonzalez		result = i2400m_reset(i2400m, rt);
210c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		if (result >= 0)
211c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez			result = 0;
21201872c641f8bb25b6d70328177c8fb08e0dd6d0bAlan Cox		break;
213c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	default:
214c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		result = -EINVAL;
215c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	}
216c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	return result;
217c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez}
218c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-GonzalezDEFINE_SIMPLE_ATTRIBUTE(fops_i2400m_reset,
219c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez			NULL, debugfs_i2400m_reset_set,
220c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez			"%llu\n");
221c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
222c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezstatic
223c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezstruct dentry *debugfs_create_i2400m_reset(
224c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	const char *name, struct dentry *parent, struct i2400m *i2400m)
225c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez{
226c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	return debugfs_create_file(name, 0200, parent, i2400m,
227c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez				   &fops_i2400m_reset);
228c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez}
229c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
230c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
231c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez#define __debugfs_register(prefix, name, parent)			\
232c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezdo {									\
233c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	result = d_level_register_debugfs(prefix, name, parent);	\
234c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	if (result < 0)							\
235c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		goto error;						\
236c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez} while (0)
237c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
238c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
239c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezint i2400m_debugfs_add(struct i2400m *i2400m)
240c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez{
241c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	int result;
242c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	struct device *dev = i2400m_dev(i2400m);
243c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	struct dentry *dentry = i2400m->wimax_dev.debugfs_dentry;
244c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	struct dentry *fd;
245c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
246c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	dentry = debugfs_create_dir("i2400m", dentry);
247c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	result = PTR_ERR(dentry);
248c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	if (IS_ERR(dentry)) {
249c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		if (result == -ENODEV)
250c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez			result = 0;	/* No debugfs support */
251c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		goto error;
252c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	}
253c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	i2400m->debugfs_dentry = dentry;
254c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	__debugfs_register("dl_", control, dentry);
255c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	__debugfs_register("dl_", driver, dentry);
256c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	__debugfs_register("dl_", debugfs, dentry);
257c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	__debugfs_register("dl_", fw, dentry);
258c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	__debugfs_register("dl_", netdev, dentry);
259c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	__debugfs_register("dl_", rfkill, dentry);
260c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	__debugfs_register("dl_", rx, dentry);
261c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	__debugfs_register("dl_", tx, dentry);
262c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
263c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	fd = debugfs_create_size_t("tx_in", 0400, dentry,
264c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez				   &i2400m->tx_in);
265c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	result = PTR_ERR(fd);
266c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	if (IS_ERR(fd) && result != -ENODEV) {
267c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		dev_err(dev, "Can't create debugfs entry "
268c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez			"tx_in: %d\n", result);
269c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		goto error;
270c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	}
271c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
272c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	fd = debugfs_create_size_t("tx_out", 0400, dentry,
273c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez				   &i2400m->tx_out);
274c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	result = PTR_ERR(fd);
275c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	if (IS_ERR(fd) && result != -ENODEV) {
276c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		dev_err(dev, "Can't create debugfs entry "
277c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez			"tx_out: %d\n", result);
278c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		goto error;
279c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	}
280c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
281c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	fd = debugfs_create_u32("state", 0600, dentry,
282c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez				&i2400m->state);
283c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	result = PTR_ERR(fd);
284c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	if (IS_ERR(fd) && result != -ENODEV) {
285c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		dev_err(dev, "Can't create debugfs entry "
286c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez			"state: %d\n", result);
287c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		goto error;
288c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	}
289c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
290c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	/*
291c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	 * Trace received messages from user space
292c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	 *
293c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	 * In order to tap the bidirectional message stream in the
294c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	 * 'msg' pipe, user space can read from the 'msg' pipe;
295c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	 * however, due to limitations in libnl, we can't know what
296c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	 * the different applications are sending down to the kernel.
297c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	 *
298c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	 * So we have this hack where the driver will echo any message
299c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	 * received on the msg pipe from user space [through a call to
300c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	 * wimax_dev->op_msg_from_user() into
301c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	 * i2400m_op_msg_from_user()] into the 'trace' pipe that this
302c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	 * driver creates.
303c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	 *
304c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	 * So then, reading from both the 'trace' and 'msg' pipes in
305c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	 * user space will provide a full dump of the traffic.
306c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	 *
307c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	 * Write 1 to activate, 0 to clear.
308c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	 *
309c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	 * It is not really very atomic, but it is also not too
310c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	 * critical.
311c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	 */
312c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	fd = debugfs_create_u8("trace_msg_from_user", 0600, dentry,
313c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez			       &i2400m->trace_msg_from_user);
314c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	result = PTR_ERR(fd);
315c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	if (IS_ERR(fd) && result != -ENODEV) {
316c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		dev_err(dev, "Can't create debugfs entry "
317c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez			"trace_msg_from_user: %d\n", result);
318c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		goto error;
319c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	}
320c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
321c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	fd = debugfs_create_netdev_queue_stopped("netdev_queue_stopped",
322c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez						 dentry, i2400m);
323c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	result = PTR_ERR(fd);
324c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	if (IS_ERR(fd) && result != -ENODEV) {
325c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		dev_err(dev, "Can't create debugfs entry "
326c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez			"netdev_queue_stopped: %d\n", result);
327c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		goto error;
328c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	}
329c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
330c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	fd = debugfs_create_file("rx_stats", 0600, dentry, i2400m,
331c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez				 &i2400m_rx_stats_fops);
332c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	result = PTR_ERR(fd);
333c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	if (IS_ERR(fd) && result != -ENODEV) {
334c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		dev_err(dev, "Can't create debugfs entry "
335c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez			"rx_stats: %d\n", result);
336c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		goto error;
337c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	}
338c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
339c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	fd = debugfs_create_file("tx_stats", 0600, dentry, i2400m,
340c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez				 &i2400m_tx_stats_fops);
341c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	result = PTR_ERR(fd);
342c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	if (IS_ERR(fd) && result != -ENODEV) {
343c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		dev_err(dev, "Can't create debugfs entry "
344c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez			"tx_stats: %d\n", result);
345c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		goto error;
346c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	}
347c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
348c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	fd = debugfs_create_i2400m_suspend("suspend", dentry, i2400m);
349c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	result = PTR_ERR(fd);
350c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	if (IS_ERR(fd) && result != -ENODEV) {
351c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		dev_err(dev, "Can't create debugfs entry suspend: %d\n",
352c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez			result);
353c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		goto error;
354c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	}
355c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
356c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	fd = debugfs_create_i2400m_reset("reset", dentry, i2400m);
357c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	result = PTR_ERR(fd);
358c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	if (IS_ERR(fd) && result != -ENODEV) {
359c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		dev_err(dev, "Can't create debugfs entry reset: %d\n", result);
360c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez		goto error;
361c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	}
362c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
363c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	result = 0;
364c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezerror:
365c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	return result;
366c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez}
367c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez
368c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalezvoid i2400m_debugfs_rm(struct i2400m *i2400m)
369c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez{
370c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez	debugfs_remove_recursive(i2400m->debugfs_dentry);
371c71228caf91ec6320b489dec5cd0087b64da9fb5Inaky Perez-Gonzalez}
372