blob: 6b546dc6672803e51a06552591ea7c7ca931e3a2 [file] [log] [blame]
Kalle Valobdcd8172011-07-18 00:22:30 +03001/*
2 * Copyright (c) 2004-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "core.h"
Kalle Valobdf53962011-09-02 10:32:04 +030018
19#include <linux/circ_buf.h>
Kalle Valo939f1cc2011-09-02 10:32:04 +030020#include <linux/fs.h>
Kalle Valo62c83ac2011-10-03 13:44:40 +030021#include <linux/vmalloc.h>
Paul Gortmakeree40fa02011-05-27 16:14:23 -040022#include <linux/export.h>
Kalle Valobdf53962011-09-02 10:32:04 +030023
Kalle Valobdcd8172011-07-18 00:22:30 +030024#include "debug.h"
Kalle Valobdf53962011-09-02 10:32:04 +030025#include "target.h"
26
27struct ath6kl_fwlog_slot {
28 __le32 timestamp;
29 __le32 length;
30
31 /* max ATH6KL_FWLOG_PAYLOAD_SIZE bytes */
32 u8 payload[0];
33};
34
35#define ATH6KL_FWLOG_SIZE 32768
36#define ATH6KL_FWLOG_SLOT_SIZE (sizeof(struct ath6kl_fwlog_slot) + \
37 ATH6KL_FWLOG_PAYLOAD_SIZE)
Kalle Valo939f1cc2011-09-02 10:32:04 +030038#define ATH6KL_FWLOG_VALID_MASK 0x1ffff
Kalle Valobdcd8172011-07-18 00:22:30 +030039
40int ath6kl_printk(const char *level, const char *fmt, ...)
41{
42 struct va_format vaf;
43 va_list args;
44 int rtn;
45
46 va_start(args, fmt);
47
48 vaf.fmt = fmt;
49 vaf.va = &args;
50
51 rtn = printk("%sath6kl: %pV", level, &vaf);
52
53 va_end(args);
54
55 return rtn;
56}
Kalle Valod6a434d2012-01-17 20:09:36 +020057EXPORT_SYMBOL(ath6kl_printk);
Kalle Valobdcd8172011-07-18 00:22:30 +030058
59#ifdef CONFIG_ATH6KL_DEBUG
Vasanthakumar Thiagarajan91d57de2011-09-02 10:40:06 +030060
Kalle Valo3b1b7d02012-01-17 20:09:27 +020061void ath6kl_dbg(enum ATH6K_DEBUG_MASK mask, const char *fmt, ...)
62{
63 struct va_format vaf;
64 va_list args;
65
66 if (!(debug_mask & mask))
67 return;
68
69 va_start(args, fmt);
70
71 vaf.fmt = fmt;
72 vaf.va = &args;
73
74 ath6kl_printk(KERN_DEBUG, "%pV", &vaf);
75
76 va_end(args);
77}
Kalle Valod6a434d2012-01-17 20:09:36 +020078EXPORT_SYMBOL(ath6kl_dbg);
Kalle Valo3b1b7d02012-01-17 20:09:27 +020079
80void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
81 const char *msg, const char *prefix,
82 const void *buf, size_t len)
83{
84 if (debug_mask & mask) {
85 if (msg)
86 ath6kl_dbg(mask, "%s\n", msg);
87
88 print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len);
89 }
90}
Kalle Valod6a434d2012-01-17 20:09:36 +020091EXPORT_SYMBOL(ath6kl_dbg_dump);
Kalle Valo3b1b7d02012-01-17 20:09:27 +020092
Vasanthakumar Thiagarajan91d57de2011-09-02 10:40:06 +030093#define REG_OUTPUT_LEN_PER_LINE 25
94#define REGTYPE_STR_LEN 100
95
96struct ath6kl_diag_reg_info {
97 u32 reg_start;
98 u32 reg_end;
99 const char *reg_info;
100};
101
102static const struct ath6kl_diag_reg_info diag_reg[] = {
103 { 0x20000, 0x200fc, "General DMA and Rx registers" },
104 { 0x28000, 0x28900, "MAC PCU register & keycache" },
105 { 0x20800, 0x20a40, "QCU" },
106 { 0x21000, 0x212f0, "DCU" },
107 { 0x4000, 0x42e4, "RTC" },
108 { 0x540000, 0x540000 + (256 * 1024), "RAM" },
109 { 0x29800, 0x2B210, "Base Band" },
110 { 0x1C000, 0x1C748, "Analog" },
111};
112
Kalle Valobdcd8172011-07-18 00:22:30 +0300113void ath6kl_dump_registers(struct ath6kl_device *dev,
114 struct ath6kl_irq_proc_registers *irq_proc_reg,
115 struct ath6kl_irq_enable_reg *irq_enable_reg)
116{
117
Kalle Valo5afa5aa2012-01-17 20:09:19 +0200118 ath6kl_dbg(ATH6KL_DBG_IRQ, ("<------- Register Table -------->\n"));
Kalle Valobdcd8172011-07-18 00:22:30 +0300119
120 if (irq_proc_reg != NULL) {
Kalle Valo5afa5aa2012-01-17 20:09:19 +0200121 ath6kl_dbg(ATH6KL_DBG_IRQ,
Kalle Valobdcd8172011-07-18 00:22:30 +0300122 "Host Int status: 0x%x\n",
123 irq_proc_reg->host_int_status);
Kalle Valo5afa5aa2012-01-17 20:09:19 +0200124 ath6kl_dbg(ATH6KL_DBG_IRQ,
Kalle Valobdcd8172011-07-18 00:22:30 +0300125 "CPU Int status: 0x%x\n",
126 irq_proc_reg->cpu_int_status);
Kalle Valo5afa5aa2012-01-17 20:09:19 +0200127 ath6kl_dbg(ATH6KL_DBG_IRQ,
Kalle Valobdcd8172011-07-18 00:22:30 +0300128 "Error Int status: 0x%x\n",
129 irq_proc_reg->error_int_status);
Kalle Valo5afa5aa2012-01-17 20:09:19 +0200130 ath6kl_dbg(ATH6KL_DBG_IRQ,
Kalle Valobdcd8172011-07-18 00:22:30 +0300131 "Counter Int status: 0x%x\n",
132 irq_proc_reg->counter_int_status);
Kalle Valo5afa5aa2012-01-17 20:09:19 +0200133 ath6kl_dbg(ATH6KL_DBG_IRQ,
Kalle Valobdcd8172011-07-18 00:22:30 +0300134 "Mbox Frame: 0x%x\n",
135 irq_proc_reg->mbox_frame);
Kalle Valo5afa5aa2012-01-17 20:09:19 +0200136 ath6kl_dbg(ATH6KL_DBG_IRQ,
Kalle Valobdcd8172011-07-18 00:22:30 +0300137 "Rx Lookahead Valid: 0x%x\n",
138 irq_proc_reg->rx_lkahd_valid);
Kalle Valo5afa5aa2012-01-17 20:09:19 +0200139 ath6kl_dbg(ATH6KL_DBG_IRQ,
Kalle Valobdcd8172011-07-18 00:22:30 +0300140 "Rx Lookahead 0: 0x%x\n",
141 irq_proc_reg->rx_lkahd[0]);
Kalle Valo5afa5aa2012-01-17 20:09:19 +0200142 ath6kl_dbg(ATH6KL_DBG_IRQ,
Kalle Valobdcd8172011-07-18 00:22:30 +0300143 "Rx Lookahead 1: 0x%x\n",
144 irq_proc_reg->rx_lkahd[1]);
145
146 if (dev->ar->mbox_info.gmbox_addr != 0) {
147 /*
148 * If the target supports GMBOX hardware, dump some
149 * additional state.
150 */
Kalle Valo5afa5aa2012-01-17 20:09:19 +0200151 ath6kl_dbg(ATH6KL_DBG_IRQ,
Kalle Valobdcd8172011-07-18 00:22:30 +0300152 "GMBOX Host Int status 2: 0x%x\n",
153 irq_proc_reg->host_int_status2);
Kalle Valo5afa5aa2012-01-17 20:09:19 +0200154 ath6kl_dbg(ATH6KL_DBG_IRQ,
Kalle Valobdcd8172011-07-18 00:22:30 +0300155 "GMBOX RX Avail: 0x%x\n",
156 irq_proc_reg->gmbox_rx_avail);
Kalle Valo5afa5aa2012-01-17 20:09:19 +0200157 ath6kl_dbg(ATH6KL_DBG_IRQ,
Kalle Valobdcd8172011-07-18 00:22:30 +0300158 "GMBOX lookahead alias 0: 0x%x\n",
159 irq_proc_reg->rx_gmbox_lkahd_alias[0]);
Kalle Valo5afa5aa2012-01-17 20:09:19 +0200160 ath6kl_dbg(ATH6KL_DBG_IRQ,
Kalle Valobdcd8172011-07-18 00:22:30 +0300161 "GMBOX lookahead alias 1: 0x%x\n",
162 irq_proc_reg->rx_gmbox_lkahd_alias[1]);
163 }
164
165 }
166
167 if (irq_enable_reg != NULL) {
Kalle Valo5afa5aa2012-01-17 20:09:19 +0200168 ath6kl_dbg(ATH6KL_DBG_IRQ,
Kalle Valobdcd8172011-07-18 00:22:30 +0300169 "Int status Enable: 0x%x\n",
170 irq_enable_reg->int_status_en);
Kalle Valo5afa5aa2012-01-17 20:09:19 +0200171 ath6kl_dbg(ATH6KL_DBG_IRQ, "Counter Int status Enable: 0x%x\n",
Kalle Valobdcd8172011-07-18 00:22:30 +0300172 irq_enable_reg->cntr_int_status_en);
173 }
Kalle Valo5afa5aa2012-01-17 20:09:19 +0200174 ath6kl_dbg(ATH6KL_DBG_IRQ, "<------------------------------->\n");
Kalle Valobdcd8172011-07-18 00:22:30 +0300175}
176
177static void dump_cred_dist(struct htc_endpoint_credit_dist *ep_dist)
178{
Kalle Valo02f0d6f2011-10-24 12:17:59 +0300179 ath6kl_dbg(ATH6KL_DBG_CREDIT,
Kalle Valobdcd8172011-07-18 00:22:30 +0300180 "--- endpoint: %d svc_id: 0x%X ---\n",
181 ep_dist->endpoint, ep_dist->svc_id);
Kalle Valo02f0d6f2011-10-24 12:17:59 +0300182 ath6kl_dbg(ATH6KL_DBG_CREDIT, " dist_flags : 0x%X\n",
Kalle Valobdcd8172011-07-18 00:22:30 +0300183 ep_dist->dist_flags);
Kalle Valo02f0d6f2011-10-24 12:17:59 +0300184 ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_norm : %d\n",
Kalle Valobdcd8172011-07-18 00:22:30 +0300185 ep_dist->cred_norm);
Kalle Valo02f0d6f2011-10-24 12:17:59 +0300186 ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_min : %d\n",
Kalle Valobdcd8172011-07-18 00:22:30 +0300187 ep_dist->cred_min);
Kalle Valo02f0d6f2011-10-24 12:17:59 +0300188 ath6kl_dbg(ATH6KL_DBG_CREDIT, " credits : %d\n",
Kalle Valobdcd8172011-07-18 00:22:30 +0300189 ep_dist->credits);
Kalle Valo02f0d6f2011-10-24 12:17:59 +0300190 ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_assngd : %d\n",
Kalle Valobdcd8172011-07-18 00:22:30 +0300191 ep_dist->cred_assngd);
Kalle Valo02f0d6f2011-10-24 12:17:59 +0300192 ath6kl_dbg(ATH6KL_DBG_CREDIT, " seek_cred : %d\n",
Kalle Valobdcd8172011-07-18 00:22:30 +0300193 ep_dist->seek_cred);
Kalle Valo02f0d6f2011-10-24 12:17:59 +0300194 ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_sz : %d\n",
Kalle Valobdcd8172011-07-18 00:22:30 +0300195 ep_dist->cred_sz);
Kalle Valo02f0d6f2011-10-24 12:17:59 +0300196 ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_per_msg : %d\n",
Kalle Valobdcd8172011-07-18 00:22:30 +0300197 ep_dist->cred_per_msg);
Kalle Valo02f0d6f2011-10-24 12:17:59 +0300198 ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_to_dist : %d\n",
Kalle Valobdcd8172011-07-18 00:22:30 +0300199 ep_dist->cred_to_dist);
Kalle Valo02f0d6f2011-10-24 12:17:59 +0300200 ath6kl_dbg(ATH6KL_DBG_CREDIT, " txq_depth : %d\n",
Kalle Valoe8c39792011-10-24 12:17:04 +0300201 get_queue_depth(&ep_dist->htc_ep->txq));
Kalle Valo02f0d6f2011-10-24 12:17:59 +0300202 ath6kl_dbg(ATH6KL_DBG_CREDIT,
Kalle Valobdcd8172011-07-18 00:22:30 +0300203 "----------------------------------\n");
204}
205
Kalle Valo02f0d6f2011-10-24 12:17:59 +0300206/* FIXME: move to htc.c */
Kalle Valobdcd8172011-07-18 00:22:30 +0300207void dump_cred_dist_stats(struct htc_target *target)
208{
209 struct htc_endpoint_credit_dist *ep_list;
210
Kalle Valobdcd8172011-07-18 00:22:30 +0300211 list_for_each_entry(ep_list, &target->cred_dist_list, list)
212 dump_cred_dist(ep_list);
213
Kalle Valo02f0d6f2011-10-24 12:17:59 +0300214 ath6kl_dbg(ATH6KL_DBG_CREDIT,
215 "credit distribution total %d free %d\n",
Kalle Valo3c370392011-10-24 12:17:12 +0300216 target->credit_info->total_avail_credits,
217 target->credit_info->cur_free_credits);
Kalle Valobdcd8172011-07-18 00:22:30 +0300218}
219
Vasanthakumar Thiagarajan03f68a92011-08-26 13:06:32 +0530220static int ath6kl_debugfs_open(struct inode *inode, struct file *file)
221{
222 file->private_data = inode->i_private;
223 return 0;
224}
225
Kalle Valo9a730832011-09-27 23:33:28 +0300226void ath6kl_debug_war(struct ath6kl *ar, enum ath6kl_war war)
227{
228 switch (war) {
229 case ATH6KL_WAR_INVALID_RATE:
230 ar->debug.war_stats.invalid_rate++;
231 break;
232 }
233}
234
235static ssize_t read_file_war_stats(struct file *file, char __user *user_buf,
236 size_t count, loff_t *ppos)
237{
238 struct ath6kl *ar = file->private_data;
239 char *buf;
240 unsigned int len = 0, buf_len = 1500;
241 ssize_t ret_cnt;
242
243 buf = kzalloc(buf_len, GFP_KERNEL);
244 if (!buf)
245 return -ENOMEM;
246
247 len += scnprintf(buf + len, buf_len - len, "\n");
248 len += scnprintf(buf + len, buf_len - len, "%25s\n",
249 "Workaround stats");
250 len += scnprintf(buf + len, buf_len - len, "%25s\n\n",
251 "=================");
252 len += scnprintf(buf + len, buf_len - len, "%20s %10u\n",
253 "Invalid rates", ar->debug.war_stats.invalid_rate);
254
255 if (WARN_ON(len > buf_len))
256 len = buf_len;
257
258 ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
259
260 kfree(buf);
261 return ret_cnt;
262}
263
264static const struct file_operations fops_war_stats = {
265 .read = read_file_war_stats,
266 .open = ath6kl_debugfs_open,
267 .owner = THIS_MODULE,
268 .llseek = default_llseek,
269};
270
Kalle Valobdf53962011-09-02 10:32:04 +0300271static void ath6kl_debug_fwlog_add(struct ath6kl *ar, const void *buf,
272 size_t buf_len)
273{
274 struct circ_buf *fwlog = &ar->debug.fwlog_buf;
275 size_t space;
276 int i;
277
278 /* entries must all be equal size */
279 if (WARN_ON(buf_len != ATH6KL_FWLOG_SLOT_SIZE))
280 return;
281
282 space = CIRC_SPACE(fwlog->head, fwlog->tail, ATH6KL_FWLOG_SIZE);
283 if (space < buf_len)
284 /* discard oldest slot */
285 fwlog->tail = (fwlog->tail + ATH6KL_FWLOG_SLOT_SIZE) &
286 (ATH6KL_FWLOG_SIZE - 1);
287
288 for (i = 0; i < buf_len; i += space) {
289 space = CIRC_SPACE_TO_END(fwlog->head, fwlog->tail,
290 ATH6KL_FWLOG_SIZE);
291
292 if ((size_t) space > buf_len - i)
293 space = buf_len - i;
294
295 memcpy(&fwlog->buf[fwlog->head], buf, space);
296 fwlog->head = (fwlog->head + space) & (ATH6KL_FWLOG_SIZE - 1);
297 }
298
299}
300
301void ath6kl_debug_fwlog_event(struct ath6kl *ar, const void *buf, size_t len)
302{
303 struct ath6kl_fwlog_slot *slot = ar->debug.fwlog_tmp;
304 size_t slot_len;
305
306 if (WARN_ON(len > ATH6KL_FWLOG_PAYLOAD_SIZE))
307 return;
308
309 spin_lock_bh(&ar->debug.fwlog_lock);
310
311 slot->timestamp = cpu_to_le32(jiffies);
312 slot->length = cpu_to_le32(len);
313 memcpy(slot->payload, buf, len);
314
315 slot_len = sizeof(*slot) + len;
316
317 if (slot_len < ATH6KL_FWLOG_SLOT_SIZE)
318 memset(slot->payload + len, 0,
319 ATH6KL_FWLOG_SLOT_SIZE - slot_len);
320
321 ath6kl_debug_fwlog_add(ar, slot, ATH6KL_FWLOG_SLOT_SIZE);
322
323 spin_unlock_bh(&ar->debug.fwlog_lock);
324}
325
326static bool ath6kl_debug_fwlog_empty(struct ath6kl *ar)
327{
328 return CIRC_CNT(ar->debug.fwlog_buf.head,
329 ar->debug.fwlog_buf.tail,
330 ATH6KL_FWLOG_SLOT_SIZE) == 0;
331}
332
333static ssize_t ath6kl_fwlog_read(struct file *file, char __user *user_buf,
334 size_t count, loff_t *ppos)
335{
336 struct ath6kl *ar = file->private_data;
337 struct circ_buf *fwlog = &ar->debug.fwlog_buf;
338 size_t len = 0, buf_len = count;
339 ssize_t ret_cnt;
340 char *buf;
341 int ccnt;
342
343 buf = vmalloc(buf_len);
344 if (!buf)
345 return -ENOMEM;
346
Kalle Valobc07ddb2011-09-02 10:32:05 +0300347 /* read undelivered logs from firmware */
348 ath6kl_read_fwlogs(ar);
349
Kalle Valobdf53962011-09-02 10:32:04 +0300350 spin_lock_bh(&ar->debug.fwlog_lock);
351
352 while (len < buf_len && !ath6kl_debug_fwlog_empty(ar)) {
353 ccnt = CIRC_CNT_TO_END(fwlog->head, fwlog->tail,
354 ATH6KL_FWLOG_SIZE);
355
356 if ((size_t) ccnt > buf_len - len)
357 ccnt = buf_len - len;
358
359 memcpy(buf + len, &fwlog->buf[fwlog->tail], ccnt);
360 len += ccnt;
361
362 fwlog->tail = (fwlog->tail + ccnt) &
363 (ATH6KL_FWLOG_SIZE - 1);
364 }
365
366 spin_unlock_bh(&ar->debug.fwlog_lock);
367
368 if (WARN_ON(len > buf_len))
369 len = buf_len;
370
371 ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
372
373 vfree(buf);
374
375 return ret_cnt;
376}
377
378static const struct file_operations fops_fwlog = {
379 .open = ath6kl_debugfs_open,
380 .read = ath6kl_fwlog_read,
381 .owner = THIS_MODULE,
382 .llseek = default_llseek,
383};
384
Kalle Valo939f1cc2011-09-02 10:32:04 +0300385static ssize_t ath6kl_fwlog_mask_read(struct file *file, char __user *user_buf,
386 size_t count, loff_t *ppos)
387{
388 struct ath6kl *ar = file->private_data;
389 char buf[16];
390 int len;
391
392 len = snprintf(buf, sizeof(buf), "0x%x\n", ar->debug.fwlog_mask);
393
394 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
395}
396
397static ssize_t ath6kl_fwlog_mask_write(struct file *file,
398 const char __user *user_buf,
399 size_t count, loff_t *ppos)
400{
401 struct ath6kl *ar = file->private_data;
402 int ret;
403
404 ret = kstrtou32_from_user(user_buf, count, 0, &ar->debug.fwlog_mask);
405 if (ret)
406 return ret;
407
408 ret = ath6kl_wmi_config_debug_module_cmd(ar->wmi,
409 ATH6KL_FWLOG_VALID_MASK,
410 ar->debug.fwlog_mask);
411 if (ret)
412 return ret;
413
414 return count;
415}
416
417static const struct file_operations fops_fwlog_mask = {
418 .open = ath6kl_debugfs_open,
419 .read = ath6kl_fwlog_mask_read,
420 .write = ath6kl_fwlog_mask_write,
421 .owner = THIS_MODULE,
422 .llseek = default_llseek,
423};
424
Vasanthakumar Thiagarajan03f68a92011-08-26 13:06:32 +0530425static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
426 size_t count, loff_t *ppos)
427{
428 struct ath6kl *ar = file->private_data;
Vasanthakumar Thiagarajan990bd912011-10-25 19:34:20 +0530429 struct ath6kl_vif *vif;
430 struct target_stats *tgt_stats;
Vasanthakumar Thiagarajan03f68a92011-08-26 13:06:32 +0530431 char *buf;
432 unsigned int len = 0, buf_len = 1500;
433 int i;
434 long left;
435 ssize_t ret_cnt;
436
Vasanthakumar Thiagarajan990bd912011-10-25 19:34:20 +0530437 vif = ath6kl_vif_first(ar);
438 if (!vif)
439 return -EIO;
440
441 tgt_stats = &vif->target_stats;
442
Vasanthakumar Thiagarajan03f68a92011-08-26 13:06:32 +0530443 buf = kzalloc(buf_len, GFP_KERNEL);
444 if (!buf)
445 return -ENOMEM;
446
447 if (down_interruptible(&ar->sem)) {
448 kfree(buf);
449 return -EBUSY;
450 }
451
Vasanthakumar Thiagarajanb95907a2011-10-25 19:34:11 +0530452 set_bit(STATS_UPDATE_PEND, &vif->flags);
Vasanthakumar Thiagarajan03f68a92011-08-26 13:06:32 +0530453
Vasanthakumar Thiagarajan334234b2011-10-25 19:34:12 +0530454 if (ath6kl_wmi_get_stats_cmd(ar->wmi, 0)) {
Vasanthakumar Thiagarajan03f68a92011-08-26 13:06:32 +0530455 up(&ar->sem);
456 kfree(buf);
457 return -EIO;
458 }
459
460 left = wait_event_interruptible_timeout(ar->event_wq,
461 !test_bit(STATS_UPDATE_PEND,
Vasanthakumar Thiagarajanb95907a2011-10-25 19:34:11 +0530462 &vif->flags), WMI_TIMEOUT);
Vasanthakumar Thiagarajan03f68a92011-08-26 13:06:32 +0530463
464 up(&ar->sem);
465
466 if (left <= 0) {
467 kfree(buf);
468 return -ETIMEDOUT;
469 }
470
471 len += scnprintf(buf + len, buf_len - len, "\n");
472 len += scnprintf(buf + len, buf_len - len, "%25s\n",
473 "Target Tx stats");
474 len += scnprintf(buf + len, buf_len - len, "%25s\n\n",
475 "=================");
476 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
477 "Ucast packets", tgt_stats->tx_ucast_pkt);
478 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
479 "Bcast packets", tgt_stats->tx_bcast_pkt);
480 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
481 "Ucast byte", tgt_stats->tx_ucast_byte);
482 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
483 "Bcast byte", tgt_stats->tx_bcast_byte);
484 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
485 "Rts success cnt", tgt_stats->tx_rts_success_cnt);
486 for (i = 0; i < 4; i++)
487 len += scnprintf(buf + len, buf_len - len,
488 "%18s %d %10llu\n", "PER on ac",
489 i, tgt_stats->tx_pkt_per_ac[i]);
490 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
491 "Error", tgt_stats->tx_err);
492 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
493 "Fail count", tgt_stats->tx_fail_cnt);
494 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
495 "Retry count", tgt_stats->tx_retry_cnt);
496 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
497 "Multi retry cnt", tgt_stats->tx_mult_retry_cnt);
498 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
499 "Rts fail cnt", tgt_stats->tx_rts_fail_cnt);
500 len += scnprintf(buf + len, buf_len - len, "%25s %10llu\n\n",
501 "TKIP counter measure used",
502 tgt_stats->tkip_cnter_measures_invoked);
503
504 len += scnprintf(buf + len, buf_len - len, "%25s\n",
505 "Target Rx stats");
506 len += scnprintf(buf + len, buf_len - len, "%25s\n",
507 "=================");
508
509 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
510 "Ucast packets", tgt_stats->rx_ucast_pkt);
511 len += scnprintf(buf + len, buf_len - len, "%20s %10d\n",
512 "Ucast Rate", tgt_stats->rx_ucast_rate);
513 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
514 "Bcast packets", tgt_stats->rx_bcast_pkt);
515 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
516 "Ucast byte", tgt_stats->rx_ucast_byte);
517 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
518 "Bcast byte", tgt_stats->rx_bcast_byte);
519 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
520 "Fragmented pkt", tgt_stats->rx_frgment_pkt);
521 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
522 "Error", tgt_stats->rx_err);
523 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
524 "CRC Err", tgt_stats->rx_crc_err);
525 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
526 "Key chache miss", tgt_stats->rx_key_cache_miss);
527 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
528 "Decrypt Err", tgt_stats->rx_decrypt_err);
529 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
530 "Duplicate frame", tgt_stats->rx_dupl_frame);
531 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
532 "Tkip Mic failure", tgt_stats->tkip_local_mic_fail);
533 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
534 "TKIP format err", tgt_stats->tkip_fmt_err);
535 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
536 "CCMP format Err", tgt_stats->ccmp_fmt_err);
537 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n\n",
538 "CCMP Replay Err", tgt_stats->ccmp_replays);
539
540 len += scnprintf(buf + len, buf_len - len, "%25s\n",
541 "Misc Target stats");
542 len += scnprintf(buf + len, buf_len - len, "%25s\n",
543 "=================");
544 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
545 "Beacon Miss count", tgt_stats->cs_bmiss_cnt);
546 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
547 "Num Connects", tgt_stats->cs_connect_cnt);
548 len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
549 "Num disconnects", tgt_stats->cs_discon_cnt);
550 len += scnprintf(buf + len, buf_len - len, "%20s %10d\n",
551 "Beacon avg rssi", tgt_stats->cs_ave_beacon_rssi);
552
553 if (len > buf_len)
554 len = buf_len;
555
556 ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
557
558 kfree(buf);
559 return ret_cnt;
560}
561
562static const struct file_operations fops_tgt_stats = {
563 .read = read_file_tgt_stats,
564 .open = ath6kl_debugfs_open,
565 .owner = THIS_MODULE,
566 .llseek = default_llseek,
567};
568
Vasanthakumar Thiagarajan78fc4852011-08-26 13:06:33 +0530569#define print_credit_info(fmt_str, ep_list_field) \
570 (len += scnprintf(buf + len, buf_len - len, fmt_str, \
571 ep_list->ep_list_field))
572#define CREDIT_INFO_DISPLAY_STRING_LEN 200
573#define CREDIT_INFO_LEN 128
574
575static ssize_t read_file_credit_dist_stats(struct file *file,
576 char __user *user_buf,
577 size_t count, loff_t *ppos)
578{
579 struct ath6kl *ar = file->private_data;
580 struct htc_target *target = ar->htc_target;
581 struct htc_endpoint_credit_dist *ep_list;
582 char *buf;
583 unsigned int buf_len, len = 0;
584 ssize_t ret_cnt;
585
586 buf_len = CREDIT_INFO_DISPLAY_STRING_LEN +
587 get_queue_depth(&target->cred_dist_list) * CREDIT_INFO_LEN;
588 buf = kzalloc(buf_len, GFP_KERNEL);
589 if (!buf)
590 return -ENOMEM;
591
592 len += scnprintf(buf + len, buf_len - len, "%25s%5d\n",
593 "Total Avail Credits: ",
Kalle Valo3c370392011-10-24 12:17:12 +0300594 target->credit_info->total_avail_credits);
Vasanthakumar Thiagarajan78fc4852011-08-26 13:06:33 +0530595 len += scnprintf(buf + len, buf_len - len, "%25s%5d\n",
596 "Free credits :",
Kalle Valo3c370392011-10-24 12:17:12 +0300597 target->credit_info->cur_free_credits);
Vasanthakumar Thiagarajan78fc4852011-08-26 13:06:33 +0530598
599 len += scnprintf(buf + len, buf_len - len,
600 " Epid Flags Cred_norm Cred_min Credits Cred_assngd"
601 " Seek_cred Cred_sz Cred_per_msg Cred_to_dist"
602 " qdepth\n");
603
604 list_for_each_entry(ep_list, &target->cred_dist_list, list) {
605 print_credit_info(" %2d", endpoint);
606 print_credit_info("%10x", dist_flags);
607 print_credit_info("%8d", cred_norm);
608 print_credit_info("%9d", cred_min);
609 print_credit_info("%9d", credits);
610 print_credit_info("%10d", cred_assngd);
611 print_credit_info("%13d", seek_cred);
612 print_credit_info("%12d", cred_sz);
613 print_credit_info("%9d", cred_per_msg);
614 print_credit_info("%14d", cred_to_dist);
615 len += scnprintf(buf + len, buf_len - len, "%12d\n",
Kalle Valoe8c39792011-10-24 12:17:04 +0300616 get_queue_depth(&ep_list->htc_ep->txq));
Vasanthakumar Thiagarajan78fc4852011-08-26 13:06:33 +0530617 }
618
619 if (len > buf_len)
620 len = buf_len;
621
622 ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
623 kfree(buf);
624 return ret_cnt;
625}
626
627static const struct file_operations fops_credit_dist_stats = {
628 .read = read_file_credit_dist_stats,
629 .open = ath6kl_debugfs_open,
630 .owner = THIS_MODULE,
631 .llseek = default_llseek,
632};
633
Jouni Malinene8091282011-10-11 17:31:53 +0300634static unsigned int print_endpoint_stat(struct htc_target *target, char *buf,
635 unsigned int buf_len, unsigned int len,
636 int offset, const char *name)
637{
638 int i;
639 struct htc_endpoint_stats *ep_st;
640 u32 *counter;
641
642 len += scnprintf(buf + len, buf_len - len, "%s:", name);
643 for (i = 0; i < ENDPOINT_MAX; i++) {
644 ep_st = &target->endpoint[i].ep_st;
645 counter = ((u32 *) ep_st) + (offset / 4);
646 len += scnprintf(buf + len, buf_len - len, " %u", *counter);
647 }
648 len += scnprintf(buf + len, buf_len - len, "\n");
649
650 return len;
651}
652
653static ssize_t ath6kl_endpoint_stats_read(struct file *file,
654 char __user *user_buf,
655 size_t count, loff_t *ppos)
656{
657 struct ath6kl *ar = file->private_data;
658 struct htc_target *target = ar->htc_target;
659 char *buf;
660 unsigned int buf_len, len = 0;
661 ssize_t ret_cnt;
662
Jouni Malinen17169322011-10-11 22:08:21 +0300663 buf_len = sizeof(struct htc_endpoint_stats) / sizeof(u32) *
664 (25 + ENDPOINT_MAX * 11);
665 buf = kmalloc(buf_len, GFP_KERNEL);
Jouni Malinene8091282011-10-11 17:31:53 +0300666 if (!buf)
667 return -ENOMEM;
668
669#define EPSTAT(name) \
670 len = print_endpoint_stat(target, buf, buf_len, len, \
671 offsetof(struct htc_endpoint_stats, name), \
672 #name)
673 EPSTAT(cred_low_indicate);
674 EPSTAT(tx_issued);
675 EPSTAT(tx_pkt_bundled);
676 EPSTAT(tx_bundles);
677 EPSTAT(tx_dropped);
678 EPSTAT(tx_cred_rpt);
679 EPSTAT(cred_rpt_from_rx);
Jouni Malinen17169322011-10-11 22:08:21 +0300680 EPSTAT(cred_rpt_from_other);
Jouni Malinene8091282011-10-11 17:31:53 +0300681 EPSTAT(cred_rpt_ep0);
682 EPSTAT(cred_from_rx);
683 EPSTAT(cred_from_other);
684 EPSTAT(cred_from_ep0);
685 EPSTAT(cred_cosumd);
686 EPSTAT(cred_retnd);
687 EPSTAT(rx_pkts);
688 EPSTAT(rx_lkahds);
689 EPSTAT(rx_bundl);
690 EPSTAT(rx_bundle_lkahd);
691 EPSTAT(rx_bundle_from_hdr);
692 EPSTAT(rx_alloc_thresh_hit);
693 EPSTAT(rxalloc_thresh_byte);
694#undef EPSTAT
695
696 if (len > buf_len)
697 len = buf_len;
698
699 ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
700 kfree(buf);
701 return ret_cnt;
702}
703
704static ssize_t ath6kl_endpoint_stats_write(struct file *file,
705 const char __user *user_buf,
706 size_t count, loff_t *ppos)
707{
708 struct ath6kl *ar = file->private_data;
709 struct htc_target *target = ar->htc_target;
710 int ret, i;
711 u32 val;
712 struct htc_endpoint_stats *ep_st;
713
714 ret = kstrtou32_from_user(user_buf, count, 0, &val);
715 if (ret)
716 return ret;
717 if (val == 0) {
718 for (i = 0; i < ENDPOINT_MAX; i++) {
719 ep_st = &target->endpoint[i].ep_st;
720 memset(ep_st, 0, sizeof(*ep_st));
721 }
722 }
723
724 return count;
725}
726
727static const struct file_operations fops_endpoint_stats = {
728 .open = ath6kl_debugfs_open,
729 .read = ath6kl_endpoint_stats_read,
730 .write = ath6kl_endpoint_stats_write,
731 .owner = THIS_MODULE,
732 .llseek = default_llseek,
733};
734
Vasanthakumar Thiagarajan91d57de2011-09-02 10:40:06 +0300735static unsigned long ath6kl_get_num_reg(void)
736{
737 int i;
738 unsigned long n_reg = 0;
739
740 for (i = 0; i < ARRAY_SIZE(diag_reg); i++)
741 n_reg = n_reg +
742 (diag_reg[i].reg_end - diag_reg[i].reg_start) / 4 + 1;
743
744 return n_reg;
745}
746
747static bool ath6kl_dbg_is_diag_reg_valid(u32 reg_addr)
748{
749 int i;
750
751 for (i = 0; i < ARRAY_SIZE(diag_reg); i++) {
752 if (reg_addr >= diag_reg[i].reg_start &&
753 reg_addr <= diag_reg[i].reg_end)
754 return true;
755 }
756
757 return false;
758}
759
760static ssize_t ath6kl_regread_read(struct file *file, char __user *user_buf,
761 size_t count, loff_t *ppos)
762{
763 struct ath6kl *ar = file->private_data;
764 u8 buf[50];
765 unsigned int len = 0;
766
767 if (ar->debug.dbgfs_diag_reg)
768 len += scnprintf(buf + len, sizeof(buf) - len, "0x%x\n",
769 ar->debug.dbgfs_diag_reg);
770 else
771 len += scnprintf(buf + len, sizeof(buf) - len,
772 "All diag registers\n");
773
774 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
775}
776
777static ssize_t ath6kl_regread_write(struct file *file,
778 const char __user *user_buf,
779 size_t count, loff_t *ppos)
780{
781 struct ath6kl *ar = file->private_data;
782 u8 buf[50];
783 unsigned int len;
784 unsigned long reg_addr;
785
786 len = min(count, sizeof(buf) - 1);
787 if (copy_from_user(buf, user_buf, len))
788 return -EFAULT;
789
790 buf[len] = '\0';
791
792 if (strict_strtoul(buf, 0, &reg_addr))
793 return -EINVAL;
794
795 if ((reg_addr % 4) != 0)
796 return -EINVAL;
797
798 if (reg_addr && !ath6kl_dbg_is_diag_reg_valid(reg_addr))
799 return -EINVAL;
800
801 ar->debug.dbgfs_diag_reg = reg_addr;
802
803 return count;
804}
805
806static const struct file_operations fops_diag_reg_read = {
807 .read = ath6kl_regread_read,
808 .write = ath6kl_regread_write,
809 .open = ath6kl_debugfs_open,
810 .owner = THIS_MODULE,
811 .llseek = default_llseek,
812};
813
814static int ath6kl_regdump_open(struct inode *inode, struct file *file)
815{
816 struct ath6kl *ar = inode->i_private;
817 u8 *buf;
818 unsigned long int reg_len;
819 unsigned int len = 0, n_reg;
820 u32 addr;
821 __le32 reg_val;
822 int i, status;
823
824 /* Dump all the registers if no register is specified */
825 if (!ar->debug.dbgfs_diag_reg)
826 n_reg = ath6kl_get_num_reg();
827 else
828 n_reg = 1;
829
830 reg_len = n_reg * REG_OUTPUT_LEN_PER_LINE;
831 if (n_reg > 1)
832 reg_len += REGTYPE_STR_LEN;
833
834 buf = vmalloc(reg_len);
835 if (!buf)
836 return -ENOMEM;
837
838 if (n_reg == 1) {
839 addr = ar->debug.dbgfs_diag_reg;
840
841 status = ath6kl_diag_read32(ar,
842 TARG_VTOP(ar->target_type, addr),
843 (u32 *)&reg_val);
844 if (status)
845 goto fail_reg_read;
846
847 len += scnprintf(buf + len, reg_len - len,
848 "0x%06x 0x%08x\n", addr, le32_to_cpu(reg_val));
849 goto done;
850 }
851
852 for (i = 0; i < ARRAY_SIZE(diag_reg); i++) {
853 len += scnprintf(buf + len, reg_len - len,
854 "%s\n", diag_reg[i].reg_info);
855 for (addr = diag_reg[i].reg_start;
856 addr <= diag_reg[i].reg_end; addr += 4) {
857 status = ath6kl_diag_read32(ar,
858 TARG_VTOP(ar->target_type, addr),
859 (u32 *)&reg_val);
860 if (status)
861 goto fail_reg_read;
862
863 len += scnprintf(buf + len, reg_len - len,
864 "0x%06x 0x%08x\n",
865 addr, le32_to_cpu(reg_val));
866 }
867 }
868
869done:
870 file->private_data = buf;
871 return 0;
872
873fail_reg_read:
874 ath6kl_warn("Unable to read memory:%u\n", addr);
875 vfree(buf);
876 return -EIO;
877}
878
879static ssize_t ath6kl_regdump_read(struct file *file, char __user *user_buf,
880 size_t count, loff_t *ppos)
881{
882 u8 *buf = file->private_data;
883 return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
884}
885
886static int ath6kl_regdump_release(struct inode *inode, struct file *file)
887{
888 vfree(file->private_data);
889 return 0;
890}
891
892static const struct file_operations fops_reg_dump = {
893 .open = ath6kl_regdump_open,
894 .read = ath6kl_regdump_read,
895 .release = ath6kl_regdump_release,
896 .owner = THIS_MODULE,
897 .llseek = default_llseek,
898};
899
Vivek Natarajane5090442011-08-31 15:02:19 +0530900static ssize_t ath6kl_lrssi_roam_write(struct file *file,
901 const char __user *user_buf,
902 size_t count, loff_t *ppos)
903{
904 struct ath6kl *ar = file->private_data;
905 unsigned long lrssi_roam_threshold;
906 char buf[32];
907 ssize_t len;
908
909 len = min(count, sizeof(buf) - 1);
910 if (copy_from_user(buf, user_buf, len))
911 return -EFAULT;
912
913 buf[len] = '\0';
914 if (strict_strtoul(buf, 0, &lrssi_roam_threshold))
915 return -EINVAL;
916
917 ar->lrssi_roam_threshold = lrssi_roam_threshold;
918
919 ath6kl_wmi_set_roam_lrssi_cmd(ar->wmi, ar->lrssi_roam_threshold);
920
921 return count;
922}
923
924static ssize_t ath6kl_lrssi_roam_read(struct file *file,
925 char __user *user_buf,
926 size_t count, loff_t *ppos)
927{
928 struct ath6kl *ar = file->private_data;
929 char buf[32];
930 unsigned int len;
931
932 len = snprintf(buf, sizeof(buf), "%u\n", ar->lrssi_roam_threshold);
933
934 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
935}
936
937static const struct file_operations fops_lrssi_roam_threshold = {
938 .read = ath6kl_lrssi_roam_read,
939 .write = ath6kl_lrssi_roam_write,
940 .open = ath6kl_debugfs_open,
941 .owner = THIS_MODULE,
942 .llseek = default_llseek,
943};
944
Vasanthakumar Thiagarajan252c0682011-09-05 11:19:46 +0300945static ssize_t ath6kl_regwrite_read(struct file *file,
946 char __user *user_buf,
947 size_t count, loff_t *ppos)
948{
949 struct ath6kl *ar = file->private_data;
950 u8 buf[32];
951 unsigned int len = 0;
952
953 len = scnprintf(buf, sizeof(buf), "Addr: 0x%x Val: 0x%x\n",
954 ar->debug.diag_reg_addr_wr, ar->debug.diag_reg_val_wr);
955
956 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
957}
958
959static ssize_t ath6kl_regwrite_write(struct file *file,
960 const char __user *user_buf,
961 size_t count, loff_t *ppos)
962{
963 struct ath6kl *ar = file->private_data;
964 char buf[32];
965 char *sptr, *token;
966 unsigned int len = 0;
967 u32 reg_addr, reg_val;
968
969 len = min(count, sizeof(buf) - 1);
970 if (copy_from_user(buf, user_buf, len))
971 return -EFAULT;
972
973 buf[len] = '\0';
974 sptr = buf;
975
976 token = strsep(&sptr, "=");
977 if (!token)
978 return -EINVAL;
979
980 if (kstrtou32(token, 0, &reg_addr))
981 return -EINVAL;
982
983 if (!ath6kl_dbg_is_diag_reg_valid(reg_addr))
984 return -EINVAL;
985
986 if (kstrtou32(sptr, 0, &reg_val))
987 return -EINVAL;
988
989 ar->debug.diag_reg_addr_wr = reg_addr;
990 ar->debug.diag_reg_val_wr = reg_val;
991
992 if (ath6kl_diag_write32(ar, ar->debug.diag_reg_addr_wr,
993 cpu_to_le32(ar->debug.diag_reg_val_wr)))
994 return -EIO;
995
996 return count;
997}
998
999static const struct file_operations fops_diag_reg_write = {
1000 .read = ath6kl_regwrite_read,
1001 .write = ath6kl_regwrite_write,
1002 .open = ath6kl_debugfs_open,
1003 .owner = THIS_MODULE,
1004 .llseek = default_llseek,
1005};
1006
Jouni Malinen4b28a802011-10-11 17:31:54 +03001007int ath6kl_debug_roam_tbl_event(struct ath6kl *ar, const void *buf,
1008 size_t len)
1009{
1010 const struct wmi_target_roam_tbl *tbl;
1011 u16 num_entries;
1012
1013 if (len < sizeof(*tbl))
1014 return -EINVAL;
1015
1016 tbl = (const struct wmi_target_roam_tbl *) buf;
1017 num_entries = le16_to_cpu(tbl->num_entries);
1018 if (sizeof(*tbl) + num_entries * sizeof(struct wmi_bss_roam_info) >
1019 len)
1020 return -EINVAL;
1021
1022 if (ar->debug.roam_tbl == NULL ||
1023 ar->debug.roam_tbl_len < (unsigned int) len) {
1024 kfree(ar->debug.roam_tbl);
1025 ar->debug.roam_tbl = kmalloc(len, GFP_ATOMIC);
1026 if (ar->debug.roam_tbl == NULL)
1027 return -ENOMEM;
1028 }
1029
1030 memcpy(ar->debug.roam_tbl, buf, len);
1031 ar->debug.roam_tbl_len = len;
1032
1033 if (test_bit(ROAM_TBL_PEND, &ar->flag)) {
1034 clear_bit(ROAM_TBL_PEND, &ar->flag);
1035 wake_up(&ar->event_wq);
1036 }
1037
1038 return 0;
1039}
1040
1041static ssize_t ath6kl_roam_table_read(struct file *file, char __user *user_buf,
1042 size_t count, loff_t *ppos)
1043{
1044 struct ath6kl *ar = file->private_data;
1045 int ret;
1046 long left;
1047 struct wmi_target_roam_tbl *tbl;
1048 u16 num_entries, i;
1049 char *buf;
1050 unsigned int len, buf_len;
1051 ssize_t ret_cnt;
1052
1053 if (down_interruptible(&ar->sem))
1054 return -EBUSY;
1055
1056 set_bit(ROAM_TBL_PEND, &ar->flag);
1057
1058 ret = ath6kl_wmi_get_roam_tbl_cmd(ar->wmi);
1059 if (ret) {
1060 up(&ar->sem);
1061 return ret;
1062 }
1063
1064 left = wait_event_interruptible_timeout(
1065 ar->event_wq, !test_bit(ROAM_TBL_PEND, &ar->flag), WMI_TIMEOUT);
1066 up(&ar->sem);
1067
1068 if (left <= 0)
1069 return -ETIMEDOUT;
1070
1071 if (ar->debug.roam_tbl == NULL)
1072 return -ENOMEM;
1073
1074 tbl = (struct wmi_target_roam_tbl *) ar->debug.roam_tbl;
1075 num_entries = le16_to_cpu(tbl->num_entries);
1076
1077 buf_len = 100 + num_entries * 100;
1078 buf = kzalloc(buf_len, GFP_KERNEL);
1079 if (buf == NULL)
1080 return -ENOMEM;
1081 len = 0;
1082 len += scnprintf(buf + len, buf_len - len,
1083 "roam_mode=%u\n\n"
1084 "# roam_util bssid rssi rssidt last_rssi util bias\n",
1085 le16_to_cpu(tbl->roam_mode));
1086
1087 for (i = 0; i < num_entries; i++) {
1088 struct wmi_bss_roam_info *info = &tbl->info[i];
1089 len += scnprintf(buf + len, buf_len - len,
1090 "%d %pM %d %d %d %d %d\n",
1091 a_sle32_to_cpu(info->roam_util), info->bssid,
1092 info->rssi, info->rssidt, info->last_rssi,
1093 info->util, info->bias);
1094 }
1095
1096 if (len > buf_len)
1097 len = buf_len;
1098
1099 ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1100
1101 kfree(buf);
1102 return ret_cnt;
1103}
1104
1105static const struct file_operations fops_roam_table = {
1106 .read = ath6kl_roam_table_read,
1107 .open = ath6kl_debugfs_open,
1108 .owner = THIS_MODULE,
1109 .llseek = default_llseek,
1110};
1111
Jouni Malinen12618752011-10-11 17:31:55 +03001112static ssize_t ath6kl_force_roam_write(struct file *file,
1113 const char __user *user_buf,
1114 size_t count, loff_t *ppos)
1115{
1116 struct ath6kl *ar = file->private_data;
1117 int ret;
1118 char buf[20];
1119 size_t len;
1120 u8 bssid[ETH_ALEN];
1121 int i;
1122 int addr[ETH_ALEN];
1123
1124 len = min(count, sizeof(buf) - 1);
1125 if (copy_from_user(buf, user_buf, len))
1126 return -EFAULT;
1127 buf[len] = '\0';
1128
1129 if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
1130 &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5])
1131 != ETH_ALEN)
1132 return -EINVAL;
1133 for (i = 0; i < ETH_ALEN; i++)
1134 bssid[i] = addr[i];
1135
1136 ret = ath6kl_wmi_force_roam_cmd(ar->wmi, bssid);
1137 if (ret)
1138 return ret;
1139
1140 return count;
1141}
1142
1143static const struct file_operations fops_force_roam = {
1144 .write = ath6kl_force_roam_write,
1145 .open = ath6kl_debugfs_open,
1146 .owner = THIS_MODULE,
1147 .llseek = default_llseek,
1148};
1149
1150static ssize_t ath6kl_roam_mode_write(struct file *file,
1151 const char __user *user_buf,
1152 size_t count, loff_t *ppos)
1153{
1154 struct ath6kl *ar = file->private_data;
1155 int ret;
1156 char buf[20];
1157 size_t len;
1158 enum wmi_roam_mode mode;
1159
1160 len = min(count, sizeof(buf) - 1);
1161 if (copy_from_user(buf, user_buf, len))
1162 return -EFAULT;
1163 buf[len] = '\0';
1164 if (len > 0 && buf[len - 1] == '\n')
1165 buf[len - 1] = '\0';
1166
1167 if (strcasecmp(buf, "default") == 0)
1168 mode = WMI_DEFAULT_ROAM_MODE;
1169 else if (strcasecmp(buf, "bssbias") == 0)
1170 mode = WMI_HOST_BIAS_ROAM_MODE;
1171 else if (strcasecmp(buf, "lock") == 0)
1172 mode = WMI_LOCK_BSS_MODE;
1173 else
1174 return -EINVAL;
1175
1176 ret = ath6kl_wmi_set_roam_mode_cmd(ar->wmi, mode);
1177 if (ret)
1178 return ret;
1179
1180 return count;
1181}
1182
1183static const struct file_operations fops_roam_mode = {
1184 .write = ath6kl_roam_mode_write,
1185 .open = ath6kl_debugfs_open,
1186 .owner = THIS_MODULE,
1187 .llseek = default_llseek,
1188};
1189
Jouni Malinenff0b0072011-10-11 17:31:56 +03001190void ath6kl_debug_set_keepalive(struct ath6kl *ar, u8 keepalive)
1191{
1192 ar->debug.keepalive = keepalive;
1193}
1194
1195static ssize_t ath6kl_keepalive_read(struct file *file, char __user *user_buf,
1196 size_t count, loff_t *ppos)
1197{
1198 struct ath6kl *ar = file->private_data;
1199 char buf[16];
1200 int len;
1201
1202 len = snprintf(buf, sizeof(buf), "%u\n", ar->debug.keepalive);
1203
1204 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1205}
1206
1207static ssize_t ath6kl_keepalive_write(struct file *file,
1208 const char __user *user_buf,
1209 size_t count, loff_t *ppos)
1210{
1211 struct ath6kl *ar = file->private_data;
1212 int ret;
1213 u8 val;
1214
1215 ret = kstrtou8_from_user(user_buf, count, 0, &val);
1216 if (ret)
1217 return ret;
1218
Vasanthakumar Thiagarajan0ce59442011-10-25 19:34:25 +05301219 ret = ath6kl_wmi_set_keepalive_cmd(ar->wmi, 0, val);
Jouni Malinenff0b0072011-10-11 17:31:56 +03001220 if (ret)
1221 return ret;
1222
1223 return count;
1224}
1225
1226static const struct file_operations fops_keepalive = {
1227 .open = ath6kl_debugfs_open,
1228 .read = ath6kl_keepalive_read,
1229 .write = ath6kl_keepalive_write,
1230 .owner = THIS_MODULE,
1231 .llseek = default_llseek,
1232};
1233
1234void ath6kl_debug_set_disconnect_timeout(struct ath6kl *ar, u8 timeout)
1235{
1236 ar->debug.disc_timeout = timeout;
1237}
1238
1239static ssize_t ath6kl_disconnect_timeout_read(struct file *file,
1240 char __user *user_buf,
1241 size_t count, loff_t *ppos)
1242{
1243 struct ath6kl *ar = file->private_data;
1244 char buf[16];
1245 int len;
1246
1247 len = snprintf(buf, sizeof(buf), "%u\n", ar->debug.disc_timeout);
1248
1249 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1250}
1251
1252static ssize_t ath6kl_disconnect_timeout_write(struct file *file,
1253 const char __user *user_buf,
1254 size_t count, loff_t *ppos)
1255{
1256 struct ath6kl *ar = file->private_data;
1257 int ret;
1258 u8 val;
1259
1260 ret = kstrtou8_from_user(user_buf, count, 0, &val);
1261 if (ret)
1262 return ret;
1263
Vasanthakumar Thiagarajan0ce59442011-10-25 19:34:25 +05301264 ret = ath6kl_wmi_disctimeout_cmd(ar->wmi, 0, val);
Jouni Malinenff0b0072011-10-11 17:31:56 +03001265 if (ret)
1266 return ret;
1267
1268 return count;
1269}
1270
1271static const struct file_operations fops_disconnect_timeout = {
1272 .open = ath6kl_debugfs_open,
1273 .read = ath6kl_disconnect_timeout_read,
1274 .write = ath6kl_disconnect_timeout_write,
1275 .owner = THIS_MODULE,
1276 .llseek = default_llseek,
1277};
1278
Rishi Panjwani8fffd9e2011-10-14 17:48:07 -07001279static ssize_t ath6kl_create_qos_write(struct file *file,
1280 const char __user *user_buf,
1281 size_t count, loff_t *ppos)
1282{
1283
1284 struct ath6kl *ar = file->private_data;
Vasanthakumar Thiagarajan990bd912011-10-25 19:34:20 +05301285 struct ath6kl_vif *vif;
Vasanthakumar Thiagarajan8cb6d992011-11-04 18:34:55 +05301286 char buf[200];
Rishi Panjwani8fffd9e2011-10-14 17:48:07 -07001287 ssize_t len;
1288 char *sptr, *token;
1289 struct wmi_create_pstream_cmd pstream;
1290 u32 val32;
1291 u16 val16;
1292
Vasanthakumar Thiagarajan990bd912011-10-25 19:34:20 +05301293 vif = ath6kl_vif_first(ar);
1294 if (!vif)
1295 return -EIO;
1296
Rishi Panjwani8fffd9e2011-10-14 17:48:07 -07001297 len = min(count, sizeof(buf) - 1);
1298 if (copy_from_user(buf, user_buf, len))
1299 return -EFAULT;
1300 buf[len] = '\0';
1301 sptr = buf;
1302
1303 token = strsep(&sptr, " ");
1304 if (!token)
1305 return -EINVAL;
1306 if (kstrtou8(token, 0, &pstream.user_pri))
1307 return -EINVAL;
1308
1309 token = strsep(&sptr, " ");
1310 if (!token)
1311 return -EINVAL;
1312 if (kstrtou8(token, 0, &pstream.traffic_direc))
1313 return -EINVAL;
1314
1315 token = strsep(&sptr, " ");
1316 if (!token)
1317 return -EINVAL;
1318 if (kstrtou8(token, 0, &pstream.traffic_class))
1319 return -EINVAL;
1320
1321 token = strsep(&sptr, " ");
1322 if (!token)
1323 return -EINVAL;
1324 if (kstrtou8(token, 0, &pstream.traffic_type))
1325 return -EINVAL;
1326
1327 token = strsep(&sptr, " ");
1328 if (!token)
1329 return -EINVAL;
1330 if (kstrtou8(token, 0, &pstream.voice_psc_cap))
1331 return -EINVAL;
1332
1333 token = strsep(&sptr, " ");
1334 if (!token)
1335 return -EINVAL;
1336 if (kstrtou32(token, 0, &val32))
1337 return -EINVAL;
1338 pstream.min_service_int = cpu_to_le32(val32);
1339
1340 token = strsep(&sptr, " ");
1341 if (!token)
1342 return -EINVAL;
1343 if (kstrtou32(token, 0, &val32))
1344 return -EINVAL;
1345 pstream.max_service_int = cpu_to_le32(val32);
1346
1347 token = strsep(&sptr, " ");
1348 if (!token)
1349 return -EINVAL;
1350 if (kstrtou32(token, 0, &val32))
1351 return -EINVAL;
1352 pstream.inactivity_int = cpu_to_le32(val32);
1353
1354 token = strsep(&sptr, " ");
1355 if (!token)
1356 return -EINVAL;
1357 if (kstrtou32(token, 0, &val32))
1358 return -EINVAL;
1359 pstream.suspension_int = cpu_to_le32(val32);
1360
1361 token = strsep(&sptr, " ");
1362 if (!token)
1363 return -EINVAL;
1364 if (kstrtou32(token, 0, &val32))
1365 return -EINVAL;
1366 pstream.service_start_time = cpu_to_le32(val32);
1367
1368 token = strsep(&sptr, " ");
1369 if (!token)
1370 return -EINVAL;
1371 if (kstrtou8(token, 0, &pstream.tsid))
1372 return -EINVAL;
1373
1374 token = strsep(&sptr, " ");
1375 if (!token)
1376 return -EINVAL;
1377 if (kstrtou16(token, 0, &val16))
1378 return -EINVAL;
1379 pstream.nominal_msdu = cpu_to_le16(val16);
1380
1381 token = strsep(&sptr, " ");
1382 if (!token)
1383 return -EINVAL;
1384 if (kstrtou16(token, 0, &val16))
1385 return -EINVAL;
1386 pstream.max_msdu = cpu_to_le16(val16);
1387
1388 token = strsep(&sptr, " ");
1389 if (!token)
1390 return -EINVAL;
1391 if (kstrtou32(token, 0, &val32))
1392 return -EINVAL;
1393 pstream.min_data_rate = cpu_to_le32(val32);
1394
1395 token = strsep(&sptr, " ");
1396 if (!token)
1397 return -EINVAL;
1398 if (kstrtou32(token, 0, &val32))
1399 return -EINVAL;
1400 pstream.mean_data_rate = cpu_to_le32(val32);
1401
1402 token = strsep(&sptr, " ");
1403 if (!token)
1404 return -EINVAL;
1405 if (kstrtou32(token, 0, &val32))
1406 return -EINVAL;
1407 pstream.peak_data_rate = cpu_to_le32(val32);
1408
1409 token = strsep(&sptr, " ");
1410 if (!token)
1411 return -EINVAL;
1412 if (kstrtou32(token, 0, &val32))
1413 return -EINVAL;
1414 pstream.max_burst_size = cpu_to_le32(val32);
1415
1416 token = strsep(&sptr, " ");
1417 if (!token)
1418 return -EINVAL;
1419 if (kstrtou32(token, 0, &val32))
1420 return -EINVAL;
1421 pstream.delay_bound = cpu_to_le32(val32);
1422
1423 token = strsep(&sptr, " ");
1424 if (!token)
1425 return -EINVAL;
1426 if (kstrtou32(token, 0, &val32))
1427 return -EINVAL;
1428 pstream.min_phy_rate = cpu_to_le32(val32);
1429
1430 token = strsep(&sptr, " ");
1431 if (!token)
1432 return -EINVAL;
1433 if (kstrtou32(token, 0, &val32))
1434 return -EINVAL;
1435 pstream.sba = cpu_to_le32(val32);
1436
1437 token = strsep(&sptr, " ");
1438 if (!token)
1439 return -EINVAL;
1440 if (kstrtou32(token, 0, &val32))
1441 return -EINVAL;
1442 pstream.medium_time = cpu_to_le32(val32);
1443
Vasanthakumar Thiagarajan240d2792011-10-25 19:34:13 +05301444 ath6kl_wmi_create_pstream_cmd(ar->wmi, vif->fw_vif_idx, &pstream);
Rishi Panjwani8fffd9e2011-10-14 17:48:07 -07001445
1446 return count;
1447}
1448
1449static const struct file_operations fops_create_qos = {
1450 .write = ath6kl_create_qos_write,
1451 .open = ath6kl_debugfs_open,
1452 .owner = THIS_MODULE,
1453 .llseek = default_llseek,
1454};
1455
1456static ssize_t ath6kl_delete_qos_write(struct file *file,
1457 const char __user *user_buf,
1458 size_t count, loff_t *ppos)
1459{
1460
1461 struct ath6kl *ar = file->private_data;
Vasanthakumar Thiagarajan990bd912011-10-25 19:34:20 +05301462 struct ath6kl_vif *vif;
Rishi Panjwani8fffd9e2011-10-14 17:48:07 -07001463 char buf[100];
1464 ssize_t len;
1465 char *sptr, *token;
1466 u8 traffic_class;
1467 u8 tsid;
1468
Vasanthakumar Thiagarajan990bd912011-10-25 19:34:20 +05301469 vif = ath6kl_vif_first(ar);
1470 if (!vif)
1471 return -EIO;
1472
Rishi Panjwani8fffd9e2011-10-14 17:48:07 -07001473 len = min(count, sizeof(buf) - 1);
1474 if (copy_from_user(buf, user_buf, len))
1475 return -EFAULT;
1476 buf[len] = '\0';
1477 sptr = buf;
1478
1479 token = strsep(&sptr, " ");
1480 if (!token)
1481 return -EINVAL;
1482 if (kstrtou8(token, 0, &traffic_class))
1483 return -EINVAL;
1484
1485 token = strsep(&sptr, " ");
1486 if (!token)
1487 return -EINVAL;
1488 if (kstrtou8(token, 0, &tsid))
1489 return -EINVAL;
1490
Vasanthakumar Thiagarajan240d2792011-10-25 19:34:13 +05301491 ath6kl_wmi_delete_pstream_cmd(ar->wmi, vif->fw_vif_idx,
1492 traffic_class, tsid);
Rishi Panjwani8fffd9e2011-10-14 17:48:07 -07001493
1494 return count;
1495}
1496
1497static const struct file_operations fops_delete_qos = {
1498 .write = ath6kl_delete_qos_write,
1499 .open = ath6kl_debugfs_open,
1500 .owner = THIS_MODULE,
1501 .llseek = default_llseek,
1502};
1503
Rishi Panjwani116b3a22011-10-18 17:20:06 -07001504static ssize_t ath6kl_bgscan_int_write(struct file *file,
1505 const char __user *user_buf,
1506 size_t count, loff_t *ppos)
1507{
1508 struct ath6kl *ar = file->private_data;
1509 u16 bgscan_int;
1510 char buf[32];
1511 ssize_t len;
1512
1513 len = min(count, sizeof(buf) - 1);
1514 if (copy_from_user(buf, user_buf, len))
1515 return -EFAULT;
1516
1517 buf[len] = '\0';
1518 if (kstrtou16(buf, 0, &bgscan_int))
1519 return -EINVAL;
1520
1521 if (bgscan_int == 0)
1522 bgscan_int = 0xffff;
1523
Vasanthakumar Thiagarajan334234b2011-10-25 19:34:12 +05301524 ath6kl_wmi_scanparams_cmd(ar->wmi, 0, 0, 0, bgscan_int, 0, 0, 0, 3,
Rishi Panjwani116b3a22011-10-18 17:20:06 -07001525 0, 0, 0);
1526
1527 return count;
1528}
1529
1530static const struct file_operations fops_bgscan_int = {
1531 .write = ath6kl_bgscan_int_write,
1532 .open = ath6kl_debugfs_open,
1533 .owner = THIS_MODULE,
1534 .llseek = default_llseek,
1535};
1536
Rishi Panjwanief8f0eb2011-10-25 17:26:29 -07001537static ssize_t ath6kl_listen_int_write(struct file *file,
Sujith Manoharan82327362012-01-10 09:54:10 +05301538 const char __user *user_buf,
1539 size_t count, loff_t *ppos)
Rishi Panjwanief8f0eb2011-10-25 17:26:29 -07001540{
1541 struct ath6kl *ar = file->private_data;
Sujith Manoharan82327362012-01-10 09:54:10 +05301542 struct ath6kl_vif *vif;
1543 u16 listen_interval;
Rishi Panjwanief8f0eb2011-10-25 17:26:29 -07001544 char buf[32];
Rishi Panjwanief8f0eb2011-10-25 17:26:29 -07001545 ssize_t len;
1546
Sujith Manoharan82327362012-01-10 09:54:10 +05301547 vif = ath6kl_vif_first(ar);
1548 if (!vif)
1549 return -EIO;
1550
Rishi Panjwanief8f0eb2011-10-25 17:26:29 -07001551 len = min(count, sizeof(buf) - 1);
1552 if (copy_from_user(buf, user_buf, len))
1553 return -EFAULT;
1554
1555 buf[len] = '\0';
Sujith Manoharan82327362012-01-10 09:54:10 +05301556 if (kstrtou16(buf, 0, &listen_interval))
Rishi Panjwanief8f0eb2011-10-25 17:26:29 -07001557 return -EINVAL;
1558
Sujith Manoharan82327362012-01-10 09:54:10 +05301559 if ((listen_interval < 1) || (listen_interval > 50))
Rishi Panjwanief8f0eb2011-10-25 17:26:29 -07001560 return -EINVAL;
1561
Sujith Manoharan82327362012-01-10 09:54:10 +05301562 ar->listen_intvl_b = listen_interval;
1563 ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, 0,
Rishi Panjwanief8f0eb2011-10-25 17:26:29 -07001564 ar->listen_intvl_b);
1565
1566 return count;
1567}
1568
1569static ssize_t ath6kl_listen_int_read(struct file *file,
Sujith Manoharan82327362012-01-10 09:54:10 +05301570 char __user *user_buf,
1571 size_t count, loff_t *ppos)
Rishi Panjwanief8f0eb2011-10-25 17:26:29 -07001572{
1573 struct ath6kl *ar = file->private_data;
Dan Carpenter50553c22011-11-23 09:34:50 +03001574 char buf[32];
Rishi Panjwanief8f0eb2011-10-25 17:26:29 -07001575 int len;
1576
Sujith Manoharan82327362012-01-10 09:54:10 +05301577 len = scnprintf(buf, sizeof(buf), "%u\n", ar->listen_intvl_b);
Rishi Panjwanief8f0eb2011-10-25 17:26:29 -07001578
1579 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1580}
1581
1582static const struct file_operations fops_listen_int = {
1583 .read = ath6kl_listen_int_read,
1584 .write = ath6kl_listen_int_write,
1585 .open = ath6kl_debugfs_open,
1586 .owner = THIS_MODULE,
1587 .llseek = default_llseek,
1588};
1589
Rishi Panjwania24fc7c2011-10-25 19:52:41 -07001590static ssize_t ath6kl_power_params_write(struct file *file,
1591 const char __user *user_buf,
1592 size_t count, loff_t *ppos)
1593{
1594 struct ath6kl *ar = file->private_data;
1595 u8 buf[100];
1596 unsigned int len = 0;
1597 char *sptr, *token;
1598 u16 idle_period, ps_poll_num, dtim,
1599 tx_wakeup, num_tx;
1600
1601 len = min(count, sizeof(buf) - 1);
1602 if (copy_from_user(buf, user_buf, len))
1603 return -EFAULT;
1604 buf[len] = '\0';
1605 sptr = buf;
1606
1607 token = strsep(&sptr, " ");
1608 if (!token)
1609 return -EINVAL;
1610 if (kstrtou16(token, 0, &idle_period))
1611 return -EINVAL;
1612
1613 token = strsep(&sptr, " ");
1614 if (!token)
1615 return -EINVAL;
1616 if (kstrtou16(token, 0, &ps_poll_num))
1617 return -EINVAL;
1618
1619 token = strsep(&sptr, " ");
1620 if (!token)
1621 return -EINVAL;
1622 if (kstrtou16(token, 0, &dtim))
1623 return -EINVAL;
1624
1625 token = strsep(&sptr, " ");
1626 if (!token)
1627 return -EINVAL;
1628 if (kstrtou16(token, 0, &tx_wakeup))
1629 return -EINVAL;
1630
1631 token = strsep(&sptr, " ");
1632 if (!token)
1633 return -EINVAL;
1634 if (kstrtou16(token, 0, &num_tx))
1635 return -EINVAL;
1636
1637 ath6kl_wmi_pmparams_cmd(ar->wmi, 0, idle_period, ps_poll_num,
1638 dtim, tx_wakeup, num_tx, 0);
1639
1640 return count;
1641}
1642
1643static const struct file_operations fops_power_params = {
1644 .write = ath6kl_power_params_write,
1645 .open = ath6kl_debugfs_open,
1646 .owner = THIS_MODULE,
1647 .llseek = default_llseek,
1648};
1649
Vasanthakumar Thiagarajand999ba32011-08-26 13:06:31 +05301650int ath6kl_debug_init(struct ath6kl *ar)
1651{
Kalle Valobdf53962011-09-02 10:32:04 +03001652 ar->debug.fwlog_buf.buf = vmalloc(ATH6KL_FWLOG_SIZE);
1653 if (ar->debug.fwlog_buf.buf == NULL)
1654 return -ENOMEM;
1655
1656 ar->debug.fwlog_tmp = kmalloc(ATH6KL_FWLOG_SLOT_SIZE, GFP_KERNEL);
1657 if (ar->debug.fwlog_tmp == NULL) {
1658 vfree(ar->debug.fwlog_buf.buf);
1659 return -ENOMEM;
1660 }
1661
1662 spin_lock_init(&ar->debug.fwlog_lock);
1663
Kalle Valo939f1cc2011-09-02 10:32:04 +03001664 /*
1665 * Actually we are lying here but don't know how to read the mask
1666 * value from the firmware.
1667 */
1668 ar->debug.fwlog_mask = 0;
1669
Vasanthakumar Thiagarajand999ba32011-08-26 13:06:31 +05301670 ar->debugfs_phy = debugfs_create_dir("ath6kl",
Vasanthakumar Thiagarajanbe98e3a2011-10-25 19:33:57 +05301671 ar->wiphy->debugfsdir);
Kalle Valobdf53962011-09-02 10:32:04 +03001672 if (!ar->debugfs_phy) {
1673 vfree(ar->debug.fwlog_buf.buf);
1674 kfree(ar->debug.fwlog_tmp);
Vasanthakumar Thiagarajand999ba32011-08-26 13:06:31 +05301675 return -ENOMEM;
Kalle Valobdf53962011-09-02 10:32:04 +03001676 }
Vasanthakumar Thiagarajand999ba32011-08-26 13:06:31 +05301677
Vasanthakumar Thiagarajan03f68a92011-08-26 13:06:32 +05301678 debugfs_create_file("tgt_stats", S_IRUSR, ar->debugfs_phy, ar,
1679 &fops_tgt_stats);
1680
Vasanthakumar Thiagarajan78fc4852011-08-26 13:06:33 +05301681 debugfs_create_file("credit_dist_stats", S_IRUSR, ar->debugfs_phy, ar,
1682 &fops_credit_dist_stats);
1683
Jouni Malinene8091282011-10-11 17:31:53 +03001684 debugfs_create_file("endpoint_stats", S_IRUSR | S_IWUSR,
1685 ar->debugfs_phy, ar, &fops_endpoint_stats);
1686
Kalle Valobdf53962011-09-02 10:32:04 +03001687 debugfs_create_file("fwlog", S_IRUSR, ar->debugfs_phy, ar,
1688 &fops_fwlog);
1689
Kalle Valo939f1cc2011-09-02 10:32:04 +03001690 debugfs_create_file("fwlog_mask", S_IRUSR | S_IWUSR, ar->debugfs_phy,
1691 ar, &fops_fwlog_mask);
1692
Vasanthakumar Thiagarajan91d57de2011-09-02 10:40:06 +03001693 debugfs_create_file("reg_addr", S_IRUSR | S_IWUSR, ar->debugfs_phy, ar,
1694 &fops_diag_reg_read);
1695
1696 debugfs_create_file("reg_dump", S_IRUSR, ar->debugfs_phy, ar,
1697 &fops_reg_dump);
1698
Vivek Natarajane5090442011-08-31 15:02:19 +05301699 debugfs_create_file("lrssi_roam_threshold", S_IRUSR | S_IWUSR,
1700 ar->debugfs_phy, ar, &fops_lrssi_roam_threshold);
Vasanthakumar Thiagarajan252c0682011-09-05 11:19:46 +03001701
1702 debugfs_create_file("reg_write", S_IRUSR | S_IWUSR,
1703 ar->debugfs_phy, ar, &fops_diag_reg_write);
1704
Kalle Valo9a730832011-09-27 23:33:28 +03001705 debugfs_create_file("war_stats", S_IRUSR, ar->debugfs_phy, ar,
1706 &fops_war_stats);
1707
Jouni Malinen4b28a802011-10-11 17:31:54 +03001708 debugfs_create_file("roam_table", S_IRUSR, ar->debugfs_phy, ar,
1709 &fops_roam_table);
1710
Jouni Malinen12618752011-10-11 17:31:55 +03001711 debugfs_create_file("force_roam", S_IWUSR, ar->debugfs_phy, ar,
1712 &fops_force_roam);
1713
1714 debugfs_create_file("roam_mode", S_IWUSR, ar->debugfs_phy, ar,
1715 &fops_roam_mode);
1716
Jouni Malinenff0b0072011-10-11 17:31:56 +03001717 debugfs_create_file("keepalive", S_IRUSR | S_IWUSR, ar->debugfs_phy, ar,
1718 &fops_keepalive);
1719
1720 debugfs_create_file("disconnect_timeout", S_IRUSR | S_IWUSR,
1721 ar->debugfs_phy, ar, &fops_disconnect_timeout);
1722
Rishi Panjwani8fffd9e2011-10-14 17:48:07 -07001723 debugfs_create_file("create_qos", S_IWUSR, ar->debugfs_phy, ar,
1724 &fops_create_qos);
1725
1726 debugfs_create_file("delete_qos", S_IWUSR, ar->debugfs_phy, ar,
1727 &fops_delete_qos);
1728
Rishi Panjwani116b3a22011-10-18 17:20:06 -07001729 debugfs_create_file("bgscan_interval", S_IWUSR,
1730 ar->debugfs_phy, ar, &fops_bgscan_int);
1731
Sujith Manoharan82327362012-01-10 09:54:10 +05301732 debugfs_create_file("listen_interval", S_IRUSR | S_IWUSR,
1733 ar->debugfs_phy, ar, &fops_listen_int);
1734
Rishi Panjwania24fc7c2011-10-25 19:52:41 -07001735 debugfs_create_file("power_params", S_IWUSR, ar->debugfs_phy, ar,
1736 &fops_power_params);
1737
Vasanthakumar Thiagarajand999ba32011-08-26 13:06:31 +05301738 return 0;
1739}
Kalle Valobdf53962011-09-02 10:32:04 +03001740
1741void ath6kl_debug_cleanup(struct ath6kl *ar)
1742{
1743 vfree(ar->debug.fwlog_buf.buf);
1744 kfree(ar->debug.fwlog_tmp);
Jouni Malinen4b28a802011-10-11 17:31:54 +03001745 kfree(ar->debug.roam_tbl);
Kalle Valobdf53962011-09-02 10:32:04 +03001746}
1747
Kalle Valobdcd8172011-07-18 00:22:30 +03001748#endif