1bdcd8170SKalle Valo /*
2bdcd8170SKalle Valo  * Copyright (c) 2004-2011 Atheros Communications Inc.
3bdcd8170SKalle Valo  *
4bdcd8170SKalle Valo  * Permission to use, copy, modify, and/or distribute this software for any
5bdcd8170SKalle Valo  * purpose with or without fee is hereby granted, provided that the above
6bdcd8170SKalle Valo  * copyright notice and this permission notice appear in all copies.
7bdcd8170SKalle Valo  *
8bdcd8170SKalle Valo  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9bdcd8170SKalle Valo  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10bdcd8170SKalle Valo  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11bdcd8170SKalle Valo  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12bdcd8170SKalle Valo  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13bdcd8170SKalle Valo  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14bdcd8170SKalle Valo  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15bdcd8170SKalle Valo  */
16bdcd8170SKalle Valo 
17bdcd8170SKalle Valo #include "core.h"
18bdcd8170SKalle Valo #include "debug.h"
19bdcd8170SKalle Valo 
20bdcd8170SKalle Valo int ath6kl_printk(const char *level, const char *fmt, ...)
21bdcd8170SKalle Valo {
22bdcd8170SKalle Valo 	struct va_format vaf;
23bdcd8170SKalle Valo 	va_list args;
24bdcd8170SKalle Valo 	int rtn;
25bdcd8170SKalle Valo 
26bdcd8170SKalle Valo 	va_start(args, fmt);
27bdcd8170SKalle Valo 
28bdcd8170SKalle Valo 	vaf.fmt = fmt;
29bdcd8170SKalle Valo 	vaf.va = &args;
30bdcd8170SKalle Valo 
31bdcd8170SKalle Valo 	rtn = printk("%sath6kl: %pV", level, &vaf);
32bdcd8170SKalle Valo 
33bdcd8170SKalle Valo 	va_end(args);
34bdcd8170SKalle Valo 
35bdcd8170SKalle Valo 	return rtn;
36bdcd8170SKalle Valo }
37bdcd8170SKalle Valo 
38bdcd8170SKalle Valo #ifdef CONFIG_ATH6KL_DEBUG
39bdcd8170SKalle Valo void ath6kl_dump_registers(struct ath6kl_device *dev,
40bdcd8170SKalle Valo 			   struct ath6kl_irq_proc_registers *irq_proc_reg,
41bdcd8170SKalle Valo 			   struct ath6kl_irq_enable_reg *irq_enable_reg)
42bdcd8170SKalle Valo {
43bdcd8170SKalle Valo 
44bdcd8170SKalle Valo 	ath6kl_dbg(ATH6KL_DBG_ANY, ("<------- Register Table -------->\n"));
45bdcd8170SKalle Valo 
46bdcd8170SKalle Valo 	if (irq_proc_reg != NULL) {
47bdcd8170SKalle Valo 		ath6kl_dbg(ATH6KL_DBG_ANY,
48bdcd8170SKalle Valo 			"Host Int status:           0x%x\n",
49bdcd8170SKalle Valo 			irq_proc_reg->host_int_status);
50bdcd8170SKalle Valo 		ath6kl_dbg(ATH6KL_DBG_ANY,
51bdcd8170SKalle Valo 			   "CPU Int status:            0x%x\n",
52bdcd8170SKalle Valo 			irq_proc_reg->cpu_int_status);
53bdcd8170SKalle Valo 		ath6kl_dbg(ATH6KL_DBG_ANY,
54bdcd8170SKalle Valo 			   "Error Int status:          0x%x\n",
55bdcd8170SKalle Valo 			irq_proc_reg->error_int_status);
56bdcd8170SKalle Valo 		ath6kl_dbg(ATH6KL_DBG_ANY,
57bdcd8170SKalle Valo 			   "Counter Int status:        0x%x\n",
58bdcd8170SKalle Valo 			irq_proc_reg->counter_int_status);
59bdcd8170SKalle Valo 		ath6kl_dbg(ATH6KL_DBG_ANY,
60bdcd8170SKalle Valo 			   "Mbox Frame:                0x%x\n",
61bdcd8170SKalle Valo 			irq_proc_reg->mbox_frame);
62bdcd8170SKalle Valo 		ath6kl_dbg(ATH6KL_DBG_ANY,
63bdcd8170SKalle Valo 			   "Rx Lookahead Valid:        0x%x\n",
64bdcd8170SKalle Valo 			irq_proc_reg->rx_lkahd_valid);
65bdcd8170SKalle Valo 		ath6kl_dbg(ATH6KL_DBG_ANY,
66bdcd8170SKalle Valo 			   "Rx Lookahead 0:            0x%x\n",
67bdcd8170SKalle Valo 			irq_proc_reg->rx_lkahd[0]);
68bdcd8170SKalle Valo 		ath6kl_dbg(ATH6KL_DBG_ANY,
69bdcd8170SKalle Valo 			   "Rx Lookahead 1:            0x%x\n",
70bdcd8170SKalle Valo 			irq_proc_reg->rx_lkahd[1]);
71bdcd8170SKalle Valo 
72bdcd8170SKalle Valo 		if (dev->ar->mbox_info.gmbox_addr != 0) {
73bdcd8170SKalle Valo 			/*
74bdcd8170SKalle Valo 			 * If the target supports GMBOX hardware, dump some
75bdcd8170SKalle Valo 			 * additional state.
76bdcd8170SKalle Valo 			 */
77bdcd8170SKalle Valo 			ath6kl_dbg(ATH6KL_DBG_ANY,
78bdcd8170SKalle Valo 				"GMBOX Host Int status 2:   0x%x\n",
79bdcd8170SKalle Valo 				irq_proc_reg->host_int_status2);
80bdcd8170SKalle Valo 			ath6kl_dbg(ATH6KL_DBG_ANY,
81bdcd8170SKalle Valo 				"GMBOX RX Avail:            0x%x\n",
82bdcd8170SKalle Valo 				irq_proc_reg->gmbox_rx_avail);
83bdcd8170SKalle Valo 			ath6kl_dbg(ATH6KL_DBG_ANY,
84bdcd8170SKalle Valo 				"GMBOX lookahead alias 0:   0x%x\n",
85bdcd8170SKalle Valo 				irq_proc_reg->rx_gmbox_lkahd_alias[0]);
86bdcd8170SKalle Valo 			ath6kl_dbg(ATH6KL_DBG_ANY,
87bdcd8170SKalle Valo 				"GMBOX lookahead alias 1:   0x%x\n",
88bdcd8170SKalle Valo 				irq_proc_reg->rx_gmbox_lkahd_alias[1]);
89bdcd8170SKalle Valo 		}
90bdcd8170SKalle Valo 
91bdcd8170SKalle Valo 	}
92bdcd8170SKalle Valo 
93bdcd8170SKalle Valo 	if (irq_enable_reg != NULL) {
94bdcd8170SKalle Valo 		ath6kl_dbg(ATH6KL_DBG_ANY,
95bdcd8170SKalle Valo 			"Int status Enable:         0x%x\n",
96bdcd8170SKalle Valo 			irq_enable_reg->int_status_en);
97bdcd8170SKalle Valo 		ath6kl_dbg(ATH6KL_DBG_ANY, "Counter Int status Enable: 0x%x\n",
98bdcd8170SKalle Valo 			irq_enable_reg->cntr_int_status_en);
99bdcd8170SKalle Valo 	}
100bdcd8170SKalle Valo 	ath6kl_dbg(ATH6KL_DBG_ANY, "<------------------------------->\n");
101bdcd8170SKalle Valo }
102bdcd8170SKalle Valo 
103bdcd8170SKalle Valo static void dump_cred_dist(struct htc_endpoint_credit_dist *ep_dist)
104bdcd8170SKalle Valo {
105bdcd8170SKalle Valo 	ath6kl_dbg(ATH6KL_DBG_ANY,
106bdcd8170SKalle Valo 		   "--- endpoint: %d  svc_id: 0x%X ---\n",
107bdcd8170SKalle Valo 		   ep_dist->endpoint, ep_dist->svc_id);
108bdcd8170SKalle Valo 	ath6kl_dbg(ATH6KL_DBG_ANY, " dist_flags     : 0x%X\n",
109bdcd8170SKalle Valo 		   ep_dist->dist_flags);
110bdcd8170SKalle Valo 	ath6kl_dbg(ATH6KL_DBG_ANY, " cred_norm      : %d\n",
111bdcd8170SKalle Valo 		   ep_dist->cred_norm);
112bdcd8170SKalle Valo 	ath6kl_dbg(ATH6KL_DBG_ANY, " cred_min       : %d\n",
113bdcd8170SKalle Valo 		   ep_dist->cred_min);
114bdcd8170SKalle Valo 	ath6kl_dbg(ATH6KL_DBG_ANY, " credits        : %d\n",
115bdcd8170SKalle Valo 		   ep_dist->credits);
116bdcd8170SKalle Valo 	ath6kl_dbg(ATH6KL_DBG_ANY, " cred_assngd    : %d\n",
117bdcd8170SKalle Valo 		   ep_dist->cred_assngd);
118bdcd8170SKalle Valo 	ath6kl_dbg(ATH6KL_DBG_ANY, " seek_cred      : %d\n",
119bdcd8170SKalle Valo 		   ep_dist->seek_cred);
120bdcd8170SKalle Valo 	ath6kl_dbg(ATH6KL_DBG_ANY, " cred_sz        : %d\n",
121bdcd8170SKalle Valo 		   ep_dist->cred_sz);
122bdcd8170SKalle Valo 	ath6kl_dbg(ATH6KL_DBG_ANY, " cred_per_msg   : %d\n",
123bdcd8170SKalle Valo 		   ep_dist->cred_per_msg);
124bdcd8170SKalle Valo 	ath6kl_dbg(ATH6KL_DBG_ANY, " cred_to_dist   : %d\n",
125bdcd8170SKalle Valo 		   ep_dist->cred_to_dist);
126bdcd8170SKalle Valo 	ath6kl_dbg(ATH6KL_DBG_ANY, " txq_depth      : %d\n",
127bdcd8170SKalle Valo 		   get_queue_depth(&((struct htc_endpoint *)
128bdcd8170SKalle Valo 				     ep_dist->htc_rsvd)->txq));
129bdcd8170SKalle Valo 	ath6kl_dbg(ATH6KL_DBG_ANY,
130bdcd8170SKalle Valo 		   "----------------------------------\n");
131bdcd8170SKalle Valo }
132bdcd8170SKalle Valo 
133bdcd8170SKalle Valo void dump_cred_dist_stats(struct htc_target *target)
134bdcd8170SKalle Valo {
135bdcd8170SKalle Valo 	struct htc_endpoint_credit_dist *ep_list;
136bdcd8170SKalle Valo 
137bdcd8170SKalle Valo 	if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_TRC))
138bdcd8170SKalle Valo 		return;
139bdcd8170SKalle Valo 
140bdcd8170SKalle Valo 	list_for_each_entry(ep_list, &target->cred_dist_list, list)
141bdcd8170SKalle Valo 		dump_cred_dist(ep_list);
142bdcd8170SKalle Valo 
143bdcd8170SKalle Valo 	ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:%p dist:%p\n",
144bdcd8170SKalle Valo 		   target->cred_dist_cntxt, NULL);
145bdcd8170SKalle Valo 	ath6kl_dbg(ATH6KL_DBG_TRC, "credit distribution, total : %d, free : %d\n",
146bdcd8170SKalle Valo 		   target->cred_dist_cntxt->total_avail_credits,
147bdcd8170SKalle Valo 		   target->cred_dist_cntxt->cur_free_credits);
148bdcd8170SKalle Valo }
149bdcd8170SKalle Valo 
15003f68a95SVasanthakumar Thiagarajan static int ath6kl_debugfs_open(struct inode *inode, struct file *file)
15103f68a95SVasanthakumar Thiagarajan {
15203f68a95SVasanthakumar Thiagarajan 	file->private_data = inode->i_private;
15303f68a95SVasanthakumar Thiagarajan 	return 0;
15403f68a95SVasanthakumar Thiagarajan }
15503f68a95SVasanthakumar Thiagarajan 
15603f68a95SVasanthakumar Thiagarajan static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
15703f68a95SVasanthakumar Thiagarajan 				   size_t count, loff_t *ppos)
15803f68a95SVasanthakumar Thiagarajan {
15903f68a95SVasanthakumar Thiagarajan 	struct ath6kl *ar = file->private_data;
16003f68a95SVasanthakumar Thiagarajan 	struct target_stats *tgt_stats = &ar->target_stats;
16103f68a95SVasanthakumar Thiagarajan 	char *buf;
16203f68a95SVasanthakumar Thiagarajan 	unsigned int len = 0, buf_len = 1500;
16303f68a95SVasanthakumar Thiagarajan 	int i;
16403f68a95SVasanthakumar Thiagarajan 	long left;
16503f68a95SVasanthakumar Thiagarajan 	ssize_t ret_cnt;
16603f68a95SVasanthakumar Thiagarajan 
16703f68a95SVasanthakumar Thiagarajan 	buf = kzalloc(buf_len, GFP_KERNEL);
16803f68a95SVasanthakumar Thiagarajan 	if (!buf)
16903f68a95SVasanthakumar Thiagarajan 		return -ENOMEM;
17003f68a95SVasanthakumar Thiagarajan 
17103f68a95SVasanthakumar Thiagarajan 	if (down_interruptible(&ar->sem)) {
17203f68a95SVasanthakumar Thiagarajan 		kfree(buf);
17303f68a95SVasanthakumar Thiagarajan 		return -EBUSY;
17403f68a95SVasanthakumar Thiagarajan 	}
17503f68a95SVasanthakumar Thiagarajan 
17603f68a95SVasanthakumar Thiagarajan 	set_bit(STATS_UPDATE_PEND, &ar->flag);
17703f68a95SVasanthakumar Thiagarajan 
17803f68a95SVasanthakumar Thiagarajan 	if (ath6kl_wmi_get_stats_cmd(ar->wmi)) {
17903f68a95SVasanthakumar Thiagarajan 		up(&ar->sem);
18003f68a95SVasanthakumar Thiagarajan 		kfree(buf);
18103f68a95SVasanthakumar Thiagarajan 		return -EIO;
18203f68a95SVasanthakumar Thiagarajan 	}
18303f68a95SVasanthakumar Thiagarajan 
18403f68a95SVasanthakumar Thiagarajan 	left = wait_event_interruptible_timeout(ar->event_wq,
18503f68a95SVasanthakumar Thiagarajan 						!test_bit(STATS_UPDATE_PEND,
18603f68a95SVasanthakumar Thiagarajan 						&ar->flag), WMI_TIMEOUT);
18703f68a95SVasanthakumar Thiagarajan 
18803f68a95SVasanthakumar Thiagarajan 	up(&ar->sem);
18903f68a95SVasanthakumar Thiagarajan 
19003f68a95SVasanthakumar Thiagarajan 	if (left <= 0) {
19103f68a95SVasanthakumar Thiagarajan 		kfree(buf);
19203f68a95SVasanthakumar Thiagarajan 		return -ETIMEDOUT;
19303f68a95SVasanthakumar Thiagarajan 	}
19403f68a95SVasanthakumar Thiagarajan 
19503f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "\n");
19603f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%25s\n",
19703f68a95SVasanthakumar Thiagarajan 			 "Target Tx stats");
19803f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%25s\n\n",
19903f68a95SVasanthakumar Thiagarajan 			 "=================");
20003f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
20103f68a95SVasanthakumar Thiagarajan 			 "Ucast packets", tgt_stats->tx_ucast_pkt);
20203f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
20303f68a95SVasanthakumar Thiagarajan 			 "Bcast packets", tgt_stats->tx_bcast_pkt);
20403f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
20503f68a95SVasanthakumar Thiagarajan 			 "Ucast byte", tgt_stats->tx_ucast_byte);
20603f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
20703f68a95SVasanthakumar Thiagarajan 			 "Bcast byte", tgt_stats->tx_bcast_byte);
20803f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
20903f68a95SVasanthakumar Thiagarajan 			 "Rts success cnt", tgt_stats->tx_rts_success_cnt);
21003f68a95SVasanthakumar Thiagarajan 	for (i = 0; i < 4; i++)
21103f68a95SVasanthakumar Thiagarajan 		len += scnprintf(buf + len, buf_len - len,
21203f68a95SVasanthakumar Thiagarajan 				 "%18s %d %10llu\n", "PER on ac",
21303f68a95SVasanthakumar Thiagarajan 				 i, tgt_stats->tx_pkt_per_ac[i]);
21403f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
21503f68a95SVasanthakumar Thiagarajan 			 "Error", tgt_stats->tx_err);
21603f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
21703f68a95SVasanthakumar Thiagarajan 			 "Fail count", tgt_stats->tx_fail_cnt);
21803f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
21903f68a95SVasanthakumar Thiagarajan 			 "Retry count", tgt_stats->tx_retry_cnt);
22003f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
22103f68a95SVasanthakumar Thiagarajan 			 "Multi retry cnt", tgt_stats->tx_mult_retry_cnt);
22203f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
22303f68a95SVasanthakumar Thiagarajan 			 "Rts fail cnt", tgt_stats->tx_rts_fail_cnt);
22403f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%25s %10llu\n\n",
22503f68a95SVasanthakumar Thiagarajan 			 "TKIP counter measure used",
22603f68a95SVasanthakumar Thiagarajan 			 tgt_stats->tkip_cnter_measures_invoked);
22703f68a95SVasanthakumar Thiagarajan 
22803f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%25s\n",
22903f68a95SVasanthakumar Thiagarajan 			 "Target Rx stats");
23003f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%25s\n",
23103f68a95SVasanthakumar Thiagarajan 			 "=================");
23203f68a95SVasanthakumar Thiagarajan 
23303f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
23403f68a95SVasanthakumar Thiagarajan 			 "Ucast packets", tgt_stats->rx_ucast_pkt);
23503f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10d\n",
23603f68a95SVasanthakumar Thiagarajan 			 "Ucast Rate", tgt_stats->rx_ucast_rate);
23703f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
23803f68a95SVasanthakumar Thiagarajan 			 "Bcast packets", tgt_stats->rx_bcast_pkt);
23903f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
24003f68a95SVasanthakumar Thiagarajan 			 "Ucast byte", tgt_stats->rx_ucast_byte);
24103f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
24203f68a95SVasanthakumar Thiagarajan 			 "Bcast byte", tgt_stats->rx_bcast_byte);
24303f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
24403f68a95SVasanthakumar Thiagarajan 			 "Fragmented pkt", tgt_stats->rx_frgment_pkt);
24503f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
24603f68a95SVasanthakumar Thiagarajan 			 "Error", tgt_stats->rx_err);
24703f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
24803f68a95SVasanthakumar Thiagarajan 			 "CRC Err", tgt_stats->rx_crc_err);
24903f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
25003f68a95SVasanthakumar Thiagarajan 			 "Key chache miss", tgt_stats->rx_key_cache_miss);
25103f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
25203f68a95SVasanthakumar Thiagarajan 			 "Decrypt Err", tgt_stats->rx_decrypt_err);
25303f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
25403f68a95SVasanthakumar Thiagarajan 			 "Duplicate frame", tgt_stats->rx_dupl_frame);
25503f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
25603f68a95SVasanthakumar Thiagarajan 			 "Tkip Mic failure", tgt_stats->tkip_local_mic_fail);
25703f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
25803f68a95SVasanthakumar Thiagarajan 			 "TKIP format err", tgt_stats->tkip_fmt_err);
25903f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
26003f68a95SVasanthakumar Thiagarajan 			 "CCMP format Err", tgt_stats->ccmp_fmt_err);
26103f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n\n",
26203f68a95SVasanthakumar Thiagarajan 			 "CCMP Replay Err", tgt_stats->ccmp_replays);
26303f68a95SVasanthakumar Thiagarajan 
26403f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%25s\n",
26503f68a95SVasanthakumar Thiagarajan 			 "Misc Target stats");
26603f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%25s\n",
26703f68a95SVasanthakumar Thiagarajan 			 "=================");
26803f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
26903f68a95SVasanthakumar Thiagarajan 			 "Beacon Miss count", tgt_stats->cs_bmiss_cnt);
27003f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
27103f68a95SVasanthakumar Thiagarajan 			 "Num Connects", tgt_stats->cs_connect_cnt);
27203f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
27303f68a95SVasanthakumar Thiagarajan 			 "Num disconnects", tgt_stats->cs_discon_cnt);
27403f68a95SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%20s %10d\n",
27503f68a95SVasanthakumar Thiagarajan 			 "Beacon avg rssi", tgt_stats->cs_ave_beacon_rssi);
27603f68a95SVasanthakumar Thiagarajan 
27703f68a95SVasanthakumar Thiagarajan 	if (len > buf_len)
27803f68a95SVasanthakumar Thiagarajan 		len = buf_len;
27903f68a95SVasanthakumar Thiagarajan 
28003f68a95SVasanthakumar Thiagarajan 	ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
28103f68a95SVasanthakumar Thiagarajan 
28203f68a95SVasanthakumar Thiagarajan 	kfree(buf);
28303f68a95SVasanthakumar Thiagarajan 	return ret_cnt;
28403f68a95SVasanthakumar Thiagarajan }
28503f68a95SVasanthakumar Thiagarajan 
28603f68a95SVasanthakumar Thiagarajan static const struct file_operations fops_tgt_stats = {
28703f68a95SVasanthakumar Thiagarajan 	.read = read_file_tgt_stats,
28803f68a95SVasanthakumar Thiagarajan 	.open = ath6kl_debugfs_open,
28903f68a95SVasanthakumar Thiagarajan 	.owner = THIS_MODULE,
29003f68a95SVasanthakumar Thiagarajan 	.llseek = default_llseek,
29103f68a95SVasanthakumar Thiagarajan };
29203f68a95SVasanthakumar Thiagarajan 
29378fc4856SVasanthakumar Thiagarajan #define print_credit_info(fmt_str, ep_list_field)		\
29478fc4856SVasanthakumar Thiagarajan 	(len += scnprintf(buf + len, buf_len - len, fmt_str,	\
29578fc4856SVasanthakumar Thiagarajan 			 ep_list->ep_list_field))
29678fc4856SVasanthakumar Thiagarajan #define CREDIT_INFO_DISPLAY_STRING_LEN	200
29778fc4856SVasanthakumar Thiagarajan #define CREDIT_INFO_LEN	128
29878fc4856SVasanthakumar Thiagarajan 
29978fc4856SVasanthakumar Thiagarajan static ssize_t read_file_credit_dist_stats(struct file *file,
30078fc4856SVasanthakumar Thiagarajan 					   char __user *user_buf,
30178fc4856SVasanthakumar Thiagarajan 					   size_t count, loff_t *ppos)
30278fc4856SVasanthakumar Thiagarajan {
30378fc4856SVasanthakumar Thiagarajan 	struct ath6kl *ar = file->private_data;
30478fc4856SVasanthakumar Thiagarajan 	struct htc_target *target = ar->htc_target;
30578fc4856SVasanthakumar Thiagarajan 	struct htc_endpoint_credit_dist *ep_list;
30678fc4856SVasanthakumar Thiagarajan 	char *buf;
30778fc4856SVasanthakumar Thiagarajan 	unsigned int buf_len, len = 0;
30878fc4856SVasanthakumar Thiagarajan 	ssize_t ret_cnt;
30978fc4856SVasanthakumar Thiagarajan 
31078fc4856SVasanthakumar Thiagarajan 	buf_len = CREDIT_INFO_DISPLAY_STRING_LEN +
31178fc4856SVasanthakumar Thiagarajan 		  get_queue_depth(&target->cred_dist_list) * CREDIT_INFO_LEN;
31278fc4856SVasanthakumar Thiagarajan 	buf = kzalloc(buf_len, GFP_KERNEL);
31378fc4856SVasanthakumar Thiagarajan 	if (!buf)
31478fc4856SVasanthakumar Thiagarajan 		return -ENOMEM;
31578fc4856SVasanthakumar Thiagarajan 
31678fc4856SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%25s%5d\n",
31778fc4856SVasanthakumar Thiagarajan 			 "Total Avail Credits: ",
31878fc4856SVasanthakumar Thiagarajan 			 target->cred_dist_cntxt->total_avail_credits);
31978fc4856SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len, "%25s%5d\n",
32078fc4856SVasanthakumar Thiagarajan 			 "Free credits :",
32178fc4856SVasanthakumar Thiagarajan 			 target->cred_dist_cntxt->cur_free_credits);
32278fc4856SVasanthakumar Thiagarajan 
32378fc4856SVasanthakumar Thiagarajan 	len += scnprintf(buf + len, buf_len - len,
32478fc4856SVasanthakumar Thiagarajan 			 " Epid  Flags    Cred_norm  Cred_min  Credits  Cred_assngd"
32578fc4856SVasanthakumar Thiagarajan 			 "  Seek_cred  Cred_sz  Cred_per_msg  Cred_to_dist"
32678fc4856SVasanthakumar Thiagarajan 			 "  qdepth\n");
32778fc4856SVasanthakumar Thiagarajan 
32878fc4856SVasanthakumar Thiagarajan 	list_for_each_entry(ep_list, &target->cred_dist_list, list) {
32978fc4856SVasanthakumar Thiagarajan 		print_credit_info("  %2d", endpoint);
33078fc4856SVasanthakumar Thiagarajan 		print_credit_info("%10x", dist_flags);
33178fc4856SVasanthakumar Thiagarajan 		print_credit_info("%8d", cred_norm);
33278fc4856SVasanthakumar Thiagarajan 		print_credit_info("%9d", cred_min);
33378fc4856SVasanthakumar Thiagarajan 		print_credit_info("%9d", credits);
33478fc4856SVasanthakumar Thiagarajan 		print_credit_info("%10d", cred_assngd);
33578fc4856SVasanthakumar Thiagarajan 		print_credit_info("%13d", seek_cred);
33678fc4856SVasanthakumar Thiagarajan 		print_credit_info("%12d", cred_sz);
33778fc4856SVasanthakumar Thiagarajan 		print_credit_info("%9d", cred_per_msg);
33878fc4856SVasanthakumar Thiagarajan 		print_credit_info("%14d", cred_to_dist);
33978fc4856SVasanthakumar Thiagarajan 		len += scnprintf(buf + len, buf_len - len, "%12d\n",
34078fc4856SVasanthakumar Thiagarajan 				 get_queue_depth(&((struct htc_endpoint *)
34178fc4856SVasanthakumar Thiagarajan 						 ep_list->htc_rsvd)->txq));
34278fc4856SVasanthakumar Thiagarajan 	}
34378fc4856SVasanthakumar Thiagarajan 
34478fc4856SVasanthakumar Thiagarajan 	if (len > buf_len)
34578fc4856SVasanthakumar Thiagarajan 		len = buf_len;
34678fc4856SVasanthakumar Thiagarajan 
34778fc4856SVasanthakumar Thiagarajan 	ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
34878fc4856SVasanthakumar Thiagarajan 	kfree(buf);
34978fc4856SVasanthakumar Thiagarajan 	return ret_cnt;
35078fc4856SVasanthakumar Thiagarajan }
35178fc4856SVasanthakumar Thiagarajan 
35278fc4856SVasanthakumar Thiagarajan static const struct file_operations fops_credit_dist_stats = {
35378fc4856SVasanthakumar Thiagarajan 	.read = read_file_credit_dist_stats,
35478fc4856SVasanthakumar Thiagarajan 	.open = ath6kl_debugfs_open,
35578fc4856SVasanthakumar Thiagarajan 	.owner = THIS_MODULE,
35678fc4856SVasanthakumar Thiagarajan 	.llseek = default_llseek,
35778fc4856SVasanthakumar Thiagarajan };
35878fc4856SVasanthakumar Thiagarajan 
359d999ba3eSVasanthakumar Thiagarajan int ath6kl_debug_init(struct ath6kl *ar)
360d999ba3eSVasanthakumar Thiagarajan {
361d999ba3eSVasanthakumar Thiagarajan 	ar->debugfs_phy = debugfs_create_dir("ath6kl",
362d999ba3eSVasanthakumar Thiagarajan 					     ar->wdev->wiphy->debugfsdir);
363d999ba3eSVasanthakumar Thiagarajan 	if (!ar->debugfs_phy)
364d999ba3eSVasanthakumar Thiagarajan 		return -ENOMEM;
365d999ba3eSVasanthakumar Thiagarajan 
36603f68a95SVasanthakumar Thiagarajan 	debugfs_create_file("tgt_stats", S_IRUSR, ar->debugfs_phy, ar,
36703f68a95SVasanthakumar Thiagarajan 			    &fops_tgt_stats);
36803f68a95SVasanthakumar Thiagarajan 
36978fc4856SVasanthakumar Thiagarajan 	debugfs_create_file("credit_dist_stats", S_IRUSR, ar->debugfs_phy, ar,
37078fc4856SVasanthakumar Thiagarajan 			    &fops_credit_dist_stats);
37178fc4856SVasanthakumar Thiagarajan 
372d999ba3eSVasanthakumar Thiagarajan 	return 0;
373d999ba3eSVasanthakumar Thiagarajan }
374bdcd8170SKalle Valo #endif
375