1bdcd8170SKalle Valo /* 2bdcd8170SKalle Valo * Copyright (c) 2004-2011 Atheros Communications Inc. 3bdcd8170SKalle Valo * 4bdcd8170SKalle Valo * Permission to use, copy, modify, and/or distribute this software for any 5bdcd8170SKalle Valo * purpose with or without fee is hereby granted, provided that the above 6bdcd8170SKalle Valo * copyright notice and this permission notice appear in all copies. 7bdcd8170SKalle Valo * 8bdcd8170SKalle Valo * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9bdcd8170SKalle Valo * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10bdcd8170SKalle Valo * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11bdcd8170SKalle Valo * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12bdcd8170SKalle Valo * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13bdcd8170SKalle Valo * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14bdcd8170SKalle Valo * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15bdcd8170SKalle Valo */ 16bdcd8170SKalle Valo 17bdcd8170SKalle Valo #include "core.h" 18bdcd8170SKalle Valo #include "debug.h" 19bdcd8170SKalle Valo 20bdcd8170SKalle Valo int ath6kl_printk(const char *level, const char *fmt, ...) 21bdcd8170SKalle Valo { 22bdcd8170SKalle Valo struct va_format vaf; 23bdcd8170SKalle Valo va_list args; 24bdcd8170SKalle Valo int rtn; 25bdcd8170SKalle Valo 26bdcd8170SKalle Valo va_start(args, fmt); 27bdcd8170SKalle Valo 28bdcd8170SKalle Valo vaf.fmt = fmt; 29bdcd8170SKalle Valo vaf.va = &args; 30bdcd8170SKalle Valo 31bdcd8170SKalle Valo rtn = printk("%sath6kl: %pV", level, &vaf); 32bdcd8170SKalle Valo 33bdcd8170SKalle Valo va_end(args); 34bdcd8170SKalle Valo 35bdcd8170SKalle Valo return rtn; 36bdcd8170SKalle Valo } 37bdcd8170SKalle Valo 38bdcd8170SKalle Valo #ifdef CONFIG_ATH6KL_DEBUG 39bdcd8170SKalle Valo void ath6kl_dump_registers(struct ath6kl_device *dev, 40bdcd8170SKalle Valo struct ath6kl_irq_proc_registers *irq_proc_reg, 41bdcd8170SKalle Valo struct ath6kl_irq_enable_reg *irq_enable_reg) 42bdcd8170SKalle Valo { 43bdcd8170SKalle Valo 44bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, ("<------- Register Table -------->\n")); 45bdcd8170SKalle Valo 46bdcd8170SKalle Valo if (irq_proc_reg != NULL) { 47bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, 48bdcd8170SKalle Valo "Host Int status: 0x%x\n", 49bdcd8170SKalle Valo irq_proc_reg->host_int_status); 50bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, 51bdcd8170SKalle Valo "CPU Int status: 0x%x\n", 52bdcd8170SKalle Valo irq_proc_reg->cpu_int_status); 53bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, 54bdcd8170SKalle Valo "Error Int status: 0x%x\n", 55bdcd8170SKalle Valo irq_proc_reg->error_int_status); 56bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, 57bdcd8170SKalle Valo "Counter Int status: 0x%x\n", 58bdcd8170SKalle Valo irq_proc_reg->counter_int_status); 59bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, 60bdcd8170SKalle Valo "Mbox Frame: 0x%x\n", 61bdcd8170SKalle Valo irq_proc_reg->mbox_frame); 62bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, 63bdcd8170SKalle Valo "Rx Lookahead Valid: 0x%x\n", 64bdcd8170SKalle Valo irq_proc_reg->rx_lkahd_valid); 65bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, 66bdcd8170SKalle Valo "Rx Lookahead 0: 0x%x\n", 67bdcd8170SKalle Valo irq_proc_reg->rx_lkahd[0]); 68bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, 69bdcd8170SKalle Valo "Rx Lookahead 1: 0x%x\n", 70bdcd8170SKalle Valo irq_proc_reg->rx_lkahd[1]); 71bdcd8170SKalle Valo 72bdcd8170SKalle Valo if (dev->ar->mbox_info.gmbox_addr != 0) { 73bdcd8170SKalle Valo /* 74bdcd8170SKalle Valo * If the target supports GMBOX hardware, dump some 75bdcd8170SKalle Valo * additional state. 76bdcd8170SKalle Valo */ 77bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, 78bdcd8170SKalle Valo "GMBOX Host Int status 2: 0x%x\n", 79bdcd8170SKalle Valo irq_proc_reg->host_int_status2); 80bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, 81bdcd8170SKalle Valo "GMBOX RX Avail: 0x%x\n", 82bdcd8170SKalle Valo irq_proc_reg->gmbox_rx_avail); 83bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, 84bdcd8170SKalle Valo "GMBOX lookahead alias 0: 0x%x\n", 85bdcd8170SKalle Valo irq_proc_reg->rx_gmbox_lkahd_alias[0]); 86bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, 87bdcd8170SKalle Valo "GMBOX lookahead alias 1: 0x%x\n", 88bdcd8170SKalle Valo irq_proc_reg->rx_gmbox_lkahd_alias[1]); 89bdcd8170SKalle Valo } 90bdcd8170SKalle Valo 91bdcd8170SKalle Valo } 92bdcd8170SKalle Valo 93bdcd8170SKalle Valo if (irq_enable_reg != NULL) { 94bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, 95bdcd8170SKalle Valo "Int status Enable: 0x%x\n", 96bdcd8170SKalle Valo irq_enable_reg->int_status_en); 97bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, "Counter Int status Enable: 0x%x\n", 98bdcd8170SKalle Valo irq_enable_reg->cntr_int_status_en); 99bdcd8170SKalle Valo } 100bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, "<------------------------------->\n"); 101bdcd8170SKalle Valo } 102bdcd8170SKalle Valo 103bdcd8170SKalle Valo static void dump_cred_dist(struct htc_endpoint_credit_dist *ep_dist) 104bdcd8170SKalle Valo { 105bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, 106bdcd8170SKalle Valo "--- endpoint: %d svc_id: 0x%X ---\n", 107bdcd8170SKalle Valo ep_dist->endpoint, ep_dist->svc_id); 108bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, " dist_flags : 0x%X\n", 109bdcd8170SKalle Valo ep_dist->dist_flags); 110bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, " cred_norm : %d\n", 111bdcd8170SKalle Valo ep_dist->cred_norm); 112bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, " cred_min : %d\n", 113bdcd8170SKalle Valo ep_dist->cred_min); 114bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, " credits : %d\n", 115bdcd8170SKalle Valo ep_dist->credits); 116bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, " cred_assngd : %d\n", 117bdcd8170SKalle Valo ep_dist->cred_assngd); 118bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, " seek_cred : %d\n", 119bdcd8170SKalle Valo ep_dist->seek_cred); 120bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, " cred_sz : %d\n", 121bdcd8170SKalle Valo ep_dist->cred_sz); 122bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, " cred_per_msg : %d\n", 123bdcd8170SKalle Valo ep_dist->cred_per_msg); 124bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, " cred_to_dist : %d\n", 125bdcd8170SKalle Valo ep_dist->cred_to_dist); 126bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, " txq_depth : %d\n", 127bdcd8170SKalle Valo get_queue_depth(&((struct htc_endpoint *) 128bdcd8170SKalle Valo ep_dist->htc_rsvd)->txq)); 129bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_ANY, 130bdcd8170SKalle Valo "----------------------------------\n"); 131bdcd8170SKalle Valo } 132bdcd8170SKalle Valo 133bdcd8170SKalle Valo void dump_cred_dist_stats(struct htc_target *target) 134bdcd8170SKalle Valo { 135bdcd8170SKalle Valo struct htc_endpoint_credit_dist *ep_list; 136bdcd8170SKalle Valo 137bdcd8170SKalle Valo if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_TRC)) 138bdcd8170SKalle Valo return; 139bdcd8170SKalle Valo 140bdcd8170SKalle Valo list_for_each_entry(ep_list, &target->cred_dist_list, list) 141bdcd8170SKalle Valo dump_cred_dist(ep_list); 142bdcd8170SKalle Valo 143bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:%p dist:%p\n", 144bdcd8170SKalle Valo target->cred_dist_cntxt, NULL); 145bdcd8170SKalle Valo ath6kl_dbg(ATH6KL_DBG_TRC, "credit distribution, total : %d, free : %d\n", 146bdcd8170SKalle Valo target->cred_dist_cntxt->total_avail_credits, 147bdcd8170SKalle Valo target->cred_dist_cntxt->cur_free_credits); 148bdcd8170SKalle Valo } 149bdcd8170SKalle Valo 150*03f68a95SVasanthakumar Thiagarajan static int ath6kl_debugfs_open(struct inode *inode, struct file *file) 151*03f68a95SVasanthakumar Thiagarajan { 152*03f68a95SVasanthakumar Thiagarajan file->private_data = inode->i_private; 153*03f68a95SVasanthakumar Thiagarajan return 0; 154*03f68a95SVasanthakumar Thiagarajan } 155*03f68a95SVasanthakumar Thiagarajan 156*03f68a95SVasanthakumar Thiagarajan static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf, 157*03f68a95SVasanthakumar Thiagarajan size_t count, loff_t *ppos) 158*03f68a95SVasanthakumar Thiagarajan { 159*03f68a95SVasanthakumar Thiagarajan struct ath6kl *ar = file->private_data; 160*03f68a95SVasanthakumar Thiagarajan struct target_stats *tgt_stats = &ar->target_stats; 161*03f68a95SVasanthakumar Thiagarajan char *buf; 162*03f68a95SVasanthakumar Thiagarajan unsigned int len = 0, buf_len = 1500; 163*03f68a95SVasanthakumar Thiagarajan int i; 164*03f68a95SVasanthakumar Thiagarajan long left; 165*03f68a95SVasanthakumar Thiagarajan ssize_t ret_cnt; 166*03f68a95SVasanthakumar Thiagarajan 167*03f68a95SVasanthakumar Thiagarajan buf = kzalloc(buf_len, GFP_KERNEL); 168*03f68a95SVasanthakumar Thiagarajan if (!buf) 169*03f68a95SVasanthakumar Thiagarajan return -ENOMEM; 170*03f68a95SVasanthakumar Thiagarajan 171*03f68a95SVasanthakumar Thiagarajan if (down_interruptible(&ar->sem)) { 172*03f68a95SVasanthakumar Thiagarajan kfree(buf); 173*03f68a95SVasanthakumar Thiagarajan return -EBUSY; 174*03f68a95SVasanthakumar Thiagarajan } 175*03f68a95SVasanthakumar Thiagarajan 176*03f68a95SVasanthakumar Thiagarajan set_bit(STATS_UPDATE_PEND, &ar->flag); 177*03f68a95SVasanthakumar Thiagarajan 178*03f68a95SVasanthakumar Thiagarajan if (ath6kl_wmi_get_stats_cmd(ar->wmi)) { 179*03f68a95SVasanthakumar Thiagarajan up(&ar->sem); 180*03f68a95SVasanthakumar Thiagarajan kfree(buf); 181*03f68a95SVasanthakumar Thiagarajan return -EIO; 182*03f68a95SVasanthakumar Thiagarajan } 183*03f68a95SVasanthakumar Thiagarajan 184*03f68a95SVasanthakumar Thiagarajan left = wait_event_interruptible_timeout(ar->event_wq, 185*03f68a95SVasanthakumar Thiagarajan !test_bit(STATS_UPDATE_PEND, 186*03f68a95SVasanthakumar Thiagarajan &ar->flag), WMI_TIMEOUT); 187*03f68a95SVasanthakumar Thiagarajan 188*03f68a95SVasanthakumar Thiagarajan up(&ar->sem); 189*03f68a95SVasanthakumar Thiagarajan 190*03f68a95SVasanthakumar Thiagarajan if (left <= 0) { 191*03f68a95SVasanthakumar Thiagarajan kfree(buf); 192*03f68a95SVasanthakumar Thiagarajan return -ETIMEDOUT; 193*03f68a95SVasanthakumar Thiagarajan } 194*03f68a95SVasanthakumar Thiagarajan 195*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "\n"); 196*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%25s\n", 197*03f68a95SVasanthakumar Thiagarajan "Target Tx stats"); 198*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%25s\n\n", 199*03f68a95SVasanthakumar Thiagarajan "================="); 200*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 201*03f68a95SVasanthakumar Thiagarajan "Ucast packets", tgt_stats->tx_ucast_pkt); 202*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 203*03f68a95SVasanthakumar Thiagarajan "Bcast packets", tgt_stats->tx_bcast_pkt); 204*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 205*03f68a95SVasanthakumar Thiagarajan "Ucast byte", tgt_stats->tx_ucast_byte); 206*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 207*03f68a95SVasanthakumar Thiagarajan "Bcast byte", tgt_stats->tx_bcast_byte); 208*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 209*03f68a95SVasanthakumar Thiagarajan "Rts success cnt", tgt_stats->tx_rts_success_cnt); 210*03f68a95SVasanthakumar Thiagarajan for (i = 0; i < 4; i++) 211*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, 212*03f68a95SVasanthakumar Thiagarajan "%18s %d %10llu\n", "PER on ac", 213*03f68a95SVasanthakumar Thiagarajan i, tgt_stats->tx_pkt_per_ac[i]); 214*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 215*03f68a95SVasanthakumar Thiagarajan "Error", tgt_stats->tx_err); 216*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 217*03f68a95SVasanthakumar Thiagarajan "Fail count", tgt_stats->tx_fail_cnt); 218*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 219*03f68a95SVasanthakumar Thiagarajan "Retry count", tgt_stats->tx_retry_cnt); 220*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 221*03f68a95SVasanthakumar Thiagarajan "Multi retry cnt", tgt_stats->tx_mult_retry_cnt); 222*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 223*03f68a95SVasanthakumar Thiagarajan "Rts fail cnt", tgt_stats->tx_rts_fail_cnt); 224*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%25s %10llu\n\n", 225*03f68a95SVasanthakumar Thiagarajan "TKIP counter measure used", 226*03f68a95SVasanthakumar Thiagarajan tgt_stats->tkip_cnter_measures_invoked); 227*03f68a95SVasanthakumar Thiagarajan 228*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%25s\n", 229*03f68a95SVasanthakumar Thiagarajan "Target Rx stats"); 230*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%25s\n", 231*03f68a95SVasanthakumar Thiagarajan "================="); 232*03f68a95SVasanthakumar Thiagarajan 233*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 234*03f68a95SVasanthakumar Thiagarajan "Ucast packets", tgt_stats->rx_ucast_pkt); 235*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10d\n", 236*03f68a95SVasanthakumar Thiagarajan "Ucast Rate", tgt_stats->rx_ucast_rate); 237*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 238*03f68a95SVasanthakumar Thiagarajan "Bcast packets", tgt_stats->rx_bcast_pkt); 239*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 240*03f68a95SVasanthakumar Thiagarajan "Ucast byte", tgt_stats->rx_ucast_byte); 241*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 242*03f68a95SVasanthakumar Thiagarajan "Bcast byte", tgt_stats->rx_bcast_byte); 243*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 244*03f68a95SVasanthakumar Thiagarajan "Fragmented pkt", tgt_stats->rx_frgment_pkt); 245*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 246*03f68a95SVasanthakumar Thiagarajan "Error", tgt_stats->rx_err); 247*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 248*03f68a95SVasanthakumar Thiagarajan "CRC Err", tgt_stats->rx_crc_err); 249*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 250*03f68a95SVasanthakumar Thiagarajan "Key chache miss", tgt_stats->rx_key_cache_miss); 251*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 252*03f68a95SVasanthakumar Thiagarajan "Decrypt Err", tgt_stats->rx_decrypt_err); 253*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 254*03f68a95SVasanthakumar Thiagarajan "Duplicate frame", tgt_stats->rx_dupl_frame); 255*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 256*03f68a95SVasanthakumar Thiagarajan "Tkip Mic failure", tgt_stats->tkip_local_mic_fail); 257*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 258*03f68a95SVasanthakumar Thiagarajan "TKIP format err", tgt_stats->tkip_fmt_err); 259*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 260*03f68a95SVasanthakumar Thiagarajan "CCMP format Err", tgt_stats->ccmp_fmt_err); 261*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n\n", 262*03f68a95SVasanthakumar Thiagarajan "CCMP Replay Err", tgt_stats->ccmp_replays); 263*03f68a95SVasanthakumar Thiagarajan 264*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%25s\n", 265*03f68a95SVasanthakumar Thiagarajan "Misc Target stats"); 266*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%25s\n", 267*03f68a95SVasanthakumar Thiagarajan "================="); 268*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 269*03f68a95SVasanthakumar Thiagarajan "Beacon Miss count", tgt_stats->cs_bmiss_cnt); 270*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 271*03f68a95SVasanthakumar Thiagarajan "Num Connects", tgt_stats->cs_connect_cnt); 272*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n", 273*03f68a95SVasanthakumar Thiagarajan "Num disconnects", tgt_stats->cs_discon_cnt); 274*03f68a95SVasanthakumar Thiagarajan len += scnprintf(buf + len, buf_len - len, "%20s %10d\n", 275*03f68a95SVasanthakumar Thiagarajan "Beacon avg rssi", tgt_stats->cs_ave_beacon_rssi); 276*03f68a95SVasanthakumar Thiagarajan 277*03f68a95SVasanthakumar Thiagarajan if (len > buf_len) 278*03f68a95SVasanthakumar Thiagarajan len = buf_len; 279*03f68a95SVasanthakumar Thiagarajan 280*03f68a95SVasanthakumar Thiagarajan ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); 281*03f68a95SVasanthakumar Thiagarajan 282*03f68a95SVasanthakumar Thiagarajan kfree(buf); 283*03f68a95SVasanthakumar Thiagarajan return ret_cnt; 284*03f68a95SVasanthakumar Thiagarajan } 285*03f68a95SVasanthakumar Thiagarajan 286*03f68a95SVasanthakumar Thiagarajan static const struct file_operations fops_tgt_stats = { 287*03f68a95SVasanthakumar Thiagarajan .read = read_file_tgt_stats, 288*03f68a95SVasanthakumar Thiagarajan .open = ath6kl_debugfs_open, 289*03f68a95SVasanthakumar Thiagarajan .owner = THIS_MODULE, 290*03f68a95SVasanthakumar Thiagarajan .llseek = default_llseek, 291*03f68a95SVasanthakumar Thiagarajan }; 292*03f68a95SVasanthakumar Thiagarajan 293d999ba3eSVasanthakumar Thiagarajan int ath6kl_debug_init(struct ath6kl *ar) 294d999ba3eSVasanthakumar Thiagarajan { 295d999ba3eSVasanthakumar Thiagarajan ar->debugfs_phy = debugfs_create_dir("ath6kl", 296d999ba3eSVasanthakumar Thiagarajan ar->wdev->wiphy->debugfsdir); 297d999ba3eSVasanthakumar Thiagarajan if (!ar->debugfs_phy) 298d999ba3eSVasanthakumar Thiagarajan return -ENOMEM; 299d999ba3eSVasanthakumar Thiagarajan 300*03f68a95SVasanthakumar Thiagarajan debugfs_create_file("tgt_stats", S_IRUSR, ar->debugfs_phy, ar, 301*03f68a95SVasanthakumar Thiagarajan &fops_tgt_stats); 302*03f68a95SVasanthakumar Thiagarajan 303d999ba3eSVasanthakumar Thiagarajan return 0; 304d999ba3eSVasanthakumar Thiagarajan } 305bdcd8170SKalle Valo #endif 306