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" 18bdf5396bSKalle Valo 19bdf5396bSKalle Valo #include <linux/circ_buf.h> 20939f1cceSKalle Valo #include <linux/fs.h> 2162c83ac4SKalle Valo #include <linux/vmalloc.h> 22ee40fa06SPaul Gortmaker #include <linux/export.h> 23bdf5396bSKalle Valo 24bdcd8170SKalle Valo #include "debug.h" 25bdf5396bSKalle Valo #include "target.h" 26bdf5396bSKalle Valo 27bdf5396bSKalle Valo struct ath6kl_fwlog_slot { 28bdf5396bSKalle Valo __le32 timestamp; 29bdf5396bSKalle Valo __le32 length; 30bdf5396bSKalle Valo 31bdf5396bSKalle Valo /* max ATH6KL_FWLOG_PAYLOAD_SIZE bytes */ 32bdf5396bSKalle Valo u8 payload[0]; 33bdf5396bSKalle Valo }; 34bdf5396bSKalle Valo 35bdf5396bSKalle Valo #define ATH6KL_FWLOG_SIZE 32768 36bdf5396bSKalle Valo #define ATH6KL_FWLOG_SLOT_SIZE (sizeof(struct ath6kl_fwlog_slot) + \ 37bdf5396bSKalle Valo ATH6KL_FWLOG_PAYLOAD_SIZE) 38939f1cceSKalle Valo #define ATH6KL_FWLOG_VALID_MASK 0x1ffff 39bdcd8170SKalle Valo 40bdcd8170SKalle Valo int ath6kl_printk(const char *level, const char *fmt, ...) 41bdcd8170SKalle Valo { 42bdcd8170SKalle Valo struct va_format vaf; 43bdcd8170SKalle Valo va_list args; 44bdcd8170SKalle Valo int rtn; 45bdcd8170SKalle Valo 46bdcd8170SKalle Valo va_start(args, fmt); 47bdcd8170SKalle Valo 48bdcd8170SKalle Valo vaf.fmt = fmt; 49bdcd8170SKalle Valo vaf.va = &args; 50bdcd8170SKalle Valo 51bdcd8170SKalle Valo rtn = printk("%sath6kl: %pV", level, &vaf); 52bdcd8170SKalle Valo 53bdcd8170SKalle Valo va_end(args); 54bdcd8170SKalle Valo 55bdcd8170SKalle Valo return rtn; 56bdcd8170SKalle Valo } 57d6a434d6SKalle Valo EXPORT_SYMBOL(ath6kl_printk); 58bdcd8170SKalle Valo 59bdcd8170SKalle Valo #ifdef CONFIG_ATH6KL_DEBUG 6091d57de5SVasanthakumar Thiagarajan 613b1b7d09SKalle Valo void ath6kl_dbg(enum ATH6K_DEBUG_MASK mask, const char *fmt, ...) 623b1b7d09SKalle Valo { 633b1b7d09SKalle Valo struct va_format vaf; 643b1b7d09SKalle Valo va_list args; 653b1b7d09SKalle Valo 663b1b7d09SKalle Valo if (!(debug_mask & mask)) 673b1b7d09SKalle Valo return; 683b1b7d09SKalle Valo 693b1b7d09SKalle Valo va_start(args, fmt); 703b1b7d09SKalle Valo 713b1b7d09SKalle Valo vaf.fmt = fmt; 723b1b7d09SKalle Valo vaf.va = &args; 733b1b7d09SKalle Valo 743b1b7d09SKalle Valo ath6kl_printk(KERN_DEBUG, "%pV", &vaf); 753b1b7d09SKalle Valo 763b1b7d09SKalle Valo va_end(args); 773b1b7d09SKalle Valo } 78d6a434d6SKalle Valo EXPORT_SYMBOL(ath6kl_dbg); 793b1b7d09SKalle Valo 803b1b7d09SKalle Valo void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask, 813b1b7d09SKalle Valo const char *msg, const char *prefix, 823b1b7d09SKalle Valo const void *buf, size_t len) 833b1b7d09SKalle Valo { 843b1b7d09SKalle Valo if (debug_mask & mask) { 853b1b7d09SKalle Valo if (msg) 863b1b7d09SKalle Valo ath6kl_dbg(mask, "%s\n", msg); 873b1b7d09SKalle Valo 883b1b7d09SKalle Valo print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len); 893b1b7d09SKalle Valo } 903b1b7d09SKalle Valo } 91d6a434d6SKalle Valo EXPORT_SYMBOL(ath6kl_dbg_dump); 923b1b7d09SKalle Valo 9391d57de5SVasanthakumar Thiagarajan #define REG_OUTPUT_LEN_PER_LINE 25 9491d57de5SVasanthakumar Thiagarajan #define REGTYPE_STR_LEN 100 9591d57de5SVasanthakumar Thiagarajan 9691d57de5SVasanthakumar Thiagarajan struct ath6kl_diag_reg_info { 9791d57de5SVasanthakumar Thiagarajan u32 reg_start; 9891d57de5SVasanthakumar Thiagarajan u32 reg_end; 9991d57de5SVasanthakumar Thiagarajan const char *reg_info; 10091d57de5SVasanthakumar Thiagarajan }; 10191d57de5SVasanthakumar Thiagarajan 10291d57de5SVasanthakumar Thiagarajan static const struct ath6kl_diag_reg_info diag_reg[] = { 10391d57de5SVasanthakumar Thiagarajan { 0x20000, 0x200fc, "General DMA and Rx registers" }, 10491d57de5SVasanthakumar Thiagarajan { 0x28000, 0x28900, "MAC PCU register & keycache" }, 10591d57de5SVasanthakumar Thiagarajan { 0x20800, 0x20a40, "QCU" }, 10691d57de5SVasanthakumar Thiagarajan { 0x21000, 0x212f0, "DCU" }, 10791d57de5SVasanthakumar Thiagarajan { 0x4000, 0x42e4, "RTC" }, 10891d57de5SVasanthakumar Thiagarajan { 0x540000, 0x540000 + (256 * 1024), "RAM" }, 10991d57de5SVasanthakumar Thiagarajan { 0x29800, 0x2B210, "Base Band" }, 11091d57de5SVasanthakumar Thiagarajan { 0x1C000, 0x1C748, "Analog" }, 11191d57de5SVasanthakumar Thiagarajan }; 11291d57de5SVasanthakumar Thiagarajan 113bdcd8170SKalle Valo void ath6kl_dump_registers(struct ath6kl_device *dev, 114bdcd8170SKalle Valo struct ath6kl_irq_proc_registers *irq_proc_reg, 115bdcd8170SKalle Valo struct ath6kl_irq_enable_reg *irq_enable_reg) 116bdcd8170SKalle Valo { 117bdcd8170SKalle Valo 1185afa5aa7SKalle Valo ath6kl_dbg(ATH6KL_DBG_IRQ, ("<------- Register Table -------->\n")); 119bdcd8170SKalle Valo 120bdcd8170SKalle Valo if (irq_proc_reg != NULL) { 1215afa5aa7SKalle Valo ath6kl_dbg(ATH6KL_DBG_IRQ, 122bdcd8170SKalle Valo "Host Int status: 0x%x\n", 123bdcd8170SKalle Valo irq_proc_reg->host_int_status); 1245afa5aa7SKalle Valo ath6kl_dbg(ATH6KL_DBG_IRQ, 125bdcd8170SKalle Valo "CPU Int status: 0x%x\n", 126bdcd8170SKalle Valo irq_proc_reg->cpu_int_status); 1275afa5aa7SKalle Valo ath6kl_dbg(ATH6KL_DBG_IRQ, 128bdcd8170SKalle Valo "Error Int status: 0x%x\n", 129bdcd8170SKalle Valo irq_proc_reg->error_int_status); 1305afa5aa7SKalle Valo ath6kl_dbg(ATH6KL_DBG_IRQ, 131bdcd8170SKalle Valo "Counter Int status: 0x%x\n", 132bdcd8170SKalle Valo irq_proc_reg->counter_int_status); 1335afa5aa7SKalle Valo ath6kl_dbg(ATH6KL_DBG_IRQ, 134bdcd8170SKalle Valo "Mbox Frame: 0x%x\n", 135bdcd8170SKalle Valo irq_proc_reg->mbox_frame); 1365afa5aa7SKalle Valo ath6kl_dbg(ATH6KL_DBG_IRQ, 137bdcd8170SKalle Valo "Rx Lookahead Valid: 0x%x\n", 138bdcd8170SKalle Valo irq_proc_reg->rx_lkahd_valid); 1395afa5aa7SKalle Valo ath6kl_dbg(ATH6KL_DBG_IRQ, 140bdcd8170SKalle Valo "Rx Lookahead 0: 0x%x\n", 141bdcd8170SKalle Valo irq_proc_reg->rx_lkahd[0]); 1425afa5aa7SKalle Valo ath6kl_dbg(ATH6KL_DBG_IRQ, 143bdcd8170SKalle Valo "Rx Lookahead 1: 0x%x\n", 144bdcd8170SKalle Valo irq_proc_reg->rx_lkahd[1]); 145bdcd8170SKalle Valo 146bdcd8170SKalle Valo if (dev->ar->mbox_info.gmbox_addr != 0) { 147bdcd8170SKalle Valo /* 148bdcd8170SKalle Valo * If the target supports GMBOX hardware, dump some 149bdcd8170SKalle Valo * additional state. 150bdcd8170SKalle Valo */ 1515afa5aa7SKalle Valo ath6kl_dbg(ATH6KL_DBG_IRQ, 152bdcd8170SKalle Valo "GMBOX Host Int status 2: 0x%x\n", 153bdcd8170SKalle Valo irq_proc_reg->host_int_status2); 1545afa5aa7SKalle Valo ath6kl_dbg(ATH6KL_DBG_IRQ, 155bdcd8170SKalle Valo "GMBOX RX Avail: 0x%x\n", 156bdcd8170SKalle Valo irq_proc_reg->gmbox_rx_avail); 1575afa5aa7SKalle Valo ath6kl_dbg(ATH6KL_DBG_IRQ, 158bdcd8170SKalle Valo "GMBOX lookahead alias 0: 0x%x\n", 159bdcd8170SKalle Valo irq_proc_reg->rx_gmbox_lkahd_alias[0]); 1605afa5aa7SKalle Valo ath6kl_dbg(ATH6KL_DBG_IRQ, 161bdcd8170SKalle Valo "GMBOX lookahead alias 1: 0x%x\n", 162bdcd8170SKalle Valo irq_proc_reg->rx_gmbox_lkahd_alias[1]); 163bdcd8170SKalle Valo } 164bdcd8170SKalle Valo 165bdcd8170SKalle Valo } 166bdcd8170SKalle Valo 167bdcd8170SKalle Valo if (irq_enable_reg != NULL) { 1685afa5aa7SKalle Valo ath6kl_dbg(ATH6KL_DBG_IRQ, 169bdcd8170SKalle Valo "Int status Enable: 0x%x\n", 170bdcd8170SKalle Valo irq_enable_reg->int_status_en); 1715afa5aa7SKalle Valo ath6kl_dbg(ATH6KL_DBG_IRQ, "Counter Int status Enable: 0x%x\n", 172bdcd8170SKalle Valo irq_enable_reg->cntr_int_status_en); 173bdcd8170SKalle Valo } 1745afa5aa7SKalle Valo ath6kl_dbg(ATH6KL_DBG_IRQ, "<------------------------------->\n"); 175bdcd8170SKalle Valo } 176bdcd8170SKalle Valo 177bdcd8170SKalle Valo static void dump_cred_dist(struct htc_endpoint_credit_dist *ep_dist) 178bdcd8170SKalle Valo { 17902f0d6fcSKalle Valo ath6kl_dbg(ATH6KL_DBG_CREDIT, 180bdcd8170SKalle Valo "--- endpoint: %d svc_id: 0x%X ---\n", 181bdcd8170SKalle Valo ep_dist->endpoint, ep_dist->svc_id); 18202f0d6fcSKalle Valo ath6kl_dbg(ATH6KL_DBG_CREDIT, " dist_flags : 0x%X\n", 183bdcd8170SKalle Valo ep_dist->dist_flags); 18402f0d6fcSKalle Valo ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_norm : %d\n", 185bdcd8170SKalle Valo ep_dist->cred_norm); 18602f0d6fcSKalle Valo ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_min : %d\n", 187bdcd8170SKalle Valo ep_dist->cred_min); 18802f0d6fcSKalle Valo ath6kl_dbg(ATH6KL_DBG_CREDIT, " credits : %d\n", 189bdcd8170SKalle Valo ep_dist->credits); 19002f0d6fcSKalle Valo ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_assngd : %d\n", 191bdcd8170SKalle Valo ep_dist->cred_assngd); 19202f0d6fcSKalle Valo ath6kl_dbg(ATH6KL_DBG_CREDIT, " seek_cred : %d\n", 193bdcd8170SKalle Valo ep_dist->seek_cred); 19402f0d6fcSKalle Valo ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_sz : %d\n", 195bdcd8170SKalle Valo ep_dist->cred_sz); 19602f0d6fcSKalle Valo ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_per_msg : %d\n", 197bdcd8170SKalle Valo ep_dist->cred_per_msg); 19802f0d6fcSKalle Valo ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_to_dist : %d\n", 199bdcd8170SKalle Valo ep_dist->cred_to_dist); 20002f0d6fcSKalle Valo ath6kl_dbg(ATH6KL_DBG_CREDIT, " txq_depth : %d\n", 201e8c39790SKalle Valo get_queue_depth(&ep_dist->htc_ep->txq)); 20202f0d6fcSKalle Valo ath6kl_dbg(ATH6KL_DBG_CREDIT, 203bdcd8170SKalle Valo "----------------------------------\n"); 204bdcd8170SKalle Valo } 205bdcd8170SKalle Valo 20602f0d6fcSKalle Valo /* FIXME: move to htc.c */ 207bdcd8170SKalle Valo void dump_cred_dist_stats(struct htc_target *target) 208bdcd8170SKalle Valo { 209bdcd8170SKalle Valo struct htc_endpoint_credit_dist *ep_list; 210bdcd8170SKalle Valo 211bdcd8170SKalle Valo list_for_each_entry(ep_list, &target->cred_dist_list, list) 212bdcd8170SKalle Valo dump_cred_dist(ep_list); 213bdcd8170SKalle Valo 21402f0d6fcSKalle Valo ath6kl_dbg(ATH6KL_DBG_CREDIT, 21502f0d6fcSKalle Valo "credit distribution total %d free %d\n", 2163c370398SKalle Valo target->credit_info->total_avail_credits, 2173c370398SKalle Valo target->credit_info->cur_free_credits); 218bdcd8170SKalle Valo } 219bdcd8170SKalle Valo 22003f68a95SVasanthakumar Thiagarajan static int ath6kl_debugfs_open(struct inode *inode, struct file *file) 22103f68a95SVasanthakumar Thiagarajan { 22203f68a95SVasanthakumar Thiagarajan file->private_data = inode->i_private; 22303f68a95SVasanthakumar Thiagarajan return 0; 22403f68a95SVasanthakumar Thiagarajan } 22503f68a95SVasanthakumar Thiagarajan 2269a730834SKalle Valo void ath6kl_debug_war(struct ath6kl *ar, enum ath6kl_war war) 2279a730834SKalle Valo { 2289a730834SKalle Valo switch (war) { 2299a730834SKalle Valo case ATH6KL_WAR_INVALID_RATE: 2309a730834SKalle Valo ar->debug.war_stats.invalid_rate++; 2319a730834SKalle Valo break; 2329a730834SKalle Valo } 2339a730834SKalle Valo } 2349a730834SKalle Valo 2359a730834SKalle Valo static ssize_t read_file_war_stats(struct file *file, char __user *user_buf, 2369a730834SKalle Valo size_t count, loff_t *ppos) 2379a730834SKalle Valo { 2389a730834SKalle Valo struct ath6kl *ar = file->private_data; 2399a730834SKalle Valo char *buf; 2409a730834SKalle Valo unsigned int len = 0, buf_len = 1500; 2419a730834SKalle Valo ssize_t ret_cnt; 2429a730834SKalle Valo 2439a730834SKalle Valo buf = kzalloc(buf_len, GFP_KERNEL); 2449a730834SKalle Valo if (!buf) 2459a730834SKalle Valo return -ENOMEM; 2469a730834SKalle Valo 2479a730834SKalle Valo len += scnprintf(buf + len, buf_len - len, "\n"); 2489a730834SKalle Valo len += scnprintf(buf + len, buf_len - len, "%25s\n", 2499a730834SKalle Valo "Workaround stats"); 2509a730834SKalle Valo len += scnprintf(buf + len, buf_len - len, "%25s\n\n", 2519a730834SKalle Valo "================="); 2529a730834SKalle Valo len += scnprintf(buf + len, buf_len - len, "%20s %10u\n", 2539a730834SKalle Valo "Invalid rates", ar->debug.war_stats.invalid_rate); 2549a730834SKalle Valo 2559a730834SKalle Valo if (WARN_ON(len > buf_len)) 2569a730834SKalle Valo len = buf_len; 2579a730834SKalle Valo 2589a730834SKalle Valo ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); 2599a730834SKalle Valo 2609a730834SKalle Valo kfree(buf); 2619a730834SKalle Valo return ret_cnt; 2629a730834SKalle Valo } 2639a730834SKalle Valo 2649a730834SKalle Valo static const struct file_operations fops_war_stats = { 2659a730834SKalle Valo .read = read_file_war_stats, 2669a730834SKalle Valo .open = ath6kl_debugfs_open, 2679a730834SKalle Valo .owner = THIS_MODULE, 2689a730834SKalle Valo .llseek = default_llseek, 2699a730834SKalle Valo }; 2709a730834SKalle Valo 271bdf5396bSKalle Valo static void ath6kl_debug_fwlog_add(struct ath6kl *ar, const void *buf, 272bdf5396bSKalle Valo size_t buf_len) 273bdf5396bSKalle Valo { 274bdf5396bSKalle Valo struct circ_buf *fwlog = &ar->debug.fwlog_buf; 275bdf5396bSKalle Valo size_t space; 276bdf5396bSKalle Valo int i; 277bdf5396bSKalle Valo 278bdf5396bSKalle Valo /* entries must all be equal size */ 279bdf5396bSKalle Valo if (WARN_ON(buf_len != ATH6KL_FWLOG_SLOT_SIZE)) 280bdf5396bSKalle Valo return; 281bdf5396bSKalle Valo 282bdf5396bSKalle Valo space = CIRC_SPACE(fwlog->head, fwlog->tail, ATH6KL_FWLOG_SIZE); 283bdf5396bSKalle Valo if (space < buf_len) 284bdf5396bSKalle Valo /* discard oldest slot */ 285bdf5396bSKalle Valo fwlog->tail = (fwlog->tail + ATH6KL_FWLOG_SLOT_SIZE) & 286bdf5396bSKalle Valo (ATH6KL_FWLOG_SIZE - 1); 287bdf5396bSKalle Valo 288bdf5396bSKalle Valo for (i = 0; i < buf_len; i += space) { 289bdf5396bSKalle Valo space = CIRC_SPACE_TO_END(fwlog->head, fwlog->tail, 290bdf5396bSKalle Valo ATH6KL_FWLOG_SIZE); 291bdf5396bSKalle Valo 292bdf5396bSKalle Valo if ((size_t) space > buf_len - i) 293bdf5396bSKalle Valo space = buf_len - i; 294bdf5396bSKalle Valo 295bdf5396bSKalle Valo memcpy(&fwlog->buf[fwlog->head], buf, space); 296bdf5396bSKalle Valo fwlog->head = (fwlog->head + space) & (ATH6KL_FWLOG_SIZE - 1); 297bdf5396bSKalle Valo } 298bdf5396bSKalle Valo 299bdf5396bSKalle Valo } 300bdf5396bSKalle Valo 301bdf5396bSKalle Valo void ath6kl_debug_fwlog_event(struct ath6kl *ar, const void *buf, size_t len) 302bdf5396bSKalle Valo { 303bdf5396bSKalle Valo struct ath6kl_fwlog_slot *slot = ar->debug.fwlog_tmp; 304bdf5396bSKalle Valo size_t slot_len; 305bdf5396bSKalle Valo 306bdf5396bSKalle Valo if (WARN_ON(len > ATH6KL_FWLOG_PAYLOAD_SIZE)) 307bdf5396bSKalle Valo return; 308bdf5396bSKalle Valo 309bdf5396bSKalle Valo spin_lock_bh(&ar->debug.fwlog_lock); 310bdf5396bSKalle Valo 311bdf5396bSKalle Valo slot->timestamp = cpu_to_le32(jiffies); 312bdf5396bSKalle Valo slot->length = cpu_to_le32(len); 313bdf5396bSKalle Valo memcpy(slot->payload, buf, len); 314bdf5396bSKalle Valo 315bdf5396bSKalle Valo slot_len = sizeof(*slot) + len; 316bdf5396bSKalle Valo 317bdf5396bSKalle Valo if (slot_len < ATH6KL_FWLOG_SLOT_SIZE) 318bdf5396bSKalle Valo memset(slot->payload + len, 0, 319bdf5396bSKalle Valo ATH6KL_FWLOG_SLOT_SIZE - slot_len); 320bdf5396bSKalle Valo 321bdf5396bSKalle Valo ath6kl_debug_fwlog_add(ar, slot, ATH6KL_FWLOG_SLOT_SIZE); 322bdf5396bSKalle Valo 323bdf5396bSKalle Valo spin_unlock_bh(&ar->debug.fwlog_lock); 324bdf5396bSKalle Valo } 325bdf5396bSKalle Valo 326bdf5396bSKalle Valo static bool ath6kl_debug_fwlog_empty(struct ath6kl *ar) 327bdf5396bSKalle Valo { 328bdf5396bSKalle Valo return CIRC_CNT(ar->debug.fwlog_buf.head, 329bdf5396bSKalle Valo ar->debug.fwlog_buf.tail, 330bdf5396bSKalle Valo ATH6KL_FWLOG_SLOT_SIZE) == 0; 331bdf5396bSKalle Valo } 332bdf5396bSKalle Valo 333bdf5396bSKalle Valo static ssize_t ath6kl_fwlog_read(struct file *file, char __user *user_buf, 334bdf5396bSKalle Valo size_t count, loff_t *ppos) 335bdf5396bSKalle Valo { 336bdf5396bSKalle Valo struct ath6kl *ar = file->private_data; 337bdf5396bSKalle Valo struct circ_buf *fwlog = &ar->debug.fwlog_buf; 338bdf5396bSKalle Valo size_t len = 0, buf_len = count; 339bdf5396bSKalle Valo ssize_t ret_cnt; 340bdf5396bSKalle Valo char *buf; 341bdf5396bSKalle Valo int ccnt; 342bdf5396bSKalle Valo 343bdf5396bSKalle Valo buf = vmalloc(buf_len); 344bdf5396bSKalle Valo if (!buf) 345bdf5396bSKalle Valo return -ENOMEM; 346bdf5396bSKalle Valo 347bc07ddb2SKalle Valo /* read undelivered logs from firmware */ 348bc07ddb2SKalle Valo ath6kl_read_fwlogs(ar); 349bc07ddb2SKalle Valo 350bdf5396bSKalle Valo spin_lock_bh(&ar->debug.fwlog_lock); 351bdf5396bSKalle Valo 352bdf5396bSKalle Valo while (len < buf_len && !ath6kl_debug_fwlog_empty(ar)) { 353bdf5396bSKalle Valo ccnt = CIRC_CNT_TO_END(fwlog->head, fwlog->tail, 354bdf5396bSKalle Valo ATH6KL_FWLOG_SIZE); 355bdf5396bSKalle Valo 356bdf5396bSKalle Valo if ((size_t) ccnt > buf_len - len) 357bdf5396bSKalle Valo ccnt = buf_len - len; 358bdf5396bSKalle Valo 359bdf5396bSKalle Valo memcpy(buf + len, &fwlog->buf[fwlog->tail], ccnt); 360bdf5396bSKalle Valo len += ccnt; 361bdf5396bSKalle Valo 362bdf5396bSKalle Valo fwlog->tail = (fwlog->tail + ccnt) & 363bdf5396bSKalle Valo (ATH6KL_FWLOG_SIZE - 1); 364bdf5396bSKalle Valo } 365bdf5396bSKalle Valo 366bdf5396bSKalle Valo spin_unlock_bh(&ar->debug.fwlog_lock); 367bdf5396bSKalle Valo 368bdf5396bSKalle Valo if (WARN_ON(len > buf_len)) 369bdf5396bSKalle Valo len = buf_len; 370bdf5396bSKalle Valo 371bdf5396bSKalle Valo ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); 372bdf5396bSKalle Valo 373bdf5396bSKalle Valo vfree(buf); 374bdf5396bSKalle Valo 375bdf5396bSKalle Valo return ret_cnt; 376bdf5396bSKalle Valo } 377bdf5396bSKalle Valo 378bdf5396bSKalle Valo static const struct file_operations fops_fwlog = { 379bdf5396bSKalle Valo .open = ath6kl_debugfs_open, 380bdf5396bSKalle Valo .read = ath6kl_fwlog_read, 381bdf5396bSKalle Valo .owner = THIS_MODULE, 382bdf5396bSKalle Valo .llseek = default_llseek, 383bdf5396bSKalle Valo }; 384bdf5396bSKalle Valo 385939f1cceSKalle Valo static ssize_t ath6kl_fwlog_mask_read(struct file *file, char __user *user_buf, 386939f1cceSKalle Valo size_t count, loff_t *ppos) 387939f1cceSKalle Valo { 388939f1cceSKalle Valo struct ath6kl *ar = file->private_data; 389939f1cceSKalle Valo char buf[16]; 390939f1cceSKalle Valo int len; 391939f1cceSKalle Valo 392939f1cceSKalle Valo len = snprintf(buf, sizeof(buf), "0x%x\n", ar->debug.fwlog_mask); 393939f1cceSKalle Valo 394939f1cceSKalle Valo return simple_read_from_buffer(user_buf, count, ppos, buf, len); 395939f1cceSKalle Valo } 396939f1cceSKalle Valo 397939f1cceSKalle Valo static ssize_t ath6kl_fwlog_mask_write(struct file *file, 398939f1cceSKalle Valo const char __user *user_buf, 399939f1cceSKalle Valo size_t count, loff_t *ppos) 400939f1cceSKalle Valo { 401939f1cceSKalle Valo struct ath6kl *ar = file->private_data; 402939f1cceSKalle Valo int ret; 403939f1cceSKalle Valo 404939f1cceSKalle Valo ret = kstrtou32_from_user(user_buf, count, 0, &ar->debug.fwlog_mask); 405939f1cceSKalle Valo if (ret) 406939f1cceSKalle Valo return ret; 407939f1cceSKalle Valo 408939f1cceSKalle Valo ret = ath6kl_wmi_config_debug_module_cmd(ar->wmi, 409939f1cceSKalle Valo ATH6KL_FWLOG_VALID_MASK, 410939f1cceSKalle Valo ar->debug.fwlog_mask); 411939f1cceSKalle Valo if (ret) 412939f1cceSKalle Valo return ret; 413939f1cceSKalle Valo 414939f1cceSKalle Valo return count; 415939f1cceSKalle Valo } 416939f1cceSKalle Valo 417939f1cceSKalle Valo static const struct file_operations fops_fwlog_mask = { 418939f1cceSKalle Valo .open = ath6kl_debugfs_open, 419939f1cceSKalle Valo .read = ath6kl_fwlog_mask_read, 420939f1cceSKalle Valo .write = ath6kl_fwlog_mask_write, 421939f1cceSKalle Valo .owner = THIS_MODULE, 422939f1cceSKalle Valo .llseek = default_llseek, 423939f1cceSKalle Valo }; 424939f1cceSKalle Valo 42503f68a95SVasanthakumar Thiagarajan static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf, 42603f68a95SVasanthakumar Thiagarajan size_t count, loff_t *ppos) 42703f68a95SVasanthakumar Thiagarajan { 42803f68a95SVasanthakumar Thiagarajan struct ath6kl *ar = file->private_data; 429990bd915SVasanthakumar Thiagarajan struct ath6kl_vif *vif; 430990bd915SVasanthakumar Thiagarajan struct target_stats *tgt_stats; 43103f68a95SVasanthakumar Thiagarajan char *buf; 43203f68a95SVasanthakumar Thiagarajan unsigned int len = 0, buf_len = 1500; 43303f68a95SVasanthakumar Thiagarajan int i; 43403f68a95SVasanthakumar Thiagarajan long left; 43503f68a95SVasanthakumar Thiagarajan ssize_t ret_cnt; 43603f68a95SVasanthakumar Thiagarajan 437990bd915SVasanthakumar Thiagarajan vif = ath6kl_vif_first(ar); 438990bd915SVasanthakumar Thiagarajan if (!vif) 439990bd915SVasanthakumar Thiagarajan return -EIO; 440990bd915SVasanthakumar Thiagarajan 441990bd915SVasanthakumar Thiagarajan tgt_stats = &vif->target_stats; 442990bd915SVasanthakumar Thiagarajan 44303f68a95SVasanthakumar Thiagarajan buf = kzalloc(buf_len, GFP_KERNEL); 44403f68a95SVasanthakumar Thiagarajan if (!buf) 44503f68a95SVasanthakumar Thiagarajan return -ENOMEM; 44603f68a95SVasanthakumar Thiagarajan 44703f68a95SVasanthakumar Thiagarajan if (down_interruptible(&ar->sem)) { 44803f68a95SVasanthakumar Thiagarajan kfree(buf); 44903f68a95SVasanthakumar Thiagarajan return -EBUSY; 45003f68a95SVasanthakumar Thiagarajan } 45103f68a95SVasanthakumar Thiagarajan 452b95907a7SVasanthakumar Thiagarajan set_bit(STATS_UPDATE_PEND, &vif->flags); 45303f68a95SVasanthakumar Thiagarajan 454334234b5SVasanthakumar Thiagarajan if (ath6kl_wmi_get_stats_cmd(ar->wmi, 0)) { 45503f68a95SVasanthakumar Thiagarajan up(&ar->sem); 45603f68a95SVasanthakumar Thiagarajan kfree(buf); 45703f68a95SVasanthakumar Thiagarajan return -EIO; 45803f68a95SVasanthakumar Thiagarajan } 45903f68a95SVasanthakumar Thiagarajan 46003f68a95SVasanthakumar Thiagarajan left = wait_event_interruptible_timeout(ar->event_wq, 46103f68a95SVasanthakumar Thiagarajan !test_bit(STATS_UPDATE_PEND, 462b95907a7SVasanthakumar Thiagarajan &vif->flags), WMI_TIMEOUT); 46303f68a95SVasanthakumar Thiagarajan 46403f68a95SVasanthakumar Thiagarajan up(&ar->sem); 46503f68a95SVasanthakumar Thiagarajan 46603f68a95SVasanthakumar Thiagarajan if (left <= 0) { 46703f68a95SVasanthakumar Thiagarajan kfree(buf); 46803f68a95SVasanthakumar Thiagarajan return -ETIMEDOUT; 46903f68a95SVasanthakumar Thiagarajan } 47003f68a95SVasanthakumar Thiagarajan 47103f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "\n"); 47203f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%25s\n", 47303f68a95SVasanthakumar Thiagarajan "Target Tx stats"); 47403f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%25s\n\n", 47503f68a95SVasanthakumar Thiagarajan "================="); 47603f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 47703f68a95SVasanthakumar Thiagarajan "Ucast packets", tgt_stats->tx_ucast_pkt); 47803f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 47903f68a95SVasanthakumar Thiagarajan "Bcast packets", tgt_stats->tx_bcast_pkt); 48003f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 48103f68a95SVasanthakumar Thiagarajan "Ucast byte", tgt_stats->tx_ucast_byte); 48203f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 48303f68a95SVasanthakumar Thiagarajan "Bcast byte", tgt_stats->tx_bcast_byte); 48403f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 48503f68a95SVasanthakumar Thiagarajan "Rts success cnt", tgt_stats->tx_rts_success_cnt); 48603f68a95SVasanthakumar Thiagarajan for (i = 0; i < 4; i++) 48703f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, 48803f68a95SVasanthakumar Thiagarajan "%18s %d %10llu\n", "PER on ac", 48903f68a95SVasanthakumar Thiagarajan i, tgt_stats->tx_pkt_per_ac[i]); 49003f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 49103f68a95SVasanthakumar Thiagarajan "Error", tgt_stats->tx_err); 49203f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 49303f68a95SVasanthakumar Thiagarajan "Fail count", tgt_stats->tx_fail_cnt); 49403f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 49503f68a95SVasanthakumar Thiagarajan "Retry count", tgt_stats->tx_retry_cnt); 49603f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 49703f68a95SVasanthakumar Thiagarajan "Multi retry cnt", tgt_stats->tx_mult_retry_cnt); 49803f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 49903f68a95SVasanthakumar Thiagarajan "Rts fail cnt", tgt_stats->tx_rts_fail_cnt); 50003f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%25s %10llu\n\n", 50103f68a95SVasanthakumar Thiagarajan "TKIP counter measure used", 50203f68a95SVasanthakumar Thiagarajan tgt_stats->tkip_cnter_measures_invoked); 50303f68a95SVasanthakumar Thiagarajan 50403f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%25s\n", 50503f68a95SVasanthakumar Thiagarajan "Target Rx stats"); 50603f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%25s\n", 50703f68a95SVasanthakumar Thiagarajan "================="); 50803f68a95SVasanthakumar Thiagarajan 50903f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 51003f68a95SVasanthakumar Thiagarajan "Ucast packets", tgt_stats->rx_ucast_pkt); 51103f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10d\n", 51203f68a95SVasanthakumar Thiagarajan "Ucast Rate", tgt_stats->rx_ucast_rate); 51303f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 51403f68a95SVasanthakumar Thiagarajan "Bcast packets", tgt_stats->rx_bcast_pkt); 51503f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 51603f68a95SVasanthakumar Thiagarajan "Ucast byte", tgt_stats->rx_ucast_byte); 51703f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 51803f68a95SVasanthakumar Thiagarajan "Bcast byte", tgt_stats->rx_bcast_byte); 51903f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 52003f68a95SVasanthakumar Thiagarajan "Fragmented pkt", tgt_stats->rx_frgment_pkt); 52103f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 52203f68a95SVasanthakumar Thiagarajan "Error", tgt_stats->rx_err); 52303f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 52403f68a95SVasanthakumar Thiagarajan "CRC Err", tgt_stats->rx_crc_err); 52503f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 52603f68a95SVasanthakumar Thiagarajan "Key chache miss", tgt_stats->rx_key_cache_miss); 52703f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 52803f68a95SVasanthakumar Thiagarajan "Decrypt Err", tgt_stats->rx_decrypt_err); 52903f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 53003f68a95SVasanthakumar Thiagarajan "Duplicate frame", tgt_stats->rx_dupl_frame); 53103f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 53203f68a95SVasanthakumar Thiagarajan "Tkip Mic failure", tgt_stats->tkip_local_mic_fail); 53303f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 53403f68a95SVasanthakumar Thiagarajan "TKIP format err", tgt_stats->tkip_fmt_err); 53503f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 53603f68a95SVasanthakumar Thiagarajan "CCMP format Err", tgt_stats->ccmp_fmt_err); 53703f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n\n", 53803f68a95SVasanthakumar Thiagarajan "CCMP Replay Err", tgt_stats->ccmp_replays); 53903f68a95SVasanthakumar Thiagarajan 54003f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%25s\n", 54103f68a95SVasanthakumar Thiagarajan "Misc Target stats"); 54203f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%25s\n", 54303f68a95SVasanthakumar Thiagarajan "================="); 54403f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 54503f68a95SVasanthakumar Thiagarajan "Beacon Miss count", tgt_stats->cs_bmiss_cnt); 54603f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 54703f68a95SVasanthakumar Thiagarajan "Num Connects", tgt_stats->cs_connect_cnt); 54803f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 54903f68a95SVasanthakumar Thiagarajan "Num disconnects", tgt_stats->cs_discon_cnt); 55003f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10d\n", 55103f68a95SVasanthakumar Thiagarajan "Beacon avg rssi", tgt_stats->cs_ave_beacon_rssi); 55203f68a95SVasanthakumar Thiagarajan 55303f68a95SVasanthakumar Thiagarajan if (len > buf_len) 55403f68a95SVasanthakumar Thiagarajan len = buf_len; 55503f68a95SVasanthakumar Thiagarajan 55603f68a95SVasanthakumar Thiagarajan ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); 55703f68a95SVasanthakumar Thiagarajan 55803f68a95SVasanthakumar Thiagarajan kfree(buf); 55903f68a95SVasanthakumar Thiagarajan return ret_cnt; 56003f68a95SVasanthakumar Thiagarajan } 56103f68a95SVasanthakumar Thiagarajan 56203f68a95SVasanthakumar Thiagarajan static const struct file_operations fops_tgt_stats = { 56303f68a95SVasanthakumar Thiagarajan .read = read_file_tgt_stats, 56403f68a95SVasanthakumar Thiagarajan .open = ath6kl_debugfs_open, 56503f68a95SVasanthakumar Thiagarajan .owner = THIS_MODULE, 56603f68a95SVasanthakumar Thiagarajan .llseek = default_llseek, 56703f68a95SVasanthakumar Thiagarajan }; 56803f68a95SVasanthakumar Thiagarajan 56978fc4856SVasanthakumar Thiagarajan #define print_credit_info(fmt_str, ep_list_field) \ 57078fc4856SVasanthakumar Thiagarajan (len += scnprintf(buf + len, buf_len - len, fmt_str, \ 57178fc4856SVasanthakumar Thiagarajan ep_list->ep_list_field)) 57278fc4856SVasanthakumar Thiagarajan #define CREDIT_INFO_DISPLAY_STRING_LEN 200 57378fc4856SVasanthakumar Thiagarajan #define CREDIT_INFO_LEN 128 57478fc4856SVasanthakumar Thiagarajan 57578fc4856SVasanthakumar Thiagarajan static ssize_t read_file_credit_dist_stats(struct file *file, 57678fc4856SVasanthakumar Thiagarajan char __user *user_buf, 57778fc4856SVasanthakumar Thiagarajan size_t count, loff_t *ppos) 57878fc4856SVasanthakumar Thiagarajan { 57978fc4856SVasanthakumar Thiagarajan struct ath6kl *ar = file->private_data; 58078fc4856SVasanthakumar Thiagarajan struct htc_target *target = ar->htc_target; 58178fc4856SVasanthakumar Thiagarajan struct htc_endpoint_credit_dist *ep_list; 58278fc4856SVasanthakumar Thiagarajan char *buf; 58378fc4856SVasanthakumar Thiagarajan unsigned int buf_len, len = 0; 58478fc4856SVasanthakumar Thiagarajan ssize_t ret_cnt; 58578fc4856SVasanthakumar Thiagarajan 58678fc4856SVasanthakumar Thiagarajan buf_len = CREDIT_INFO_DISPLAY_STRING_LEN + 58778fc4856SVasanthakumar Thiagarajan get_queue_depth(&target->cred_dist_list) * CREDIT_INFO_LEN; 58878fc4856SVasanthakumar Thiagarajan buf = kzalloc(buf_len, GFP_KERNEL); 58978fc4856SVasanthakumar Thiagarajan if (!buf) 59078fc4856SVasanthakumar Thiagarajan return -ENOMEM; 59178fc4856SVasanthakumar Thiagarajan 59278fc4856SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%25s%5d\n", 59378fc4856SVasanthakumar Thiagarajan "Total Avail Credits: ", 5943c370398SKalle Valo target->credit_info->total_avail_credits); 59578fc4856SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%25s%5d\n", 59678fc4856SVasanthakumar Thiagarajan "Free credits :", 5973c370398SKalle Valo target->credit_info->cur_free_credits); 59878fc4856SVasanthakumar Thiagarajan 59978fc4856SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, 60078fc4856SVasanthakumar Thiagarajan " Epid Flags Cred_norm Cred_min Credits Cred_assngd" 60178fc4856SVasanthakumar Thiagarajan " Seek_cred Cred_sz Cred_per_msg Cred_to_dist" 60278fc4856SVasanthakumar Thiagarajan " qdepth\n"); 60378fc4856SVasanthakumar Thiagarajan 60478fc4856SVasanthakumar Thiagarajan list_for_each_entry(ep_list, &target->cred_dist_list, list) { 60578fc4856SVasanthakumar Thiagarajan print_credit_info(" %2d", endpoint); 60678fc4856SVasanthakumar Thiagarajan print_credit_info("%10x", dist_flags); 60778fc4856SVasanthakumar Thiagarajan print_credit_info("%8d", cred_norm); 60878fc4856SVasanthakumar Thiagarajan print_credit_info("%9d", cred_min); 60978fc4856SVasanthakumar Thiagarajan print_credit_info("%9d", credits); 61078fc4856SVasanthakumar Thiagarajan print_credit_info("%10d", cred_assngd); 61178fc4856SVasanthakumar Thiagarajan print_credit_info("%13d", seek_cred); 61278fc4856SVasanthakumar Thiagarajan print_credit_info("%12d", cred_sz); 61378fc4856SVasanthakumar Thiagarajan print_credit_info("%9d", cred_per_msg); 61478fc4856SVasanthakumar Thiagarajan print_credit_info("%14d", cred_to_dist); 61578fc4856SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%12d\n", 616e8c39790SKalle Valo get_queue_depth(&ep_list->htc_ep->txq)); 61778fc4856SVasanthakumar Thiagarajan } 61878fc4856SVasanthakumar Thiagarajan 61978fc4856SVasanthakumar Thiagarajan if (len > buf_len) 62078fc4856SVasanthakumar Thiagarajan len = buf_len; 62178fc4856SVasanthakumar Thiagarajan 62278fc4856SVasanthakumar Thiagarajan ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); 62378fc4856SVasanthakumar Thiagarajan kfree(buf); 62478fc4856SVasanthakumar Thiagarajan return ret_cnt; 62578fc4856SVasanthakumar Thiagarajan } 62678fc4856SVasanthakumar Thiagarajan 62778fc4856SVasanthakumar Thiagarajan static const struct file_operations fops_credit_dist_stats = { 62878fc4856SVasanthakumar Thiagarajan .read = read_file_credit_dist_stats, 62978fc4856SVasanthakumar Thiagarajan .open = ath6kl_debugfs_open, 63078fc4856SVasanthakumar Thiagarajan .owner = THIS_MODULE, 63178fc4856SVasanthakumar Thiagarajan .llseek = default_llseek, 63278fc4856SVasanthakumar Thiagarajan }; 63378fc4856SVasanthakumar Thiagarajan 634e8091281SJouni Malinen static unsigned int print_endpoint_stat(struct htc_target *target, char *buf, 635e8091281SJouni Malinen unsigned int buf_len, unsigned int len, 636e8091281SJouni Malinen int offset, const char *name) 637e8091281SJouni Malinen { 638e8091281SJouni Malinen int i; 639e8091281SJouni Malinen struct htc_endpoint_stats *ep_st; 640e8091281SJouni Malinen u32 *counter; 641e8091281SJouni Malinen 642e8091281SJouni Malinen len += scnprintf(buf + len, buf_len - len, "%s:", name); 643e8091281SJouni Malinen for (i = 0; i < ENDPOINT_MAX; i++) { 644e8091281SJouni Malinen ep_st = &target->endpoint[i].ep_st; 645e8091281SJouni Malinen counter = ((u32 *) ep_st) + (offset / 4); 646e8091281SJouni Malinen len += scnprintf(buf + len, buf_len - len, " %u", *counter); 647e8091281SJouni Malinen } 648e8091281SJouni Malinen len += scnprintf(buf + len, buf_len - len, "\n"); 649e8091281SJouni Malinen 650e8091281SJouni Malinen return len; 651e8091281SJouni Malinen } 652e8091281SJouni Malinen 653e8091281SJouni Malinen static ssize_t ath6kl_endpoint_stats_read(struct file *file, 654e8091281SJouni Malinen char __user *user_buf, 655e8091281SJouni Malinen size_t count, loff_t *ppos) 656e8091281SJouni Malinen { 657e8091281SJouni Malinen struct ath6kl *ar = file->private_data; 658e8091281SJouni Malinen struct htc_target *target = ar->htc_target; 659e8091281SJouni Malinen char *buf; 660e8091281SJouni Malinen unsigned int buf_len, len = 0; 661e8091281SJouni Malinen ssize_t ret_cnt; 662e8091281SJouni Malinen 66317169329SJouni Malinen buf_len = sizeof(struct htc_endpoint_stats) / sizeof(u32) * 66417169329SJouni Malinen (25 + ENDPOINT_MAX * 11); 66517169329SJouni Malinen buf = kmalloc(buf_len, GFP_KERNEL); 666e8091281SJouni Malinen if (!buf) 667e8091281SJouni Malinen return -ENOMEM; 668e8091281SJouni Malinen 669e8091281SJouni Malinen #define EPSTAT(name) \ 670e8091281SJouni Malinen len = print_endpoint_stat(target, buf, buf_len, len, \ 671e8091281SJouni Malinen offsetof(struct htc_endpoint_stats, name), \ 672e8091281SJouni Malinen #name) 673e8091281SJouni Malinen EPSTAT(cred_low_indicate); 674e8091281SJouni Malinen EPSTAT(tx_issued); 675e8091281SJouni Malinen EPSTAT(tx_pkt_bundled); 676e8091281SJouni Malinen EPSTAT(tx_bundles); 677e8091281SJouni Malinen EPSTAT(tx_dropped); 678e8091281SJouni Malinen EPSTAT(tx_cred_rpt); 679e8091281SJouni Malinen EPSTAT(cred_rpt_from_rx); 68017169329SJouni Malinen EPSTAT(cred_rpt_from_other); 681e8091281SJouni Malinen EPSTAT(cred_rpt_ep0); 682e8091281SJouni Malinen EPSTAT(cred_from_rx); 683e8091281SJouni Malinen EPSTAT(cred_from_other); 684e8091281SJouni Malinen EPSTAT(cred_from_ep0); 685e8091281SJouni Malinen EPSTAT(cred_cosumd); 686e8091281SJouni Malinen EPSTAT(cred_retnd); 687e8091281SJouni Malinen EPSTAT(rx_pkts); 688e8091281SJouni Malinen EPSTAT(rx_lkahds); 689e8091281SJouni Malinen EPSTAT(rx_bundl); 690e8091281SJouni Malinen EPSTAT(rx_bundle_lkahd); 691e8091281SJouni Malinen EPSTAT(rx_bundle_from_hdr); 692e8091281SJouni Malinen EPSTAT(rx_alloc_thresh_hit); 693e8091281SJouni Malinen EPSTAT(rxalloc_thresh_byte); 694e8091281SJouni Malinen #undef EPSTAT 695e8091281SJouni Malinen 696e8091281SJouni Malinen if (len > buf_len) 697e8091281SJouni Malinen len = buf_len; 698e8091281SJouni Malinen 699e8091281SJouni Malinen ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); 700e8091281SJouni Malinen kfree(buf); 701e8091281SJouni Malinen return ret_cnt; 702e8091281SJouni Malinen } 703e8091281SJouni Malinen 704e8091281SJouni Malinen static ssize_t ath6kl_endpoint_stats_write(struct file *file, 705e8091281SJouni Malinen const char __user *user_buf, 706e8091281SJouni Malinen size_t count, loff_t *ppos) 707e8091281SJouni Malinen { 708e8091281SJouni Malinen struct ath6kl *ar = file->private_data; 709e8091281SJouni Malinen struct htc_target *target = ar->htc_target; 710e8091281SJouni Malinen int ret, i; 711e8091281SJouni Malinen u32 val; 712e8091281SJouni Malinen struct htc_endpoint_stats *ep_st; 713e8091281SJouni Malinen 714e8091281SJouni Malinen ret = kstrtou32_from_user(user_buf, count, 0, &val); 715e8091281SJouni Malinen if (ret) 716e8091281SJouni Malinen return ret; 717e8091281SJouni Malinen if (val == 0) { 718e8091281SJouni Malinen for (i = 0; i < ENDPOINT_MAX; i++) { 719e8091281SJouni Malinen ep_st = &target->endpoint[i].ep_st; 720e8091281SJouni Malinen memset(ep_st, 0, sizeof(*ep_st)); 721e8091281SJouni Malinen } 722e8091281SJouni Malinen } 723e8091281SJouni Malinen 724e8091281SJouni Malinen return count; 725e8091281SJouni Malinen } 726e8091281SJouni Malinen 727e8091281SJouni Malinen static const struct file_operations fops_endpoint_stats = { 728e8091281SJouni Malinen .open = ath6kl_debugfs_open, 729e8091281SJouni Malinen .read = ath6kl_endpoint_stats_read, 730e8091281SJouni Malinen .write = ath6kl_endpoint_stats_write, 731e8091281SJouni Malinen .owner = THIS_MODULE, 732e8091281SJouni Malinen .llseek = default_llseek, 733e8091281SJouni Malinen }; 734e8091281SJouni Malinen 73591d57de5SVasanthakumar Thiagarajan static unsigned long ath6kl_get_num_reg(void) 73691d57de5SVasanthakumar Thiagarajan { 73791d57de5SVasanthakumar Thiagarajan int i; 73891d57de5SVasanthakumar Thiagarajan unsigned long n_reg = 0; 73991d57de5SVasanthakumar Thiagarajan 74091d57de5SVasanthakumar Thiagarajan for (i = 0; i < ARRAY_SIZE(diag_reg); i++) 74191d57de5SVasanthakumar Thiagarajan n_reg = n_reg + 74291d57de5SVasanthakumar Thiagarajan (diag_reg[i].reg_end - diag_reg[i].reg_start) / 4 + 1; 74391d57de5SVasanthakumar Thiagarajan 74491d57de5SVasanthakumar Thiagarajan return n_reg; 74591d57de5SVasanthakumar Thiagarajan } 74691d57de5SVasanthakumar Thiagarajan 74791d57de5SVasanthakumar Thiagarajan static bool ath6kl_dbg_is_diag_reg_valid(u32 reg_addr) 74891d57de5SVasanthakumar Thiagarajan { 74991d57de5SVasanthakumar Thiagarajan int i; 75091d57de5SVasanthakumar Thiagarajan 75191d57de5SVasanthakumar Thiagarajan for (i = 0; i < ARRAY_SIZE(diag_reg); i++) { 75291d57de5SVasanthakumar Thiagarajan if (reg_addr >= diag_reg[i].reg_start && 75391d57de5SVasanthakumar Thiagarajan reg_addr <= diag_reg[i].reg_end) 75491d57de5SVasanthakumar Thiagarajan return true; 75591d57de5SVasanthakumar Thiagarajan } 75691d57de5SVasanthakumar Thiagarajan 75791d57de5SVasanthakumar Thiagarajan return false; 75891d57de5SVasanthakumar Thiagarajan } 75991d57de5SVasanthakumar Thiagarajan 76091d57de5SVasanthakumar Thiagarajan static ssize_t ath6kl_regread_read(struct file *file, char __user *user_buf, 76191d57de5SVasanthakumar Thiagarajan size_t count, loff_t *ppos) 76291d57de5SVasanthakumar Thiagarajan { 76391d57de5SVasanthakumar Thiagarajan struct ath6kl *ar = file->private_data; 76491d57de5SVasanthakumar Thiagarajan u8 buf[50]; 76591d57de5SVasanthakumar Thiagarajan unsigned int len = 0; 76691d57de5SVasanthakumar Thiagarajan 76791d57de5SVasanthakumar Thiagarajan if (ar->debug.dbgfs_diag_reg) 76891d57de5SVasanthakumar Thiagarajan len += scnprintf(buf + len, sizeof(buf) - len, "0x%x\n", 76991d57de5SVasanthakumar Thiagarajan ar->debug.dbgfs_diag_reg); 77091d57de5SVasanthakumar Thiagarajan else 77191d57de5SVasanthakumar Thiagarajan len += scnprintf(buf + len, sizeof(buf) - len, 77291d57de5SVasanthakumar Thiagarajan "All diag registers\n"); 77391d57de5SVasanthakumar Thiagarajan 77491d57de5SVasanthakumar Thiagarajan return simple_read_from_buffer(user_buf, count, ppos, buf, len); 77591d57de5SVasanthakumar Thiagarajan } 77691d57de5SVasanthakumar Thiagarajan 77791d57de5SVasanthakumar Thiagarajan static ssize_t ath6kl_regread_write(struct file *file, 77891d57de5SVasanthakumar Thiagarajan const char __user *user_buf, 77991d57de5SVasanthakumar Thiagarajan size_t count, loff_t *ppos) 78091d57de5SVasanthakumar Thiagarajan { 78191d57de5SVasanthakumar Thiagarajan struct ath6kl *ar = file->private_data; 78291d57de5SVasanthakumar Thiagarajan u8 buf[50]; 78391d57de5SVasanthakumar Thiagarajan unsigned int len; 78491d57de5SVasanthakumar Thiagarajan unsigned long reg_addr; 78591d57de5SVasanthakumar Thiagarajan 78691d57de5SVasanthakumar Thiagarajan len = min(count, sizeof(buf) - 1); 78791d57de5SVasanthakumar Thiagarajan if (copy_from_user(buf, user_buf, len)) 78891d57de5SVasanthakumar Thiagarajan return -EFAULT; 78991d57de5SVasanthakumar Thiagarajan 79091d57de5SVasanthakumar Thiagarajan buf[len] = '\0'; 79191d57de5SVasanthakumar Thiagarajan 79291d57de5SVasanthakumar Thiagarajan if (strict_strtoul(buf, 0, ®_addr)) 79391d57de5SVasanthakumar Thiagarajan return -EINVAL; 79491d57de5SVasanthakumar Thiagarajan 79591d57de5SVasanthakumar Thiagarajan if ((reg_addr % 4) != 0) 79691d57de5SVasanthakumar Thiagarajan return -EINVAL; 79791d57de5SVasanthakumar Thiagarajan 79891d57de5SVasanthakumar Thiagarajan if (reg_addr && !ath6kl_dbg_is_diag_reg_valid(reg_addr)) 79991d57de5SVasanthakumar Thiagarajan return -EINVAL; 80091d57de5SVasanthakumar Thiagarajan 80191d57de5SVasanthakumar Thiagarajan ar->debug.dbgfs_diag_reg = reg_addr; 80291d57de5SVasanthakumar Thiagarajan 80391d57de5SVasanthakumar Thiagarajan return count; 80491d57de5SVasanthakumar Thiagarajan } 80591d57de5SVasanthakumar Thiagarajan 80691d57de5SVasanthakumar Thiagarajan static const struct file_operations fops_diag_reg_read = { 80791d57de5SVasanthakumar Thiagarajan .read = ath6kl_regread_read, 80891d57de5SVasanthakumar Thiagarajan .write = ath6kl_regread_write, 80991d57de5SVasanthakumar Thiagarajan .open = ath6kl_debugfs_open, 81091d57de5SVasanthakumar Thiagarajan .owner = THIS_MODULE, 81191d57de5SVasanthakumar Thiagarajan .llseek = default_llseek, 81291d57de5SVasanthakumar Thiagarajan }; 81391d57de5SVasanthakumar Thiagarajan 81491d57de5SVasanthakumar Thiagarajan static int ath6kl_regdump_open(struct inode *inode, struct file *file) 81591d57de5SVasanthakumar Thiagarajan { 81691d57de5SVasanthakumar Thiagarajan struct ath6kl *ar = inode->i_private; 81791d57de5SVasanthakumar Thiagarajan u8 *buf; 81891d57de5SVasanthakumar Thiagarajan unsigned long int reg_len; 81991d57de5SVasanthakumar Thiagarajan unsigned int len = 0, n_reg; 82091d57de5SVasanthakumar Thiagarajan u32 addr; 82191d57de5SVasanthakumar Thiagarajan __le32 reg_val; 82291d57de5SVasanthakumar Thiagarajan int i, status; 82391d57de5SVasanthakumar Thiagarajan 82491d57de5SVasanthakumar Thiagarajan /* Dump all the registers if no register is specified */ 82591d57de5SVasanthakumar Thiagarajan if (!ar->debug.dbgfs_diag_reg) 82691d57de5SVasanthakumar Thiagarajan n_reg = ath6kl_get_num_reg(); 82791d57de5SVasanthakumar Thiagarajan else 82891d57de5SVasanthakumar Thiagarajan n_reg = 1; 82991d57de5SVasanthakumar Thiagarajan 83091d57de5SVasanthakumar Thiagarajan reg_len = n_reg * REG_OUTPUT_LEN_PER_LINE; 83191d57de5SVasanthakumar Thiagarajan if (n_reg > 1) 83291d57de5SVasanthakumar Thiagarajan reg_len += REGTYPE_STR_LEN; 83391d57de5SVasanthakumar Thiagarajan 83491d57de5SVasanthakumar Thiagarajan buf = vmalloc(reg_len); 83591d57de5SVasanthakumar Thiagarajan if (!buf) 83691d57de5SVasanthakumar Thiagarajan return -ENOMEM; 83791d57de5SVasanthakumar Thiagarajan 83891d57de5SVasanthakumar Thiagarajan if (n_reg == 1) { 83991d57de5SVasanthakumar Thiagarajan addr = ar->debug.dbgfs_diag_reg; 84091d57de5SVasanthakumar Thiagarajan 84191d57de5SVasanthakumar Thiagarajan status = ath6kl_diag_read32(ar, 84291d57de5SVasanthakumar Thiagarajan TARG_VTOP(ar->target_type, addr), 84391d57de5SVasanthakumar Thiagarajan (u32 *)®_val); 84491d57de5SVasanthakumar Thiagarajan if (status) 84591d57de5SVasanthakumar Thiagarajan goto fail_reg_read; 84691d57de5SVasanthakumar Thiagarajan 84791d57de5SVasanthakumar Thiagarajan len += scnprintf(buf + len, reg_len - len, 84891d57de5SVasanthakumar Thiagarajan "0x%06x 0x%08x\n", addr, le32_to_cpu(reg_val)); 84991d57de5SVasanthakumar Thiagarajan goto done; 85091d57de5SVasanthakumar Thiagarajan } 85191d57de5SVasanthakumar Thiagarajan 85291d57de5SVasanthakumar Thiagarajan for (i = 0; i < ARRAY_SIZE(diag_reg); i++) { 85391d57de5SVasanthakumar Thiagarajan len += scnprintf(buf + len, reg_len - len, 85491d57de5SVasanthakumar Thiagarajan "%s\n", diag_reg[i].reg_info); 85591d57de5SVasanthakumar Thiagarajan for (addr = diag_reg[i].reg_start; 85691d57de5SVasanthakumar Thiagarajan addr <= diag_reg[i].reg_end; addr += 4) { 85791d57de5SVasanthakumar Thiagarajan status = ath6kl_diag_read32(ar, 85891d57de5SVasanthakumar Thiagarajan TARG_VTOP(ar->target_type, addr), 85991d57de5SVasanthakumar Thiagarajan (u32 *)®_val); 86091d57de5SVasanthakumar Thiagarajan if (status) 86191d57de5SVasanthakumar Thiagarajan goto fail_reg_read; 86291d57de5SVasanthakumar Thiagarajan 86391d57de5SVasanthakumar Thiagarajan len += scnprintf(buf + len, reg_len - len, 86491d57de5SVasanthakumar Thiagarajan "0x%06x 0x%08x\n", 86591d57de5SVasanthakumar Thiagarajan addr, le32_to_cpu(reg_val)); 86691d57de5SVasanthakumar Thiagarajan } 86791d57de5SVasanthakumar Thiagarajan } 86891d57de5SVasanthakumar Thiagarajan 86991d57de5SVasanthakumar Thiagarajan done: 87091d57de5SVasanthakumar Thiagarajan file->private_data = buf; 87191d57de5SVasanthakumar Thiagarajan return 0; 87291d57de5SVasanthakumar Thiagarajan 87391d57de5SVasanthakumar Thiagarajan fail_reg_read: 87491d57de5SVasanthakumar Thiagarajan ath6kl_warn("Unable to read memory:%u\n", addr); 87591d57de5SVasanthakumar Thiagarajan vfree(buf); 87691d57de5SVasanthakumar Thiagarajan return -EIO; 87791d57de5SVasanthakumar Thiagarajan } 87891d57de5SVasanthakumar Thiagarajan 87991d57de5SVasanthakumar Thiagarajan static ssize_t ath6kl_regdump_read(struct file *file, char __user *user_buf, 88091d57de5SVasanthakumar Thiagarajan size_t count, loff_t *ppos) 88191d57de5SVasanthakumar Thiagarajan { 88291d57de5SVasanthakumar Thiagarajan u8 *buf = file->private_data; 88391d57de5SVasanthakumar Thiagarajan return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); 88491d57de5SVasanthakumar Thiagarajan } 88591d57de5SVasanthakumar Thiagarajan 88691d57de5SVasanthakumar Thiagarajan static int ath6kl_regdump_release(struct inode *inode, struct file *file) 88791d57de5SVasanthakumar Thiagarajan { 88891d57de5SVasanthakumar Thiagarajan vfree(file->private_data); 88991d57de5SVasanthakumar Thiagarajan return 0; 89091d57de5SVasanthakumar Thiagarajan } 89191d57de5SVasanthakumar Thiagarajan 89291d57de5SVasanthakumar Thiagarajan static const struct file_operations fops_reg_dump = { 89391d57de5SVasanthakumar Thiagarajan .open = ath6kl_regdump_open, 89491d57de5SVasanthakumar Thiagarajan .read = ath6kl_regdump_read, 89591d57de5SVasanthakumar Thiagarajan .release = ath6kl_regdump_release, 89691d57de5SVasanthakumar Thiagarajan .owner = THIS_MODULE, 89791d57de5SVasanthakumar Thiagarajan .llseek = default_llseek, 89891d57de5SVasanthakumar Thiagarajan }; 89991d57de5SVasanthakumar Thiagarajan 900e5090444SVivek Natarajan static ssize_t ath6kl_lrssi_roam_write(struct file *file, 901e5090444SVivek Natarajan const char __user *user_buf, 902e5090444SVivek Natarajan size_t count, loff_t *ppos) 903e5090444SVivek Natarajan { 904e5090444SVivek Natarajan struct ath6kl *ar = file->private_data; 905e5090444SVivek Natarajan unsigned long lrssi_roam_threshold; 906e5090444SVivek Natarajan char buf[32]; 907e5090444SVivek Natarajan ssize_t len; 908e5090444SVivek Natarajan 909e5090444SVivek Natarajan len = min(count, sizeof(buf) - 1); 910e5090444SVivek Natarajan if (copy_from_user(buf, user_buf, len)) 911e5090444SVivek Natarajan return -EFAULT; 912e5090444SVivek Natarajan 913e5090444SVivek Natarajan buf[len] = '\0'; 914e5090444SVivek Natarajan if (strict_strtoul(buf, 0, &lrssi_roam_threshold)) 915e5090444SVivek Natarajan return -EINVAL; 916e5090444SVivek Natarajan 917e5090444SVivek Natarajan ar->lrssi_roam_threshold = lrssi_roam_threshold; 918e5090444SVivek Natarajan 919e5090444SVivek Natarajan ath6kl_wmi_set_roam_lrssi_cmd(ar->wmi, ar->lrssi_roam_threshold); 920e5090444SVivek Natarajan 921e5090444SVivek Natarajan return count; 922e5090444SVivek Natarajan } 923e5090444SVivek Natarajan 924e5090444SVivek Natarajan static ssize_t ath6kl_lrssi_roam_read(struct file *file, 925e5090444SVivek Natarajan char __user *user_buf, 926e5090444SVivek Natarajan size_t count, loff_t *ppos) 927e5090444SVivek Natarajan { 928e5090444SVivek Natarajan struct ath6kl *ar = file->private_data; 929e5090444SVivek Natarajan char buf[32]; 930e5090444SVivek Natarajan unsigned int len; 931e5090444SVivek Natarajan 932e5090444SVivek Natarajan len = snprintf(buf, sizeof(buf), "%u\n", ar->lrssi_roam_threshold); 933e5090444SVivek Natarajan 934e5090444SVivek Natarajan return simple_read_from_buffer(user_buf, count, ppos, buf, len); 935e5090444SVivek Natarajan } 936e5090444SVivek Natarajan 937e5090444SVivek Natarajan static const struct file_operations fops_lrssi_roam_threshold = { 938e5090444SVivek Natarajan .read = ath6kl_lrssi_roam_read, 939e5090444SVivek Natarajan .write = ath6kl_lrssi_roam_write, 940e5090444SVivek Natarajan .open = ath6kl_debugfs_open, 941e5090444SVivek Natarajan .owner = THIS_MODULE, 942e5090444SVivek Natarajan .llseek = default_llseek, 943e5090444SVivek Natarajan }; 944e5090444SVivek Natarajan 945252c068bSVasanthakumar Thiagarajan static ssize_t ath6kl_regwrite_read(struct file *file, 946252c068bSVasanthakumar Thiagarajan char __user *user_buf, 947252c068bSVasanthakumar Thiagarajan size_t count, loff_t *ppos) 948252c068bSVasanthakumar Thiagarajan { 949252c068bSVasanthakumar Thiagarajan struct ath6kl *ar = file->private_data; 950252c068bSVasanthakumar Thiagarajan u8 buf[32]; 951252c068bSVasanthakumar Thiagarajan unsigned int len = 0; 952252c068bSVasanthakumar Thiagarajan 953252c068bSVasanthakumar Thiagarajan len = scnprintf(buf, sizeof(buf), "Addr: 0x%x Val: 0x%x\n", 954252c068bSVasanthakumar Thiagarajan ar->debug.diag_reg_addr_wr, ar->debug.diag_reg_val_wr); 955252c068bSVasanthakumar Thiagarajan 956252c068bSVasanthakumar Thiagarajan return simple_read_from_buffer(user_buf, count, ppos, buf, len); 957252c068bSVasanthakumar Thiagarajan } 958252c068bSVasanthakumar Thiagarajan 959252c068bSVasanthakumar Thiagarajan static ssize_t ath6kl_regwrite_write(struct file *file, 960252c068bSVasanthakumar Thiagarajan const char __user *user_buf, 961252c068bSVasanthakumar Thiagarajan size_t count, loff_t *ppos) 962252c068bSVasanthakumar Thiagarajan { 963252c068bSVasanthakumar Thiagarajan struct ath6kl *ar = file->private_data; 964252c068bSVasanthakumar Thiagarajan char buf[32]; 965252c068bSVasanthakumar Thiagarajan char *sptr, *token; 966252c068bSVasanthakumar Thiagarajan unsigned int len = 0; 967252c068bSVasanthakumar Thiagarajan u32 reg_addr, reg_val; 968252c068bSVasanthakumar Thiagarajan 969252c068bSVasanthakumar Thiagarajan len = min(count, sizeof(buf) - 1); 970252c068bSVasanthakumar Thiagarajan if (copy_from_user(buf, user_buf, len)) 971252c068bSVasanthakumar Thiagarajan return -EFAULT; 972252c068bSVasanthakumar Thiagarajan 973252c068bSVasanthakumar Thiagarajan buf[len] = '\0'; 974252c068bSVasanthakumar Thiagarajan sptr = buf; 975252c068bSVasanthakumar Thiagarajan 976252c068bSVasanthakumar Thiagarajan token = strsep(&sptr, "="); 977252c068bSVasanthakumar Thiagarajan if (!token) 978252c068bSVasanthakumar Thiagarajan return -EINVAL; 979252c068bSVasanthakumar Thiagarajan 980252c068bSVasanthakumar Thiagarajan if (kstrtou32(token, 0, ®_addr)) 981252c068bSVasanthakumar Thiagarajan return -EINVAL; 982252c068bSVasanthakumar Thiagarajan 983252c068bSVasanthakumar Thiagarajan if (!ath6kl_dbg_is_diag_reg_valid(reg_addr)) 984252c068bSVasanthakumar Thiagarajan return -EINVAL; 985252c068bSVasanthakumar Thiagarajan 986252c068bSVasanthakumar Thiagarajan if (kstrtou32(sptr, 0, ®_val)) 987252c068bSVasanthakumar Thiagarajan return -EINVAL; 988252c068bSVasanthakumar Thiagarajan 989252c068bSVasanthakumar Thiagarajan ar->debug.diag_reg_addr_wr = reg_addr; 990252c068bSVasanthakumar Thiagarajan ar->debug.diag_reg_val_wr = reg_val; 991252c068bSVasanthakumar Thiagarajan 992252c068bSVasanthakumar Thiagarajan if (ath6kl_diag_write32(ar, ar->debug.diag_reg_addr_wr, 993252c068bSVasanthakumar Thiagarajan cpu_to_le32(ar->debug.diag_reg_val_wr))) 994252c068bSVasanthakumar Thiagarajan return -EIO; 995252c068bSVasanthakumar Thiagarajan 996252c068bSVasanthakumar Thiagarajan return count; 997252c068bSVasanthakumar Thiagarajan } 998252c068bSVasanthakumar Thiagarajan 999252c068bSVasanthakumar Thiagarajan static const struct file_operations fops_diag_reg_write = { 1000252c068bSVasanthakumar Thiagarajan .read = ath6kl_regwrite_read, 1001252c068bSVasanthakumar Thiagarajan .write = ath6kl_regwrite_write, 1002252c068bSVasanthakumar Thiagarajan .open = ath6kl_debugfs_open, 1003252c068bSVasanthakumar Thiagarajan .owner = THIS_MODULE, 1004252c068bSVasanthakumar Thiagarajan .llseek = default_llseek, 1005252c068bSVasanthakumar Thiagarajan }; 1006252c068bSVasanthakumar Thiagarajan 10074b28a80dSJouni Malinen int ath6kl_debug_roam_tbl_event(struct ath6kl *ar, const void *buf, 10084b28a80dSJouni Malinen size_t len) 10094b28a80dSJouni Malinen { 10104b28a80dSJouni Malinen const struct wmi_target_roam_tbl *tbl; 10114b28a80dSJouni Malinen u16 num_entries; 10124b28a80dSJouni Malinen 10134b28a80dSJouni Malinen if (len < sizeof(*tbl)) 10144b28a80dSJouni Malinen return -EINVAL; 10154b28a80dSJouni Malinen 10164b28a80dSJouni Malinen tbl = (const struct wmi_target_roam_tbl *) buf; 10174b28a80dSJouni Malinen num_entries = le16_to_cpu(tbl->num_entries); 10184b28a80dSJouni Malinen if (sizeof(*tbl) + num_entries * sizeof(struct wmi_bss_roam_info) > 10194b28a80dSJouni Malinen len) 10204b28a80dSJouni Malinen return -EINVAL; 10214b28a80dSJouni Malinen 10224b28a80dSJouni Malinen if (ar->debug.roam_tbl == NULL || 10234b28a80dSJouni Malinen ar->debug.roam_tbl_len < (unsigned int) len) { 10244b28a80dSJouni Malinen kfree(ar->debug.roam_tbl); 10254b28a80dSJouni Malinen ar->debug.roam_tbl = kmalloc(len, GFP_ATOMIC); 10264b28a80dSJouni Malinen if (ar->debug.roam_tbl == NULL) 10274b28a80dSJouni Malinen return -ENOMEM; 10284b28a80dSJouni Malinen } 10294b28a80dSJouni Malinen 10304b28a80dSJouni Malinen memcpy(ar->debug.roam_tbl, buf, len); 10314b28a80dSJouni Malinen ar->debug.roam_tbl_len = len; 10324b28a80dSJouni Malinen 10334b28a80dSJouni Malinen if (test_bit(ROAM_TBL_PEND, &ar->flag)) { 10344b28a80dSJouni Malinen clear_bit(ROAM_TBL_PEND, &ar->flag); 10354b28a80dSJouni Malinen wake_up(&ar->event_wq); 10364b28a80dSJouni Malinen } 10374b28a80dSJouni Malinen 10384b28a80dSJouni Malinen return 0; 10394b28a80dSJouni Malinen } 10404b28a80dSJouni Malinen 10414b28a80dSJouni Malinen static ssize_t ath6kl_roam_table_read(struct file *file, char __user *user_buf, 10424b28a80dSJouni Malinen size_t count, loff_t *ppos) 10434b28a80dSJouni Malinen { 10444b28a80dSJouni Malinen struct ath6kl *ar = file->private_data; 10454b28a80dSJouni Malinen int ret; 10464b28a80dSJouni Malinen long left; 10474b28a80dSJouni Malinen struct wmi_target_roam_tbl *tbl; 10484b28a80dSJouni Malinen u16 num_entries, i; 10494b28a80dSJouni Malinen char *buf; 10504b28a80dSJouni Malinen unsigned int len, buf_len; 10514b28a80dSJouni Malinen ssize_t ret_cnt; 10524b28a80dSJouni Malinen 10534b28a80dSJouni Malinen if (down_interruptible(&ar->sem)) 10544b28a80dSJouni Malinen return -EBUSY; 10554b28a80dSJouni Malinen 10564b28a80dSJouni Malinen set_bit(ROAM_TBL_PEND, &ar->flag); 10574b28a80dSJouni Malinen 10584b28a80dSJouni Malinen ret = ath6kl_wmi_get_roam_tbl_cmd(ar->wmi); 10594b28a80dSJouni Malinen if (ret) { 10604b28a80dSJouni Malinen up(&ar->sem); 10614b28a80dSJouni Malinen return ret; 10624b28a80dSJouni Malinen } 10634b28a80dSJouni Malinen 10644b28a80dSJouni Malinen left = wait_event_interruptible_timeout( 10654b28a80dSJouni Malinen ar->event_wq, !test_bit(ROAM_TBL_PEND, &ar->flag), WMI_TIMEOUT); 10664b28a80dSJouni Malinen up(&ar->sem); 10674b28a80dSJouni Malinen 10684b28a80dSJouni Malinen if (left <= 0) 10694b28a80dSJouni Malinen return -ETIMEDOUT; 10704b28a80dSJouni Malinen 10714b28a80dSJouni Malinen if (ar->debug.roam_tbl == NULL) 10724b28a80dSJouni Malinen return -ENOMEM; 10734b28a80dSJouni Malinen 10744b28a80dSJouni Malinen tbl = (struct wmi_target_roam_tbl *) ar->debug.roam_tbl; 10754b28a80dSJouni Malinen num_entries = le16_to_cpu(tbl->num_entries); 10764b28a80dSJouni Malinen 10774b28a80dSJouni Malinen buf_len = 100 + num_entries * 100; 10784b28a80dSJouni Malinen buf = kzalloc(buf_len, GFP_KERNEL); 10794b28a80dSJouni Malinen if (buf == NULL) 10804b28a80dSJouni Malinen return -ENOMEM; 10814b28a80dSJouni Malinen len = 0; 10824b28a80dSJouni Malinen len += scnprintf(buf + len, buf_len - len, 10834b28a80dSJouni Malinen "roam_mode=%u\n\n" 10844b28a80dSJouni Malinen "# roam_util bssid rssi rssidt last_rssi util bias\n", 10854b28a80dSJouni Malinen le16_to_cpu(tbl->roam_mode)); 10864b28a80dSJouni Malinen 10874b28a80dSJouni Malinen for (i = 0; i < num_entries; i++) { 10884b28a80dSJouni Malinen struct wmi_bss_roam_info *info = &tbl->info[i]; 10894b28a80dSJouni Malinen len += scnprintf(buf + len, buf_len - len, 10904b28a80dSJouni Malinen "%d %pM %d %d %d %d %d\n", 10914b28a80dSJouni Malinen a_sle32_to_cpu(info->roam_util), info->bssid, 10924b28a80dSJouni Malinen info->rssi, info->rssidt, info->last_rssi, 10934b28a80dSJouni Malinen info->util, info->bias); 10944b28a80dSJouni Malinen } 10954b28a80dSJouni Malinen 10964b28a80dSJouni Malinen if (len > buf_len) 10974b28a80dSJouni Malinen len = buf_len; 10984b28a80dSJouni Malinen 10994b28a80dSJouni Malinen ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); 11004b28a80dSJouni Malinen 11014b28a80dSJouni Malinen kfree(buf); 11024b28a80dSJouni Malinen return ret_cnt; 11034b28a80dSJouni Malinen } 11044b28a80dSJouni Malinen 11054b28a80dSJouni Malinen static const struct file_operations fops_roam_table = { 11064b28a80dSJouni Malinen .read = ath6kl_roam_table_read, 11074b28a80dSJouni Malinen .open = ath6kl_debugfs_open, 11084b28a80dSJouni Malinen .owner = THIS_MODULE, 11094b28a80dSJouni Malinen .llseek = default_llseek, 11104b28a80dSJouni Malinen }; 11114b28a80dSJouni Malinen 11121261875fSJouni Malinen static ssize_t ath6kl_force_roam_write(struct file *file, 11131261875fSJouni Malinen const char __user *user_buf, 11141261875fSJouni Malinen size_t count, loff_t *ppos) 11151261875fSJouni Malinen { 11161261875fSJouni Malinen struct ath6kl *ar = file->private_data; 11171261875fSJouni Malinen int ret; 11181261875fSJouni Malinen char buf[20]; 11191261875fSJouni Malinen size_t len; 11201261875fSJouni Malinen u8 bssid[ETH_ALEN]; 11211261875fSJouni Malinen int i; 11221261875fSJouni Malinen int addr[ETH_ALEN]; 11231261875fSJouni Malinen 11241261875fSJouni Malinen len = min(count, sizeof(buf) - 1); 11251261875fSJouni Malinen if (copy_from_user(buf, user_buf, len)) 11261261875fSJouni Malinen return -EFAULT; 11271261875fSJouni Malinen buf[len] = '\0'; 11281261875fSJouni Malinen 11291261875fSJouni Malinen if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", 11301261875fSJouni Malinen &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5]) 11311261875fSJouni Malinen != ETH_ALEN) 11321261875fSJouni Malinen return -EINVAL; 11331261875fSJouni Malinen for (i = 0; i < ETH_ALEN; i++) 11341261875fSJouni Malinen bssid[i] = addr[i]; 11351261875fSJouni Malinen 11361261875fSJouni Malinen ret = ath6kl_wmi_force_roam_cmd(ar->wmi, bssid); 11371261875fSJouni Malinen if (ret) 11381261875fSJouni Malinen return ret; 11391261875fSJouni Malinen 11401261875fSJouni Malinen return count; 11411261875fSJouni Malinen } 11421261875fSJouni Malinen 11431261875fSJouni Malinen static const struct file_operations fops_force_roam = { 11441261875fSJouni Malinen .write = ath6kl_force_roam_write, 11451261875fSJouni Malinen .open = ath6kl_debugfs_open, 11461261875fSJouni Malinen .owner = THIS_MODULE, 11471261875fSJouni Malinen .llseek = default_llseek, 11481261875fSJouni Malinen }; 11491261875fSJouni Malinen 11501261875fSJouni Malinen static ssize_t ath6kl_roam_mode_write(struct file *file, 11511261875fSJouni Malinen const char __user *user_buf, 11521261875fSJouni Malinen size_t count, loff_t *ppos) 11531261875fSJouni Malinen { 11541261875fSJouni Malinen struct ath6kl *ar = file->private_data; 11551261875fSJouni Malinen int ret; 11561261875fSJouni Malinen char buf[20]; 11571261875fSJouni Malinen size_t len; 11581261875fSJouni Malinen enum wmi_roam_mode mode; 11591261875fSJouni Malinen 11601261875fSJouni Malinen len = min(count, sizeof(buf) - 1); 11611261875fSJouni Malinen if (copy_from_user(buf, user_buf, len)) 11621261875fSJouni Malinen return -EFAULT; 11631261875fSJouni Malinen buf[len] = '\0'; 11641261875fSJouni Malinen if (len > 0 && buf[len - 1] == '\n') 11651261875fSJouni Malinen buf[len - 1] = '\0'; 11661261875fSJouni Malinen 11671261875fSJouni Malinen if (strcasecmp(buf, "default") == 0) 11681261875fSJouni Malinen mode = WMI_DEFAULT_ROAM_MODE; 11691261875fSJouni Malinen else if (strcasecmp(buf, "bssbias") == 0) 11701261875fSJouni Malinen mode = WMI_HOST_BIAS_ROAM_MODE; 11711261875fSJouni Malinen else if (strcasecmp(buf, "lock") == 0) 11721261875fSJouni Malinen mode = WMI_LOCK_BSS_MODE; 11731261875fSJouni Malinen else 11741261875fSJouni Malinen return -EINVAL; 11751261875fSJouni Malinen 11761261875fSJouni Malinen ret = ath6kl_wmi_set_roam_mode_cmd(ar->wmi, mode); 11771261875fSJouni Malinen if (ret) 11781261875fSJouni Malinen return ret; 11791261875fSJouni Malinen 11801261875fSJouni Malinen return count; 11811261875fSJouni Malinen } 11821261875fSJouni Malinen 11831261875fSJouni Malinen static const struct file_operations fops_roam_mode = { 11841261875fSJouni Malinen .write = ath6kl_roam_mode_write, 11851261875fSJouni Malinen .open = ath6kl_debugfs_open, 11861261875fSJouni Malinen .owner = THIS_MODULE, 11871261875fSJouni Malinen .llseek = default_llseek, 11881261875fSJouni Malinen }; 11891261875fSJouni Malinen 1190ff0b0075SJouni Malinen void ath6kl_debug_set_keepalive(struct ath6kl *ar, u8 keepalive) 1191ff0b0075SJouni Malinen { 1192ff0b0075SJouni Malinen ar->debug.keepalive = keepalive; 1193ff0b0075SJouni Malinen } 1194ff0b0075SJouni Malinen 1195ff0b0075SJouni Malinen static ssize_t ath6kl_keepalive_read(struct file *file, char __user *user_buf, 1196ff0b0075SJouni Malinen size_t count, loff_t *ppos) 1197ff0b0075SJouni Malinen { 1198ff0b0075SJouni Malinen struct ath6kl *ar = file->private_data; 1199ff0b0075SJouni Malinen char buf[16]; 1200ff0b0075SJouni Malinen int len; 1201ff0b0075SJouni Malinen 1202ff0b0075SJouni Malinen len = snprintf(buf, sizeof(buf), "%u\n", ar->debug.keepalive); 1203ff0b0075SJouni Malinen 1204ff0b0075SJouni Malinen return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1205ff0b0075SJouni Malinen } 1206ff0b0075SJouni Malinen 1207ff0b0075SJouni Malinen static ssize_t ath6kl_keepalive_write(struct file *file, 1208ff0b0075SJouni Malinen const char __user *user_buf, 1209ff0b0075SJouni Malinen size_t count, loff_t *ppos) 1210ff0b0075SJouni Malinen { 1211ff0b0075SJouni Malinen struct ath6kl *ar = file->private_data; 1212ff0b0075SJouni Malinen int ret; 1213ff0b0075SJouni Malinen u8 val; 1214ff0b0075SJouni Malinen 1215ff0b0075SJouni Malinen ret = kstrtou8_from_user(user_buf, count, 0, &val); 1216ff0b0075SJouni Malinen if (ret) 1217ff0b0075SJouni Malinen return ret; 1218ff0b0075SJouni Malinen 12190ce59445SVasanthakumar Thiagarajan ret = ath6kl_wmi_set_keepalive_cmd(ar->wmi, 0, val); 1220ff0b0075SJouni Malinen if (ret) 1221ff0b0075SJouni Malinen return ret; 1222ff0b0075SJouni Malinen 1223ff0b0075SJouni Malinen return count; 1224ff0b0075SJouni Malinen } 1225ff0b0075SJouni Malinen 1226ff0b0075SJouni Malinen static const struct file_operations fops_keepalive = { 1227ff0b0075SJouni Malinen .open = ath6kl_debugfs_open, 1228ff0b0075SJouni Malinen .read = ath6kl_keepalive_read, 1229ff0b0075SJouni Malinen .write = ath6kl_keepalive_write, 1230ff0b0075SJouni Malinen .owner = THIS_MODULE, 1231ff0b0075SJouni Malinen .llseek = default_llseek, 1232ff0b0075SJouni Malinen }; 1233ff0b0075SJouni Malinen 1234ff0b0075SJouni Malinen void ath6kl_debug_set_disconnect_timeout(struct ath6kl *ar, u8 timeout) 1235ff0b0075SJouni Malinen { 1236ff0b0075SJouni Malinen ar->debug.disc_timeout = timeout; 1237ff0b0075SJouni Malinen } 1238ff0b0075SJouni Malinen 1239ff0b0075SJouni Malinen static ssize_t ath6kl_disconnect_timeout_read(struct file *file, 1240ff0b0075SJouni Malinen char __user *user_buf, 1241ff0b0075SJouni Malinen size_t count, loff_t *ppos) 1242ff0b0075SJouni Malinen { 1243ff0b0075SJouni Malinen struct ath6kl *ar = file->private_data; 1244ff0b0075SJouni Malinen char buf[16]; 1245ff0b0075SJouni Malinen int len; 1246ff0b0075SJouni Malinen 1247ff0b0075SJouni Malinen len = snprintf(buf, sizeof(buf), "%u\n", ar->debug.disc_timeout); 1248ff0b0075SJouni Malinen 1249ff0b0075SJouni Malinen return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1250ff0b0075SJouni Malinen } 1251ff0b0075SJouni Malinen 1252ff0b0075SJouni Malinen static ssize_t ath6kl_disconnect_timeout_write(struct file *file, 1253ff0b0075SJouni Malinen const char __user *user_buf, 1254ff0b0075SJouni Malinen size_t count, loff_t *ppos) 1255ff0b0075SJouni Malinen { 1256ff0b0075SJouni Malinen struct ath6kl *ar = file->private_data; 1257ff0b0075SJouni Malinen int ret; 1258ff0b0075SJouni Malinen u8 val; 1259ff0b0075SJouni Malinen 1260ff0b0075SJouni Malinen ret = kstrtou8_from_user(user_buf, count, 0, &val); 1261ff0b0075SJouni Malinen if (ret) 1262ff0b0075SJouni Malinen return ret; 1263ff0b0075SJouni Malinen 12640ce59445SVasanthakumar Thiagarajan ret = ath6kl_wmi_disctimeout_cmd(ar->wmi, 0, val); 1265ff0b0075SJouni Malinen if (ret) 1266ff0b0075SJouni Malinen return ret; 1267ff0b0075SJouni Malinen 1268ff0b0075SJouni Malinen return count; 1269ff0b0075SJouni Malinen } 1270ff0b0075SJouni Malinen 1271ff0b0075SJouni Malinen static const struct file_operations fops_disconnect_timeout = { 1272ff0b0075SJouni Malinen .open = ath6kl_debugfs_open, 1273ff0b0075SJouni Malinen .read = ath6kl_disconnect_timeout_read, 1274ff0b0075SJouni Malinen .write = ath6kl_disconnect_timeout_write, 1275ff0b0075SJouni Malinen .owner = THIS_MODULE, 1276ff0b0075SJouni Malinen .llseek = default_llseek, 1277ff0b0075SJouni Malinen }; 1278ff0b0075SJouni Malinen 12798fffd9e5SRishi Panjwani static ssize_t ath6kl_create_qos_write(struct file *file, 12808fffd9e5SRishi Panjwani const char __user *user_buf, 12818fffd9e5SRishi Panjwani size_t count, loff_t *ppos) 12828fffd9e5SRishi Panjwani { 12838fffd9e5SRishi Panjwani 12848fffd9e5SRishi Panjwani struct ath6kl *ar = file->private_data; 1285990bd915SVasanthakumar Thiagarajan struct ath6kl_vif *vif; 12868cb6d991SVasanthakumar Thiagarajan char buf[200]; 12878fffd9e5SRishi Panjwani ssize_t len; 12888fffd9e5SRishi Panjwani char *sptr, *token; 12898fffd9e5SRishi Panjwani struct wmi_create_pstream_cmd pstream; 12908fffd9e5SRishi Panjwani u32 val32; 12918fffd9e5SRishi Panjwani u16 val16; 12928fffd9e5SRishi Panjwani 1293990bd915SVasanthakumar Thiagarajan vif = ath6kl_vif_first(ar); 1294990bd915SVasanthakumar Thiagarajan if (!vif) 1295990bd915SVasanthakumar Thiagarajan return -EIO; 1296990bd915SVasanthakumar Thiagarajan 12978fffd9e5SRishi Panjwani len = min(count, sizeof(buf) - 1); 12988fffd9e5SRishi Panjwani if (copy_from_user(buf, user_buf, len)) 12998fffd9e5SRishi Panjwani return -EFAULT; 13008fffd9e5SRishi Panjwani buf[len] = '\0'; 13018fffd9e5SRishi Panjwani sptr = buf; 13028fffd9e5SRishi Panjwani 13038fffd9e5SRishi Panjwani token = strsep(&sptr, " "); 13048fffd9e5SRishi Panjwani if (!token) 13058fffd9e5SRishi Panjwani return -EINVAL; 13068fffd9e5SRishi Panjwani if (kstrtou8(token, 0, &pstream.user_pri)) 13078fffd9e5SRishi Panjwani return -EINVAL; 13088fffd9e5SRishi Panjwani 13098fffd9e5SRishi Panjwani token = strsep(&sptr, " "); 13108fffd9e5SRishi Panjwani if (!token) 13118fffd9e5SRishi Panjwani return -EINVAL; 13128fffd9e5SRishi Panjwani if (kstrtou8(token, 0, &pstream.traffic_direc)) 13138fffd9e5SRishi Panjwani return -EINVAL; 13148fffd9e5SRishi Panjwani 13158fffd9e5SRishi Panjwani token = strsep(&sptr, " "); 13168fffd9e5SRishi Panjwani if (!token) 13178fffd9e5SRishi Panjwani return -EINVAL; 13188fffd9e5SRishi Panjwani if (kstrtou8(token, 0, &pstream.traffic_class)) 13198fffd9e5SRishi Panjwani return -EINVAL; 13208fffd9e5SRishi Panjwani 13218fffd9e5SRishi Panjwani token = strsep(&sptr, " "); 13228fffd9e5SRishi Panjwani if (!token) 13238fffd9e5SRishi Panjwani return -EINVAL; 13248fffd9e5SRishi Panjwani if (kstrtou8(token, 0, &pstream.traffic_type)) 13258fffd9e5SRishi Panjwani return -EINVAL; 13268fffd9e5SRishi Panjwani 13278fffd9e5SRishi Panjwani token = strsep(&sptr, " "); 13288fffd9e5SRishi Panjwani if (!token) 13298fffd9e5SRishi Panjwani return -EINVAL; 13308fffd9e5SRishi Panjwani if (kstrtou8(token, 0, &pstream.voice_psc_cap)) 13318fffd9e5SRishi Panjwani return -EINVAL; 13328fffd9e5SRishi Panjwani 13338fffd9e5SRishi Panjwani token = strsep(&sptr, " "); 13348fffd9e5SRishi Panjwani if (!token) 13358fffd9e5SRishi Panjwani return -EINVAL; 13368fffd9e5SRishi Panjwani if (kstrtou32(token, 0, &val32)) 13378fffd9e5SRishi Panjwani return -EINVAL; 13388fffd9e5SRishi Panjwani pstream.min_service_int = cpu_to_le32(val32); 13398fffd9e5SRishi Panjwani 13408fffd9e5SRishi Panjwani token = strsep(&sptr, " "); 13418fffd9e5SRishi Panjwani if (!token) 13428fffd9e5SRishi Panjwani return -EINVAL; 13438fffd9e5SRishi Panjwani if (kstrtou32(token, 0, &val32)) 13448fffd9e5SRishi Panjwani return -EINVAL; 13458fffd9e5SRishi Panjwani pstream.max_service_int = cpu_to_le32(val32); 13468fffd9e5SRishi Panjwani 13478fffd9e5SRishi Panjwani token = strsep(&sptr, " "); 13488fffd9e5SRishi Panjwani if (!token) 13498fffd9e5SRishi Panjwani return -EINVAL; 13508fffd9e5SRishi Panjwani if (kstrtou32(token, 0, &val32)) 13518fffd9e5SRishi Panjwani return -EINVAL; 13528fffd9e5SRishi Panjwani pstream.inactivity_int = cpu_to_le32(val32); 13538fffd9e5SRishi Panjwani 13548fffd9e5SRishi Panjwani token = strsep(&sptr, " "); 13558fffd9e5SRishi Panjwani if (!token) 13568fffd9e5SRishi Panjwani return -EINVAL; 13578fffd9e5SRishi Panjwani if (kstrtou32(token, 0, &val32)) 13588fffd9e5SRishi Panjwani return -EINVAL; 13598fffd9e5SRishi Panjwani pstream.suspension_int = cpu_to_le32(val32); 13608fffd9e5SRishi Panjwani 13618fffd9e5SRishi Panjwani token = strsep(&sptr, " "); 13628fffd9e5SRishi Panjwani if (!token) 13638fffd9e5SRishi Panjwani return -EINVAL; 13648fffd9e5SRishi Panjwani if (kstrtou32(token, 0, &val32)) 13658fffd9e5SRishi Panjwani return -EINVAL; 13668fffd9e5SRishi Panjwani pstream.service_start_time = cpu_to_le32(val32); 13678fffd9e5SRishi Panjwani 13688fffd9e5SRishi Panjwani token = strsep(&sptr, " "); 13698fffd9e5SRishi Panjwani if (!token) 13708fffd9e5SRishi Panjwani return -EINVAL; 13718fffd9e5SRishi Panjwani if (kstrtou8(token, 0, &pstream.tsid)) 13728fffd9e5SRishi Panjwani return -EINVAL; 13738fffd9e5SRishi Panjwani 13748fffd9e5SRishi Panjwani token = strsep(&sptr, " "); 13758fffd9e5SRishi Panjwani if (!token) 13768fffd9e5SRishi Panjwani return -EINVAL; 13778fffd9e5SRishi Panjwani if (kstrtou16(token, 0, &val16)) 13788fffd9e5SRishi Panjwani return -EINVAL; 13798fffd9e5SRishi Panjwani pstream.nominal_msdu = cpu_to_le16(val16); 13808fffd9e5SRishi Panjwani 13818fffd9e5SRishi Panjwani token = strsep(&sptr, " "); 13828fffd9e5SRishi Panjwani if (!token) 13838fffd9e5SRishi Panjwani return -EINVAL; 13848fffd9e5SRishi Panjwani if (kstrtou16(token, 0, &val16)) 13858fffd9e5SRishi Panjwani return -EINVAL; 13868fffd9e5SRishi Panjwani pstream.max_msdu = cpu_to_le16(val16); 13878fffd9e5SRishi Panjwani 13888fffd9e5SRishi Panjwani token = strsep(&sptr, " "); 13898fffd9e5SRishi Panjwani if (!token) 13908fffd9e5SRishi Panjwani return -EINVAL; 13918fffd9e5SRishi Panjwani if (kstrtou32(token, 0, &val32)) 13928fffd9e5SRishi Panjwani return -EINVAL; 13938fffd9e5SRishi Panjwani pstream.min_data_rate = cpu_to_le32(val32); 13948fffd9e5SRishi Panjwani 13958fffd9e5SRishi Panjwani token = strsep(&sptr, " "); 13968fffd9e5SRishi Panjwani if (!token) 13978fffd9e5SRishi Panjwani return -EINVAL; 13988fffd9e5SRishi Panjwani if (kstrtou32(token, 0, &val32)) 13998fffd9e5SRishi Panjwani return -EINVAL; 14008fffd9e5SRishi Panjwani pstream.mean_data_rate = cpu_to_le32(val32); 14018fffd9e5SRishi Panjwani 14028fffd9e5SRishi Panjwani token = strsep(&sptr, " "); 14038fffd9e5SRishi Panjwani if (!token) 14048fffd9e5SRishi Panjwani return -EINVAL; 14058fffd9e5SRishi Panjwani if (kstrtou32(token, 0, &val32)) 14068fffd9e5SRishi Panjwani return -EINVAL; 14078fffd9e5SRishi Panjwani pstream.peak_data_rate = cpu_to_le32(val32); 14088fffd9e5SRishi Panjwani 14098fffd9e5SRishi Panjwani token = strsep(&sptr, " "); 14108fffd9e5SRishi Panjwani if (!token) 14118fffd9e5SRishi Panjwani return -EINVAL; 14128fffd9e5SRishi Panjwani if (kstrtou32(token, 0, &val32)) 14138fffd9e5SRishi Panjwani return -EINVAL; 14148fffd9e5SRishi Panjwani pstream.max_burst_size = cpu_to_le32(val32); 14158fffd9e5SRishi Panjwani 14168fffd9e5SRishi Panjwani token = strsep(&sptr, " "); 14178fffd9e5SRishi Panjwani if (!token) 14188fffd9e5SRishi Panjwani return -EINVAL; 14198fffd9e5SRishi Panjwani if (kstrtou32(token, 0, &val32)) 14208fffd9e5SRishi Panjwani return -EINVAL; 14218fffd9e5SRishi Panjwani pstream.delay_bound = cpu_to_le32(val32); 14228fffd9e5SRishi Panjwani 14238fffd9e5SRishi Panjwani token = strsep(&sptr, " "); 14248fffd9e5SRishi Panjwani if (!token) 14258fffd9e5SRishi Panjwani return -EINVAL; 14268fffd9e5SRishi Panjwani if (kstrtou32(token, 0, &val32)) 14278fffd9e5SRishi Panjwani return -EINVAL; 14288fffd9e5SRishi Panjwani pstream.min_phy_rate = cpu_to_le32(val32); 14298fffd9e5SRishi Panjwani 14308fffd9e5SRishi Panjwani token = strsep(&sptr, " "); 14318fffd9e5SRishi Panjwani if (!token) 14328fffd9e5SRishi Panjwani return -EINVAL; 14338fffd9e5SRishi Panjwani if (kstrtou32(token, 0, &val32)) 14348fffd9e5SRishi Panjwani return -EINVAL; 14358fffd9e5SRishi Panjwani pstream.sba = cpu_to_le32(val32); 14368fffd9e5SRishi Panjwani 14378fffd9e5SRishi Panjwani token = strsep(&sptr, " "); 14388fffd9e5SRishi Panjwani if (!token) 14398fffd9e5SRishi Panjwani return -EINVAL; 14408fffd9e5SRishi Panjwani if (kstrtou32(token, 0, &val32)) 14418fffd9e5SRishi Panjwani return -EINVAL; 14428fffd9e5SRishi Panjwani pstream.medium_time = cpu_to_le32(val32); 14438fffd9e5SRishi Panjwani 14445fbea5dcSChilam Ng pstream.nominal_phy = le32_to_cpu(pstream.min_phy_rate) / 1000000; 14455fbea5dcSChilam Ng 1446240d2799SVasanthakumar Thiagarajan ath6kl_wmi_create_pstream_cmd(ar->wmi, vif->fw_vif_idx, &pstream); 14478fffd9e5SRishi Panjwani 14488fffd9e5SRishi Panjwani return count; 14498fffd9e5SRishi Panjwani } 14508fffd9e5SRishi Panjwani 14518fffd9e5SRishi Panjwani static const struct file_operations fops_create_qos = { 14528fffd9e5SRishi Panjwani .write = ath6kl_create_qos_write, 14538fffd9e5SRishi Panjwani .open = ath6kl_debugfs_open, 14548fffd9e5SRishi Panjwani .owner = THIS_MODULE, 14558fffd9e5SRishi Panjwani .llseek = default_llseek, 14568fffd9e5SRishi Panjwani }; 14578fffd9e5SRishi Panjwani 14588fffd9e5SRishi Panjwani static ssize_t ath6kl_delete_qos_write(struct file *file, 14598fffd9e5SRishi Panjwani const char __user *user_buf, 14608fffd9e5SRishi Panjwani size_t count, loff_t *ppos) 14618fffd9e5SRishi Panjwani { 14628fffd9e5SRishi Panjwani 14638fffd9e5SRishi Panjwani struct ath6kl *ar = file->private_data; 1464990bd915SVasanthakumar Thiagarajan struct ath6kl_vif *vif; 14658fffd9e5SRishi Panjwani char buf[100]; 14668fffd9e5SRishi Panjwani ssize_t len; 14678fffd9e5SRishi Panjwani char *sptr, *token; 14688fffd9e5SRishi Panjwani u8 traffic_class; 14698fffd9e5SRishi Panjwani u8 tsid; 14708fffd9e5SRishi Panjwani 1471990bd915SVasanthakumar Thiagarajan vif = ath6kl_vif_first(ar); 1472990bd915SVasanthakumar Thiagarajan if (!vif) 1473990bd915SVasanthakumar Thiagarajan return -EIO; 1474990bd915SVasanthakumar Thiagarajan 14758fffd9e5SRishi Panjwani len = min(count, sizeof(buf) - 1); 14768fffd9e5SRishi Panjwani if (copy_from_user(buf, user_buf, len)) 14778fffd9e5SRishi Panjwani return -EFAULT; 14788fffd9e5SRishi Panjwani buf[len] = '\0'; 14798fffd9e5SRishi Panjwani sptr = buf; 14808fffd9e5SRishi Panjwani 14818fffd9e5SRishi Panjwani token = strsep(&sptr, " "); 14828fffd9e5SRishi Panjwani if (!token) 14838fffd9e5SRishi Panjwani return -EINVAL; 14848fffd9e5SRishi Panjwani if (kstrtou8(token, 0, &traffic_class)) 14858fffd9e5SRishi Panjwani return -EINVAL; 14868fffd9e5SRishi Panjwani 14878fffd9e5SRishi Panjwani token = strsep(&sptr, " "); 14888fffd9e5SRishi Panjwani if (!token) 14898fffd9e5SRishi Panjwani return -EINVAL; 14908fffd9e5SRishi Panjwani if (kstrtou8(token, 0, &tsid)) 14918fffd9e5SRishi Panjwani return -EINVAL; 14928fffd9e5SRishi Panjwani 1493240d2799SVasanthakumar Thiagarajan ath6kl_wmi_delete_pstream_cmd(ar->wmi, vif->fw_vif_idx, 1494240d2799SVasanthakumar Thiagarajan traffic_class, tsid); 14958fffd9e5SRishi Panjwani 14968fffd9e5SRishi Panjwani return count; 14978fffd9e5SRishi Panjwani } 14988fffd9e5SRishi Panjwani 14998fffd9e5SRishi Panjwani static const struct file_operations fops_delete_qos = { 15008fffd9e5SRishi Panjwani .write = ath6kl_delete_qos_write, 15018fffd9e5SRishi Panjwani .open = ath6kl_debugfs_open, 15028fffd9e5SRishi Panjwani .owner = THIS_MODULE, 15038fffd9e5SRishi Panjwani .llseek = default_llseek, 15048fffd9e5SRishi Panjwani }; 15058fffd9e5SRishi Panjwani 1506116b3a2eSRishi Panjwani static ssize_t ath6kl_bgscan_int_write(struct file *file, 1507116b3a2eSRishi Panjwani const char __user *user_buf, 1508116b3a2eSRishi Panjwani size_t count, loff_t *ppos) 1509116b3a2eSRishi Panjwani { 1510116b3a2eSRishi Panjwani struct ath6kl *ar = file->private_data; 1511116b3a2eSRishi Panjwani u16 bgscan_int; 1512116b3a2eSRishi Panjwani char buf[32]; 1513116b3a2eSRishi Panjwani ssize_t len; 1514116b3a2eSRishi Panjwani 1515116b3a2eSRishi Panjwani len = min(count, sizeof(buf) - 1); 1516116b3a2eSRishi Panjwani if (copy_from_user(buf, user_buf, len)) 1517116b3a2eSRishi Panjwani return -EFAULT; 1518116b3a2eSRishi Panjwani 1519116b3a2eSRishi Panjwani buf[len] = '\0'; 1520116b3a2eSRishi Panjwani if (kstrtou16(buf, 0, &bgscan_int)) 1521116b3a2eSRishi Panjwani return -EINVAL; 1522116b3a2eSRishi Panjwani 1523116b3a2eSRishi Panjwani if (bgscan_int == 0) 1524116b3a2eSRishi Panjwani bgscan_int = 0xffff; 1525116b3a2eSRishi Panjwani 1526334234b5SVasanthakumar Thiagarajan ath6kl_wmi_scanparams_cmd(ar->wmi, 0, 0, 0, bgscan_int, 0, 0, 0, 3, 1527116b3a2eSRishi Panjwani 0, 0, 0); 1528116b3a2eSRishi Panjwani 1529116b3a2eSRishi Panjwani return count; 1530116b3a2eSRishi Panjwani } 1531116b3a2eSRishi Panjwani 1532116b3a2eSRishi Panjwani static const struct file_operations fops_bgscan_int = { 1533116b3a2eSRishi Panjwani .write = ath6kl_bgscan_int_write, 1534116b3a2eSRishi Panjwani .open = ath6kl_debugfs_open, 1535116b3a2eSRishi Panjwani .owner = THIS_MODULE, 1536116b3a2eSRishi Panjwani .llseek = default_llseek, 1537116b3a2eSRishi Panjwani }; 1538116b3a2eSRishi Panjwani 1539ef8f0ebaSRishi Panjwani static ssize_t ath6kl_listen_int_write(struct file *file, 1540ef8f0ebaSRishi Panjwani const char __user *user_buf, 1541ef8f0ebaSRishi Panjwani size_t count, loff_t *ppos) 1542ef8f0ebaSRishi Panjwani { 1543ef8f0ebaSRishi Panjwani struct ath6kl *ar = file->private_data; 15448232736dSSujith Manoharan struct ath6kl_vif *vif; 15458232736dSSujith Manoharan u16 listen_interval; 1546ef8f0ebaSRishi Panjwani char buf[32]; 1547ef8f0ebaSRishi Panjwani ssize_t len; 1548ef8f0ebaSRishi Panjwani 15498232736dSSujith Manoharan vif = ath6kl_vif_first(ar); 15508232736dSSujith Manoharan if (!vif) 15518232736dSSujith Manoharan return -EIO; 15528232736dSSujith Manoharan 1553ef8f0ebaSRishi Panjwani len = min(count, sizeof(buf) - 1); 1554ef8f0ebaSRishi Panjwani if (copy_from_user(buf, user_buf, len)) 1555ef8f0ebaSRishi Panjwani return -EFAULT; 1556ef8f0ebaSRishi Panjwani 1557ef8f0ebaSRishi Panjwani buf[len] = '\0'; 15588232736dSSujith Manoharan if (kstrtou16(buf, 0, &listen_interval)) 1559ef8f0ebaSRishi Panjwani return -EINVAL; 1560ef8f0ebaSRishi Panjwani 15618232736dSSujith Manoharan if ((listen_interval < 1) || (listen_interval > 50)) 1562ef8f0ebaSRishi Panjwani return -EINVAL; 1563ef8f0ebaSRishi Panjwani 15648232736dSSujith Manoharan ar->listen_intvl_b = listen_interval; 15658232736dSSujith Manoharan ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, 0, 1566ef8f0ebaSRishi Panjwani ar->listen_intvl_b); 1567ef8f0ebaSRishi Panjwani 1568ef8f0ebaSRishi Panjwani return count; 1569ef8f0ebaSRishi Panjwani } 1570ef8f0ebaSRishi Panjwani 1571ef8f0ebaSRishi Panjwani static ssize_t ath6kl_listen_int_read(struct file *file, 1572ef8f0ebaSRishi Panjwani char __user *user_buf, 1573ef8f0ebaSRishi Panjwani size_t count, loff_t *ppos) 1574ef8f0ebaSRishi Panjwani { 1575ef8f0ebaSRishi Panjwani struct ath6kl *ar = file->private_data; 157650553c2cSDan Carpenter char buf[32]; 1577ef8f0ebaSRishi Panjwani int len; 1578ef8f0ebaSRishi Panjwani 15798232736dSSujith Manoharan len = scnprintf(buf, sizeof(buf), "%u\n", ar->listen_intvl_b); 1580ef8f0ebaSRishi Panjwani 1581ef8f0ebaSRishi Panjwani return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1582ef8f0ebaSRishi Panjwani } 1583ef8f0ebaSRishi Panjwani 1584ef8f0ebaSRishi Panjwani static const struct file_operations fops_listen_int = { 1585ef8f0ebaSRishi Panjwani .read = ath6kl_listen_int_read, 1586ef8f0ebaSRishi Panjwani .write = ath6kl_listen_int_write, 1587ef8f0ebaSRishi Panjwani .open = ath6kl_debugfs_open, 1588ef8f0ebaSRishi Panjwani .owner = THIS_MODULE, 1589ef8f0ebaSRishi Panjwani .llseek = default_llseek, 1590ef8f0ebaSRishi Panjwani }; 1591ef8f0ebaSRishi Panjwani 1592a24fc7c3SRishi Panjwani static ssize_t ath6kl_power_params_write(struct file *file, 1593a24fc7c3SRishi Panjwani const char __user *user_buf, 1594a24fc7c3SRishi Panjwani size_t count, loff_t *ppos) 1595a24fc7c3SRishi Panjwani { 1596a24fc7c3SRishi Panjwani struct ath6kl *ar = file->private_data; 1597a24fc7c3SRishi Panjwani u8 buf[100]; 1598a24fc7c3SRishi Panjwani unsigned int len = 0; 1599a24fc7c3SRishi Panjwani char *sptr, *token; 1600a24fc7c3SRishi Panjwani u16 idle_period, ps_poll_num, dtim, 1601a24fc7c3SRishi Panjwani tx_wakeup, num_tx; 1602a24fc7c3SRishi Panjwani 1603a24fc7c3SRishi Panjwani len = min(count, sizeof(buf) - 1); 1604a24fc7c3SRishi Panjwani if (copy_from_user(buf, user_buf, len)) 1605a24fc7c3SRishi Panjwani return -EFAULT; 1606a24fc7c3SRishi Panjwani buf[len] = '\0'; 1607a24fc7c3SRishi Panjwani sptr = buf; 1608a24fc7c3SRishi Panjwani 1609a24fc7c3SRishi Panjwani token = strsep(&sptr, " "); 1610a24fc7c3SRishi Panjwani if (!token) 1611a24fc7c3SRishi Panjwani return -EINVAL; 1612a24fc7c3SRishi Panjwani if (kstrtou16(token, 0, &idle_period)) 1613a24fc7c3SRishi Panjwani return -EINVAL; 1614a24fc7c3SRishi Panjwani 1615a24fc7c3SRishi Panjwani token = strsep(&sptr, " "); 1616a24fc7c3SRishi Panjwani if (!token) 1617a24fc7c3SRishi Panjwani return -EINVAL; 1618a24fc7c3SRishi Panjwani if (kstrtou16(token, 0, &ps_poll_num)) 1619a24fc7c3SRishi Panjwani return -EINVAL; 1620a24fc7c3SRishi Panjwani 1621a24fc7c3SRishi Panjwani token = strsep(&sptr, " "); 1622a24fc7c3SRishi Panjwani if (!token) 1623a24fc7c3SRishi Panjwani return -EINVAL; 1624a24fc7c3SRishi Panjwani if (kstrtou16(token, 0, &dtim)) 1625a24fc7c3SRishi Panjwani return -EINVAL; 1626a24fc7c3SRishi Panjwani 1627a24fc7c3SRishi Panjwani token = strsep(&sptr, " "); 1628a24fc7c3SRishi Panjwani if (!token) 1629a24fc7c3SRishi Panjwani return -EINVAL; 1630a24fc7c3SRishi Panjwani if (kstrtou16(token, 0, &tx_wakeup)) 1631a24fc7c3SRishi Panjwani return -EINVAL; 1632a24fc7c3SRishi Panjwani 1633a24fc7c3SRishi Panjwani token = strsep(&sptr, " "); 1634a24fc7c3SRishi Panjwani if (!token) 1635a24fc7c3SRishi Panjwani return -EINVAL; 1636a24fc7c3SRishi Panjwani if (kstrtou16(token, 0, &num_tx)) 1637a24fc7c3SRishi Panjwani return -EINVAL; 1638a24fc7c3SRishi Panjwani 1639a24fc7c3SRishi Panjwani ath6kl_wmi_pmparams_cmd(ar->wmi, 0, idle_period, ps_poll_num, 1640a24fc7c3SRishi Panjwani dtim, tx_wakeup, num_tx, 0); 1641a24fc7c3SRishi Panjwani 1642a24fc7c3SRishi Panjwani return count; 1643a24fc7c3SRishi Panjwani } 1644a24fc7c3SRishi Panjwani 1645a24fc7c3SRishi Panjwani static const struct file_operations fops_power_params = { 1646a24fc7c3SRishi Panjwani .write = ath6kl_power_params_write, 1647a24fc7c3SRishi Panjwani .open = ath6kl_debugfs_open, 1648a24fc7c3SRishi Panjwani .owner = THIS_MODULE, 1649a24fc7c3SRishi Panjwani .llseek = default_llseek, 1650a24fc7c3SRishi Panjwani }; 1651a24fc7c3SRishi Panjwani 1652d999ba3eSVasanthakumar Thiagarajan int ath6kl_debug_init(struct ath6kl *ar) 1653d999ba3eSVasanthakumar Thiagarajan { 1654bdf5396bSKalle Valo ar->debug.fwlog_buf.buf = vmalloc(ATH6KL_FWLOG_SIZE); 1655bdf5396bSKalle Valo if (ar->debug.fwlog_buf.buf == NULL) 1656bdf5396bSKalle Valo return -ENOMEM; 1657bdf5396bSKalle Valo 1658bdf5396bSKalle Valo ar->debug.fwlog_tmp = kmalloc(ATH6KL_FWLOG_SLOT_SIZE, GFP_KERNEL); 1659bdf5396bSKalle Valo if (ar->debug.fwlog_tmp == NULL) { 1660bdf5396bSKalle Valo vfree(ar->debug.fwlog_buf.buf); 1661bdf5396bSKalle Valo return -ENOMEM; 1662bdf5396bSKalle Valo } 1663bdf5396bSKalle Valo 1664bdf5396bSKalle Valo spin_lock_init(&ar->debug.fwlog_lock); 1665bdf5396bSKalle Valo 1666939f1cceSKalle Valo /* 1667939f1cceSKalle Valo * Actually we are lying here but don't know how to read the mask 1668939f1cceSKalle Valo * value from the firmware. 1669939f1cceSKalle Valo */ 1670939f1cceSKalle Valo ar->debug.fwlog_mask = 0; 1671939f1cceSKalle Valo 1672d999ba3eSVasanthakumar Thiagarajan ar->debugfs_phy = debugfs_create_dir("ath6kl", 1673be98e3a4SVasanthakumar Thiagarajan ar->wiphy->debugfsdir); 1674bdf5396bSKalle Valo if (!ar->debugfs_phy) { 1675bdf5396bSKalle Valo vfree(ar->debug.fwlog_buf.buf); 1676bdf5396bSKalle Valo kfree(ar->debug.fwlog_tmp); 1677d999ba3eSVasanthakumar Thiagarajan return -ENOMEM; 1678bdf5396bSKalle Valo } 1679d999ba3eSVasanthakumar Thiagarajan 168003f68a95SVasanthakumar Thiagarajan debugfs_create_file("tgt_stats", S_IRUSR, ar->debugfs_phy, ar, 168103f68a95SVasanthakumar Thiagarajan &fops_tgt_stats); 168203f68a95SVasanthakumar Thiagarajan 168378fc4856SVasanthakumar Thiagarajan debugfs_create_file("credit_dist_stats", S_IRUSR, ar->debugfs_phy, ar, 168478fc4856SVasanthakumar Thiagarajan &fops_credit_dist_stats); 168578fc4856SVasanthakumar Thiagarajan 1686e8091281SJouni Malinen debugfs_create_file("endpoint_stats", S_IRUSR | S_IWUSR, 1687e8091281SJouni Malinen ar->debugfs_phy, ar, &fops_endpoint_stats); 1688e8091281SJouni Malinen 1689bdf5396bSKalle Valo debugfs_create_file("fwlog", S_IRUSR, ar->debugfs_phy, ar, 1690bdf5396bSKalle Valo &fops_fwlog); 1691bdf5396bSKalle Valo 1692939f1cceSKalle Valo debugfs_create_file("fwlog_mask", S_IRUSR | S_IWUSR, ar->debugfs_phy, 1693939f1cceSKalle Valo ar, &fops_fwlog_mask); 1694939f1cceSKalle Valo 169591d57de5SVasanthakumar Thiagarajan debugfs_create_file("reg_addr", S_IRUSR | S_IWUSR, ar->debugfs_phy, ar, 169691d57de5SVasanthakumar Thiagarajan &fops_diag_reg_read); 169791d57de5SVasanthakumar Thiagarajan 169891d57de5SVasanthakumar Thiagarajan debugfs_create_file("reg_dump", S_IRUSR, ar->debugfs_phy, ar, 169991d57de5SVasanthakumar Thiagarajan &fops_reg_dump); 170091d57de5SVasanthakumar Thiagarajan 1701e5090444SVivek Natarajan debugfs_create_file("lrssi_roam_threshold", S_IRUSR | S_IWUSR, 1702e5090444SVivek Natarajan ar->debugfs_phy, ar, &fops_lrssi_roam_threshold); 1703252c068bSVasanthakumar Thiagarajan 1704252c068bSVasanthakumar Thiagarajan debugfs_create_file("reg_write", S_IRUSR | S_IWUSR, 1705252c068bSVasanthakumar Thiagarajan ar->debugfs_phy, ar, &fops_diag_reg_write); 1706252c068bSVasanthakumar Thiagarajan 17079a730834SKalle Valo debugfs_create_file("war_stats", S_IRUSR, ar->debugfs_phy, ar, 17089a730834SKalle Valo &fops_war_stats); 17099a730834SKalle Valo 17104b28a80dSJouni Malinen debugfs_create_file("roam_table", S_IRUSR, ar->debugfs_phy, ar, 17114b28a80dSJouni Malinen &fops_roam_table); 17124b28a80dSJouni Malinen 17131261875fSJouni Malinen debugfs_create_file("force_roam", S_IWUSR, ar->debugfs_phy, ar, 17141261875fSJouni Malinen &fops_force_roam); 17151261875fSJouni Malinen 17161261875fSJouni Malinen debugfs_create_file("roam_mode", S_IWUSR, ar->debugfs_phy, ar, 17171261875fSJouni Malinen &fops_roam_mode); 17181261875fSJouni Malinen 1719ff0b0075SJouni Malinen debugfs_create_file("keepalive", S_IRUSR | S_IWUSR, ar->debugfs_phy, ar, 1720ff0b0075SJouni Malinen &fops_keepalive); 1721ff0b0075SJouni Malinen 1722ff0b0075SJouni Malinen debugfs_create_file("disconnect_timeout", S_IRUSR | S_IWUSR, 1723ff0b0075SJouni Malinen ar->debugfs_phy, ar, &fops_disconnect_timeout); 1724ff0b0075SJouni Malinen 17258fffd9e5SRishi Panjwani debugfs_create_file("create_qos", S_IWUSR, ar->debugfs_phy, ar, 17268fffd9e5SRishi Panjwani &fops_create_qos); 17278fffd9e5SRishi Panjwani 17288fffd9e5SRishi Panjwani debugfs_create_file("delete_qos", S_IWUSR, ar->debugfs_phy, ar, 17298fffd9e5SRishi Panjwani &fops_delete_qos); 17308fffd9e5SRishi Panjwani 1731116b3a2eSRishi Panjwani debugfs_create_file("bgscan_interval", S_IWUSR, 1732116b3a2eSRishi Panjwani ar->debugfs_phy, ar, &fops_bgscan_int); 1733116b3a2eSRishi Panjwani 17348232736dSSujith Manoharan debugfs_create_file("listen_interval", S_IRUSR | S_IWUSR, 17358232736dSSujith Manoharan ar->debugfs_phy, ar, &fops_listen_int); 17368232736dSSujith Manoharan 1737a24fc7c3SRishi Panjwani debugfs_create_file("power_params", S_IWUSR, ar->debugfs_phy, ar, 1738a24fc7c3SRishi Panjwani &fops_power_params); 1739a24fc7c3SRishi Panjwani 1740d999ba3eSVasanthakumar Thiagarajan return 0; 1741d999ba3eSVasanthakumar Thiagarajan } 1742bdf5396bSKalle Valo 1743bdf5396bSKalle Valo void ath6kl_debug_cleanup(struct ath6kl *ar) 1744bdf5396bSKalle Valo { 1745bdf5396bSKalle Valo vfree(ar->debug.fwlog_buf.buf); 1746bdf5396bSKalle Valo kfree(ar->debug.fwlog_tmp); 17474b28a80dSJouni Malinen kfree(ar->debug.roam_tbl); 1748bdf5396bSKalle Valo } 1749bdf5396bSKalle Valo 1750bdcd8170SKalle Valo #endif 1751