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}
v6.9.4
  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}