1fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby/*
2be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf * Copyright (c) 2007-2008 Bruno Randolf <bruno@thinktube.com>
3fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *
4fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *  This file is free software: you may copy, redistribute and/or modify it
5fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *  under the terms of the GNU General Public License as published by the
6fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *  Free Software Foundation, either version 2 of the License, or (at your
7fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *  option) any later version.
8fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *
9fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *  This file is distributed in the hope that it will be useful, but
10fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *  WITHOUT ANY WARRANTY; without even the implied warranty of
11fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *  General Public License for more details.
13fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *
14fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *  You should have received a copy of the GNU General Public License
15fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *
17fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *
18fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * This file incorporates work covered by the following copyright and
19fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * permission notice:
20fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *
21fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
22fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * Copyright (c) 2004-2005 Atheros Communications, Inc.
23fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * Copyright (c) 2006 Devicescape Software, Inc.
24fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
25fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
26fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *
27fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * All rights reserved.
28fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *
29fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * Redistribution and use in source and binary forms, with or without
30fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * modification, are permitted provided that the following conditions
31fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * are met:
32fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * 1. Redistributions of source code must retain the above copyright
33fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *    notice, this list of conditions and the following disclaimer,
34fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *    without modification.
35fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * 2. Redistributions in binary form must reproduce at minimum a disclaimer
36fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
37fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *    redistribution must be conditioned upon including a substantially
38fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *    similar Disclaimer requirement for further binary redistribution.
39fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * 3. Neither the names of the above-listed copyright holders nor the names
40fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *    of any contributors may be used to endorse or promote products derived
41fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *    from this software without specific prior written permission.
42fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *
43fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * Alternatively, this software may be distributed under the terms of the
44fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * GNU General Public License ("GPL") version 2 as published by the Free
45fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * Software Foundation.
46fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby *
47fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * NO WARRANTY
48fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
49fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
50fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
51fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
52fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
53fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
54fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
55fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
56fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
57fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
58fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby * THE POSSIBILITY OF SUCH DAMAGES.
59fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby */
60ee40fa0656a730491765545ff7550f3c1ceb0fbcPaul Gortmaker#include <linux/export.h>
616eb07caf1ac5723720caea2ee93cd11b7058a0aaPaul Gortmaker#include <linux/moduleparam.h>
62fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
63931be260ed54843edac37cb3ff09a40b86114b31Pavel Roskin#include <linux/seq_file.h>
64931be260ed54843edac37cb3ff09a40b86114b31Pavel Roskin#include <linux/list.h>
65c6e387a214f4b2c4bd48020409e366c133385d98Nick Kossifidis#include "debug.h"
66931be260ed54843edac37cb3ff09a40b86114b31Pavel Roskin#include "ath5k.h"
67931be260ed54843edac37cb3ff09a40b86114b31Pavel Roskin#include "reg.h"
68931be260ed54843edac37cb3ff09a40b86114b31Pavel Roskin#include "base.h"
69fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
70fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slabystatic unsigned int ath5k_debug;
71fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slabymodule_param_named(debug, ath5k_debug, uint, 0);
72fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
73fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
74fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby/* debugfs: registers */
75fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
76fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slabystruct reg {
772c91108c55477334f6854a587ec6e9111d8f1407Jiri Slaby	const char *name;
78fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	int addr;
79fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby};
80fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
81fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby#define REG_STRUCT_INIT(r) { #r, r }
82fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
83fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby/* just a few random registers, might want to add more */
842c91108c55477334f6854a587ec6e9111d8f1407Jiri Slabystatic const struct reg regs[] = {
85fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_CR),
86fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_RXDP),
87fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_CFG),
88fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_IER),
89fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_BCR),
90fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_RTSD0),
91fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_RTSD1),
92fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_TXCFG),
93fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_RXCFG),
94fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_RXJLA),
95fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_MIBC),
96fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_TOPS),
97fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_RXNOFRM),
98fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_TXNOFRM),
99fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_RPGTO),
100fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_RFCNT),
101fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_MISC),
102fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_QCUDCU_CLKGT),
103fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_ISR),
104fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_PISR),
105fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_SISR0),
106fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_SISR1),
107fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_SISR2),
108fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_SISR3),
109fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_SISR4),
110fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_IMR),
111fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_PIMR),
112fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_SIMR0),
113fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_SIMR1),
114fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_SIMR2),
115fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_SIMR3),
116fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_SIMR4),
117fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_DCM_ADDR),
118fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_DCCFG),
119fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_CCFG),
120fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_CPC0),
121fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_CPC1),
122fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_CPC2),
123fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_CPC3),
1240bacdf303f72a3ed34252934114bc04e79222687Nick Kossifidis	REG_STRUCT_INIT(AR5K_CPCOVF),
125fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_RESET_CTL),
126fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_SLEEP_CTL),
127fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_INTPEND),
128fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_SFR),
129fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_PCICFG),
130fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_GPIOCR),
131fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_GPIODO),
132fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	REG_STRUCT_INIT(AR5K_SREV),
133fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby};
134fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
135fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slabystatic void *reg_start(struct seq_file *seq, loff_t *pos)
136fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby{
1372c91108c55477334f6854a587ec6e9111d8f1407Jiri Slaby	return *pos < ARRAY_SIZE(regs) ? (void *)&regs[*pos] : NULL;
138fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby}
139fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
140fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slabystatic void reg_stop(struct seq_file *seq, void *p)
141fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby{
142fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	/* nothing to do */
143fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby}
144fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
145fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slabystatic void *reg_next(struct seq_file *seq, void *p, loff_t *pos)
146fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby{
147fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	++*pos;
1482c91108c55477334f6854a587ec6e9111d8f1407Jiri Slaby	return *pos < ARRAY_SIZE(regs) ? (void *)&regs[*pos] : NULL;
149fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby}
150fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
151fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slabystatic int reg_show(struct seq_file *seq, void *p)
152fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby{
153e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	struct ath5k_hw *ah = seq->private;
154fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	struct reg *r = p;
155fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	seq_printf(seq, "%-25s0x%08x\n", r->name,
156e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		ath5k_hw_reg_read(ah, r->addr));
157fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	return 0;
158fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby}
159fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
1604101dec9ca64d40f0d673f0a40ba46ba2c60e117Jan Engelhardtstatic const struct seq_operations register_seq_ops = {
161fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	.start = reg_start,
162fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	.next  = reg_next,
163fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	.stop  = reg_stop,
164fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	.show  = reg_show
165fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby};
166fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
167fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slabystatic int open_file_registers(struct inode *inode, struct file *file)
168fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby{
169fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	struct seq_file *s;
170fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	int res;
171fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	res = seq_open(file, &register_seq_ops);
172fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	if (res == 0) {
173fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby		s = file->private_data;
174fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby		s->private = inode->i_private;
175fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	}
176fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	return res;
177fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby}
178fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
179fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slabystatic const struct file_operations fops_registers = {
180fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	.open = open_file_registers,
181fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	.read    = seq_read,
182fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	.llseek  = seq_lseek,
183fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	.release = seq_release,
184fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	.owner = THIS_MODULE,
185fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby};
186fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
187fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
188fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby/* debugfs: beacons */
189fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
190fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slabystatic ssize_t read_file_beacon(struct file *file, char __user *user_buf,
191fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby				   size_t count, loff_t *ppos)
192fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby{
193e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	struct ath5k_hw *ah = file->private_data;
194be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	char buf[500];
195be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	unsigned int len = 0;
196fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	unsigned int v;
197fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	u64 tsf;
198fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
199e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	v = ath5k_hw_reg_read(ah, AR5K_BEACON);
200e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
201fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby		"%-24s0x%08x\tintval: %d\tTIM: 0x%x\n",
202fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby		"AR5K_BEACON", v, v & AR5K_BEACON_PERIOD,
203fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby		(v & AR5K_BEACON_TIM) >> AR5K_BEACON_TIM_S);
204fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
205e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\n",
206e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		"AR5K_LAST_TSTP", ath5k_hw_reg_read(ah, AR5K_LAST_TSTP));
207fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
208e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\n\n",
209e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		"AR5K_BEACON_CNT", ath5k_hw_reg_read(ah, AR5K_BEACON_CNT));
210fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
211e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	v = ath5k_hw_reg_read(ah, AR5K_TIMER0);
212e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\tTU: %08x\n",
213fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby		"AR5K_TIMER0 (TBTT)", v, v);
214fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
215e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	v = ath5k_hw_reg_read(ah, AR5K_TIMER1);
216e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\tTU: %08x\n",
217fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby		"AR5K_TIMER1 (DMA)", v, v >> 3);
218fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
219e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	v = ath5k_hw_reg_read(ah, AR5K_TIMER2);
220e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\tTU: %08x\n",
221fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby		"AR5K_TIMER2 (SWBA)", v, v >> 3);
222fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
223e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	v = ath5k_hw_reg_read(ah, AR5K_TIMER3);
224e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\tTU: %08x\n",
225fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby		"AR5K_TIMER3 (ATIM)", v, v);
226fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
227e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	tsf = ath5k_hw_get_tsf64(ah);
228e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
229f868f4e196177ee96f77304ab707a0ad5ddd6fe4John W. Linville		"TSF\t\t0x%016llx\tTU: %08x\n",
230f868f4e196177ee96f77304ab707a0ad5ddd6fe4John W. Linville		(unsigned long long)tsf, TSF_TO_TU(tsf));
231fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
2322189d13f6cfc58627a01d6a91591e59a2fa62902Dan Carpenter	if (len > sizeof(buf))
2332189d13f6cfc58627a01d6a91591e59a2fa62902Dan Carpenter		len = sizeof(buf);
2342189d13f6cfc58627a01d6a91591e59a2fa62902Dan Carpenter
235fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
236fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby}
237fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
238fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slabystatic ssize_t write_file_beacon(struct file *file,
239fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby				 const char __user *userbuf,
240fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby				 size_t count, loff_t *ppos)
241fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby{
242e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	struct ath5k_hw *ah = file->private_data;
243be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	char buf[20];
244fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
245be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
246be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf		return -EFAULT;
247be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf
248be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	if (strncmp(buf, "disable", 7) == 0) {
249fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby		AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
250fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby		printk(KERN_INFO "debugfs disable beacons\n");
251be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	} else if (strncmp(buf, "enable", 6) == 0) {
252fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby		AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
253fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby		printk(KERN_INFO "debugfs enable beacons\n");
254fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	}
255fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	return count;
256fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby}
257fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
258fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slabystatic const struct file_operations fops_beacon = {
259fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	.read = read_file_beacon,
260fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	.write = write_file_beacon,
261234e340582901211f40d8c732afc49f0630ecf05Stephen Boyd	.open = simple_open,
262fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	.owner = THIS_MODULE,
2636038f373a3dc1f1c26496e60b6c40b164716f07eArnd Bergmann	.llseek = default_llseek,
264fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby};
265fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
266fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
267fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby/* debugfs: reset */
268fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
269fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slabystatic ssize_t write_file_reset(struct file *file,
270fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby				 const char __user *userbuf,
271fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby				 size_t count, loff_t *ppos)
272fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby{
273e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	struct ath5k_hw *ah = file->private_data;
274e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "debug file triggered reset\n");
275e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	ieee80211_queue_work(ah->hw, &ah->reset_work);
276fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	return count;
277fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby}
278fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
279fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slabystatic const struct file_operations fops_reset = {
280fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	.write = write_file_reset,
281234e340582901211f40d8c732afc49f0630ecf05Stephen Boyd	.open = simple_open,
282fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	.owner = THIS_MODULE,
2836038f373a3dc1f1c26496e60b6c40b164716f07eArnd Bergmann	.llseek = noop_llseek,
284fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby};
285fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
286fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
287be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf/* debugfs: debug level */
288be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf
2892c91108c55477334f6854a587ec6e9111d8f1407Jiri Slabystatic const struct {
290be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	enum ath5k_debug_level level;
291be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	const char *name;
292be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	const char *desc;
293be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf} dbg_info[] = {
294be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	{ ATH5K_DEBUG_RESET,	"reset",	"reset and initialization" },
295be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	{ ATH5K_DEBUG_INTR,	"intr",		"interrupt handling" },
296be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	{ ATH5K_DEBUG_MODE,	"mode",		"mode init/setup" },
297be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	{ ATH5K_DEBUG_XMIT,	"xmit",		"basic xmit operation" },
298be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	{ ATH5K_DEBUG_BEACON,	"beacon",	"beacon handling" },
299be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	{ ATH5K_DEBUG_CALIBRATE, "calib",	"periodic calibration" },
300be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	{ ATH5K_DEBUG_TXPOWER,	"txpower",	"transmit power setting" },
30185519a65fd1100ceede7318a89f77a219c69c6acBob Copeland	{ ATH5K_DEBUG_LED,	"led",		"LED management" },
302b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez	{ ATH5K_DEBUG_DUMPBANDS, "dumpbands",	"dump bands" },
303b3a28e68d5c8d788a4e538a119a5d326545add8aNick Kossifidis	{ ATH5K_DEBUG_DMA,	"dma",		"dma start/stop" },
3042111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	{ ATH5K_DEBUG_ANI,	"ani",		"adaptive noise immunity" },
305b4c52612069c2756ad7506754765bfee57315efeBob Copeland	{ ATH5K_DEBUG_DESC,	"desc",		"descriptor chains" },
306be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	{ ATH5K_DEBUG_ANY,	"all",		"show all debug levels" },
307be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf};
308be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf
309be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolfstatic ssize_t read_file_debug(struct file *file, char __user *user_buf,
310be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf				   size_t count, loff_t *ppos)
311be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf{
312e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	struct ath5k_hw *ah = file->private_data;
313be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	char buf[700];
314be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	unsigned int len = 0;
315be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	unsigned int i;
316be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf
317e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
318e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		"DEBUG LEVEL: 0x%08x\n\n", ah->debug.level);
319be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf
320be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	for (i = 0; i < ARRAY_SIZE(dbg_info) - 1; i++) {
321e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin		len += snprintf(buf + len, sizeof(buf) - len,
322be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf			"%10s %c 0x%08x - %s\n", dbg_info[i].name,
323e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin			ah->debug.level & dbg_info[i].level ? '+' : ' ',
324be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf			dbg_info[i].level, dbg_info[i].desc);
325be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	}
326e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
327be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf		"%10s %c 0x%08x - %s\n", dbg_info[i].name,
328e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		ah->debug.level == dbg_info[i].level ? '+' : ' ',
329be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf		dbg_info[i].level, dbg_info[i].desc);
330be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf
3312189d13f6cfc58627a01d6a91591e59a2fa62902Dan Carpenter	if (len > sizeof(buf))
3322189d13f6cfc58627a01d6a91591e59a2fa62902Dan Carpenter		len = sizeof(buf);
3332189d13f6cfc58627a01d6a91591e59a2fa62902Dan Carpenter
334be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
335be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf}
336be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf
337be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolfstatic ssize_t write_file_debug(struct file *file,
338be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf				 const char __user *userbuf,
339be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf				 size_t count, loff_t *ppos)
340be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf{
341e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	struct ath5k_hw *ah = file->private_data;
342be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	unsigned int i;
343be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	char buf[20];
344be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf
345be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
346be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf		return -EFAULT;
347be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf
348be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	for (i = 0; i < ARRAY_SIZE(dbg_info); i++) {
349be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf		if (strncmp(buf, dbg_info[i].name,
350be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf					strlen(dbg_info[i].name)) == 0) {
351e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin			ah->debug.level ^= dbg_info[i].level; /* toggle bit */
352be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf			break;
353be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf		}
354be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	}
355be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	return count;
356be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf}
357be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf
358be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolfstatic const struct file_operations fops_debug = {
359be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	.read = read_file_debug,
360be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	.write = write_file_debug,
361234e340582901211f40d8c732afc49f0630ecf05Stephen Boyd	.open = simple_open,
362be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf	.owner = THIS_MODULE,
3636038f373a3dc1f1c26496e60b6c40b164716f07eArnd Bergmann	.llseek = default_llseek,
364be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf};
365be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf
366be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf
367604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf/* debugfs: antenna */
368604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf
369604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolfstatic ssize_t read_file_antenna(struct file *file, char __user *user_buf,
370604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf				   size_t count, loff_t *ppos)
371604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf{
372e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	struct ath5k_hw *ah = file->private_data;
373604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf	char buf[700];
374604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf	unsigned int len = 0;
375604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf	unsigned int i;
376604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf	unsigned int v;
377604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf
378e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "antenna mode\t%d\n",
379e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		ah->ah_ant_mode);
380e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "default antenna\t%d\n",
381e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		ah->ah_def_ant);
382e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "tx antenna\t%d\n",
383e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		ah->ah_tx_ant);
384604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf
385e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "\nANTENNA\t\tRX\tTX\n");
386e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	for (i = 1; i < ARRAY_SIZE(ah->stats.antenna_rx); i++) {
387e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin		len += snprintf(buf + len, sizeof(buf) - len,
388604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf			"[antenna %d]\t%d\t%d\n",
389e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin			i, ah->stats.antenna_rx[i], ah->stats.antenna_tx[i]);
390604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf	}
391e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "[invalid]\t%d\t%d\n",
392e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin			ah->stats.antenna_rx[0], ah->stats.antenna_tx[0]);
393604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf
394e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	v = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
395e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
396604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf			"\nAR5K_DEFAULT_ANTENNA\t0x%08x\n", v);
397604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf
398e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	v = ath5k_hw_reg_read(ah, AR5K_STA_ID1);
399e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
400604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf		"AR5K_STA_ID1_DEFAULT_ANTENNA\t%d\n",
401604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf		(v & AR5K_STA_ID1_DEFAULT_ANTENNA) != 0);
402e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
403604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf		"AR5K_STA_ID1_DESC_ANTENNA\t%d\n",
404604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf		(v & AR5K_STA_ID1_DESC_ANTENNA) != 0);
405e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
406604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf		"AR5K_STA_ID1_RTS_DEF_ANTENNA\t%d\n",
407604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf		(v & AR5K_STA_ID1_RTS_DEF_ANTENNA) != 0);
408e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
409604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf		"AR5K_STA_ID1_SELFGEN_DEF_ANT\t%d\n",
410604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf		(v & AR5K_STA_ID1_SELFGEN_DEF_ANT) != 0);
411604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf
412e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	v = ath5k_hw_reg_read(ah, AR5K_PHY_AGCCTL);
413e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
414604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf		"\nAR5K_PHY_AGCCTL_OFDM_DIV_DIS\t%d\n",
415604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf		(v & AR5K_PHY_AGCCTL_OFDM_DIV_DIS) != 0);
416604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf
417e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	v = ath5k_hw_reg_read(ah, AR5K_PHY_RESTART);
418e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
419604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf		"AR5K_PHY_RESTART_DIV_GC\t\t%x\n",
420604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf		(v & AR5K_PHY_RESTART_DIV_GC) >> AR5K_PHY_RESTART_DIV_GC_S);
421604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf
422e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	v = ath5k_hw_reg_read(ah, AR5K_PHY_FAST_ANT_DIV);
423e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
424604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf		"AR5K_PHY_FAST_ANT_DIV_EN\t%d\n",
425604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf		(v & AR5K_PHY_FAST_ANT_DIV_EN) != 0);
426604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf
427e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	v = ath5k_hw_reg_read(ah, AR5K_PHY_ANT_SWITCH_TABLE_0);
428e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
4290ca74027ac709f99aae1805e593c95843dd18234Bruno Randolf			"\nAR5K_PHY_ANT_SWITCH_TABLE_0\t0x%08x\n", v);
430e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	v = ath5k_hw_reg_read(ah, AR5K_PHY_ANT_SWITCH_TABLE_1);
431e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
4320ca74027ac709f99aae1805e593c95843dd18234Bruno Randolf			"AR5K_PHY_ANT_SWITCH_TABLE_1\t0x%08x\n", v);
4330ca74027ac709f99aae1805e593c95843dd18234Bruno Randolf
4342189d13f6cfc58627a01d6a91591e59a2fa62902Dan Carpenter	if (len > sizeof(buf))
4352189d13f6cfc58627a01d6a91591e59a2fa62902Dan Carpenter		len = sizeof(buf);
4362189d13f6cfc58627a01d6a91591e59a2fa62902Dan Carpenter
437604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
438604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf}
439604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf
440604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolfstatic ssize_t write_file_antenna(struct file *file,
441604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf				 const char __user *userbuf,
442604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf				 size_t count, loff_t *ppos)
443604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf{
444e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	struct ath5k_hw *ah = file->private_data;
445604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf	unsigned int i;
446604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf	char buf[20];
447604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf
448604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf	if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
449604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf		return -EFAULT;
450604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf
451604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf	if (strncmp(buf, "diversity", 9) == 0) {
452e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT);
453604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf		printk(KERN_INFO "ath5k debug: enable diversity\n");
454604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf	} else if (strncmp(buf, "fixed-a", 7) == 0) {
455e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_FIXED_A);
456604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf		printk(KERN_INFO "ath5k debugfs: fixed antenna A\n");
457604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf	} else if (strncmp(buf, "fixed-b", 7) == 0) {
458e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_FIXED_B);
459604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf		printk(KERN_INFO "ath5k debug: fixed antenna B\n");
460604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf	} else if (strncmp(buf, "clear", 5) == 0) {
461e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		for (i = 0; i < ARRAY_SIZE(ah->stats.antenna_rx); i++) {
462e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin			ah->stats.antenna_rx[i] = 0;
463e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin			ah->stats.antenna_tx[i] = 0;
464604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf		}
465604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf		printk(KERN_INFO "ath5k debug: cleared antenna stats\n");
466604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf	}
467604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf	return count;
468604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf}
469604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf
470604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolfstatic const struct file_operations fops_antenna = {
471604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf	.read = read_file_antenna,
472604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf	.write = write_file_antenna,
473234e340582901211f40d8c732afc49f0630ecf05Stephen Boyd	.open = simple_open,
474604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf	.owner = THIS_MODULE,
4756038f373a3dc1f1c26496e60b6c40b164716f07eArnd Bergmann	.llseek = default_llseek,
476604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf};
477604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf
47887fd2e6c90acb45a5741207fc953190596f93841Ben Greear/* debugfs: misc */
47987fd2e6c90acb45a5741207fc953190596f93841Ben Greear
48087fd2e6c90acb45a5741207fc953190596f93841Ben Greearstatic ssize_t read_file_misc(struct file *file, char __user *user_buf,
48187fd2e6c90acb45a5741207fc953190596f93841Ben Greear				   size_t count, loff_t *ppos)
48287fd2e6c90acb45a5741207fc953190596f93841Ben Greear{
483e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	struct ath5k_hw *ah = file->private_data;
48487fd2e6c90acb45a5741207fc953190596f93841Ben Greear	char buf[700];
48587fd2e6c90acb45a5741207fc953190596f93841Ben Greear	unsigned int len = 0;
486e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	u32 filt = ath5k_hw_get_rx_filter(ah);
48787fd2e6c90acb45a5741207fc953190596f93841Ben Greear
488e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "bssid-mask: %pM\n",
489e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin			ah->bssidmask);
490e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "filter-flags: 0x%x ",
49187fd2e6c90acb45a5741207fc953190596f93841Ben Greear			filt);
49287fd2e6c90acb45a5741207fc953190596f93841Ben Greear	if (filt & AR5K_RX_FILTER_UCAST)
493e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin		len += snprintf(buf + len, sizeof(buf) - len, " UCAST");
49487fd2e6c90acb45a5741207fc953190596f93841Ben Greear	if (filt & AR5K_RX_FILTER_MCAST)
495e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin		len += snprintf(buf + len, sizeof(buf) - len, " MCAST");
49687fd2e6c90acb45a5741207fc953190596f93841Ben Greear	if (filt & AR5K_RX_FILTER_BCAST)
497e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin		len += snprintf(buf + len, sizeof(buf) - len, " BCAST");
49887fd2e6c90acb45a5741207fc953190596f93841Ben Greear	if (filt & AR5K_RX_FILTER_CONTROL)
499e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin		len += snprintf(buf + len, sizeof(buf) - len, " CONTROL");
50087fd2e6c90acb45a5741207fc953190596f93841Ben Greear	if (filt & AR5K_RX_FILTER_BEACON)
501e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin		len += snprintf(buf + len, sizeof(buf) - len, " BEACON");
50287fd2e6c90acb45a5741207fc953190596f93841Ben Greear	if (filt & AR5K_RX_FILTER_PROM)
503e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin		len += snprintf(buf + len, sizeof(buf) - len, " PROM");
50487fd2e6c90acb45a5741207fc953190596f93841Ben Greear	if (filt & AR5K_RX_FILTER_XRPOLL)
505e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin		len += snprintf(buf + len, sizeof(buf) - len, " XRPOLL");
50687fd2e6c90acb45a5741207fc953190596f93841Ben Greear	if (filt & AR5K_RX_FILTER_PROBEREQ)
507e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin		len += snprintf(buf + len, sizeof(buf) - len, " PROBEREQ");
50887fd2e6c90acb45a5741207fc953190596f93841Ben Greear	if (filt & AR5K_RX_FILTER_PHYERR_5212)
509e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin		len += snprintf(buf + len, sizeof(buf) - len, " PHYERR-5212");
51087fd2e6c90acb45a5741207fc953190596f93841Ben Greear	if (filt & AR5K_RX_FILTER_RADARERR_5212)
511e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin		len += snprintf(buf + len, sizeof(buf) - len, " RADARERR-5212");
51287fd2e6c90acb45a5741207fc953190596f93841Ben Greear	if (filt & AR5K_RX_FILTER_PHYERR_5211)
513e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin		snprintf(buf + len, sizeof(buf) - len, " PHYERR-5211");
51487fd2e6c90acb45a5741207fc953190596f93841Ben Greear	if (filt & AR5K_RX_FILTER_RADARERR_5211)
515e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin		len += snprintf(buf + len, sizeof(buf) - len, " RADARERR-5211");
516908ebfb95d16bdf7f5f37ad911ccd9b7350ba780Joe Perches
517e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "\nopmode: %s (%d)\n",
518e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin			ath_opmode_to_string(ah->opmode), ah->opmode);
51992c68a66a8f73c51f062ae8cae958c86a21fea78Ben Greear
52087fd2e6c90acb45a5741207fc953190596f93841Ben Greear	if (len > sizeof(buf))
52187fd2e6c90acb45a5741207fc953190596f93841Ben Greear		len = sizeof(buf);
52287fd2e6c90acb45a5741207fc953190596f93841Ben Greear
52387fd2e6c90acb45a5741207fc953190596f93841Ben Greear	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
52487fd2e6c90acb45a5741207fc953190596f93841Ben Greear}
52587fd2e6c90acb45a5741207fc953190596f93841Ben Greear
52687fd2e6c90acb45a5741207fc953190596f93841Ben Greearstatic const struct file_operations fops_misc = {
52787fd2e6c90acb45a5741207fc953190596f93841Ben Greear	.read = read_file_misc,
528234e340582901211f40d8c732afc49f0630ecf05Stephen Boyd	.open = simple_open,
52987fd2e6c90acb45a5741207fc953190596f93841Ben Greear	.owner = THIS_MODULE,
53087fd2e6c90acb45a5741207fc953190596f93841Ben Greear};
53187fd2e6c90acb45a5741207fc953190596f93841Ben Greear
532604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf
5337644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf/* debugfs: frameerrors */
5347644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf
5357644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolfstatic ssize_t read_file_frameerrors(struct file *file, char __user *user_buf,
5367644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf				   size_t count, loff_t *ppos)
5377644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf{
538e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	struct ath5k_hw *ah = file->private_data;
539e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	struct ath5k_statistics *st = &ah->stats;
5407644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf	char buf[700];
5417644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf	unsigned int len = 0;
542da35111ad970081bdf6e848d1861c7d16e71079bBruno Randolf	int i;
5437644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf
544e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
5457644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf			"RX\n---------------------\n");
546e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "CRC\t%u\t(%u%%)\n",
5477644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf			st->rxerr_crc,
5487644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf			st->rx_all_count > 0 ?
549e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin				st->rxerr_crc * 100 / st->rx_all_count : 0);
550e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "PHY\t%u\t(%u%%)\n",
5517644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf			st->rxerr_phy,
5527644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf			st->rx_all_count > 0 ?
553e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin				st->rxerr_phy * 100 / st->rx_all_count : 0);
554da35111ad970081bdf6e848d1861c7d16e71079bBruno Randolf	for (i = 0; i < 32; i++) {
555da35111ad970081bdf6e848d1861c7d16e71079bBruno Randolf		if (st->rxerr_phy_code[i])
556e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin			len += snprintf(buf + len, sizeof(buf) - len,
5575d882c97e2c958df9f8b78832fa1ecbecef6ea1dBen Greear				" phy_err[%u]\t%u\n",
558da35111ad970081bdf6e848d1861c7d16e71079bBruno Randolf				i, st->rxerr_phy_code[i]);
559da35111ad970081bdf6e848d1861c7d16e71079bBruno Randolf	}
560da35111ad970081bdf6e848d1861c7d16e71079bBruno Randolf
561e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "FIFO\t%u\t(%u%%)\n",
5627644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf			st->rxerr_fifo,
5637644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf			st->rx_all_count > 0 ?
564e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin				st->rxerr_fifo * 100 / st->rx_all_count : 0);
565e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "decrypt\t%u\t(%u%%)\n",
5667644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf			st->rxerr_decrypt,
5677644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf			st->rx_all_count > 0 ?
568e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin				st->rxerr_decrypt * 100 / st->rx_all_count : 0);
569e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "MIC\t%u\t(%u%%)\n",
5707644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf			st->rxerr_mic,
5717644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf			st->rx_all_count > 0 ?
572e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin				st->rxerr_mic * 100 / st->rx_all_count : 0);
573e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "process\t%u\t(%u%%)\n",
5747644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf			st->rxerr_proc,
5757644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf			st->rx_all_count > 0 ?
576e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin				st->rxerr_proc * 100 / st->rx_all_count : 0);
577e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "jumbo\t%u\t(%u%%)\n",
5787644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf			st->rxerr_jumbo,
5797644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf			st->rx_all_count > 0 ?
580e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin				st->rxerr_jumbo * 100 / st->rx_all_count : 0);
581e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "[RX all\t%u]\n",
5827644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf			st->rx_all_count);
583e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "RX-all-bytes\t%u\n",
584b72acddbbe521d1372e7e9106e9d72e1cbab3010Ben Greear			st->rx_bytes_count);
5857644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf
586e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
5877644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf			"\nTX\n---------------------\n");
588e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "retry\t%u\t(%u%%)\n",
5897644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf			st->txerr_retry,
5907644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf			st->tx_all_count > 0 ?
591e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin				st->txerr_retry * 100 / st->tx_all_count : 0);
592e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "FIFO\t%u\t(%u%%)\n",
5937644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf			st->txerr_fifo,
5947644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf			st->tx_all_count > 0 ?
595e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin				st->txerr_fifo * 100 / st->tx_all_count : 0);
596e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "filter\t%u\t(%u%%)\n",
5977644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf			st->txerr_filt,
5987644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf			st->tx_all_count > 0 ?
599e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin				st->txerr_filt * 100 / st->tx_all_count : 0);
600e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "[TX all\t%u]\n",
6017644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf			st->tx_all_count);
602e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "TX-all-bytes\t%u\n",
603b72acddbbe521d1372e7e9106e9d72e1cbab3010Ben Greear			st->tx_bytes_count);
6047644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf
6052189d13f6cfc58627a01d6a91591e59a2fa62902Dan Carpenter	if (len > sizeof(buf))
6062189d13f6cfc58627a01d6a91591e59a2fa62902Dan Carpenter		len = sizeof(buf);
6072189d13f6cfc58627a01d6a91591e59a2fa62902Dan Carpenter
6087644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
6097644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf}
6107644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf
6117644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolfstatic ssize_t write_file_frameerrors(struct file *file,
6127644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf				 const char __user *userbuf,
6137644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf				 size_t count, loff_t *ppos)
6147644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf{
615e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	struct ath5k_hw *ah = file->private_data;
616e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	struct ath5k_statistics *st = &ah->stats;
6177644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf	char buf[20];
6187644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf
6197644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf	if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
6207644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf		return -EFAULT;
6217644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf
6227644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf	if (strncmp(buf, "clear", 5) == 0) {
6237644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf		st->rxerr_crc = 0;
6247644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf		st->rxerr_phy = 0;
6257644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf		st->rxerr_fifo = 0;
6267644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf		st->rxerr_decrypt = 0;
6277644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf		st->rxerr_mic = 0;
6287644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf		st->rxerr_proc = 0;
6297644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf		st->rxerr_jumbo = 0;
6307644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf		st->rx_all_count = 0;
6317644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf		st->txerr_retry = 0;
6327644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf		st->txerr_fifo = 0;
6337644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf		st->txerr_filt = 0;
6347644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf		st->tx_all_count = 0;
6357644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf		printk(KERN_INFO "ath5k debug: cleared frameerrors stats\n");
6367644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf	}
6377644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf	return count;
6387644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf}
6397644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf
6407644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolfstatic const struct file_operations fops_frameerrors = {
6417644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf	.read = read_file_frameerrors,
6427644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf	.write = write_file_frameerrors,
643234e340582901211f40d8c732afc49f0630ecf05Stephen Boyd	.open = simple_open,
6447644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf	.owner = THIS_MODULE,
6456038f373a3dc1f1c26496e60b6c40b164716f07eArnd Bergmann	.llseek = default_llseek,
6467644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf};
6477644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf
6487644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf
6492111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf/* debugfs: ani */
6502111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf
6512111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolfstatic ssize_t read_file_ani(struct file *file, char __user *user_buf,
6522111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf				   size_t count, loff_t *ppos)
6532111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf{
654e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	struct ath5k_hw *ah = file->private_data;
655e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	struct ath5k_statistics *st = &ah->stats;
656e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	struct ath5k_ani_state *as = &ah->ani_state;
6572111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf
6582111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	char buf[700];
6592111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	unsigned int len = 0;
6602111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf
661e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
6622111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			"HW has PHY error counters:\t%s\n",
663e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin			ah->ah_capabilities.cap_has_phyerr_counters ?
6642111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			"yes" : "no");
665e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
6662111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			"HW max spur immunity level:\t%d\n",
6672111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			as->max_spur_level);
668e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
6692111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf		"\nANI state\n--------------------------------------------\n");
670e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "operating mode:\t\t\t");
6712111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	switch (as->ani_mode) {
6722111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	case ATH5K_ANI_MODE_OFF:
673e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin		len += snprintf(buf + len, sizeof(buf) - len, "OFF\n");
6742111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf		break;
6752111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	case ATH5K_ANI_MODE_MANUAL_LOW:
676e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin		len += snprintf(buf + len, sizeof(buf) - len,
6772111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			"MANUAL LOW\n");
6782111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf		break;
6792111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	case ATH5K_ANI_MODE_MANUAL_HIGH:
680e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin		len += snprintf(buf + len, sizeof(buf) - len,
6812111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			"MANUAL HIGH\n");
6822111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf		break;
6832111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	case ATH5K_ANI_MODE_AUTO:
684e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin		len += snprintf(buf + len, sizeof(buf) - len, "AUTO\n");
6852111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf		break;
6862111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	default:
687e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin		len += snprintf(buf + len, sizeof(buf) - len,
6882111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			"??? (not good)\n");
6892111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf		break;
6902111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	}
691e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
6922111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			"noise immunity level:\t\t%d\n",
6932111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			as->noise_imm_level);
694e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
6952111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			"spur immunity level:\t\t%d\n",
6962111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			as->spur_level);
697e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
698e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin			"firstep level:\t\t\t%d\n",
6992111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			as->firstep_level);
700e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
7012111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			"OFDM weak signal detection:\t%s\n",
7022111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			as->ofdm_weak_sig ? "on" : "off");
703e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
7042111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			"CCK weak signal detection:\t%s\n",
7052111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			as->cck_weak_sig ? "on" : "off");
7062111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf
707e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
7082111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			"\nMIB INTERRUPTS:\t\t%u\n",
7092111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			st->mib_intr);
710e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
7112111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			"beacon RSSI average:\t%d\n",
712e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin			(int)ewma_read(&ah->ah_beacon_rssi_avg));
7137109ca5c80a0bb94378ebd7f8bb6d00edb5e6fbaFelix Fietkau
7147109ca5c80a0bb94378ebd7f8bb6d00edb5e6fbaFelix Fietkau#define CC_PRINT(_struct, _field) \
7157109ca5c80a0bb94378ebd7f8bb6d00edb5e6fbaFelix Fietkau	_struct._field, \
7167109ca5c80a0bb94378ebd7f8bb6d00edb5e6fbaFelix Fietkau	_struct.cycles > 0 ? \
717e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	_struct._field * 100 / _struct.cycles : 0
7187109ca5c80a0bb94378ebd7f8bb6d00edb5e6fbaFelix Fietkau
719e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
720e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin			"profcnt tx\t\t%u\t(%d%%)\n",
7217109ca5c80a0bb94378ebd7f8bb6d00edb5e6fbaFelix Fietkau			CC_PRINT(as->last_cc, tx_frame));
722e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
723e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin			"profcnt rx\t\t%u\t(%d%%)\n",
7247109ca5c80a0bb94378ebd7f8bb6d00edb5e6fbaFelix Fietkau			CC_PRINT(as->last_cc, rx_frame));
725e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
726e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin			"profcnt busy\t\t%u\t(%d%%)\n",
7277109ca5c80a0bb94378ebd7f8bb6d00edb5e6fbaFelix Fietkau			CC_PRINT(as->last_cc, rx_busy));
7287109ca5c80a0bb94378ebd7f8bb6d00edb5e6fbaFelix Fietkau#undef CC_PRINT
729e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len, "profcnt cycles\t\t%u\n",
7307109ca5c80a0bb94378ebd7f8bb6d00edb5e6fbaFelix Fietkau			as->last_cc.cycles);
731e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
7322111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			"listen time\t\t%d\tlast: %d\n",
7332111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			as->listen_time, as->last_listen);
734e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
7352111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			"OFDM errors\t\t%u\tlast: %u\tsum: %u\n",
7362111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			as->ofdm_errors, as->last_ofdm_errors,
7372111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			as->sum_ofdm_errors);
738e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
7392111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			"CCK errors\t\t%u\tlast: %u\tsum: %u\n",
7402111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			as->cck_errors, as->last_cck_errors,
7412111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			as->sum_cck_errors);
742e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
7432111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			"AR5K_PHYERR_CNT1\t%x\t(=%d)\n",
744e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin			ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT1),
7452111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			ATH5K_ANI_OFDM_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX -
746e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin			ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT1)));
747e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
7482111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			"AR5K_PHYERR_CNT2\t%x\t(=%d)\n",
749e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin			ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT2),
7502111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf			ATH5K_ANI_CCK_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX -
751e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin			ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT2)));
7522111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf
7532189d13f6cfc58627a01d6a91591e59a2fa62902Dan Carpenter	if (len > sizeof(buf))
7542189d13f6cfc58627a01d6a91591e59a2fa62902Dan Carpenter		len = sizeof(buf);
7552189d13f6cfc58627a01d6a91591e59a2fa62902Dan Carpenter
7562111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
7572111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf}
7582111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf
7592111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolfstatic ssize_t write_file_ani(struct file *file,
7602111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf				 const char __user *userbuf,
7612111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf				 size_t count, loff_t *ppos)
7622111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf{
763e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	struct ath5k_hw *ah = file->private_data;
7642111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	char buf[20];
7652111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf
7662111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
7672111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf		return -EFAULT;
7682111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf
7692111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	if (strncmp(buf, "sens-low", 8) == 0) {
770e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		ath5k_ani_init(ah, ATH5K_ANI_MODE_MANUAL_HIGH);
7712111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	} else if (strncmp(buf, "sens-high", 9) == 0) {
772e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		ath5k_ani_init(ah, ATH5K_ANI_MODE_MANUAL_LOW);
7732111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	} else if (strncmp(buf, "ani-off", 7) == 0) {
774e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		ath5k_ani_init(ah, ATH5K_ANI_MODE_OFF);
7752111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	} else if (strncmp(buf, "ani-on", 6) == 0) {
776e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		ath5k_ani_init(ah, ATH5K_ANI_MODE_AUTO);
7772111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	} else if (strncmp(buf, "noise-low", 9) == 0) {
778e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		ath5k_ani_set_noise_immunity_level(ah, 0);
7792111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	} else if (strncmp(buf, "noise-high", 10) == 0) {
780e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		ath5k_ani_set_noise_immunity_level(ah,
7812111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf						   ATH5K_ANI_MAX_NOISE_IMM_LVL);
7822111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	} else if (strncmp(buf, "spur-low", 8) == 0) {
783e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		ath5k_ani_set_spur_immunity_level(ah, 0);
7842111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	} else if (strncmp(buf, "spur-high", 9) == 0) {
785e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		ath5k_ani_set_spur_immunity_level(ah,
786e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin						  ah->ani_state.max_spur_level);
7872111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	} else if (strncmp(buf, "fir-low", 7) == 0) {
788e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		ath5k_ani_set_firstep_level(ah, 0);
7892111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	} else if (strncmp(buf, "fir-high", 8) == 0) {
790e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		ath5k_ani_set_firstep_level(ah, ATH5K_ANI_MAX_FIRSTEP_LVL);
7912111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	} else if (strncmp(buf, "ofdm-off", 8) == 0) {
792e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		ath5k_ani_set_ofdm_weak_signal_detection(ah, false);
7932111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	} else if (strncmp(buf, "ofdm-on", 7) == 0) {
794e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		ath5k_ani_set_ofdm_weak_signal_detection(ah, true);
7952111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	} else if (strncmp(buf, "cck-off", 7) == 0) {
796e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		ath5k_ani_set_cck_weak_signal_detection(ah, false);
7972111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	} else if (strncmp(buf, "cck-on", 6) == 0) {
798e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		ath5k_ani_set_cck_weak_signal_detection(ah, true);
7992111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	}
8002111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	return count;
8012111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf}
8022111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf
8032111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolfstatic const struct file_operations fops_ani = {
8042111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	.read = read_file_ani,
8052111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	.write = write_file_ani,
806234e340582901211f40d8c732afc49f0630ecf05Stephen Boyd	.open = simple_open,
8072111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf	.owner = THIS_MODULE,
8086038f373a3dc1f1c26496e60b6c40b164716f07eArnd Bergmann	.llseek = default_llseek,
8092111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf};
8102111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf
8112111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf
8123cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf/* debugfs: queues etc */
8133cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf
8143cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolfstatic ssize_t read_file_queue(struct file *file, char __user *user_buf,
8153cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf				   size_t count, loff_t *ppos)
8163cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf{
817e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	struct ath5k_hw *ah = file->private_data;
8183cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf	char buf[700];
8193cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf	unsigned int len = 0;
8203cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf
8213cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf	struct ath5k_txq *txq;
8223cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf	struct ath5k_buf *bf, *bf0;
823cfddc11c429a655e418ffc111372cc69dee6a1a5Bruno Randolf	int i, n;
8243cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf
825e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin	len += snprintf(buf + len, sizeof(buf) - len,
826e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin			"available txbuffers: %d\n", ah->txbuf_len);
8273cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf
828e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	for (i = 0; i < ARRAY_SIZE(ah->txqs); i++) {
829e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		txq = &ah->txqs[i];
8303cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf
831e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin		len += snprintf(buf + len, sizeof(buf) - len,
8323cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf			"%02d: %ssetup\n", i, txq->setup ? "" : "not ");
8333cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf
8343cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf		if (!txq->setup)
8353cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf			continue;
8363cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf
837cfddc11c429a655e418ffc111372cc69dee6a1a5Bruno Randolf		n = 0;
838cfddc11c429a655e418ffc111372cc69dee6a1a5Bruno Randolf		spin_lock_bh(&txq->lock);
8393cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf		list_for_each_entry_safe(bf, bf0, &txq->q, list)
8403cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf			n++;
841cfddc11c429a655e418ffc111372cc69dee6a1a5Bruno Randolf		spin_unlock_bh(&txq->lock);
842cfddc11c429a655e418ffc111372cc69dee6a1a5Bruno Randolf
843e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin		len += snprintf(buf + len, sizeof(buf) - len,
844cfddc11c429a655e418ffc111372cc69dee6a1a5Bruno Randolf				"  len: %d bufs: %d\n", txq->txq_len, n);
845e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin		len += snprintf(buf + len, sizeof(buf) - len,
846923e5b3d3d773b9956b943ac64f782d5a127bdeaBruno Randolf				"  stuck: %d\n", txq->txq_stuck);
8473cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf	}
8483cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf
8492189d13f6cfc58627a01d6a91591e59a2fa62902Dan Carpenter	if (len > sizeof(buf))
8502189d13f6cfc58627a01d6a91591e59a2fa62902Dan Carpenter		len = sizeof(buf);
8512189d13f6cfc58627a01d6a91591e59a2fa62902Dan Carpenter
8523cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
8533cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf}
8543cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf
8553cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolfstatic ssize_t write_file_queue(struct file *file,
8563cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf				 const char __user *userbuf,
8573cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf				 size_t count, loff_t *ppos)
8583cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf{
859e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	struct ath5k_hw *ah = file->private_data;
8603cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf	char buf[20];
8613cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf
8623cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf	if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
8633cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf		return -EFAULT;
8643cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf
8653cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf	if (strncmp(buf, "start", 5) == 0)
866e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		ieee80211_wake_queues(ah->hw);
8673cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf	else if (strncmp(buf, "stop", 4) == 0)
868e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		ieee80211_stop_queues(ah->hw);
8693cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf
8703cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf	return count;
8713cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf}
8723cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf
8733cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf
8743cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolfstatic const struct file_operations fops_queue = {
8753cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf	.read = read_file_queue,
8763cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf	.write = write_file_queue,
877234e340582901211f40d8c732afc49f0630ecf05Stephen Boyd	.open = simple_open,
8783cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf	.owner = THIS_MODULE,
8796038f373a3dc1f1c26496e60b6c40b164716f07eArnd Bergmann	.llseek = default_llseek,
8803cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf};
8813cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf
8823cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf
883fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slabyvoid
884e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskinath5k_debug_init_device(struct ath5k_hw *ah)
885fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby{
8865b7916ad8c29da9f30fbf03a8b61862acdba00ceFelix Fietkau	struct dentry *phydir;
887be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf
888e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	ah->debug.level = ath5k_debug;
889be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf
890e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	phydir = debugfs_create_dir("ath5k", ah->hw->wiphy->debugfsdir);
8915b7916ad8c29da9f30fbf03a8b61862acdba00ceFelix Fietkau	if (!phydir)
892e4bbf2f541501dcde47ce687ffc6d238bd2f7813Pavel Roskin		return;
893fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
894e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	debugfs_create_file("debug", S_IWUSR | S_IRUSR, phydir, ah,
8955b7916ad8c29da9f30fbf03a8b61862acdba00ceFelix Fietkau			    &fops_debug);
896fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
897e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	debugfs_create_file("registers", S_IRUSR, phydir, ah, &fops_registers);
898fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
899e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	debugfs_create_file("beacon", S_IWUSR | S_IRUSR, phydir, ah,
9005b7916ad8c29da9f30fbf03a8b61862acdba00ceFelix Fietkau			    &fops_beacon);
901604eeadd1880bddfb155369491cc13fb8d3f9df6Bruno Randolf
902e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	debugfs_create_file("reset", S_IWUSR, phydir, ah, &fops_reset);
9037644395f8df9aa5b42af268a485b83e44bba2784Bruno Randolf
904e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	debugfs_create_file("antenna", S_IWUSR | S_IRUSR, phydir, ah,
9055b7916ad8c29da9f30fbf03a8b61862acdba00ceFelix Fietkau			    &fops_antenna);
90687fd2e6c90acb45a5741207fc953190596f93841Ben Greear
907e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	debugfs_create_file("misc", S_IRUSR, phydir, ah, &fops_misc);
9082111ac0d888767999c7dd6d1309dcc1fb8012022Bruno Randolf
909e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	debugfs_create_file("frameerrors", S_IWUSR | S_IRUSR, phydir, ah,
9105b7916ad8c29da9f30fbf03a8b61862acdba00ceFelix Fietkau			    &fops_frameerrors);
9113cfd43f484c8d4bcb38db83f7be19fbd4ac8440cBruno Randolf
912e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	debugfs_create_file("ani", S_IWUSR | S_IRUSR, phydir, ah, &fops_ani);
913fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
914e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	debugfs_create_file("queue", S_IWUSR | S_IRUSR, phydir, ah,
9155b7916ad8c29da9f30fbf03a8b61862acdba00ceFelix Fietkau			    &fops_queue);
9166340211c5f4775a52c98052fb5661565f79249fdFelix Fietkau
9176340211c5f4775a52c98052fb5661565f79249fdFelix Fietkau	debugfs_create_bool("32khz_clock", S_IWUSR | S_IRUSR, phydir,
918e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin			    &ah->ah_use_32khz_clock);
919fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby}
920fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
921fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby/* functions used in other places */
922fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
923fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slabyvoid
924e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskinath5k_debug_dump_bands(struct ath5k_hw *ah)
925fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby{
926b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez	unsigned int b, i;
927fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
928e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	if (likely(!(ah->debug.level & ATH5K_DEBUG_DUMPBANDS)))
929fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby		return;
930fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
931e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	BUG_ON(!ah->sbands);
932b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez
933b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez	for (b = 0; b < IEEE80211_NUM_BANDS; b++) {
934e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		struct ieee80211_supported_band *band = &ah->sbands[b];
935b7fcb5c4a4c27da2f6d86cb03d18687e537442cfBob Copeland		char bname[6];
936b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez		switch (band->band) {
937b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez		case IEEE80211_BAND_2GHZ:
938b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez			strcpy(bname, "2 GHz");
939b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez			break;
940b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez		case IEEE80211_BAND_5GHZ:
941b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez			strcpy(bname, "5 GHz");
942b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez			break;
943b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez		default:
944b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez			printk(KERN_DEBUG "Band not supported: %d\n",
945b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez				band->band);
946b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez			return;
947b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez		}
948b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez		printk(KERN_DEBUG "Band %s: channels %d, rates %d\n", bname,
949b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez				band->n_channels, band->n_bitrates);
950fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby		printk(KERN_DEBUG " channels:\n");
951b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez		for (i = 0; i < band->n_channels; i++)
952fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby			printk(KERN_DEBUG "  %3d %d %.4x %.4x\n",
953b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez					ieee80211_frequency_to_channel(
954b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez						band->channels[i].center_freq),
955b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez					band->channels[i].center_freq,
956b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez					band->channels[i].hw_value,
957b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez					band->channels[i].flags);
958fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby		printk(KERN_DEBUG " rates:\n");
959b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez		for (i = 0; i < band->n_bitrates; i++)
960fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby			printk(KERN_DEBUG "  %4d %.4x %.4x %.4x\n",
961b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez					band->bitrates[i].bitrate,
962b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez					band->bitrates[i].hw_value,
963b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez					band->bitrates[i].flags,
964b446197cc14ef060baeed5acbcddf148c04d03f8Luis R. Rodriguez					band->bitrates[i].hw_value_short);
965fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	}
966fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby}
967fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
968fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slabystatic inline void
969b47f407bef0d5349dacf65cd3560a976609d4b45Bruno Randolfath5k_debug_printrxbuf(struct ath5k_buf *bf, int done,
970b47f407bef0d5349dacf65cd3560a976609d4b45Bruno Randolf		       struct ath5k_rx_status *rs)
971fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby{
972fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	struct ath5k_desc *ds = bf->desc;
97319fd6e5510f6991148e2210753b58f0eab95e0f6Bruno Randolf	struct ath5k_hw_all_rx_desc *rd = &ds->ud.ds_rx;
974fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
975fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	printk(KERN_DEBUG "R (%p %llx) %08x %08x %08x %08x %08x %08x %c\n",
976fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby		ds, (unsigned long long)bf->daddr,
97719fd6e5510f6991148e2210753b58f0eab95e0f6Bruno Randolf		ds->ds_link, ds->ds_data,
97819fd6e5510f6991148e2210753b58f0eab95e0f6Bruno Randolf		rd->rx_ctl.rx_control_0, rd->rx_ctl.rx_control_1,
97962412a8f0ded6e5741c67c24f9e7c5b2bc33e042Bruno Randolf		rd->rx_stat.rx_status_0, rd->rx_stat.rx_status_1,
980b47f407bef0d5349dacf65cd3560a976609d4b45Bruno Randolf		!done ? ' ' : (rs->rs_status == 0) ? '*' : '!');
981fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby}
982fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
983fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slabyvoid
984e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskinath5k_debug_printrxbuffs(struct ath5k_hw *ah)
985fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby{
986fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	struct ath5k_desc *ds;
987fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	struct ath5k_buf *bf;
988b47f407bef0d5349dacf65cd3560a976609d4b45Bruno Randolf	struct ath5k_rx_status rs = {};
989fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	int status;
990fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
991e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	if (likely(!(ah->debug.level & ATH5K_DEBUG_DESC)))
992fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby		return;
993fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
994265faadd6a01b9462bbc3ead26a3e32a717525c5Bruno Randolf	printk(KERN_DEBUG "rxdp %x, rxlink %p\n",
995e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin		ath5k_hw_get_rxdp(ah), ah->rxlink);
996fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
997e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	spin_lock_bh(&ah->rxbuflock);
998e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	list_for_each_entry(bf, &ah->rxbuf, list) {
999fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby		ds = bf->desc;
1000b47f407bef0d5349dacf65cd3560a976609d4b45Bruno Randolf		status = ah->ah_proc_rx_desc(ah, ds, &rs);
1001be9b72590c05daf34c2b55cd5b7c68375a4a795bBruno Randolf		if (!status)
1002b47f407bef0d5349dacf65cd3560a976609d4b45Bruno Randolf			ath5k_debug_printrxbuf(bf, status == 0, &rs);
1003fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	}
1004e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	spin_unlock_bh(&ah->rxbuflock);
1005fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby}
1006fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
1007fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slabyvoid
1008e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskinath5k_debug_printtxbuf(struct ath5k_hw *ah, struct ath5k_buf *bf)
1009fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby{
1010fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	struct ath5k_desc *ds = bf->desc;
101119fd6e5510f6991148e2210753b58f0eab95e0f6Bruno Randolf	struct ath5k_hw_5212_tx_desc *td = &ds->ud.ds_tx5212;
1012b47f407bef0d5349dacf65cd3560a976609d4b45Bruno Randolf	struct ath5k_tx_status ts = {};
1013b47f407bef0d5349dacf65cd3560a976609d4b45Bruno Randolf	int done;
1014fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
1015e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	if (likely(!(ah->debug.level & ATH5K_DEBUG_DESC)))
1016fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby		return;
1017fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby
1018e0d687bd9df218ba3d97aac15919d30816d72dcbPavel Roskin	done = ah->ah_proc_tx_desc(ah, bf->desc, &ts);
1019b47f407bef0d5349dacf65cd3560a976609d4b45Bruno Randolf
1020fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby	printk(KERN_DEBUG "T (%p %llx) %08x %08x %08x %08x %08x %08x %08x "
1021fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby		"%08x %c\n", ds, (unsigned long long)bf->daddr, ds->ds_link,
102219fd6e5510f6991148e2210753b58f0eab95e0f6Bruno Randolf		ds->ds_data, td->tx_ctl.tx_control_0, td->tx_ctl.tx_control_1,
102319fd6e5510f6991148e2210753b58f0eab95e0f6Bruno Randolf		td->tx_ctl.tx_control_2, td->tx_ctl.tx_control_3,
102419fd6e5510f6991148e2210753b58f0eab95e0f6Bruno Randolf		td->tx_stat.tx_status_0, td->tx_stat.tx_status_1,
1025b47f407bef0d5349dacf65cd3560a976609d4b45Bruno Randolf		done ? ' ' : (ts.ts_status == 0) ? '*' : '!');
1026fa1c114fdaa605496045e56c42d0c8aa4c139e57Jiri Slaby}
1027