18e42e4baSSujith Manoharan /* 28e42e4baSSujith Manoharan * Copyright (c) 2010-2011 Atheros Communications Inc. 38e42e4baSSujith Manoharan * 48e42e4baSSujith Manoharan * Permission to use, copy, modify, and/or distribute this software for any 58e42e4baSSujith Manoharan * purpose with or without fee is hereby granted, provided that the above 68e42e4baSSujith Manoharan * copyright notice and this permission notice appear in all copies. 78e42e4baSSujith Manoharan * 88e42e4baSSujith Manoharan * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 98e42e4baSSujith Manoharan * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 108e42e4baSSujith Manoharan * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 118e42e4baSSujith Manoharan * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 128e42e4baSSujith Manoharan * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 138e42e4baSSujith Manoharan * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 148e42e4baSSujith Manoharan * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 158e42e4baSSujith Manoharan */ 168e42e4baSSujith Manoharan 178e42e4baSSujith Manoharan #include "htc.h" 188e42e4baSSujith Manoharan 19fbc29d6cSSujith Manoharan static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf, 208e42e4baSSujith Manoharan size_t count, loff_t *ppos) 218e42e4baSSujith Manoharan { 228e42e4baSSujith Manoharan struct ath9k_htc_priv *priv = file->private_data; 23fbc29d6cSSujith Manoharan struct ath9k_htc_target_int_stats cmd_rsp; 248e42e4baSSujith Manoharan char buf[512]; 258e42e4baSSujith Manoharan unsigned int len = 0; 268e42e4baSSujith Manoharan int ret = 0; 278e42e4baSSujith Manoharan 288e42e4baSSujith Manoharan memset(&cmd_rsp, 0, sizeof(cmd_rsp)); 298e42e4baSSujith Manoharan 30c58ca5b5SSujith Manoharan ath9k_htc_ps_wakeup(priv); 31c58ca5b5SSujith Manoharan 32fbc29d6cSSujith Manoharan WMI_CMD(WMI_INT_STATS_CMDID); 33c58ca5b5SSujith Manoharan if (ret) { 34c58ca5b5SSujith Manoharan ath9k_htc_ps_restore(priv); 358e42e4baSSujith Manoharan return -EINVAL; 36c58ca5b5SSujith Manoharan } 37c58ca5b5SSujith Manoharan 38c58ca5b5SSujith Manoharan ath9k_htc_ps_restore(priv); 398e42e4baSSujith Manoharan 405e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 41fbc29d6cSSujith Manoharan "%20s : %10u\n", "RX", 42fbc29d6cSSujith Manoharan be32_to_cpu(cmd_rsp.rx)); 438e42e4baSSujith Manoharan 445e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 45fbc29d6cSSujith Manoharan "%20s : %10u\n", "RXORN", 46fbc29d6cSSujith Manoharan be32_to_cpu(cmd_rsp.rxorn)); 47fbc29d6cSSujith Manoharan 485e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 49fbc29d6cSSujith Manoharan "%20s : %10u\n", "RXEOL", 50fbc29d6cSSujith Manoharan be32_to_cpu(cmd_rsp.rxeol)); 51fbc29d6cSSujith Manoharan 525e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 53fbc29d6cSSujith Manoharan "%20s : %10u\n", "TXURN", 54fbc29d6cSSujith Manoharan be32_to_cpu(cmd_rsp.txurn)); 55fbc29d6cSSujith Manoharan 565e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 57fbc29d6cSSujith Manoharan "%20s : %10u\n", "TXTO", 58fbc29d6cSSujith Manoharan be32_to_cpu(cmd_rsp.txto)); 59fbc29d6cSSujith Manoharan 605e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 61fbc29d6cSSujith Manoharan "%20s : %10u\n", "CST", 62fbc29d6cSSujith Manoharan be32_to_cpu(cmd_rsp.cst)); 638e42e4baSSujith Manoharan 648e42e4baSSujith Manoharan if (len > sizeof(buf)) 658e42e4baSSujith Manoharan len = sizeof(buf); 668e42e4baSSujith Manoharan 678e42e4baSSujith Manoharan return simple_read_from_buffer(user_buf, count, ppos, buf, len); 688e42e4baSSujith Manoharan } 698e42e4baSSujith Manoharan 70fbc29d6cSSujith Manoharan static const struct file_operations fops_tgt_int_stats = { 71fbc29d6cSSujith Manoharan .read = read_file_tgt_int_stats, 72234e3405SStephen Boyd .open = simple_open, 73fbc29d6cSSujith Manoharan .owner = THIS_MODULE, 74fbc29d6cSSujith Manoharan .llseek = default_llseek, 75fbc29d6cSSujith Manoharan }; 76fbc29d6cSSujith Manoharan 77fbc29d6cSSujith Manoharan static ssize_t read_file_tgt_tx_stats(struct file *file, char __user *user_buf, 78fbc29d6cSSujith Manoharan size_t count, loff_t *ppos) 79fbc29d6cSSujith Manoharan { 80fbc29d6cSSujith Manoharan struct ath9k_htc_priv *priv = file->private_data; 81fbc29d6cSSujith Manoharan struct ath9k_htc_target_tx_stats cmd_rsp; 82fbc29d6cSSujith Manoharan char buf[512]; 83fbc29d6cSSujith Manoharan unsigned int len = 0; 84fbc29d6cSSujith Manoharan int ret = 0; 85fbc29d6cSSujith Manoharan 86fbc29d6cSSujith Manoharan memset(&cmd_rsp, 0, sizeof(cmd_rsp)); 87fbc29d6cSSujith Manoharan 88c58ca5b5SSujith Manoharan ath9k_htc_ps_wakeup(priv); 89c58ca5b5SSujith Manoharan 90fbc29d6cSSujith Manoharan WMI_CMD(WMI_TX_STATS_CMDID); 91c58ca5b5SSujith Manoharan if (ret) { 92c58ca5b5SSujith Manoharan ath9k_htc_ps_restore(priv); 93fbc29d6cSSujith Manoharan return -EINVAL; 94c58ca5b5SSujith Manoharan } 95c58ca5b5SSujith Manoharan 96c58ca5b5SSujith Manoharan ath9k_htc_ps_restore(priv); 97fbc29d6cSSujith Manoharan 985e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 99fbc29d6cSSujith Manoharan "%20s : %10u\n", "Xretries", 100fbc29d6cSSujith Manoharan be32_to_cpu(cmd_rsp.xretries)); 101fbc29d6cSSujith Manoharan 1025e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 103fbc29d6cSSujith Manoharan "%20s : %10u\n", "FifoErr", 104fbc29d6cSSujith Manoharan be32_to_cpu(cmd_rsp.fifoerr)); 105fbc29d6cSSujith Manoharan 1065e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 107fbc29d6cSSujith Manoharan "%20s : %10u\n", "Filtered", 108fbc29d6cSSujith Manoharan be32_to_cpu(cmd_rsp.filtered)); 109fbc29d6cSSujith Manoharan 1105e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 111fbc29d6cSSujith Manoharan "%20s : %10u\n", "TimerExp", 112fbc29d6cSSujith Manoharan be32_to_cpu(cmd_rsp.timer_exp)); 113fbc29d6cSSujith Manoharan 1145e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 115fbc29d6cSSujith Manoharan "%20s : %10u\n", "ShortRetries", 116fbc29d6cSSujith Manoharan be32_to_cpu(cmd_rsp.shortretries)); 117fbc29d6cSSujith Manoharan 1185e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 119fbc29d6cSSujith Manoharan "%20s : %10u\n", "LongRetries", 120fbc29d6cSSujith Manoharan be32_to_cpu(cmd_rsp.longretries)); 121fbc29d6cSSujith Manoharan 1225e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 123fbc29d6cSSujith Manoharan "%20s : %10u\n", "QueueNull", 124fbc29d6cSSujith Manoharan be32_to_cpu(cmd_rsp.qnull)); 125fbc29d6cSSujith Manoharan 1265e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 127fbc29d6cSSujith Manoharan "%20s : %10u\n", "EncapFail", 128fbc29d6cSSujith Manoharan be32_to_cpu(cmd_rsp.encap_fail)); 129fbc29d6cSSujith Manoharan 1305e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 131fbc29d6cSSujith Manoharan "%20s : %10u\n", "NoBuf", 132fbc29d6cSSujith Manoharan be32_to_cpu(cmd_rsp.nobuf)); 133fbc29d6cSSujith Manoharan 134fbc29d6cSSujith Manoharan if (len > sizeof(buf)) 135fbc29d6cSSujith Manoharan len = sizeof(buf); 136fbc29d6cSSujith Manoharan 137fbc29d6cSSujith Manoharan return simple_read_from_buffer(user_buf, count, ppos, buf, len); 138fbc29d6cSSujith Manoharan } 139fbc29d6cSSujith Manoharan 140fbc29d6cSSujith Manoharan static const struct file_operations fops_tgt_tx_stats = { 141fbc29d6cSSujith Manoharan .read = read_file_tgt_tx_stats, 142234e3405SStephen Boyd .open = simple_open, 143fbc29d6cSSujith Manoharan .owner = THIS_MODULE, 144fbc29d6cSSujith Manoharan .llseek = default_llseek, 145fbc29d6cSSujith Manoharan }; 146fbc29d6cSSujith Manoharan 147fbc29d6cSSujith Manoharan static ssize_t read_file_tgt_rx_stats(struct file *file, char __user *user_buf, 148fbc29d6cSSujith Manoharan size_t count, loff_t *ppos) 149fbc29d6cSSujith Manoharan { 150fbc29d6cSSujith Manoharan struct ath9k_htc_priv *priv = file->private_data; 151fbc29d6cSSujith Manoharan struct ath9k_htc_target_rx_stats cmd_rsp; 152fbc29d6cSSujith Manoharan char buf[512]; 153fbc29d6cSSujith Manoharan unsigned int len = 0; 154fbc29d6cSSujith Manoharan int ret = 0; 155fbc29d6cSSujith Manoharan 156fbc29d6cSSujith Manoharan memset(&cmd_rsp, 0, sizeof(cmd_rsp)); 157fbc29d6cSSujith Manoharan 158c58ca5b5SSujith Manoharan ath9k_htc_ps_wakeup(priv); 159c58ca5b5SSujith Manoharan 160fbc29d6cSSujith Manoharan WMI_CMD(WMI_RX_STATS_CMDID); 161c58ca5b5SSujith Manoharan if (ret) { 162c58ca5b5SSujith Manoharan ath9k_htc_ps_restore(priv); 163fbc29d6cSSujith Manoharan return -EINVAL; 164c58ca5b5SSujith Manoharan } 165c58ca5b5SSujith Manoharan 166c58ca5b5SSujith Manoharan ath9k_htc_ps_restore(priv); 167fbc29d6cSSujith Manoharan 1685e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 169fbc29d6cSSujith Manoharan "%20s : %10u\n", "NoBuf", 170fbc29d6cSSujith Manoharan be32_to_cpu(cmd_rsp.nobuf)); 171fbc29d6cSSujith Manoharan 1725e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 173fbc29d6cSSujith Manoharan "%20s : %10u\n", "HostSend", 174fbc29d6cSSujith Manoharan be32_to_cpu(cmd_rsp.host_send)); 175fbc29d6cSSujith Manoharan 1765e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 177fbc29d6cSSujith Manoharan "%20s : %10u\n", "HostDone", 178fbc29d6cSSujith Manoharan be32_to_cpu(cmd_rsp.host_done)); 179fbc29d6cSSujith Manoharan 180fbc29d6cSSujith Manoharan if (len > sizeof(buf)) 181fbc29d6cSSujith Manoharan len = sizeof(buf); 182fbc29d6cSSujith Manoharan 183fbc29d6cSSujith Manoharan return simple_read_from_buffer(user_buf, count, ppos, buf, len); 184fbc29d6cSSujith Manoharan } 185fbc29d6cSSujith Manoharan 186fbc29d6cSSujith Manoharan static const struct file_operations fops_tgt_rx_stats = { 187fbc29d6cSSujith Manoharan .read = read_file_tgt_rx_stats, 188234e3405SStephen Boyd .open = simple_open, 1898e42e4baSSujith Manoharan .owner = THIS_MODULE, 1908e42e4baSSujith Manoharan .llseek = default_llseek, 1918e42e4baSSujith Manoharan }; 1928e42e4baSSujith Manoharan 1938e42e4baSSujith Manoharan static ssize_t read_file_xmit(struct file *file, char __user *user_buf, 1948e42e4baSSujith Manoharan size_t count, loff_t *ppos) 1958e42e4baSSujith Manoharan { 1968e42e4baSSujith Manoharan struct ath9k_htc_priv *priv = file->private_data; 1978e42e4baSSujith Manoharan char buf[512]; 1988e42e4baSSujith Manoharan unsigned int len = 0; 1998e42e4baSSujith Manoharan 2005e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 2018e42e4baSSujith Manoharan "%20s : %10u\n", "Buffers queued", 2028e42e4baSSujith Manoharan priv->debug.tx_stats.buf_queued); 2035e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 2048e42e4baSSujith Manoharan "%20s : %10u\n", "Buffers completed", 2058e42e4baSSujith Manoharan priv->debug.tx_stats.buf_completed); 2065e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 2078e42e4baSSujith Manoharan "%20s : %10u\n", "SKBs queued", 2088e42e4baSSujith Manoharan priv->debug.tx_stats.skb_queued); 2095e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 210b587fc81SSujith Manoharan "%20s : %10u\n", "SKBs success", 211b587fc81SSujith Manoharan priv->debug.tx_stats.skb_success); 2125e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 213b587fc81SSujith Manoharan "%20s : %10u\n", "SKBs failed", 214b587fc81SSujith Manoharan priv->debug.tx_stats.skb_failed); 2155e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 2168e42e4baSSujith Manoharan "%20s : %10u\n", "CAB queued", 2178e42e4baSSujith Manoharan priv->debug.tx_stats.cab_queued); 2188e42e4baSSujith Manoharan 2195e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 2208e42e4baSSujith Manoharan "%20s : %10u\n", "BE queued", 221bea843c7SSujith Manoharan priv->debug.tx_stats.queue_stats[IEEE80211_AC_BE]); 2225e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 2238e42e4baSSujith Manoharan "%20s : %10u\n", "BK queued", 224bea843c7SSujith Manoharan priv->debug.tx_stats.queue_stats[IEEE80211_AC_BK]); 2255e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 2268e42e4baSSujith Manoharan "%20s : %10u\n", "VI queued", 227bea843c7SSujith Manoharan priv->debug.tx_stats.queue_stats[IEEE80211_AC_VI]); 2285e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, 2298e42e4baSSujith Manoharan "%20s : %10u\n", "VO queued", 230bea843c7SSujith Manoharan priv->debug.tx_stats.queue_stats[IEEE80211_AC_VO]); 2318e42e4baSSujith Manoharan 2328e42e4baSSujith Manoharan if (len > sizeof(buf)) 2338e42e4baSSujith Manoharan len = sizeof(buf); 2348e42e4baSSujith Manoharan 2358e42e4baSSujith Manoharan return simple_read_from_buffer(user_buf, count, ppos, buf, len); 2368e42e4baSSujith Manoharan } 2378e42e4baSSujith Manoharan 2388e42e4baSSujith Manoharan static const struct file_operations fops_xmit = { 2398e42e4baSSujith Manoharan .read = read_file_xmit, 240234e3405SStephen Boyd .open = simple_open, 2418e42e4baSSujith Manoharan .owner = THIS_MODULE, 2428e42e4baSSujith Manoharan .llseek = default_llseek, 2438e42e4baSSujith Manoharan }; 2448e42e4baSSujith Manoharan 245719c4cf6SSujith Manoharan void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, 246b5a0c86aSOleksij Rempel struct ath_rx_status *rs) 247719c4cf6SSujith Manoharan { 248b5a0c86aSOleksij Rempel ath9k_cmn_debug_stat_rx(&priv->debug.rx_stats, rs); 249719c4cf6SSujith Manoharan } 250719c4cf6SSujith Manoharan 2513eb6ed23SOleksij Rempel static ssize_t read_file_skb_rx(struct file *file, char __user *user_buf, 2528e42e4baSSujith Manoharan size_t count, loff_t *ppos) 2538e42e4baSSujith Manoharan { 254719c4cf6SSujith Manoharan struct ath9k_htc_priv *priv = file->private_data; 255719c4cf6SSujith Manoharan char *buf; 256719c4cf6SSujith Manoharan unsigned int len = 0, size = 1500; 257719c4cf6SSujith Manoharan ssize_t retval = 0; 258719c4cf6SSujith Manoharan 259719c4cf6SSujith Manoharan buf = kzalloc(size, GFP_KERNEL); 260719c4cf6SSujith Manoharan if (buf == NULL) 261719c4cf6SSujith Manoharan return -ENOMEM; 262719c4cf6SSujith Manoharan 2635e88ba62SZefir Kurtisi len += scnprintf(buf + len, size - len, 2648e42e4baSSujith Manoharan "%20s : %10u\n", "SKBs allocated", 265b5a0c86aSOleksij Rempel priv->debug.skbrx_stats.skb_allocated); 2665e88ba62SZefir Kurtisi len += scnprintf(buf + len, size - len, 2678e42e4baSSujith Manoharan "%20s : %10u\n", "SKBs completed", 268b5a0c86aSOleksij Rempel priv->debug.skbrx_stats.skb_completed); 2695e88ba62SZefir Kurtisi len += scnprintf(buf + len, size - len, 2708e42e4baSSujith Manoharan "%20s : %10u\n", "SKBs Dropped", 271b5a0c86aSOleksij Rempel priv->debug.skbrx_stats.skb_dropped); 272719c4cf6SSujith Manoharan 273719c4cf6SSujith Manoharan if (len > size) 274719c4cf6SSujith Manoharan len = size; 275719c4cf6SSujith Manoharan 276719c4cf6SSujith Manoharan retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); 277719c4cf6SSujith Manoharan kfree(buf); 278719c4cf6SSujith Manoharan 279719c4cf6SSujith Manoharan return retval; 2808e42e4baSSujith Manoharan } 2818e42e4baSSujith Manoharan 2823eb6ed23SOleksij Rempel static const struct file_operations fops_skb_rx = { 2833eb6ed23SOleksij Rempel .read = read_file_skb_rx, 284234e3405SStephen Boyd .open = simple_open, 2858e42e4baSSujith Manoharan .owner = THIS_MODULE, 2868e42e4baSSujith Manoharan .llseek = default_llseek, 2878e42e4baSSujith Manoharan }; 2888e42e4baSSujith Manoharan 28901f684deSSujith Manoharan static ssize_t read_file_slot(struct file *file, char __user *user_buf, 29001f684deSSujith Manoharan size_t count, loff_t *ppos) 29101f684deSSujith Manoharan { 29201f684deSSujith Manoharan struct ath9k_htc_priv *priv = file->private_data; 29301f684deSSujith Manoharan char buf[512]; 29489860038STejun Heo unsigned int len; 29501f684deSSujith Manoharan 29601f684deSSujith Manoharan spin_lock_bh(&priv->tx.tx_lock); 29789860038STejun Heo len = scnprintf(buf, sizeof(buf), 29889860038STejun Heo "TX slot bitmap : %*pb\n" 29901f684deSSujith Manoharan "Used slots : %d\n", 30089860038STejun Heo MAX_TX_BUF_NUM, priv->tx.tx_slot, 30101f684deSSujith Manoharan bitmap_weight(priv->tx.tx_slot, MAX_TX_BUF_NUM)); 30201f684deSSujith Manoharan spin_unlock_bh(&priv->tx.tx_lock); 30301f684deSSujith Manoharan return simple_read_from_buffer(user_buf, count, ppos, buf, len); 30401f684deSSujith Manoharan } 30501f684deSSujith Manoharan 30601f684deSSujith Manoharan static const struct file_operations fops_slot = { 30701f684deSSujith Manoharan .read = read_file_slot, 308234e3405SStephen Boyd .open = simple_open, 30901f684deSSujith Manoharan .owner = THIS_MODULE, 31001f684deSSujith Manoharan .llseek = default_llseek, 31101f684deSSujith Manoharan }; 31201f684deSSujith Manoharan 313c4d04186SSujith Manoharan static ssize_t read_file_queue(struct file *file, char __user *user_buf, 314c4d04186SSujith Manoharan size_t count, loff_t *ppos) 315c4d04186SSujith Manoharan { 316c4d04186SSujith Manoharan struct ath9k_htc_priv *priv = file->private_data; 317c4d04186SSujith Manoharan char buf[512]; 318c4d04186SSujith Manoharan unsigned int len = 0; 319c4d04186SSujith Manoharan 3205e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", 321c4d04186SSujith Manoharan "Mgmt endpoint", skb_queue_len(&priv->tx.mgmt_ep_queue)); 322c4d04186SSujith Manoharan 3235e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", 324c4d04186SSujith Manoharan "Cab endpoint", skb_queue_len(&priv->tx.cab_ep_queue)); 325c4d04186SSujith Manoharan 3265e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", 327c4d04186SSujith Manoharan "Data BE endpoint", skb_queue_len(&priv->tx.data_be_queue)); 328c4d04186SSujith Manoharan 3295e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", 330c4d04186SSujith Manoharan "Data BK endpoint", skb_queue_len(&priv->tx.data_bk_queue)); 331c4d04186SSujith Manoharan 3325e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", 333c4d04186SSujith Manoharan "Data VI endpoint", skb_queue_len(&priv->tx.data_vi_queue)); 334c4d04186SSujith Manoharan 3355e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", 336c4d04186SSujith Manoharan "Data VO endpoint", skb_queue_len(&priv->tx.data_vo_queue)); 337c4d04186SSujith Manoharan 3385e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", 339c4d04186SSujith Manoharan "Failed queue", skb_queue_len(&priv->tx.tx_failed)); 340c4d04186SSujith Manoharan 341c4d04186SSujith Manoharan spin_lock_bh(&priv->tx.tx_lock); 3425e88ba62SZefir Kurtisi len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", 343c4d04186SSujith Manoharan "Queued count", priv->tx.queued_cnt); 344c4d04186SSujith Manoharan spin_unlock_bh(&priv->tx.tx_lock); 345c4d04186SSujith Manoharan 346c4d04186SSujith Manoharan if (len > sizeof(buf)) 347c4d04186SSujith Manoharan len = sizeof(buf); 348c4d04186SSujith Manoharan 349c4d04186SSujith Manoharan return simple_read_from_buffer(user_buf, count, ppos, buf, len); 350c4d04186SSujith Manoharan 351c4d04186SSujith Manoharan } 352c4d04186SSujith Manoharan 353c4d04186SSujith Manoharan static const struct file_operations fops_queue = { 354c4d04186SSujith Manoharan .read = read_file_queue, 355234e3405SStephen Boyd .open = simple_open, 356c4d04186SSujith Manoharan .owner = THIS_MODULE, 357c4d04186SSujith Manoharan .llseek = default_llseek, 358c4d04186SSujith Manoharan }; 359c4d04186SSujith Manoharan 36000bca7e2SRajkumar Manoharan static ssize_t read_file_debug(struct file *file, char __user *user_buf, 36100bca7e2SRajkumar Manoharan size_t count, loff_t *ppos) 36200bca7e2SRajkumar Manoharan { 36300bca7e2SRajkumar Manoharan struct ath9k_htc_priv *priv = file->private_data; 36400bca7e2SRajkumar Manoharan struct ath_common *common = ath9k_hw_common(priv->ah); 36500bca7e2SRajkumar Manoharan char buf[32]; 36600bca7e2SRajkumar Manoharan unsigned int len; 36700bca7e2SRajkumar Manoharan 36800bca7e2SRajkumar Manoharan len = sprintf(buf, "0x%08x\n", common->debug_mask); 36900bca7e2SRajkumar Manoharan return simple_read_from_buffer(user_buf, count, ppos, buf, len); 37000bca7e2SRajkumar Manoharan } 37100bca7e2SRajkumar Manoharan 37200bca7e2SRajkumar Manoharan static ssize_t write_file_debug(struct file *file, const char __user *user_buf, 37300bca7e2SRajkumar Manoharan size_t count, loff_t *ppos) 37400bca7e2SRajkumar Manoharan { 37500bca7e2SRajkumar Manoharan struct ath9k_htc_priv *priv = file->private_data; 37600bca7e2SRajkumar Manoharan struct ath_common *common = ath9k_hw_common(priv->ah); 37700bca7e2SRajkumar Manoharan unsigned long mask; 37800bca7e2SRajkumar Manoharan char buf[32]; 37900bca7e2SRajkumar Manoharan ssize_t len; 38000bca7e2SRajkumar Manoharan 38100bca7e2SRajkumar Manoharan len = min(count, sizeof(buf) - 1); 38200bca7e2SRajkumar Manoharan if (copy_from_user(buf, user_buf, len)) 38300bca7e2SRajkumar Manoharan return -EFAULT; 38400bca7e2SRajkumar Manoharan 38500bca7e2SRajkumar Manoharan buf[len] = '\0'; 38627d7f477SJingoo Han if (kstrtoul(buf, 0, &mask)) 38700bca7e2SRajkumar Manoharan return -EINVAL; 38800bca7e2SRajkumar Manoharan 38900bca7e2SRajkumar Manoharan common->debug_mask = mask; 39000bca7e2SRajkumar Manoharan return count; 39100bca7e2SRajkumar Manoharan } 39200bca7e2SRajkumar Manoharan 39300bca7e2SRajkumar Manoharan static const struct file_operations fops_debug = { 39400bca7e2SRajkumar Manoharan .read = read_file_debug, 39500bca7e2SRajkumar Manoharan .write = write_file_debug, 396234e3405SStephen Boyd .open = simple_open, 39700bca7e2SRajkumar Manoharan .owner = THIS_MODULE, 39800bca7e2SRajkumar Manoharan .llseek = default_llseek, 39900bca7e2SRajkumar Manoharan }; 40000bca7e2SRajkumar Manoharan 40168185a4bSBen Greear /* Ethtool support for get-stats */ 40268185a4bSBen Greear #define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO" 40368185a4bSBen Greear static const char ath9k_htc_gstrings_stats[][ETH_GSTRING_LEN] = { 40468185a4bSBen Greear "tx_pkts_nic", 40568185a4bSBen Greear "tx_bytes_nic", 40668185a4bSBen Greear "rx_pkts_nic", 40768185a4bSBen Greear "rx_bytes_nic", 40868185a4bSBen Greear 40968185a4bSBen Greear AMKSTR(d_tx_pkts), 41068185a4bSBen Greear 41168185a4bSBen Greear "d_rx_crc_err", 41268185a4bSBen Greear "d_rx_decrypt_crc_err", 41368185a4bSBen Greear "d_rx_phy_err", 41468185a4bSBen Greear "d_rx_mic_err", 41568185a4bSBen Greear "d_rx_pre_delim_crc_err", 41668185a4bSBen Greear "d_rx_post_delim_crc_err", 41768185a4bSBen Greear "d_rx_decrypt_busy_err", 41868185a4bSBen Greear 41968185a4bSBen Greear "d_rx_phyerr_radar", 42068185a4bSBen Greear "d_rx_phyerr_ofdm_timing", 42168185a4bSBen Greear "d_rx_phyerr_cck_timing", 42268185a4bSBen Greear 42368185a4bSBen Greear }; 42468185a4bSBen Greear #define ATH9K_HTC_SSTATS_LEN ARRAY_SIZE(ath9k_htc_gstrings_stats) 42568185a4bSBen Greear 42668185a4bSBen Greear void ath9k_htc_get_et_strings(struct ieee80211_hw *hw, 42768185a4bSBen Greear struct ieee80211_vif *vif, 42868185a4bSBen Greear u32 sset, u8 *data) 42968185a4bSBen Greear { 43068185a4bSBen Greear if (sset == ETH_SS_STATS) 43168185a4bSBen Greear memcpy(data, *ath9k_htc_gstrings_stats, 43268185a4bSBen Greear sizeof(ath9k_htc_gstrings_stats)); 43368185a4bSBen Greear } 43468185a4bSBen Greear 43568185a4bSBen Greear int ath9k_htc_get_et_sset_count(struct ieee80211_hw *hw, 43668185a4bSBen Greear struct ieee80211_vif *vif, int sset) 43768185a4bSBen Greear { 43868185a4bSBen Greear if (sset == ETH_SS_STATS) 43968185a4bSBen Greear return ATH9K_HTC_SSTATS_LEN; 44068185a4bSBen Greear return 0; 44168185a4bSBen Greear } 44268185a4bSBen Greear 44368185a4bSBen Greear #define STXBASE priv->debug.tx_stats 44468185a4bSBen Greear #define SRXBASE priv->debug.rx_stats 445b5a0c86aSOleksij Rempel #define SKBTXBASE priv->debug.tx_stats 446b5a0c86aSOleksij Rempel #define SKBRXBASE priv->debug.skbrx_stats 44768185a4bSBen Greear #define ASTXQ(a) \ 44868185a4bSBen Greear data[i++] = STXBASE.a[IEEE80211_AC_BE]; \ 44968185a4bSBen Greear data[i++] = STXBASE.a[IEEE80211_AC_BK]; \ 45068185a4bSBen Greear data[i++] = STXBASE.a[IEEE80211_AC_VI]; \ 45168185a4bSBen Greear data[i++] = STXBASE.a[IEEE80211_AC_VO] 45268185a4bSBen Greear 45368185a4bSBen Greear void ath9k_htc_get_et_stats(struct ieee80211_hw *hw, 45468185a4bSBen Greear struct ieee80211_vif *vif, 45568185a4bSBen Greear struct ethtool_stats *stats, u64 *data) 45668185a4bSBen Greear { 45768185a4bSBen Greear struct ath9k_htc_priv *priv = hw->priv; 45868185a4bSBen Greear int i = 0; 45968185a4bSBen Greear 460b5a0c86aSOleksij Rempel data[i++] = SKBTXBASE.skb_success; 461b5a0c86aSOleksij Rempel data[i++] = SKBTXBASE.skb_success_bytes; 462b5a0c86aSOleksij Rempel data[i++] = SKBRXBASE.skb_completed; 463b5a0c86aSOleksij Rempel data[i++] = SKBRXBASE.skb_completed_bytes; 46468185a4bSBen Greear 46568185a4bSBen Greear ASTXQ(queue_stats); 46668185a4bSBen Greear 467b5a0c86aSOleksij Rempel data[i++] = SRXBASE.crc_err; 468b5a0c86aSOleksij Rempel data[i++] = SRXBASE.decrypt_crc_err; 469b5a0c86aSOleksij Rempel data[i++] = SRXBASE.phy_err; 470b5a0c86aSOleksij Rempel data[i++] = SRXBASE.mic_err; 471b5a0c86aSOleksij Rempel data[i++] = SRXBASE.pre_delim_crc_err; 472b5a0c86aSOleksij Rempel data[i++] = SRXBASE.post_delim_crc_err; 473b5a0c86aSOleksij Rempel data[i++] = SRXBASE.decrypt_busy_err; 47468185a4bSBen Greear 475b5a0c86aSOleksij Rempel data[i++] = SRXBASE.phy_err_stats[ATH9K_PHYERR_RADAR]; 476b5a0c86aSOleksij Rempel data[i++] = SRXBASE.phy_err_stats[ATH9K_PHYERR_OFDM_TIMING]; 477b5a0c86aSOleksij Rempel data[i++] = SRXBASE.phy_err_stats[ATH9K_PHYERR_CCK_TIMING]; 47868185a4bSBen Greear 47968185a4bSBen Greear WARN_ON(i != ATH9K_HTC_SSTATS_LEN); 48068185a4bSBen Greear } 48168185a4bSBen Greear 4823f2aa13fSOleksij Rempel void ath9k_htc_deinit_debug(struct ath9k_htc_priv *priv) 4833f2aa13fSOleksij Rempel { 4843f2aa13fSOleksij Rempel ath9k_cmn_spectral_deinit_debug(&priv->spec_priv); 4853f2aa13fSOleksij Rempel } 48668185a4bSBen Greear 4878e42e4baSSujith Manoharan int ath9k_htc_init_debug(struct ath_hw *ah) 4888e42e4baSSujith Manoharan { 4898e42e4baSSujith Manoharan struct ath_common *common = ath9k_hw_common(ah); 4908e42e4baSSujith Manoharan struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; 4918e42e4baSSujith Manoharan 492e5facc75SRajkumar Manoharan priv->debug.debugfs_phy = debugfs_create_dir(KBUILD_MODNAME, 493e5facc75SRajkumar Manoharan priv->hw->wiphy->debugfsdir); 4948e42e4baSSujith Manoharan if (!priv->debug.debugfs_phy) 4958e42e4baSSujith Manoharan return -ENOMEM; 4968e42e4baSSujith Manoharan 4973f2aa13fSOleksij Rempel ath9k_cmn_spectral_init_debug(&priv->spec_priv, priv->debug.debugfs_phy); 4983f2aa13fSOleksij Rempel 499*2ef00c53SJoe Perches debugfs_create_file("tgt_int_stats", 0400, priv->debug.debugfs_phy, 500e5facc75SRajkumar Manoharan priv, &fops_tgt_int_stats); 501*2ef00c53SJoe Perches debugfs_create_file("tgt_tx_stats", 0400, priv->debug.debugfs_phy, 502e5facc75SRajkumar Manoharan priv, &fops_tgt_tx_stats); 503*2ef00c53SJoe Perches debugfs_create_file("tgt_rx_stats", 0400, priv->debug.debugfs_phy, 504e5facc75SRajkumar Manoharan priv, &fops_tgt_rx_stats); 505*2ef00c53SJoe Perches debugfs_create_file("xmit", 0400, priv->debug.debugfs_phy, 506e5facc75SRajkumar Manoharan priv, &fops_xmit); 507*2ef00c53SJoe Perches debugfs_create_file("skb_rx", 0400, priv->debug.debugfs_phy, 5083eb6ed23SOleksij Rempel priv, &fops_skb_rx); 509f14c17ccSOleksij Rempel 510f14c17ccSOleksij Rempel ath9k_cmn_debug_recv(priv->debug.debugfs_phy, &priv->debug.rx_stats); 5113eb6ed23SOleksij Rempel ath9k_cmn_debug_phy_err(priv->debug.debugfs_phy, &priv->debug.rx_stats); 512f14c17ccSOleksij Rempel 513*2ef00c53SJoe Perches debugfs_create_file("slot", 0400, priv->debug.debugfs_phy, 514e5facc75SRajkumar Manoharan priv, &fops_slot); 515*2ef00c53SJoe Perches debugfs_create_file("queue", 0400, priv->debug.debugfs_phy, 516e5facc75SRajkumar Manoharan priv, &fops_queue); 517*2ef00c53SJoe Perches debugfs_create_file("debug", 0600, priv->debug.debugfs_phy, 518e5facc75SRajkumar Manoharan priv, &fops_debug); 5197e9bed71SOleksij Rempel 520df738209SOleksij Rempel ath9k_cmn_debug_base_eeprom(priv->debug.debugfs_phy, priv->ah); 5217e9bed71SOleksij Rempel ath9k_cmn_debug_modal_eeprom(priv->debug.debugfs_phy, priv->ah); 5228e42e4baSSujith Manoharan 5238e42e4baSSujith Manoharan return 0; 5248e42e4baSSujith Manoharan } 525