11ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez/* 21ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez * cfg80211 debugfs 31ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez * 41ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez * Copyright 2009 Luis R. Rodriguez <lrodriguez@atheros.com> 51ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> 61ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez * 71ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez * This program is free software; you can redistribute it and/or modify 81ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez * it under the terms of the GNU General Public License version 2 as 91ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez * published by the Free Software Foundation. 101ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez */ 111ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez 125a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 131ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez#include "core.h" 141ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez#include "debugfs.h" 151ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez 161ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \ 171ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguezstatic ssize_t name## _read(struct file *file, char __user *userbuf, \ 181ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez size_t count, loff_t *ppos) \ 191ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez{ \ 201ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez struct wiphy *wiphy= file->private_data; \ 211ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez char buf[buflen]; \ 221ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez int res; \ 231ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez \ 241ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez res = scnprintf(buf, buflen, fmt "\n", ##value); \ 251ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez return simple_read_from_buffer(userbuf, count, ppos, buf, res); \ 261ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez} \ 271ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez \ 281ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguezstatic const struct file_operations name## _ops = { \ 291ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez .read = name## _read, \ 30234e340582901211f40d8c732afc49f0630ecf05Stephen Boyd .open = simple_open, \ 312b18ab36cf7e956fb5b5ee12847e94fc66d496f4Arnd Bergmann .llseek = generic_file_llseek, \ 321ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez}; 331ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez 341ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. RodriguezDEBUGFS_READONLY_FILE(rts_threshold, 20, "%d", 351ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez wiphy->rts_threshold) 361ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. RodriguezDEBUGFS_READONLY_FILE(fragmentation_threshold, 20, "%d", 371ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez wiphy->frag_threshold); 381ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. RodriguezDEBUGFS_READONLY_FILE(short_retry_limit, 20, "%d", 391ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez wiphy->retry_short) 401ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. RodriguezDEBUGFS_READONLY_FILE(long_retry_limit, 20, "%d", 411ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez wiphy->retry_long); 421ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez 4380a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguezstatic int ht_print_chan(struct ieee80211_channel *chan, 4480a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez char *buf, int buf_size, int offset) 4580a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez{ 4680a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez if (WARN_ON(offset > buf_size)) 4780a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez return 0; 4880a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez 4980a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez if (chan->flags & IEEE80211_CHAN_DISABLED) 50f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller return scnprintf(buf + offset, 51f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller buf_size - offset, 52f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller "%d Disabled\n", 53f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller chan->center_freq); 5480a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez 55f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller return scnprintf(buf + offset, 56f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller buf_size - offset, 57f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller "%d HT40 %c%c\n", 58f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller chan->center_freq, 59f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller (chan->flags & IEEE80211_CHAN_NO_HT40MINUS) ? 60f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller ' ' : '-', 61f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller (chan->flags & IEEE80211_CHAN_NO_HT40PLUS) ? 62f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller ' ' : '+'); 6380a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez} 6480a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez 6580a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguezstatic ssize_t ht40allow_map_read(struct file *file, 6680a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez char __user *user_buf, 6780a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez size_t count, loff_t *ppos) 6880a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez{ 6980a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez struct wiphy *wiphy = file->private_data; 7080a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez char *buf; 7180a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez unsigned int offset = 0, buf_size = PAGE_SIZE, i, r; 7280a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez enum ieee80211_band band; 7380a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez struct ieee80211_supported_band *sband; 7480a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez 7580a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez buf = kzalloc(buf_size, GFP_KERNEL); 7680a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez if (!buf) 7780a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez return -ENOMEM; 7880a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez 795fe231e873729fa2f57cdc417d5c1f80871e2d7dJohannes Berg rtnl_lock(); 8080a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez 8180a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 8280a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez sband = wiphy->bands[band]; 8380a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez if (!sband) 8480a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez continue; 8580a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez for (i = 0; i < sband->n_channels; i++) 8680a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez offset += ht_print_chan(&sband->channels[i], 8780a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez buf, buf_size, offset); 8880a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez } 8980a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez 905fe231e873729fa2f57cdc417d5c1f80871e2d7dJohannes Berg rtnl_unlock(); 9180a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez 9280a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez r = simple_read_from_buffer(user_buf, count, ppos, buf, offset); 9380a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez 9480a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez kfree(buf); 9580a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez 9680a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez return r; 9780a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez} 9880a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez 9980a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguezstatic const struct file_operations ht40allow_map_ops = { 10080a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez .read = ht40allow_map_read, 101234e340582901211f40d8c732afc49f0630ecf05Stephen Boyd .open = simple_open, 1026038f373a3dc1f1c26496e60b6c40b164716f07eArnd Bergmann .llseek = default_llseek, 10380a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez}; 10480a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez 1051ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez#define DEBUGFS_ADD(name) \ 1067bcfaf2f431c09c51fe776fc06638b25d3b421c5Johannes Berg debugfs_create_file(#name, S_IRUGO, phyd, &rdev->wiphy, &name## _ops); 1071ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez 10879c97e97aed7f760d2826c7daf2d42d8eefe9838Johannes Bergvoid cfg80211_debugfs_rdev_add(struct cfg80211_registered_device *rdev) 1091ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez{ 11079c97e97aed7f760d2826c7daf2d42d8eefe9838Johannes Berg struct dentry *phyd = rdev->wiphy.debugfsdir; 1111ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez 1121ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez DEBUGFS_ADD(rts_threshold); 1131ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez DEBUGFS_ADD(fragmentation_threshold); 1141ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez DEBUGFS_ADD(short_retry_limit); 1151ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez DEBUGFS_ADD(long_retry_limit); 11680a3511d70e8fc7ed3fe4417d7b0bf6c3f642f64Luis R. Rodriguez DEBUGFS_ADD(ht40allow_map); 1171ac61302dcd18880e28c29e5728cd4d0efeb5366Luis R. Rodriguez} 118