1/*
2 * Atheros CARL9170 driver
3 *
4 * debug(fs) probing
5 *
6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
7 * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; see the file COPYING.  If not, see
21 * http://www.gnu.org/licenses/.
22 *
23 * This file incorporates work covered by the following copyright and
24 * permission notice:
25 *    Copyright (c) 2008-2009 Atheros Communications, Inc.
26 *
27 *    Permission to use, copy, modify, and/or distribute this software for any
28 *    purpose with or without fee is hereby granted, provided that the above
29 *    copyright notice and this permission notice appear in all copies.
30 *
31 *    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
32 *    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
33 *    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
34 *    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
35 *    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
36 *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
37 *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
38 */
39
40#include <linux/slab.h>
41#include <linux/module.h>
42#include <linux/seq_file.h>
43#include <linux/vmalloc.h>
44#include "carl9170.h"
45#include "cmd.h"
46
47#define ADD(buf, off, max, fmt, args...)				\
48	off += scnprintf(&buf[off], max - off, fmt, ##args)
49
50
51struct carl9170_debugfs_fops {
52	unsigned int read_bufsize;
53	umode_t attr;
54	char *(*read)(struct ar9170 *ar, char *buf, size_t bufsize,
55		      ssize_t *len);
56	ssize_t (*write)(struct ar9170 *aru, const char *buf, size_t size);
57	const struct file_operations fops;
58
59	enum carl9170_device_state req_dev_state;
60};
61
62static ssize_t carl9170_debugfs_read(struct file *file, char __user *userbuf,
63				     size_t count, loff_t *ppos)
64{
65	struct carl9170_debugfs_fops *dfops;
66	struct ar9170 *ar;
67	char *buf = NULL, *res_buf = NULL;
68	ssize_t ret = 0;
69	int err = 0;
70
71	if (!count)
72		return 0;
73
74	ar = file->private_data;
75
76	if (!ar)
77		return -ENODEV;
78	dfops = container_of(debugfs_real_fops(file),
79			     struct carl9170_debugfs_fops, fops);
80
81	if (!dfops->read)
82		return -ENOSYS;
83
84	if (dfops->read_bufsize) {
85		buf = vmalloc(dfops->read_bufsize);
86		if (!buf)
87			return -ENOMEM;
88	}
89
90	mutex_lock(&ar->mutex);
91	if (!CHK_DEV_STATE(ar, dfops->req_dev_state)) {
92		err = -ENODEV;
93		res_buf = buf;
94		goto out_free;
95	}
96
97	res_buf = dfops->read(ar, buf, dfops->read_bufsize, &ret);
98
99	if (ret > 0)
100		err = simple_read_from_buffer(userbuf, count, ppos,
101					      res_buf, ret);
102	else
103		err = ret;
104
105	WARN_ON_ONCE(dfops->read_bufsize && (res_buf != buf));
106
107out_free:
108	vfree(res_buf);
109	mutex_unlock(&ar->mutex);
110	return err;
111}
112
113static ssize_t carl9170_debugfs_write(struct file *file,
114	const char __user *userbuf, size_t count, loff_t *ppos)
115{
116	struct carl9170_debugfs_fops *dfops;
117	struct ar9170 *ar;
118	char *buf = NULL;
119	int err = 0;
120
121	if (!count)
122		return 0;
123
124	if (count > PAGE_SIZE)
125		return -E2BIG;
126
127	ar = file->private_data;
128
129	if (!ar)
130		return -ENODEV;
131	dfops = container_of(debugfs_real_fops(file),
132			     struct carl9170_debugfs_fops, fops);
133
134	if (!dfops->write)
135		return -ENOSYS;
136
137	buf = vmalloc(count);
138	if (!buf)
139		return -ENOMEM;
140
141	if (copy_from_user(buf, userbuf, count)) {
142		err = -EFAULT;
143		goto out_free;
144	}
145
146	if (mutex_trylock(&ar->mutex) == 0) {
147		err = -EAGAIN;
148		goto out_free;
149	}
150
151	if (!CHK_DEV_STATE(ar, dfops->req_dev_state)) {
152		err = -ENODEV;
153		goto out_unlock;
154	}
155
156	err = dfops->write(ar, buf, count);
157	if (err)
158		goto out_unlock;
159
160out_unlock:
161	mutex_unlock(&ar->mutex);
162
163out_free:
164	vfree(buf);
165	return err;
166}
167
168#define __DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize,	\
169			       _attr, _dstate)				\
170static const struct carl9170_debugfs_fops carl_debugfs_##name ##_ops = {\
171	.read_bufsize = _read_bufsize,					\
172	.read = _read,							\
173	.write = _write,						\
174	.attr = _attr,							\
175	.req_dev_state = _dstate,					\
176	.fops = {							\
177		.open	= simple_open,					\
178		.read	= carl9170_debugfs_read,			\
179		.write	= carl9170_debugfs_write,			\
180		.owner	= THIS_MODULE					\
181	},								\
182}
183
184#define DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize, _attr)	\
185	__DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize,	\
186			       _attr, CARL9170_STARTED)			\
187
188#define DEBUGFS_DECLARE_RO_FILE(name, _read_bufsize)			\
189	DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read,	\
190			     NULL, _read_bufsize, 0400)
191
192#define DEBUGFS_DECLARE_WO_FILE(name)					\
193	DEBUGFS_DECLARE_FILE(name, NULL, carl9170_debugfs_##name ##_write,\
194			     0, 0200)
195
196#define DEBUGFS_DECLARE_RW_FILE(name, _read_bufsize)			\
197	DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read,	\
198			     carl9170_debugfs_##name ##_write,		\
199			     _read_bufsize, 0600)
200
201#define __DEBUGFS_DECLARE_RW_FILE(name, _read_bufsize, _dstate)		\
202	__DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read,	\
203			     carl9170_debugfs_##name ##_write,		\
204			     _read_bufsize, 0600, _dstate)
205
206#define DEBUGFS_READONLY_FILE(name, _read_bufsize, fmt, value...)	\
207static char *carl9170_debugfs_ ##name ## _read(struct ar9170 *ar,	\
208					     char *buf, size_t buf_size,\
209					     ssize_t *len)		\
210{									\
211	ADD(buf, *len, buf_size, fmt "\n", ##value);			\
212	return buf;							\
213}									\
214DEBUGFS_DECLARE_RO_FILE(name, _read_bufsize)
215
216static char *carl9170_debugfs_mem_usage_read(struct ar9170 *ar, char *buf,
217					     size_t bufsize, ssize_t *len)
218{
219	spin_lock_bh(&ar->mem_lock);
220
221	ADD(buf, *len, bufsize, "jar: [%*pb]\n",
222	    ar->fw.mem_blocks, ar->mem_bitmap);
223
224	ADD(buf, *len, bufsize, "cookies: used:%3d / total:%3d, allocs:%d\n",
225	    bitmap_weight(ar->mem_bitmap, ar->fw.mem_blocks),
226	    ar->fw.mem_blocks, atomic_read(&ar->mem_allocs));
227
228	ADD(buf, *len, bufsize, "memory: free:%3d (%3d KiB) / total:%3d KiB)\n",
229	    atomic_read(&ar->mem_free_blocks),
230	    (atomic_read(&ar->mem_free_blocks) * ar->fw.mem_block_size) / 1024,
231	    (ar->fw.mem_blocks * ar->fw.mem_block_size) / 1024);
232
233	spin_unlock_bh(&ar->mem_lock);
234
235	return buf;
236}
237DEBUGFS_DECLARE_RO_FILE(mem_usage, 512);
238
239static char *carl9170_debugfs_qos_stat_read(struct ar9170 *ar, char *buf,
240					    size_t bufsize, ssize_t *len)
241{
242	ADD(buf, *len, bufsize, "%s QoS AC\n", modparam_noht ? "Hardware" :
243	    "Software");
244
245	ADD(buf, *len, bufsize, "[     VO            VI       "
246				 "     BE            BK      ]\n");
247
248	spin_lock_bh(&ar->tx_stats_lock);
249	ADD(buf, *len, bufsize, "[length/limit  length/limit  "
250				 "length/limit  length/limit ]\n"
251				"[   %3d/%3d       %3d/%3d    "
252				 "   %3d/%3d       %3d/%3d   ]\n\n",
253	    ar->tx_stats[0].len, ar->tx_stats[0].limit,
254	    ar->tx_stats[1].len, ar->tx_stats[1].limit,
255	    ar->tx_stats[2].len, ar->tx_stats[2].limit,
256	    ar->tx_stats[3].len, ar->tx_stats[3].limit);
257
258	ADD(buf, *len, bufsize, "[    total         total     "
259				 "    total         total    ]\n"
260				"[%10d    %10d    %10d    %10d   ]\n\n",
261	    ar->tx_stats[0].count, ar->tx_stats[1].count,
262	    ar->tx_stats[2].count, ar->tx_stats[3].count);
263
264	spin_unlock_bh(&ar->tx_stats_lock);
265
266	ADD(buf, *len, bufsize, "[  pend/waittx   pend/waittx "
267				 "  pend/waittx   pend/waittx]\n"
268				"[   %3d/%3d       %3d/%3d    "
269				 "   %3d/%3d       %3d/%3d   ]\n\n",
270	    skb_queue_len(&ar->tx_pending[0]),
271	    skb_queue_len(&ar->tx_status[0]),
272	    skb_queue_len(&ar->tx_pending[1]),
273	    skb_queue_len(&ar->tx_status[1]),
274	    skb_queue_len(&ar->tx_pending[2]),
275	    skb_queue_len(&ar->tx_status[2]),
276	    skb_queue_len(&ar->tx_pending[3]),
277	    skb_queue_len(&ar->tx_status[3]));
278
279	return buf;
280}
281DEBUGFS_DECLARE_RO_FILE(qos_stat, 512);
282
283static void carl9170_debugfs_format_frame(struct ar9170 *ar,
284	struct sk_buff *skb, const char *prefix, char *buf,
285	ssize_t *off, ssize_t bufsize)
286{
287	struct _carl9170_tx_superframe *txc = (void *) skb->data;
288	struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
289	struct carl9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
290	struct ieee80211_hdr *hdr = (void *) txc->frame_data;
291
292	ADD(buf, *off, bufsize, "%s %p, c:%2x, DA:%pM, sq:%4d, mc:%.4x, "
293	    "pc:%.8x, to:%d ms\n", prefix, skb, txc->s.cookie,
294	    ieee80211_get_DA(hdr), get_seq_h(hdr),
295	    le16_to_cpu(txc->f.mac_control), le32_to_cpu(txc->f.phy_control),
296	    jiffies_to_msecs(jiffies - arinfo->timeout));
297}
298
299
300static char *carl9170_debugfs_ampdu_state_read(struct ar9170 *ar, char *buf,
301					       size_t bufsize, ssize_t *len)
302{
303	struct carl9170_sta_tid *iter;
304	struct sk_buff *skb;
305	int cnt = 0, fc;
306	int offset;
307
308	rcu_read_lock();
309	list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) {
310
311		spin_lock_bh(&iter->lock);
312		ADD(buf, *len, bufsize, "Entry: #%2d TID:%1d, BSN:%4d, "
313		    "SNX:%4d, HSN:%4d, BAW:%2d, state:%1d, toggles:%d\n",
314		    cnt, iter->tid, iter->bsn, iter->snx, iter->hsn,
315		    iter->max, iter->state, iter->counter);
316
317		ADD(buf, *len, bufsize, "\tWindow:  [%*pb,W]\n",
318		    CARL9170_BAW_BITS, iter->bitmap);
319
320#define BM_STR_OFF(offset)					\
321	((CARL9170_BAW_BITS - (offset) - 1) / 4 +		\
322	 (CARL9170_BAW_BITS - (offset) - 1) / 32 + 1)
323
324		offset = BM_STR_OFF(0);
325		ADD(buf, *len, bufsize, "\tBase Seq: %*s\n", offset, "T");
326
327		offset = BM_STR_OFF(SEQ_DIFF(iter->snx, iter->bsn));
328		ADD(buf, *len, bufsize, "\tNext Seq: %*s\n", offset, "W");
329
330		offset = BM_STR_OFF(((int)iter->hsn - (int)iter->bsn) %
331				     CARL9170_BAW_BITS);
332		ADD(buf, *len, bufsize, "\tLast Seq: %*s\n", offset, "N");
333
334		ADD(buf, *len, bufsize, "\tPre-Aggregation reorder buffer: "
335		    " currently queued:%d\n", skb_queue_len(&iter->queue));
336
337		fc = 0;
338		skb_queue_walk(&iter->queue, skb) {
339			char prefix[32];
340
341			snprintf(prefix, sizeof(prefix), "\t\t%3d :", fc);
342			carl9170_debugfs_format_frame(ar, skb, prefix, buf,
343						      len, bufsize);
344
345			fc++;
346		}
347		spin_unlock_bh(&iter->lock);
348		cnt++;
349	}
350	rcu_read_unlock();
351
352	return buf;
353}
354DEBUGFS_DECLARE_RO_FILE(ampdu_state, 8000);
355
356static void carl9170_debugfs_queue_dump(struct ar9170 *ar, char *buf,
357	ssize_t *len, size_t bufsize, struct sk_buff_head *queue)
358{
359	struct sk_buff *skb;
360	char prefix[16];
361	int fc = 0;
362
363	spin_lock_bh(&queue->lock);
364	skb_queue_walk(queue, skb) {
365		snprintf(prefix, sizeof(prefix), "%3d :", fc);
366		carl9170_debugfs_format_frame(ar, skb, prefix, buf,
367					      len, bufsize);
368		fc++;
369	}
370	spin_unlock_bh(&queue->lock);
371}
372
373#define DEBUGFS_QUEUE_DUMP(q, qi)					\
374static char *carl9170_debugfs_##q ##_##qi ##_read(struct ar9170 *ar,	\
375	char *buf, size_t bufsize, ssize_t *len)			\
376{									\
377	carl9170_debugfs_queue_dump(ar, buf, len, bufsize, &ar->q[qi]);	\
378	return buf;							\
379}									\
380DEBUGFS_DECLARE_RO_FILE(q##_##qi, 8000);
381
382static char *carl9170_debugfs_sta_psm_read(struct ar9170 *ar, char *buf,
383					   size_t bufsize, ssize_t *len)
384{
385	ADD(buf, *len, bufsize, "psm state: %s\n", (ar->ps.off_override ?
386	    "FORCE CAM" : (ar->ps.state ? "PSM" : "CAM")));
387
388	ADD(buf, *len, bufsize, "sleep duration: %d ms.\n", ar->ps.sleep_ms);
389	ADD(buf, *len, bufsize, "last power-state transition: %d ms ago.\n",
390	    jiffies_to_msecs(jiffies - ar->ps.last_action));
391	ADD(buf, *len, bufsize, "last CAM->PSM transition: %d ms ago.\n",
392	    jiffies_to_msecs(jiffies - ar->ps.last_slept));
393
394	return buf;
395}
396DEBUGFS_DECLARE_RO_FILE(sta_psm, 160);
397
398static char *carl9170_debugfs_tx_stuck_read(struct ar9170 *ar, char *buf,
399					    size_t bufsize, ssize_t *len)
400{
401	int i;
402
403	for (i = 0; i < ar->hw->queues; i++) {
404		ADD(buf, *len, bufsize, "TX queue [%d]: %10d max:%10d ms.\n",
405		    i, ieee80211_queue_stopped(ar->hw, i) ?
406		    jiffies_to_msecs(jiffies - ar->queue_stop_timeout[i]) : 0,
407		    jiffies_to_msecs(ar->max_queue_stop_timeout[i]));
408
409		ar->max_queue_stop_timeout[i] = 0;
410	}
411
412	return buf;
413}
414DEBUGFS_DECLARE_RO_FILE(tx_stuck, 180);
415
416static char *carl9170_debugfs_phy_noise_read(struct ar9170 *ar, char *buf,
417					     size_t bufsize, ssize_t *len)
418{
419	int err;
420
421	err = carl9170_get_noisefloor(ar);
422	if (err) {
423		*len = err;
424		return buf;
425	}
426
427	ADD(buf, *len, bufsize, "Chain 0: %10d dBm, ext. chan.:%10d dBm\n",
428	    ar->noise[0], ar->noise[2]);
429	ADD(buf, *len, bufsize, "Chain 2: %10d dBm, ext. chan.:%10d dBm\n",
430	    ar->noise[1], ar->noise[3]);
431
432	return buf;
433}
434DEBUGFS_DECLARE_RO_FILE(phy_noise, 180);
435
436static char *carl9170_debugfs_vif_dump_read(struct ar9170 *ar, char *buf,
437					    size_t bufsize, ssize_t *len)
438{
439	struct carl9170_vif_info *iter;
440	int i = 0;
441
442	ADD(buf, *len, bufsize, "registered VIFs:%d \\ %d\n",
443	    ar->vifs, ar->fw.vif_num);
444
445	ADD(buf, *len, bufsize, "VIF bitmap: [%*pb]\n",
446	    ar->fw.vif_num, &ar->vif_bitmap);
447
448	rcu_read_lock();
449	list_for_each_entry_rcu(iter, &ar->vif_list, list) {
450		struct ieee80211_vif *vif = carl9170_get_vif(iter);
451		ADD(buf, *len, bufsize, "\t%d = [%s VIF, id:%d, type:%x "
452		    " mac:%pM %s]\n", i, (carl9170_get_main_vif(ar) == vif ?
453		    "Master" : " Slave"), iter->id, vif->type, vif->addr,
454		    iter->enable_beacon ? "beaconing " : "");
455		i++;
456	}
457	rcu_read_unlock();
458
459	return buf;
460}
461DEBUGFS_DECLARE_RO_FILE(vif_dump, 8000);
462
463#define UPDATE_COUNTER(ar, name)	({				\
464	u32 __tmp[ARRAY_SIZE(name##_regs)];				\
465	unsigned int __i, __err = -ENODEV;				\
466									\
467	for (__i = 0; __i < ARRAY_SIZE(name##_regs); __i++) {		\
468		__tmp[__i] = name##_regs[__i].reg;			\
469		ar->debug.stats.name##_counter[__i] = 0;		\
470	}								\
471									\
472	if (IS_STARTED(ar))						\
473		__err = carl9170_read_mreg(ar, ARRAY_SIZE(name##_regs),	\
474			__tmp, ar->debug.stats.name##_counter);		\
475	(__err); })
476
477#define TALLY_SUM_UP(ar, name)	do {					\
478	unsigned int __i;						\
479									\
480	for (__i = 0; __i < ARRAY_SIZE(name##_regs); __i++) {		\
481		ar->debug.stats.name##_sum[__i] +=			\
482			ar->debug.stats.name##_counter[__i];		\
483	}								\
484} while (0)
485
486#define DEBUGFS_HW_TALLY_FILE(name, f)					\
487static char *carl9170_debugfs_##name ## _read(struct ar9170 *ar,	\
488	 char *dum, size_t bufsize, ssize_t *ret)			\
489{									\
490	char *buf;							\
491	int i, max_len, err;						\
492									\
493	max_len = ARRAY_SIZE(name##_regs) * 80;				\
494	buf = vmalloc(max_len);						\
495	if (!buf)							\
496		return NULL;						\
497									\
498	err = UPDATE_COUNTER(ar, name);					\
499	if (err) {							\
500		*ret = err;						\
501		return buf;						\
502	}								\
503									\
504	TALLY_SUM_UP(ar, name);						\
505									\
506	for (i = 0; i < ARRAY_SIZE(name##_regs); i++) {			\
507		ADD(buf, *ret, max_len, "%22s = %" f "[+%" f "]\n",	\
508		    name##_regs[i].nreg, ar->debug.stats.name ##_sum[i],\
509		    ar->debug.stats.name ##_counter[i]);		\
510	}								\
511									\
512	return buf;							\
513}									\
514DEBUGFS_DECLARE_RO_FILE(name, 0);
515
516#define DEBUGFS_HW_REG_FILE(name, f)					\
517static char *carl9170_debugfs_##name ## _read(struct ar9170 *ar,	\
518	char *dum, size_t bufsize, ssize_t *ret)			\
519{									\
520	char *buf;							\
521	int i, max_len, err;						\
522									\
523	max_len = ARRAY_SIZE(name##_regs) * 80;				\
524	buf = vmalloc(max_len);						\
525	if (!buf)							\
526		return NULL;						\
527									\
528	err = UPDATE_COUNTER(ar, name);					\
529	if (err) {							\
530		*ret = err;						\
531		return buf;						\
532	}								\
533									\
534	for (i = 0; i < ARRAY_SIZE(name##_regs); i++) {			\
535		ADD(buf, *ret, max_len, "%22s = %" f "\n",		\
536		    name##_regs[i].nreg,				\
537		    ar->debug.stats.name##_counter[i]);			\
538	}								\
539									\
540	return buf;							\
541}									\
542DEBUGFS_DECLARE_RO_FILE(name, 0);
543
544static ssize_t carl9170_debugfs_hw_ioread32_write(struct ar9170 *ar,
545	const char *buf, size_t count)
546{
547	int err = 0, i, n = 0, max_len = 32, res;
548	unsigned int reg, tmp;
549
550	if (!count)
551		return 0;
552
553	if (count > max_len)
554		return -E2BIG;
555
556	res = sscanf(buf, "0x%X %d", &reg, &n);
557	if (res < 1) {
558		err = -EINVAL;
559		goto out;
560	}
561
562	if (res == 1)
563		n = 1;
564
565	if (n > 15) {
566		err = -EMSGSIZE;
567		goto out;
568	}
569
570	if ((reg >= 0x280000) || ((reg + (n << 2)) >= 0x280000)) {
571		err = -EADDRNOTAVAIL;
572		goto out;
573	}
574
575	if (reg & 3) {
576		err = -EINVAL;
577		goto out;
578	}
579
580	for (i = 0; i < n; i++) {
581		err = carl9170_read_reg(ar, reg + (i << 2), &tmp);
582		if (err)
583			goto out;
584
585		ar->debug.ring[ar->debug.ring_tail].reg = reg + (i << 2);
586		ar->debug.ring[ar->debug.ring_tail].value = tmp;
587		ar->debug.ring_tail++;
588		ar->debug.ring_tail %= CARL9170_DEBUG_RING_SIZE;
589	}
590
591out:
592	return err ? err : count;
593}
594
595static char *carl9170_debugfs_hw_ioread32_read(struct ar9170 *ar, char *buf,
596					       size_t bufsize, ssize_t *ret)
597{
598	int i = 0;
599
600	while (ar->debug.ring_head != ar->debug.ring_tail) {
601		ADD(buf, *ret, bufsize, "%.8x = %.8x\n",
602		    ar->debug.ring[ar->debug.ring_head].reg,
603		    ar->debug.ring[ar->debug.ring_head].value);
604
605		ar->debug.ring_head++;
606		ar->debug.ring_head %= CARL9170_DEBUG_RING_SIZE;
607
608		if (i++ == 64)
609			break;
610	}
611	ar->debug.ring_head = ar->debug.ring_tail;
612	return buf;
613}
614DEBUGFS_DECLARE_RW_FILE(hw_ioread32, CARL9170_DEBUG_RING_SIZE * 40);
615
616static ssize_t carl9170_debugfs_bug_write(struct ar9170 *ar, const char *buf,
617					  size_t count)
618{
619	int err;
620
621	if (count < 1)
622		return -EINVAL;
623
624	switch (buf[0]) {
625	case 'F':
626		ar->needs_full_reset = true;
627		break;
628
629	case 'R':
630		if (!IS_STARTED(ar)) {
631			err = -EAGAIN;
632			goto out;
633		}
634
635		ar->needs_full_reset = false;
636		break;
637
638	case 'M':
639		err = carl9170_mac_reset(ar);
640		if (err < 0)
641			count = err;
642
643		goto out;
644
645	case 'P':
646		err = carl9170_set_channel(ar, ar->hw->conf.chandef.chan,
647			cfg80211_get_chandef_type(&ar->hw->conf.chandef));
648		if (err < 0)
649			count = err;
650
651		goto out;
652
653	default:
654		return -EINVAL;
655	}
656
657	carl9170_restart(ar, CARL9170_RR_USER_REQUEST);
658
659out:
660	return count;
661}
662
663static char *carl9170_debugfs_bug_read(struct ar9170 *ar, char *buf,
664				       size_t bufsize, ssize_t *ret)
665{
666	ADD(buf, *ret, bufsize, "[P]hy reinit, [R]estart, [F]ull usb reset, "
667	    "[M]ac reset\n");
668	ADD(buf, *ret, bufsize, "firmware restarts:%d, last reason:%d\n",
669		ar->restart_counter, ar->last_reason);
670	ADD(buf, *ret, bufsize, "phy reinit errors:%d (%d)\n",
671		ar->total_chan_fail, ar->chan_fail);
672	ADD(buf, *ret, bufsize, "reported firmware errors:%d\n",
673		ar->fw.err_counter);
674	ADD(buf, *ret, bufsize, "reported firmware BUGs:%d\n",
675		ar->fw.bug_counter);
676	ADD(buf, *ret, bufsize, "pending restart requests:%d\n",
677		atomic_read(&ar->pending_restarts));
678	return buf;
679}
680__DEBUGFS_DECLARE_RW_FILE(bug, 400, CARL9170_STOPPED);
681
682static const char *const erp_modes[] = {
683	[CARL9170_ERP_INVALID] = "INVALID",
684	[CARL9170_ERP_AUTO] = "Automatic",
685	[CARL9170_ERP_MAC80211] = "Set by MAC80211",
686	[CARL9170_ERP_OFF] = "Force Off",
687	[CARL9170_ERP_RTS] = "Force RTS",
688	[CARL9170_ERP_CTS] = "Force CTS"
689};
690
691static char *carl9170_debugfs_erp_read(struct ar9170 *ar, char *buf,
692				       size_t bufsize, ssize_t *ret)
693{
694	ADD(buf, *ret, bufsize, "ERP Setting: (%d) -> %s\n", ar->erp_mode,
695	    erp_modes[ar->erp_mode]);
696	return buf;
697}
698
699static ssize_t carl9170_debugfs_erp_write(struct ar9170 *ar, const char *buf,
700					  size_t count)
701{
702	int res, val;
703
704	if (count < 1)
705		return -EINVAL;
706
707	res = sscanf(buf, "%d", &val);
708	if (res != 1)
709		return -EINVAL;
710
711	if (!((val > CARL9170_ERP_INVALID) &&
712	      (val < __CARL9170_ERP_NUM)))
713		return -EINVAL;
714
715	ar->erp_mode = val;
716	return count;
717}
718
719DEBUGFS_DECLARE_RW_FILE(erp, 80);
720
721static ssize_t carl9170_debugfs_hw_iowrite32_write(struct ar9170 *ar,
722	const char *buf, size_t count)
723{
724	int err = 0, max_len = 22, res;
725	u32 reg, val;
726
727	if (!count)
728		return 0;
729
730	if (count > max_len)
731		return -E2BIG;
732
733	res = sscanf(buf, "0x%X 0x%X", &reg, &val);
734	if (res != 2) {
735		err = -EINVAL;
736		goto out;
737	}
738
739	if (reg <= 0x100000 || reg >= 0x280000) {
740		err = -EADDRNOTAVAIL;
741		goto out;
742	}
743
744	if (reg & 3) {
745		err = -EINVAL;
746		goto out;
747	}
748
749	err = carl9170_write_reg(ar, reg, val);
750	if (err)
751		goto out;
752
753out:
754	return err ? err : count;
755}
756DEBUGFS_DECLARE_WO_FILE(hw_iowrite32);
757
758DEBUGFS_HW_TALLY_FILE(hw_tx_tally, "u");
759DEBUGFS_HW_TALLY_FILE(hw_rx_tally, "u");
760DEBUGFS_HW_TALLY_FILE(hw_phy_errors, "u");
761DEBUGFS_HW_REG_FILE(hw_wlan_queue, ".8x");
762DEBUGFS_HW_REG_FILE(hw_pta_queue, ".8x");
763DEBUGFS_HW_REG_FILE(hw_ampdu_info, ".8x");
764DEBUGFS_QUEUE_DUMP(tx_status, 0);
765DEBUGFS_QUEUE_DUMP(tx_status, 1);
766DEBUGFS_QUEUE_DUMP(tx_status, 2);
767DEBUGFS_QUEUE_DUMP(tx_status, 3);
768DEBUGFS_QUEUE_DUMP(tx_pending, 0);
769DEBUGFS_QUEUE_DUMP(tx_pending, 1);
770DEBUGFS_QUEUE_DUMP(tx_pending, 2);
771DEBUGFS_QUEUE_DUMP(tx_pending, 3);
772DEBUGFS_READONLY_FILE(usb_tx_anch_urbs, 20, "%d",
773		      atomic_read(&ar->tx_anch_urbs));
774DEBUGFS_READONLY_FILE(usb_rx_anch_urbs, 20, "%d",
775		      atomic_read(&ar->rx_anch_urbs));
776DEBUGFS_READONLY_FILE(usb_rx_work_urbs, 20, "%d",
777		      atomic_read(&ar->rx_work_urbs));
778DEBUGFS_READONLY_FILE(usb_rx_pool_urbs, 20, "%d",
779		      atomic_read(&ar->rx_pool_urbs));
780
781DEBUGFS_READONLY_FILE(tx_total_queued, 20, "%d",
782		      atomic_read(&ar->tx_total_queued));
783DEBUGFS_READONLY_FILE(tx_ampdu_scheduler, 20, "%d",
784		      atomic_read(&ar->tx_ampdu_scheduler));
785
786DEBUGFS_READONLY_FILE(tx_total_pending, 20, "%d",
787		      atomic_read(&ar->tx_total_pending));
788
789DEBUGFS_READONLY_FILE(tx_ampdu_list_len, 20, "%d",
790		      ar->tx_ampdu_list_len);
791
792DEBUGFS_READONLY_FILE(tx_ampdu_upload, 20, "%d",
793		      atomic_read(&ar->tx_ampdu_upload));
794
795DEBUGFS_READONLY_FILE(tx_janitor_last_run, 64, "last run:%d ms ago",
796	jiffies_to_msecs(jiffies - ar->tx_janitor_last_run));
797
798DEBUGFS_READONLY_FILE(tx_dropped, 20, "%d", ar->tx_dropped);
799
800DEBUGFS_READONLY_FILE(rx_dropped, 20, "%d", ar->rx_dropped);
801
802DEBUGFS_READONLY_FILE(sniffer_enabled, 20, "%d", ar->sniffer_enabled);
803DEBUGFS_READONLY_FILE(rx_software_decryption, 20, "%d",
804		      ar->rx_software_decryption);
805DEBUGFS_READONLY_FILE(ampdu_factor, 20, "%d",
806		      ar->current_factor);
807DEBUGFS_READONLY_FILE(ampdu_density, 20, "%d",
808		      ar->current_density);
809
810DEBUGFS_READONLY_FILE(beacon_int, 20, "%d TU", ar->global_beacon_int);
811DEBUGFS_READONLY_FILE(pretbtt, 20, "%d TU", ar->global_pretbtt);
812
813void carl9170_debugfs_register(struct ar9170 *ar)
814{
815	ar->debug_dir = debugfs_create_dir(KBUILD_MODNAME,
816		ar->hw->wiphy->debugfsdir);
817
818#define DEBUGFS_ADD(name)						\
819	debugfs_create_file(#name, carl_debugfs_##name ##_ops.attr,	\
820			    ar->debug_dir, ar,				\
821			    &carl_debugfs_##name ## _ops.fops)
822
823	DEBUGFS_ADD(usb_tx_anch_urbs);
824	DEBUGFS_ADD(usb_rx_pool_urbs);
825	DEBUGFS_ADD(usb_rx_anch_urbs);
826	DEBUGFS_ADD(usb_rx_work_urbs);
827
828	DEBUGFS_ADD(tx_total_queued);
829	DEBUGFS_ADD(tx_total_pending);
830	DEBUGFS_ADD(tx_dropped);
831	DEBUGFS_ADD(tx_stuck);
832	DEBUGFS_ADD(tx_ampdu_upload);
833	DEBUGFS_ADD(tx_ampdu_scheduler);
834	DEBUGFS_ADD(tx_ampdu_list_len);
835
836	DEBUGFS_ADD(rx_dropped);
837	DEBUGFS_ADD(sniffer_enabled);
838	DEBUGFS_ADD(rx_software_decryption);
839
840	DEBUGFS_ADD(mem_usage);
841	DEBUGFS_ADD(qos_stat);
842	DEBUGFS_ADD(sta_psm);
843	DEBUGFS_ADD(ampdu_state);
844
845	DEBUGFS_ADD(hw_tx_tally);
846	DEBUGFS_ADD(hw_rx_tally);
847	DEBUGFS_ADD(hw_phy_errors);
848	DEBUGFS_ADD(phy_noise);
849
850	DEBUGFS_ADD(hw_wlan_queue);
851	DEBUGFS_ADD(hw_pta_queue);
852	DEBUGFS_ADD(hw_ampdu_info);
853
854	DEBUGFS_ADD(ampdu_density);
855	DEBUGFS_ADD(ampdu_factor);
856
857	DEBUGFS_ADD(tx_janitor_last_run);
858
859	DEBUGFS_ADD(tx_status_0);
860	DEBUGFS_ADD(tx_status_1);
861	DEBUGFS_ADD(tx_status_2);
862	DEBUGFS_ADD(tx_status_3);
863
864	DEBUGFS_ADD(tx_pending_0);
865	DEBUGFS_ADD(tx_pending_1);
866	DEBUGFS_ADD(tx_pending_2);
867	DEBUGFS_ADD(tx_pending_3);
868
869	DEBUGFS_ADD(hw_ioread32);
870	DEBUGFS_ADD(hw_iowrite32);
871	DEBUGFS_ADD(bug);
872
873	DEBUGFS_ADD(erp);
874
875	DEBUGFS_ADD(vif_dump);
876
877	DEBUGFS_ADD(beacon_int);
878	DEBUGFS_ADD(pretbtt);
879
880#undef DEBUGFS_ADD
881}
882
883void carl9170_debugfs_unregister(struct ar9170 *ar)
884{
885	debugfs_remove_recursive(ar->debug_dir);
886}
887