Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Atheros CARL9170 driver
0003  *
0004  * debug(fs) probing
0005  *
0006  * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
0007  * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
0008  *
0009  * This program is free software; you can redistribute it and/or modify
0010  * it under the terms of the GNU General Public License as published by
0011  * the Free Software Foundation; either version 2 of the License, or
0012  * (at your option) any later version.
0013  *
0014  * This program is distributed in the hope that it will be useful,
0015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0017  * GNU General Public License for more details.
0018  *
0019  * You should have received a copy of the GNU General Public License
0020  * along with this program; see the file COPYING.  If not, see
0021  * http://www.gnu.org/licenses/.
0022  *
0023  * This file incorporates work covered by the following copyright and
0024  * permission notice:
0025  *    Copyright (c) 2008-2009 Atheros Communications, Inc.
0026  *
0027  *    Permission to use, copy, modify, and/or distribute this software for any
0028  *    purpose with or without fee is hereby granted, provided that the above
0029  *    copyright notice and this permission notice appear in all copies.
0030  *
0031  *    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
0032  *    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
0033  *    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
0034  *    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
0035  *    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
0036  *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
0037  *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0038  */
0039 
0040 #include <linux/slab.h>
0041 #include <linux/module.h>
0042 #include <linux/seq_file.h>
0043 #include <linux/vmalloc.h>
0044 #include "carl9170.h"
0045 #include "cmd.h"
0046 
0047 #define ADD(buf, off, max, fmt, args...)                \
0048     off += scnprintf(&buf[off], max - off, fmt, ##args)
0049 
0050 
0051 struct carl9170_debugfs_fops {
0052     unsigned int read_bufsize;
0053     umode_t attr;
0054     char *(*read)(struct ar9170 *ar, char *buf, size_t bufsize,
0055               ssize_t *len);
0056     ssize_t (*write)(struct ar9170 *aru, const char *buf, size_t size);
0057     const struct file_operations fops;
0058 
0059     enum carl9170_device_state req_dev_state;
0060 };
0061 
0062 static ssize_t carl9170_debugfs_read(struct file *file, char __user *userbuf,
0063                      size_t count, loff_t *ppos)
0064 {
0065     struct carl9170_debugfs_fops *dfops;
0066     struct ar9170 *ar;
0067     char *buf = NULL, *res_buf = NULL;
0068     ssize_t ret = 0;
0069     int err = 0;
0070 
0071     if (!count)
0072         return 0;
0073 
0074     ar = file->private_data;
0075 
0076     if (!ar)
0077         return -ENODEV;
0078     dfops = container_of(debugfs_real_fops(file),
0079                  struct carl9170_debugfs_fops, fops);
0080 
0081     if (!dfops->read)
0082         return -ENOSYS;
0083 
0084     if (dfops->read_bufsize) {
0085         buf = vmalloc(dfops->read_bufsize);
0086         if (!buf)
0087             return -ENOMEM;
0088     }
0089 
0090     mutex_lock(&ar->mutex);
0091     if (!CHK_DEV_STATE(ar, dfops->req_dev_state)) {
0092         err = -ENODEV;
0093         res_buf = buf;
0094         goto out_free;
0095     }
0096 
0097     res_buf = dfops->read(ar, buf, dfops->read_bufsize, &ret);
0098 
0099     if (ret > 0)
0100         err = simple_read_from_buffer(userbuf, count, ppos,
0101                           res_buf, ret);
0102     else
0103         err = ret;
0104 
0105     WARN_ON_ONCE(dfops->read_bufsize && (res_buf != buf));
0106 
0107 out_free:
0108     vfree(res_buf);
0109     mutex_unlock(&ar->mutex);
0110     return err;
0111 }
0112 
0113 static ssize_t carl9170_debugfs_write(struct file *file,
0114     const char __user *userbuf, size_t count, loff_t *ppos)
0115 {
0116     struct carl9170_debugfs_fops *dfops;
0117     struct ar9170 *ar;
0118     char *buf = NULL;
0119     int err = 0;
0120 
0121     if (!count)
0122         return 0;
0123 
0124     if (count > PAGE_SIZE)
0125         return -E2BIG;
0126 
0127     ar = file->private_data;
0128 
0129     if (!ar)
0130         return -ENODEV;
0131     dfops = container_of(debugfs_real_fops(file),
0132                  struct carl9170_debugfs_fops, fops);
0133 
0134     if (!dfops->write)
0135         return -ENOSYS;
0136 
0137     buf = vmalloc(count);
0138     if (!buf)
0139         return -ENOMEM;
0140 
0141     if (copy_from_user(buf, userbuf, count)) {
0142         err = -EFAULT;
0143         goto out_free;
0144     }
0145 
0146     if (mutex_trylock(&ar->mutex) == 0) {
0147         err = -EAGAIN;
0148         goto out_free;
0149     }
0150 
0151     if (!CHK_DEV_STATE(ar, dfops->req_dev_state)) {
0152         err = -ENODEV;
0153         goto out_unlock;
0154     }
0155 
0156     err = dfops->write(ar, buf, count);
0157     if (err)
0158         goto out_unlock;
0159 
0160 out_unlock:
0161     mutex_unlock(&ar->mutex);
0162 
0163 out_free:
0164     vfree(buf);
0165     return err;
0166 }
0167 
0168 #define __DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize,  \
0169                    _attr, _dstate)              \
0170 static const struct carl9170_debugfs_fops carl_debugfs_##name ##_ops = {\
0171     .read_bufsize = _read_bufsize,                  \
0172     .read = _read,                          \
0173     .write = _write,                        \
0174     .attr = _attr,                          \
0175     .req_dev_state = _dstate,                   \
0176     .fops = {                           \
0177         .open   = simple_open,                  \
0178         .read   = carl9170_debugfs_read,            \
0179         .write  = carl9170_debugfs_write,           \
0180         .owner  = THIS_MODULE                   \
0181     },                              \
0182 }
0183 
0184 #define DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize, _attr) \
0185     __DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize,  \
0186                    _attr, CARL9170_STARTED)         \
0187 
0188 #define DEBUGFS_DECLARE_RO_FILE(name, _read_bufsize)            \
0189     DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \
0190                  NULL, _read_bufsize, 0400)
0191 
0192 #define DEBUGFS_DECLARE_WO_FILE(name)                   \
0193     DEBUGFS_DECLARE_FILE(name, NULL, carl9170_debugfs_##name ##_write,\
0194                  0, 0200)
0195 
0196 #define DEBUGFS_DECLARE_RW_FILE(name, _read_bufsize)            \
0197     DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \
0198                  carl9170_debugfs_##name ##_write,      \
0199                  _read_bufsize, 0600)
0200 
0201 #define __DEBUGFS_DECLARE_RW_FILE(name, _read_bufsize, _dstate)     \
0202     __DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read,   \
0203                  carl9170_debugfs_##name ##_write,      \
0204                  _read_bufsize, 0600, _dstate)
0205 
0206 #define DEBUGFS_READONLY_FILE(name, _read_bufsize, fmt, value...)   \
0207 static char *carl9170_debugfs_ ##name ## _read(struct ar9170 *ar,   \
0208                          char *buf, size_t buf_size,\
0209                          ssize_t *len)      \
0210 {                                   \
0211     ADD(buf, *len, buf_size, fmt "\n", ##value);            \
0212     return buf;                         \
0213 }                                   \
0214 DEBUGFS_DECLARE_RO_FILE(name, _read_bufsize)
0215 
0216 static char *carl9170_debugfs_mem_usage_read(struct ar9170 *ar, char *buf,
0217                          size_t bufsize, ssize_t *len)
0218 {
0219     spin_lock_bh(&ar->mem_lock);
0220 
0221     ADD(buf, *len, bufsize, "jar: [%*pb]\n",
0222         ar->fw.mem_blocks, ar->mem_bitmap);
0223 
0224     ADD(buf, *len, bufsize, "cookies: used:%3d / total:%3d, allocs:%d\n",
0225         bitmap_weight(ar->mem_bitmap, ar->fw.mem_blocks),
0226         ar->fw.mem_blocks, atomic_read(&ar->mem_allocs));
0227 
0228     ADD(buf, *len, bufsize, "memory: free:%3d (%3d KiB) / total:%3d KiB)\n",
0229         atomic_read(&ar->mem_free_blocks),
0230         (atomic_read(&ar->mem_free_blocks) * ar->fw.mem_block_size) / 1024,
0231         (ar->fw.mem_blocks * ar->fw.mem_block_size) / 1024);
0232 
0233     spin_unlock_bh(&ar->mem_lock);
0234 
0235     return buf;
0236 }
0237 DEBUGFS_DECLARE_RO_FILE(mem_usage, 512);
0238 
0239 static char *carl9170_debugfs_qos_stat_read(struct ar9170 *ar, char *buf,
0240                         size_t bufsize, ssize_t *len)
0241 {
0242     ADD(buf, *len, bufsize, "%s QoS AC\n", modparam_noht ? "Hardware" :
0243         "Software");
0244 
0245     ADD(buf, *len, bufsize, "[     VO            VI       "
0246                  "     BE            BK      ]\n");
0247 
0248     spin_lock_bh(&ar->tx_stats_lock);
0249     ADD(buf, *len, bufsize, "[length/limit  length/limit  "
0250                  "length/limit  length/limit ]\n"
0251                 "[   %3d/%3d       %3d/%3d    "
0252                  "   %3d/%3d       %3d/%3d   ]\n\n",
0253         ar->tx_stats[0].len, ar->tx_stats[0].limit,
0254         ar->tx_stats[1].len, ar->tx_stats[1].limit,
0255         ar->tx_stats[2].len, ar->tx_stats[2].limit,
0256         ar->tx_stats[3].len, ar->tx_stats[3].limit);
0257 
0258     ADD(buf, *len, bufsize, "[    total         total     "
0259                  "    total         total    ]\n"
0260                 "[%10d    %10d    %10d    %10d   ]\n\n",
0261         ar->tx_stats[0].count, ar->tx_stats[1].count,
0262         ar->tx_stats[2].count, ar->tx_stats[3].count);
0263 
0264     spin_unlock_bh(&ar->tx_stats_lock);
0265 
0266     ADD(buf, *len, bufsize, "[  pend/waittx   pend/waittx "
0267                  "  pend/waittx   pend/waittx]\n"
0268                 "[   %3d/%3d       %3d/%3d    "
0269                  "   %3d/%3d       %3d/%3d   ]\n\n",
0270         skb_queue_len(&ar->tx_pending[0]),
0271         skb_queue_len(&ar->tx_status[0]),
0272         skb_queue_len(&ar->tx_pending[1]),
0273         skb_queue_len(&ar->tx_status[1]),
0274         skb_queue_len(&ar->tx_pending[2]),
0275         skb_queue_len(&ar->tx_status[2]),
0276         skb_queue_len(&ar->tx_pending[3]),
0277         skb_queue_len(&ar->tx_status[3]));
0278 
0279     return buf;
0280 }
0281 DEBUGFS_DECLARE_RO_FILE(qos_stat, 512);
0282 
0283 static void carl9170_debugfs_format_frame(struct ar9170 *ar,
0284     struct sk_buff *skb, const char *prefix, char *buf,
0285     ssize_t *off, ssize_t bufsize)
0286 {
0287     struct _carl9170_tx_superframe *txc = (void *) skb->data;
0288     struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
0289     struct carl9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
0290     struct ieee80211_hdr *hdr = (void *) txc->frame_data;
0291 
0292     ADD(buf, *off, bufsize, "%s %p, c:%2x, DA:%pM, sq:%4d, mc:%.4x, "
0293         "pc:%.8x, to:%d ms\n", prefix, skb, txc->s.cookie,
0294         ieee80211_get_DA(hdr), get_seq_h(hdr),
0295         le16_to_cpu(txc->f.mac_control), le32_to_cpu(txc->f.phy_control),
0296         jiffies_to_msecs(jiffies - arinfo->timeout));
0297 }
0298 
0299 
0300 static char *carl9170_debugfs_ampdu_state_read(struct ar9170 *ar, char *buf,
0301                            size_t bufsize, ssize_t *len)
0302 {
0303     struct carl9170_sta_tid *iter;
0304     struct sk_buff *skb;
0305     int cnt = 0, fc;
0306     int offset;
0307 
0308     rcu_read_lock();
0309     list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) {
0310 
0311         spin_lock_bh(&iter->lock);
0312         ADD(buf, *len, bufsize, "Entry: #%2d TID:%1d, BSN:%4d, "
0313             "SNX:%4d, HSN:%4d, BAW:%2d, state:%1d, toggles:%d\n",
0314             cnt, iter->tid, iter->bsn, iter->snx, iter->hsn,
0315             iter->max, iter->state, iter->counter);
0316 
0317         ADD(buf, *len, bufsize, "\tWindow:  [%*pb,W]\n",
0318             CARL9170_BAW_BITS, iter->bitmap);
0319 
0320 #define BM_STR_OFF(offset)                  \
0321     ((CARL9170_BAW_BITS - (offset) - 1) / 4 +       \
0322      (CARL9170_BAW_BITS - (offset) - 1) / 32 + 1)
0323 
0324         offset = BM_STR_OFF(0);
0325         ADD(buf, *len, bufsize, "\tBase Seq: %*s\n", offset, "T");
0326 
0327         offset = BM_STR_OFF(SEQ_DIFF(iter->snx, iter->bsn));
0328         ADD(buf, *len, bufsize, "\tNext Seq: %*s\n", offset, "W");
0329 
0330         offset = BM_STR_OFF(((int)iter->hsn - (int)iter->bsn) %
0331                      CARL9170_BAW_BITS);
0332         ADD(buf, *len, bufsize, "\tLast Seq: %*s\n", offset, "N");
0333 
0334         ADD(buf, *len, bufsize, "\tPre-Aggregation reorder buffer: "
0335             " currently queued:%d\n", skb_queue_len(&iter->queue));
0336 
0337         fc = 0;
0338         skb_queue_walk(&iter->queue, skb) {
0339             char prefix[32];
0340 
0341             snprintf(prefix, sizeof(prefix), "\t\t%3d :", fc);
0342             carl9170_debugfs_format_frame(ar, skb, prefix, buf,
0343                               len, bufsize);
0344 
0345             fc++;
0346         }
0347         spin_unlock_bh(&iter->lock);
0348         cnt++;
0349     }
0350     rcu_read_unlock();
0351 
0352     return buf;
0353 }
0354 DEBUGFS_DECLARE_RO_FILE(ampdu_state, 8000);
0355 
0356 static void carl9170_debugfs_queue_dump(struct ar9170 *ar, char *buf,
0357     ssize_t *len, size_t bufsize, struct sk_buff_head *queue)
0358 {
0359     struct sk_buff *skb;
0360     char prefix[16];
0361     int fc = 0;
0362 
0363     spin_lock_bh(&queue->lock);
0364     skb_queue_walk(queue, skb) {
0365         snprintf(prefix, sizeof(prefix), "%3d :", fc);
0366         carl9170_debugfs_format_frame(ar, skb, prefix, buf,
0367                           len, bufsize);
0368         fc++;
0369     }
0370     spin_unlock_bh(&queue->lock);
0371 }
0372 
0373 #define DEBUGFS_QUEUE_DUMP(q, qi)                   \
0374 static char *carl9170_debugfs_##q ##_##qi ##_read(struct ar9170 *ar,    \
0375     char *buf, size_t bufsize, ssize_t *len)            \
0376 {                                   \
0377     carl9170_debugfs_queue_dump(ar, buf, len, bufsize, &ar->q[qi]); \
0378     return buf;                         \
0379 }                                   \
0380 DEBUGFS_DECLARE_RO_FILE(q##_##qi, 8000);
0381 
0382 static char *carl9170_debugfs_sta_psm_read(struct ar9170 *ar, char *buf,
0383                        size_t bufsize, ssize_t *len)
0384 {
0385     ADD(buf, *len, bufsize, "psm state: %s\n", (ar->ps.off_override ?
0386         "FORCE CAM" : (ar->ps.state ? "PSM" : "CAM")));
0387 
0388     ADD(buf, *len, bufsize, "sleep duration: %d ms.\n", ar->ps.sleep_ms);
0389     ADD(buf, *len, bufsize, "last power-state transition: %d ms ago.\n",
0390         jiffies_to_msecs(jiffies - ar->ps.last_action));
0391     ADD(buf, *len, bufsize, "last CAM->PSM transition: %d ms ago.\n",
0392         jiffies_to_msecs(jiffies - ar->ps.last_slept));
0393 
0394     return buf;
0395 }
0396 DEBUGFS_DECLARE_RO_FILE(sta_psm, 160);
0397 
0398 static char *carl9170_debugfs_tx_stuck_read(struct ar9170 *ar, char *buf,
0399                         size_t bufsize, ssize_t *len)
0400 {
0401     int i;
0402 
0403     for (i = 0; i < ar->hw->queues; i++) {
0404         ADD(buf, *len, bufsize, "TX queue [%d]: %10d max:%10d ms.\n",
0405             i, ieee80211_queue_stopped(ar->hw, i) ?
0406             jiffies_to_msecs(jiffies - ar->queue_stop_timeout[i]) : 0,
0407             jiffies_to_msecs(ar->max_queue_stop_timeout[i]));
0408 
0409         ar->max_queue_stop_timeout[i] = 0;
0410     }
0411 
0412     return buf;
0413 }
0414 DEBUGFS_DECLARE_RO_FILE(tx_stuck, 180);
0415 
0416 static char *carl9170_debugfs_phy_noise_read(struct ar9170 *ar, char *buf,
0417                          size_t bufsize, ssize_t *len)
0418 {
0419     int err;
0420 
0421     err = carl9170_get_noisefloor(ar);
0422     if (err) {
0423         *len = err;
0424         return buf;
0425     }
0426 
0427     ADD(buf, *len, bufsize, "Chain 0: %10d dBm, ext. chan.:%10d dBm\n",
0428         ar->noise[0], ar->noise[2]);
0429     ADD(buf, *len, bufsize, "Chain 2: %10d dBm, ext. chan.:%10d dBm\n",
0430         ar->noise[1], ar->noise[3]);
0431 
0432     return buf;
0433 }
0434 DEBUGFS_DECLARE_RO_FILE(phy_noise, 180);
0435 
0436 static char *carl9170_debugfs_vif_dump_read(struct ar9170 *ar, char *buf,
0437                         size_t bufsize, ssize_t *len)
0438 {
0439     struct carl9170_vif_info *iter;
0440     int i = 0;
0441 
0442     ADD(buf, *len, bufsize, "registered VIFs:%d \\ %d\n",
0443         ar->vifs, ar->fw.vif_num);
0444 
0445     ADD(buf, *len, bufsize, "VIF bitmap: [%*pb]\n",
0446         ar->fw.vif_num, &ar->vif_bitmap);
0447 
0448     rcu_read_lock();
0449     list_for_each_entry_rcu(iter, &ar->vif_list, list) {
0450         struct ieee80211_vif *vif = carl9170_get_vif(iter);
0451         ADD(buf, *len, bufsize, "\t%d = [%s VIF, id:%d, type:%x "
0452             " mac:%pM %s]\n", i, (carl9170_get_main_vif(ar) == vif ?
0453             "Master" : " Slave"), iter->id, vif->type, vif->addr,
0454             iter->enable_beacon ? "beaconing " : "");
0455         i++;
0456     }
0457     rcu_read_unlock();
0458 
0459     return buf;
0460 }
0461 DEBUGFS_DECLARE_RO_FILE(vif_dump, 8000);
0462 
0463 #define UPDATE_COUNTER(ar, name)    ({              \
0464     u32 __tmp[ARRAY_SIZE(name##_regs)];             \
0465     unsigned int __i, __err = -ENODEV;              \
0466                                     \
0467     for (__i = 0; __i < ARRAY_SIZE(name##_regs); __i++) {       \
0468         __tmp[__i] = name##_regs[__i].reg;          \
0469         ar->debug.stats.name##_counter[__i] = 0;        \
0470     }                               \
0471                                     \
0472     if (IS_STARTED(ar))                     \
0473         __err = carl9170_read_mreg(ar, ARRAY_SIZE(name##_regs), \
0474             __tmp, ar->debug.stats.name##_counter);     \
0475     (__err); })
0476 
0477 #define TALLY_SUM_UP(ar, name)  do {                    \
0478     unsigned int __i;                       \
0479                                     \
0480     for (__i = 0; __i < ARRAY_SIZE(name##_regs); __i++) {       \
0481         ar->debug.stats.name##_sum[__i] +=          \
0482             ar->debug.stats.name##_counter[__i];        \
0483     }                               \
0484 } while (0)
0485 
0486 #define DEBUGFS_HW_TALLY_FILE(name, f)                  \
0487 static char *carl9170_debugfs_##name ## _read(struct ar9170 *ar,    \
0488      char *dum, size_t bufsize, ssize_t *ret)           \
0489 {                                   \
0490     char *buf;                          \
0491     int i, max_len, err;                        \
0492                                     \
0493     max_len = ARRAY_SIZE(name##_regs) * 80;             \
0494     buf = vmalloc(max_len);                     \
0495     if (!buf)                           \
0496         return NULL;                        \
0497                                     \
0498     err = UPDATE_COUNTER(ar, name);                 \
0499     if (err) {                          \
0500         *ret = err;                     \
0501         return buf;                     \
0502     }                               \
0503                                     \
0504     TALLY_SUM_UP(ar, name);                     \
0505                                     \
0506     for (i = 0; i < ARRAY_SIZE(name##_regs); i++) {         \
0507         ADD(buf, *ret, max_len, "%22s = %" f "[+%" f "]\n", \
0508             name##_regs[i].nreg, ar->debug.stats.name ##_sum[i],\
0509             ar->debug.stats.name ##_counter[i]);        \
0510     }                               \
0511                                     \
0512     return buf;                         \
0513 }                                   \
0514 DEBUGFS_DECLARE_RO_FILE(name, 0);
0515 
0516 #define DEBUGFS_HW_REG_FILE(name, f)                    \
0517 static char *carl9170_debugfs_##name ## _read(struct ar9170 *ar,    \
0518     char *dum, size_t bufsize, ssize_t *ret)            \
0519 {                                   \
0520     char *buf;                          \
0521     int i, max_len, err;                        \
0522                                     \
0523     max_len = ARRAY_SIZE(name##_regs) * 80;             \
0524     buf = vmalloc(max_len);                     \
0525     if (!buf)                           \
0526         return NULL;                        \
0527                                     \
0528     err = UPDATE_COUNTER(ar, name);                 \
0529     if (err) {                          \
0530         *ret = err;                     \
0531         return buf;                     \
0532     }                               \
0533                                     \
0534     for (i = 0; i < ARRAY_SIZE(name##_regs); i++) {         \
0535         ADD(buf, *ret, max_len, "%22s = %" f "\n",      \
0536             name##_regs[i].nreg,                \
0537             ar->debug.stats.name##_counter[i]);         \
0538     }                               \
0539                                     \
0540     return buf;                         \
0541 }                                   \
0542 DEBUGFS_DECLARE_RO_FILE(name, 0);
0543 
0544 static ssize_t carl9170_debugfs_hw_ioread32_write(struct ar9170 *ar,
0545     const char *buf, size_t count)
0546 {
0547     int err = 0, i, n = 0, max_len = 32, res;
0548     unsigned int reg, tmp;
0549 
0550     if (!count)
0551         return 0;
0552 
0553     if (count > max_len)
0554         return -E2BIG;
0555 
0556     res = sscanf(buf, "0x%X %d", &reg, &n);
0557     if (res < 1) {
0558         err = -EINVAL;
0559         goto out;
0560     }
0561 
0562     if (res == 1)
0563         n = 1;
0564 
0565     if (n > 15) {
0566         err = -EMSGSIZE;
0567         goto out;
0568     }
0569 
0570     if ((reg >= 0x280000) || ((reg + (n << 2)) >= 0x280000)) {
0571         err = -EADDRNOTAVAIL;
0572         goto out;
0573     }
0574 
0575     if (reg & 3) {
0576         err = -EINVAL;
0577         goto out;
0578     }
0579 
0580     for (i = 0; i < n; i++) {
0581         err = carl9170_read_reg(ar, reg + (i << 2), &tmp);
0582         if (err)
0583             goto out;
0584 
0585         ar->debug.ring[ar->debug.ring_tail].reg = reg + (i << 2);
0586         ar->debug.ring[ar->debug.ring_tail].value = tmp;
0587         ar->debug.ring_tail++;
0588         ar->debug.ring_tail %= CARL9170_DEBUG_RING_SIZE;
0589     }
0590 
0591 out:
0592     return err ? err : count;
0593 }
0594 
0595 static char *carl9170_debugfs_hw_ioread32_read(struct ar9170 *ar, char *buf,
0596                            size_t bufsize, ssize_t *ret)
0597 {
0598     int i = 0;
0599 
0600     while (ar->debug.ring_head != ar->debug.ring_tail) {
0601         ADD(buf, *ret, bufsize, "%.8x = %.8x\n",
0602             ar->debug.ring[ar->debug.ring_head].reg,
0603             ar->debug.ring[ar->debug.ring_head].value);
0604 
0605         ar->debug.ring_head++;
0606         ar->debug.ring_head %= CARL9170_DEBUG_RING_SIZE;
0607 
0608         if (i++ == 64)
0609             break;
0610     }
0611     ar->debug.ring_head = ar->debug.ring_tail;
0612     return buf;
0613 }
0614 DEBUGFS_DECLARE_RW_FILE(hw_ioread32, CARL9170_DEBUG_RING_SIZE * 40);
0615 
0616 static ssize_t carl9170_debugfs_bug_write(struct ar9170 *ar, const char *buf,
0617                       size_t count)
0618 {
0619     int err;
0620 
0621     if (count < 1)
0622         return -EINVAL;
0623 
0624     switch (buf[0]) {
0625     case 'F':
0626         ar->needs_full_reset = true;
0627         break;
0628 
0629     case 'R':
0630         if (!IS_STARTED(ar)) {
0631             err = -EAGAIN;
0632             goto out;
0633         }
0634 
0635         ar->needs_full_reset = false;
0636         break;
0637 
0638     case 'M':
0639         err = carl9170_mac_reset(ar);
0640         if (err < 0)
0641             count = err;
0642 
0643         goto out;
0644 
0645     case 'P':
0646         err = carl9170_set_channel(ar, ar->hw->conf.chandef.chan,
0647             cfg80211_get_chandef_type(&ar->hw->conf.chandef));
0648         if (err < 0)
0649             count = err;
0650 
0651         goto out;
0652 
0653     default:
0654         return -EINVAL;
0655     }
0656 
0657     carl9170_restart(ar, CARL9170_RR_USER_REQUEST);
0658 
0659 out:
0660     return count;
0661 }
0662 
0663 static char *carl9170_debugfs_bug_read(struct ar9170 *ar, char *buf,
0664                        size_t bufsize, ssize_t *ret)
0665 {
0666     ADD(buf, *ret, bufsize, "[P]hy reinit, [R]estart, [F]ull usb reset, "
0667         "[M]ac reset\n");
0668     ADD(buf, *ret, bufsize, "firmware restarts:%d, last reason:%d\n",
0669         ar->restart_counter, ar->last_reason);
0670     ADD(buf, *ret, bufsize, "phy reinit errors:%d (%d)\n",
0671         ar->total_chan_fail, ar->chan_fail);
0672     ADD(buf, *ret, bufsize, "reported firmware errors:%d\n",
0673         ar->fw.err_counter);
0674     ADD(buf, *ret, bufsize, "reported firmware BUGs:%d\n",
0675         ar->fw.bug_counter);
0676     ADD(buf, *ret, bufsize, "pending restart requests:%d\n",
0677         atomic_read(&ar->pending_restarts));
0678     return buf;
0679 }
0680 __DEBUGFS_DECLARE_RW_FILE(bug, 400, CARL9170_STOPPED);
0681 
0682 static const char *const erp_modes[] = {
0683     [CARL9170_ERP_INVALID] = "INVALID",
0684     [CARL9170_ERP_AUTO] = "Automatic",
0685     [CARL9170_ERP_MAC80211] = "Set by MAC80211",
0686     [CARL9170_ERP_OFF] = "Force Off",
0687     [CARL9170_ERP_RTS] = "Force RTS",
0688     [CARL9170_ERP_CTS] = "Force CTS"
0689 };
0690 
0691 static char *carl9170_debugfs_erp_read(struct ar9170 *ar, char *buf,
0692                        size_t bufsize, ssize_t *ret)
0693 {
0694     ADD(buf, *ret, bufsize, "ERP Setting: (%d) -> %s\n", ar->erp_mode,
0695         erp_modes[ar->erp_mode]);
0696     return buf;
0697 }
0698 
0699 static ssize_t carl9170_debugfs_erp_write(struct ar9170 *ar, const char *buf,
0700                       size_t count)
0701 {
0702     int res, val;
0703 
0704     if (count < 1)
0705         return -EINVAL;
0706 
0707     res = sscanf(buf, "%d", &val);
0708     if (res != 1)
0709         return -EINVAL;
0710 
0711     if (!((val > CARL9170_ERP_INVALID) &&
0712           (val < __CARL9170_ERP_NUM)))
0713         return -EINVAL;
0714 
0715     ar->erp_mode = val;
0716     return count;
0717 }
0718 
0719 DEBUGFS_DECLARE_RW_FILE(erp, 80);
0720 
0721 static ssize_t carl9170_debugfs_hw_iowrite32_write(struct ar9170 *ar,
0722     const char *buf, size_t count)
0723 {
0724     int err = 0, max_len = 22, res;
0725     u32 reg, val;
0726 
0727     if (!count)
0728         return 0;
0729 
0730     if (count > max_len)
0731         return -E2BIG;
0732 
0733     res = sscanf(buf, "0x%X 0x%X", &reg, &val);
0734     if (res != 2) {
0735         err = -EINVAL;
0736         goto out;
0737     }
0738 
0739     if (reg <= 0x100000 || reg >= 0x280000) {
0740         err = -EADDRNOTAVAIL;
0741         goto out;
0742     }
0743 
0744     if (reg & 3) {
0745         err = -EINVAL;
0746         goto out;
0747     }
0748 
0749     err = carl9170_write_reg(ar, reg, val);
0750     if (err)
0751         goto out;
0752 
0753 out:
0754     return err ? err : count;
0755 }
0756 DEBUGFS_DECLARE_WO_FILE(hw_iowrite32);
0757 
0758 DEBUGFS_HW_TALLY_FILE(hw_tx_tally, "u");
0759 DEBUGFS_HW_TALLY_FILE(hw_rx_tally, "u");
0760 DEBUGFS_HW_TALLY_FILE(hw_phy_errors, "u");
0761 DEBUGFS_HW_REG_FILE(hw_wlan_queue, ".8x");
0762 DEBUGFS_HW_REG_FILE(hw_pta_queue, ".8x");
0763 DEBUGFS_HW_REG_FILE(hw_ampdu_info, ".8x");
0764 DEBUGFS_QUEUE_DUMP(tx_status, 0);
0765 DEBUGFS_QUEUE_DUMP(tx_status, 1);
0766 DEBUGFS_QUEUE_DUMP(tx_status, 2);
0767 DEBUGFS_QUEUE_DUMP(tx_status, 3);
0768 DEBUGFS_QUEUE_DUMP(tx_pending, 0);
0769 DEBUGFS_QUEUE_DUMP(tx_pending, 1);
0770 DEBUGFS_QUEUE_DUMP(tx_pending, 2);
0771 DEBUGFS_QUEUE_DUMP(tx_pending, 3);
0772 DEBUGFS_READONLY_FILE(usb_tx_anch_urbs, 20, "%d",
0773               atomic_read(&ar->tx_anch_urbs));
0774 DEBUGFS_READONLY_FILE(usb_rx_anch_urbs, 20, "%d",
0775               atomic_read(&ar->rx_anch_urbs));
0776 DEBUGFS_READONLY_FILE(usb_rx_work_urbs, 20, "%d",
0777               atomic_read(&ar->rx_work_urbs));
0778 DEBUGFS_READONLY_FILE(usb_rx_pool_urbs, 20, "%d",
0779               atomic_read(&ar->rx_pool_urbs));
0780 
0781 DEBUGFS_READONLY_FILE(tx_total_queued, 20, "%d",
0782               atomic_read(&ar->tx_total_queued));
0783 DEBUGFS_READONLY_FILE(tx_ampdu_scheduler, 20, "%d",
0784               atomic_read(&ar->tx_ampdu_scheduler));
0785 
0786 DEBUGFS_READONLY_FILE(tx_total_pending, 20, "%d",
0787               atomic_read(&ar->tx_total_pending));
0788 
0789 DEBUGFS_READONLY_FILE(tx_ampdu_list_len, 20, "%d",
0790               ar->tx_ampdu_list_len);
0791 
0792 DEBUGFS_READONLY_FILE(tx_ampdu_upload, 20, "%d",
0793               atomic_read(&ar->tx_ampdu_upload));
0794 
0795 DEBUGFS_READONLY_FILE(tx_janitor_last_run, 64, "last run:%d ms ago",
0796     jiffies_to_msecs(jiffies - ar->tx_janitor_last_run));
0797 
0798 DEBUGFS_READONLY_FILE(tx_dropped, 20, "%d", ar->tx_dropped);
0799 
0800 DEBUGFS_READONLY_FILE(rx_dropped, 20, "%d", ar->rx_dropped);
0801 
0802 DEBUGFS_READONLY_FILE(sniffer_enabled, 20, "%d", ar->sniffer_enabled);
0803 DEBUGFS_READONLY_FILE(rx_software_decryption, 20, "%d",
0804               ar->rx_software_decryption);
0805 DEBUGFS_READONLY_FILE(ampdu_factor, 20, "%d",
0806               ar->current_factor);
0807 DEBUGFS_READONLY_FILE(ampdu_density, 20, "%d",
0808               ar->current_density);
0809 
0810 DEBUGFS_READONLY_FILE(beacon_int, 20, "%d TU", ar->global_beacon_int);
0811 DEBUGFS_READONLY_FILE(pretbtt, 20, "%d TU", ar->global_pretbtt);
0812 
0813 void carl9170_debugfs_register(struct ar9170 *ar)
0814 {
0815     ar->debug_dir = debugfs_create_dir(KBUILD_MODNAME,
0816         ar->hw->wiphy->debugfsdir);
0817 
0818 #define DEBUGFS_ADD(name)                       \
0819     debugfs_create_file(#name, carl_debugfs_##name ##_ops.attr, \
0820                 ar->debug_dir, ar,              \
0821                 &carl_debugfs_##name ## _ops.fops)
0822 
0823     DEBUGFS_ADD(usb_tx_anch_urbs);
0824     DEBUGFS_ADD(usb_rx_pool_urbs);
0825     DEBUGFS_ADD(usb_rx_anch_urbs);
0826     DEBUGFS_ADD(usb_rx_work_urbs);
0827 
0828     DEBUGFS_ADD(tx_total_queued);
0829     DEBUGFS_ADD(tx_total_pending);
0830     DEBUGFS_ADD(tx_dropped);
0831     DEBUGFS_ADD(tx_stuck);
0832     DEBUGFS_ADD(tx_ampdu_upload);
0833     DEBUGFS_ADD(tx_ampdu_scheduler);
0834     DEBUGFS_ADD(tx_ampdu_list_len);
0835 
0836     DEBUGFS_ADD(rx_dropped);
0837     DEBUGFS_ADD(sniffer_enabled);
0838     DEBUGFS_ADD(rx_software_decryption);
0839 
0840     DEBUGFS_ADD(mem_usage);
0841     DEBUGFS_ADD(qos_stat);
0842     DEBUGFS_ADD(sta_psm);
0843     DEBUGFS_ADD(ampdu_state);
0844 
0845     DEBUGFS_ADD(hw_tx_tally);
0846     DEBUGFS_ADD(hw_rx_tally);
0847     DEBUGFS_ADD(hw_phy_errors);
0848     DEBUGFS_ADD(phy_noise);
0849 
0850     DEBUGFS_ADD(hw_wlan_queue);
0851     DEBUGFS_ADD(hw_pta_queue);
0852     DEBUGFS_ADD(hw_ampdu_info);
0853 
0854     DEBUGFS_ADD(ampdu_density);
0855     DEBUGFS_ADD(ampdu_factor);
0856 
0857     DEBUGFS_ADD(tx_janitor_last_run);
0858 
0859     DEBUGFS_ADD(tx_status_0);
0860     DEBUGFS_ADD(tx_status_1);
0861     DEBUGFS_ADD(tx_status_2);
0862     DEBUGFS_ADD(tx_status_3);
0863 
0864     DEBUGFS_ADD(tx_pending_0);
0865     DEBUGFS_ADD(tx_pending_1);
0866     DEBUGFS_ADD(tx_pending_2);
0867     DEBUGFS_ADD(tx_pending_3);
0868 
0869     DEBUGFS_ADD(hw_ioread32);
0870     DEBUGFS_ADD(hw_iowrite32);
0871     DEBUGFS_ADD(bug);
0872 
0873     DEBUGFS_ADD(erp);
0874 
0875     DEBUGFS_ADD(vif_dump);
0876 
0877     DEBUGFS_ADD(beacon_int);
0878     DEBUGFS_ADD(pretbtt);
0879 
0880 #undef DEBUGFS_ADD
0881 }
0882 
0883 void carl9170_debugfs_unregister(struct ar9170 *ar)
0884 {
0885     debugfs_remove_recursive(ar->debug_dir);
0886 }