0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
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", ®, &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", ®, &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 }