Linux Audio

Check our new training course

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