17bcfaf2fSJohannes Berg 2e9f207f0SJiri Benc /* 3e9f207f0SJiri Benc * mac80211 debugfs for wireless PHYs 4e9f207f0SJiri Benc * 5e9f207f0SJiri Benc * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> 6e9f207f0SJiri Benc * 7e9f207f0SJiri Benc * GPLv2 8e9f207f0SJiri Benc * 9e9f207f0SJiri Benc */ 10e9f207f0SJiri Benc 11e9f207f0SJiri Benc #include <linux/debugfs.h> 12e9f207f0SJiri Benc #include <linux/rtnetlink.h> 13e9f207f0SJiri Benc #include "ieee80211_i.h" 1424487981SJohannes Berg #include "driver-ops.h" 152c8dccc7SJohannes Berg #include "rate.h" 16e9f207f0SJiri Benc #include "debugfs.h" 17e9f207f0SJiri Benc 18e9f207f0SJiri Benc int mac80211_open_file_generic(struct inode *inode, struct file *file) 19e9f207f0SJiri Benc { 20e9f207f0SJiri Benc file->private_data = inode->i_private; 21e9f207f0SJiri Benc return 0; 22e9f207f0SJiri Benc } 23e9f207f0SJiri Benc 24e9f207f0SJiri Benc #define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \ 25e9f207f0SJiri Benc static ssize_t name## _read(struct file *file, char __user *userbuf, \ 26e9f207f0SJiri Benc size_t count, loff_t *ppos) \ 27e9f207f0SJiri Benc { \ 28e9f207f0SJiri Benc struct ieee80211_local *local = file->private_data; \ 29e9f207f0SJiri Benc char buf[buflen]; \ 30e9f207f0SJiri Benc int res; \ 31e9f207f0SJiri Benc \ 32e9f207f0SJiri Benc res = scnprintf(buf, buflen, fmt "\n", ##value); \ 33e9f207f0SJiri Benc return simple_read_from_buffer(userbuf, count, ppos, buf, res); \ 34e9f207f0SJiri Benc } \ 35e9f207f0SJiri Benc \ 36e9f207f0SJiri Benc static const struct file_operations name## _ops = { \ 37e9f207f0SJiri Benc .read = name## _read, \ 38e9f207f0SJiri Benc .open = mac80211_open_file_generic, \ 39e9f207f0SJiri Benc }; 40e9f207f0SJiri Benc 41e9f207f0SJiri Benc #define DEBUGFS_ADD(name) \ 427bcfaf2fSJohannes Berg debugfs_create_file(#name, 0400, phyd, local, &name## _ops); 43e9f207f0SJiri Benc 44827b1fb4SJohannes Berg #define DEBUGFS_ADD_MODE(name, mode) \ 457bcfaf2fSJohannes Berg debugfs_create_file(#name, mode, phyd, local, &name## _ops); 46e9f207f0SJiri Benc 47e9f207f0SJiri Benc 48e9f207f0SJiri Benc DEBUGFS_READONLY_FILE(frequency, 20, "%d", 498318d78aSJohannes Berg local->hw.conf.channel->center_freq); 50e9f207f0SJiri Benc DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d", 51e9f207f0SJiri Benc local->total_ps_buffered); 523b5d665bSAlina Friedrichsen DEBUGFS_READONLY_FILE(wep_iv, 20, "%#08x", 53e9f207f0SJiri Benc local->wep_iv & 0xffffff); 54e9f207f0SJiri Benc DEBUGFS_READONLY_FILE(rate_ctrl_alg, 100, "%s", 55af65cd96SJohannes Berg local->rate_ctrl ? local->rate_ctrl->ops->name : "hw/driver"); 563b5d665bSAlina Friedrichsen 573b5d665bSAlina Friedrichsen static ssize_t tsf_read(struct file *file, char __user *user_buf, 583b5d665bSAlina Friedrichsen size_t count, loff_t *ppos) 593b5d665bSAlina Friedrichsen { 603b5d665bSAlina Friedrichsen struct ieee80211_local *local = file->private_data; 6124487981SJohannes Berg u64 tsf; 623b5d665bSAlina Friedrichsen char buf[100]; 633b5d665bSAlina Friedrichsen 6424487981SJohannes Berg tsf = drv_get_tsf(local); 653b5d665bSAlina Friedrichsen 663b5d665bSAlina Friedrichsen snprintf(buf, sizeof(buf), "0x%016llx\n", (unsigned long long) tsf); 673b5d665bSAlina Friedrichsen 683b5d665bSAlina Friedrichsen return simple_read_from_buffer(user_buf, count, ppos, buf, 19); 693b5d665bSAlina Friedrichsen } 703b5d665bSAlina Friedrichsen 713b5d665bSAlina Friedrichsen static ssize_t tsf_write(struct file *file, 723b5d665bSAlina Friedrichsen const char __user *user_buf, 733b5d665bSAlina Friedrichsen size_t count, loff_t *ppos) 743b5d665bSAlina Friedrichsen { 753b5d665bSAlina Friedrichsen struct ieee80211_local *local = file->private_data; 763b5d665bSAlina Friedrichsen unsigned long long tsf; 773b5d665bSAlina Friedrichsen char buf[100]; 783b5d665bSAlina Friedrichsen size_t len; 793b5d665bSAlina Friedrichsen 803b5d665bSAlina Friedrichsen len = min(count, sizeof(buf) - 1); 813b5d665bSAlina Friedrichsen if (copy_from_user(buf, user_buf, len)) 823b5d665bSAlina Friedrichsen return -EFAULT; 833b5d665bSAlina Friedrichsen buf[len] = '\0'; 843b5d665bSAlina Friedrichsen 853b5d665bSAlina Friedrichsen if (strncmp(buf, "reset", 5) == 0) { 863b5d665bSAlina Friedrichsen if (local->ops->reset_tsf) { 8724487981SJohannes Berg drv_reset_tsf(local); 883b5d665bSAlina Friedrichsen printk(KERN_INFO "%s: debugfs reset TSF\n", wiphy_name(local->hw.wiphy)); 893b5d665bSAlina Friedrichsen } 903b5d665bSAlina Friedrichsen } else { 913b5d665bSAlina Friedrichsen tsf = simple_strtoul(buf, NULL, 0); 923b5d665bSAlina Friedrichsen if (local->ops->set_tsf) { 9324487981SJohannes Berg drv_set_tsf(local, tsf); 943b5d665bSAlina Friedrichsen printk(KERN_INFO "%s: debugfs set TSF to %#018llx\n", wiphy_name(local->hw.wiphy), tsf); 953b5d665bSAlina Friedrichsen } 963b5d665bSAlina Friedrichsen } 973b5d665bSAlina Friedrichsen 983b5d665bSAlina Friedrichsen return count; 993b5d665bSAlina Friedrichsen } 1003b5d665bSAlina Friedrichsen 1013b5d665bSAlina Friedrichsen static const struct file_operations tsf_ops = { 1023b5d665bSAlina Friedrichsen .read = tsf_read, 1033b5d665bSAlina Friedrichsen .write = tsf_write, 1043b5d665bSAlina Friedrichsen .open = mac80211_open_file_generic 1053b5d665bSAlina Friedrichsen }; 106e9f207f0SJiri Benc 107827b1fb4SJohannes Berg static ssize_t reset_write(struct file *file, const char __user *user_buf, 108827b1fb4SJohannes Berg size_t count, loff_t *ppos) 109827b1fb4SJohannes Berg { 110827b1fb4SJohannes Berg struct ieee80211_local *local = file->private_data; 111827b1fb4SJohannes Berg 112827b1fb4SJohannes Berg rtnl_lock(); 113827b1fb4SJohannes Berg __ieee80211_suspend(&local->hw); 114827b1fb4SJohannes Berg __ieee80211_resume(&local->hw); 115827b1fb4SJohannes Berg rtnl_unlock(); 116827b1fb4SJohannes Berg 117827b1fb4SJohannes Berg return count; 118827b1fb4SJohannes Berg } 119827b1fb4SJohannes Berg 120827b1fb4SJohannes Berg static const struct file_operations reset_ops = { 121827b1fb4SJohannes Berg .write = reset_write, 122827b1fb4SJohannes Berg .open = mac80211_open_file_generic, 123827b1fb4SJohannes Berg }; 124827b1fb4SJohannes Berg 125d3707d99SJohannes Berg static ssize_t noack_read(struct file *file, char __user *user_buf, 126d3707d99SJohannes Berg size_t count, loff_t *ppos) 127d3707d99SJohannes Berg { 128d3707d99SJohannes Berg struct ieee80211_local *local = file->private_data; 129d3707d99SJohannes Berg int res; 130d3707d99SJohannes Berg char buf[10]; 131d3707d99SJohannes Berg 132d3707d99SJohannes Berg res = scnprintf(buf, sizeof(buf), "%d\n", local->wifi_wme_noack_test); 133d3707d99SJohannes Berg 134d3707d99SJohannes Berg return simple_read_from_buffer(user_buf, count, ppos, buf, res); 135d3707d99SJohannes Berg } 136d3707d99SJohannes Berg 137d3707d99SJohannes Berg static ssize_t noack_write(struct file *file, 138d3707d99SJohannes Berg const char __user *user_buf, 139d3707d99SJohannes Berg size_t count, loff_t *ppos) 140d3707d99SJohannes Berg { 141d3707d99SJohannes Berg struct ieee80211_local *local = file->private_data; 142d3707d99SJohannes Berg char buf[10]; 143d3707d99SJohannes Berg size_t len; 144d3707d99SJohannes Berg 145d3707d99SJohannes Berg len = min(count, sizeof(buf) - 1); 146d3707d99SJohannes Berg if (copy_from_user(buf, user_buf, len)) 147d3707d99SJohannes Berg return -EFAULT; 148d3707d99SJohannes Berg buf[len] = '\0'; 149d3707d99SJohannes Berg 150d3707d99SJohannes Berg local->wifi_wme_noack_test = !!simple_strtoul(buf, NULL, 0); 151d3707d99SJohannes Berg 152d3707d99SJohannes Berg return count; 153d3707d99SJohannes Berg } 154d3707d99SJohannes Berg 155d3707d99SJohannes Berg static const struct file_operations noack_ops = { 156d3707d99SJohannes Berg .read = noack_read, 157d3707d99SJohannes Berg .write = noack_write, 158d3707d99SJohannes Berg .open = mac80211_open_file_generic 159d3707d99SJohannes Berg }; 160d3707d99SJohannes Berg 16150ae0cf1SKalle Valo static ssize_t uapsd_queues_read(struct file *file, char __user *user_buf, 16250ae0cf1SKalle Valo size_t count, loff_t *ppos) 16350ae0cf1SKalle Valo { 16450ae0cf1SKalle Valo struct ieee80211_local *local = file->private_data; 16550ae0cf1SKalle Valo int res; 16650ae0cf1SKalle Valo char buf[10]; 16750ae0cf1SKalle Valo 16850ae0cf1SKalle Valo res = scnprintf(buf, sizeof(buf), "0x%x\n", local->uapsd_queues); 16950ae0cf1SKalle Valo 17050ae0cf1SKalle Valo return simple_read_from_buffer(user_buf, count, ppos, buf, res); 17150ae0cf1SKalle Valo } 17250ae0cf1SKalle Valo 17350ae0cf1SKalle Valo static ssize_t uapsd_queues_write(struct file *file, 17450ae0cf1SKalle Valo const char __user *user_buf, 17550ae0cf1SKalle Valo size_t count, loff_t *ppos) 17650ae0cf1SKalle Valo { 17750ae0cf1SKalle Valo struct ieee80211_local *local = file->private_data; 17850ae0cf1SKalle Valo unsigned long val; 17950ae0cf1SKalle Valo char buf[10]; 18050ae0cf1SKalle Valo size_t len; 18150ae0cf1SKalle Valo int ret; 18250ae0cf1SKalle Valo 18350ae0cf1SKalle Valo len = min(count, sizeof(buf) - 1); 18450ae0cf1SKalle Valo if (copy_from_user(buf, user_buf, len)) 18550ae0cf1SKalle Valo return -EFAULT; 18650ae0cf1SKalle Valo buf[len] = '\0'; 18750ae0cf1SKalle Valo 18850ae0cf1SKalle Valo ret = strict_strtoul(buf, 0, &val); 18950ae0cf1SKalle Valo 19050ae0cf1SKalle Valo if (ret) 19150ae0cf1SKalle Valo return -EINVAL; 19250ae0cf1SKalle Valo 19350ae0cf1SKalle Valo if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) 19450ae0cf1SKalle Valo return -ERANGE; 19550ae0cf1SKalle Valo 19650ae0cf1SKalle Valo local->uapsd_queues = val; 19750ae0cf1SKalle Valo 19850ae0cf1SKalle Valo return count; 19950ae0cf1SKalle Valo } 20050ae0cf1SKalle Valo 20150ae0cf1SKalle Valo static const struct file_operations uapsd_queues_ops = { 20250ae0cf1SKalle Valo .read = uapsd_queues_read, 20350ae0cf1SKalle Valo .write = uapsd_queues_write, 20450ae0cf1SKalle Valo .open = mac80211_open_file_generic 20550ae0cf1SKalle Valo }; 20650ae0cf1SKalle Valo 20750ae0cf1SKalle Valo static ssize_t uapsd_max_sp_len_read(struct file *file, char __user *user_buf, 20850ae0cf1SKalle Valo size_t count, loff_t *ppos) 20950ae0cf1SKalle Valo { 21050ae0cf1SKalle Valo struct ieee80211_local *local = file->private_data; 21150ae0cf1SKalle Valo int res; 21250ae0cf1SKalle Valo char buf[10]; 21350ae0cf1SKalle Valo 21450ae0cf1SKalle Valo res = scnprintf(buf, sizeof(buf), "0x%x\n", local->uapsd_max_sp_len); 21550ae0cf1SKalle Valo 21650ae0cf1SKalle Valo return simple_read_from_buffer(user_buf, count, ppos, buf, res); 21750ae0cf1SKalle Valo } 21850ae0cf1SKalle Valo 21950ae0cf1SKalle Valo static ssize_t uapsd_max_sp_len_write(struct file *file, 22050ae0cf1SKalle Valo const char __user *user_buf, 22150ae0cf1SKalle Valo size_t count, loff_t *ppos) 22250ae0cf1SKalle Valo { 22350ae0cf1SKalle Valo struct ieee80211_local *local = file->private_data; 22450ae0cf1SKalle Valo unsigned long val; 22550ae0cf1SKalle Valo char buf[10]; 22650ae0cf1SKalle Valo size_t len; 22750ae0cf1SKalle Valo int ret; 22850ae0cf1SKalle Valo 22950ae0cf1SKalle Valo len = min(count, sizeof(buf) - 1); 23050ae0cf1SKalle Valo if (copy_from_user(buf, user_buf, len)) 23150ae0cf1SKalle Valo return -EFAULT; 23250ae0cf1SKalle Valo buf[len] = '\0'; 23350ae0cf1SKalle Valo 23450ae0cf1SKalle Valo ret = strict_strtoul(buf, 0, &val); 23550ae0cf1SKalle Valo 23650ae0cf1SKalle Valo if (ret) 23750ae0cf1SKalle Valo return -EINVAL; 23850ae0cf1SKalle Valo 23950ae0cf1SKalle Valo if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK) 24050ae0cf1SKalle Valo return -ERANGE; 24150ae0cf1SKalle Valo 24250ae0cf1SKalle Valo local->uapsd_max_sp_len = val; 24350ae0cf1SKalle Valo 24450ae0cf1SKalle Valo return count; 24550ae0cf1SKalle Valo } 24650ae0cf1SKalle Valo 24750ae0cf1SKalle Valo static const struct file_operations uapsd_max_sp_len_ops = { 24850ae0cf1SKalle Valo .read = uapsd_max_sp_len_read, 24950ae0cf1SKalle Valo .write = uapsd_max_sp_len_write, 25050ae0cf1SKalle Valo .open = mac80211_open_file_generic 25150ae0cf1SKalle Valo }; 25250ae0cf1SKalle Valo 253*199d69f2SBenoit Papillault static ssize_t channel_type_read(struct file *file, char __user *user_buf, 254*199d69f2SBenoit Papillault size_t count, loff_t *ppos) 255*199d69f2SBenoit Papillault { 256*199d69f2SBenoit Papillault struct ieee80211_local *local = file->private_data; 257*199d69f2SBenoit Papillault const char *buf; 258*199d69f2SBenoit Papillault 259*199d69f2SBenoit Papillault switch (local->hw.conf.channel_type) { 260*199d69f2SBenoit Papillault case NL80211_CHAN_NO_HT: 261*199d69f2SBenoit Papillault buf = "no ht\n"; 262*199d69f2SBenoit Papillault break; 263*199d69f2SBenoit Papillault case NL80211_CHAN_HT20: 264*199d69f2SBenoit Papillault buf = "ht20\n"; 265*199d69f2SBenoit Papillault break; 266*199d69f2SBenoit Papillault case NL80211_CHAN_HT40MINUS: 267*199d69f2SBenoit Papillault buf = "ht40-\n"; 268*199d69f2SBenoit Papillault break; 269*199d69f2SBenoit Papillault case NL80211_CHAN_HT40PLUS: 270*199d69f2SBenoit Papillault buf = "ht40+\n"; 271*199d69f2SBenoit Papillault break; 272*199d69f2SBenoit Papillault default: 273*199d69f2SBenoit Papillault buf = "???"; 274*199d69f2SBenoit Papillault break; 275*199d69f2SBenoit Papillault } 276*199d69f2SBenoit Papillault 277*199d69f2SBenoit Papillault return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); 278*199d69f2SBenoit Papillault } 279*199d69f2SBenoit Papillault 280*199d69f2SBenoit Papillault static const struct file_operations channel_type_ops = { 281*199d69f2SBenoit Papillault .read = channel_type_read, 282*199d69f2SBenoit Papillault .open = mac80211_open_file_generic 283*199d69f2SBenoit Papillault }; 284*199d69f2SBenoit Papillault 285db2e6bd4SJohannes Berg static ssize_t queues_read(struct file *file, char __user *user_buf, 286db2e6bd4SJohannes Berg size_t count, loff_t *ppos) 287db2e6bd4SJohannes Berg { 288db2e6bd4SJohannes Berg struct ieee80211_local *local = file->private_data; 289db2e6bd4SJohannes Berg unsigned long flags; 290db2e6bd4SJohannes Berg char buf[IEEE80211_MAX_QUEUES * 20]; 291db2e6bd4SJohannes Berg int q, res = 0; 292db2e6bd4SJohannes Berg 293db2e6bd4SJohannes Berg spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 294db2e6bd4SJohannes Berg for (q = 0; q < local->hw.queues; q++) 295db2e6bd4SJohannes Berg res += sprintf(buf + res, "%02d: %#.8lx/%d\n", q, 296db2e6bd4SJohannes Berg local->queue_stop_reasons[q], 2973b8d81e0SJohannes Berg skb_queue_len(&local->pending[q])); 298db2e6bd4SJohannes Berg spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 299db2e6bd4SJohannes Berg 300db2e6bd4SJohannes Berg return simple_read_from_buffer(user_buf, count, ppos, buf, res); 301db2e6bd4SJohannes Berg } 302db2e6bd4SJohannes Berg 303db2e6bd4SJohannes Berg static const struct file_operations queues_ops = { 304db2e6bd4SJohannes Berg .read = queues_read, 305db2e6bd4SJohannes Berg .open = mac80211_open_file_generic 306db2e6bd4SJohannes Berg }; 307db2e6bd4SJohannes Berg 308e9f207f0SJiri Benc /* statistics stuff */ 309e9f207f0SJiri Benc 310e9f207f0SJiri Benc #define DEBUGFS_STATS_FILE(name, buflen, fmt, value...) \ 311e9f207f0SJiri Benc DEBUGFS_READONLY_FILE(stats_ ##name, buflen, fmt, ##value) 312e9f207f0SJiri Benc 313e9f207f0SJiri Benc static ssize_t format_devstat_counter(struct ieee80211_local *local, 314e9f207f0SJiri Benc char __user *userbuf, 315e9f207f0SJiri Benc size_t count, loff_t *ppos, 316e9f207f0SJiri Benc int (*printvalue)(struct ieee80211_low_level_stats *stats, char *buf, 317e9f207f0SJiri Benc int buflen)) 318e9f207f0SJiri Benc { 319e9f207f0SJiri Benc struct ieee80211_low_level_stats stats; 320e9f207f0SJiri Benc char buf[20]; 321e9f207f0SJiri Benc int res; 322e9f207f0SJiri Benc 32375636525SJohannes Berg rtnl_lock(); 32424487981SJohannes Berg res = drv_get_stats(local, &stats); 325e9f207f0SJiri Benc rtnl_unlock(); 32624487981SJohannes Berg if (res) 32724487981SJohannes Berg return res; 328e9f207f0SJiri Benc res = printvalue(&stats, buf, sizeof(buf)); 329e9f207f0SJiri Benc return simple_read_from_buffer(userbuf, count, ppos, buf, res); 330e9f207f0SJiri Benc } 331e9f207f0SJiri Benc 332e9f207f0SJiri Benc #define DEBUGFS_DEVSTATS_FILE(name) \ 333e9f207f0SJiri Benc static int print_devstats_##name(struct ieee80211_low_level_stats *stats,\ 334e9f207f0SJiri Benc char *buf, int buflen) \ 335e9f207f0SJiri Benc { \ 336e9f207f0SJiri Benc return scnprintf(buf, buflen, "%u\n", stats->name); \ 337e9f207f0SJiri Benc } \ 338e9f207f0SJiri Benc static ssize_t stats_ ##name## _read(struct file *file, \ 339e9f207f0SJiri Benc char __user *userbuf, \ 340e9f207f0SJiri Benc size_t count, loff_t *ppos) \ 341e9f207f0SJiri Benc { \ 342e9f207f0SJiri Benc return format_devstat_counter(file->private_data, \ 343e9f207f0SJiri Benc userbuf, \ 344e9f207f0SJiri Benc count, \ 345e9f207f0SJiri Benc ppos, \ 346e9f207f0SJiri Benc print_devstats_##name); \ 347e9f207f0SJiri Benc } \ 348e9f207f0SJiri Benc \ 349e9f207f0SJiri Benc static const struct file_operations stats_ ##name## _ops = { \ 350e9f207f0SJiri Benc .read = stats_ ##name## _read, \ 351e9f207f0SJiri Benc .open = mac80211_open_file_generic, \ 352e9f207f0SJiri Benc }; 353e9f207f0SJiri Benc 354e9f207f0SJiri Benc #define DEBUGFS_STATS_ADD(name) \ 3557bcfaf2fSJohannes Berg debugfs_create_file(#name, 0400, statsd, local, &stats_ ##name## _ops); 356e9f207f0SJiri Benc 357e9f207f0SJiri Benc DEBUGFS_STATS_FILE(transmitted_fragment_count, 20, "%u", 358e9f207f0SJiri Benc local->dot11TransmittedFragmentCount); 359e9f207f0SJiri Benc DEBUGFS_STATS_FILE(multicast_transmitted_frame_count, 20, "%u", 360e9f207f0SJiri Benc local->dot11MulticastTransmittedFrameCount); 361e9f207f0SJiri Benc DEBUGFS_STATS_FILE(failed_count, 20, "%u", 362e9f207f0SJiri Benc local->dot11FailedCount); 363e9f207f0SJiri Benc DEBUGFS_STATS_FILE(retry_count, 20, "%u", 364e9f207f0SJiri Benc local->dot11RetryCount); 365e9f207f0SJiri Benc DEBUGFS_STATS_FILE(multiple_retry_count, 20, "%u", 366e9f207f0SJiri Benc local->dot11MultipleRetryCount); 367e9f207f0SJiri Benc DEBUGFS_STATS_FILE(frame_duplicate_count, 20, "%u", 368e9f207f0SJiri Benc local->dot11FrameDuplicateCount); 369e9f207f0SJiri Benc DEBUGFS_STATS_FILE(received_fragment_count, 20, "%u", 370e9f207f0SJiri Benc local->dot11ReceivedFragmentCount); 371e9f207f0SJiri Benc DEBUGFS_STATS_FILE(multicast_received_frame_count, 20, "%u", 372e9f207f0SJiri Benc local->dot11MulticastReceivedFrameCount); 373e9f207f0SJiri Benc DEBUGFS_STATS_FILE(transmitted_frame_count, 20, "%u", 374e9f207f0SJiri Benc local->dot11TransmittedFrameCount); 375e9f207f0SJiri Benc #ifdef CONFIG_MAC80211_DEBUG_COUNTERS 376e9f207f0SJiri Benc DEBUGFS_STATS_FILE(tx_handlers_drop, 20, "%u", 377e9f207f0SJiri Benc local->tx_handlers_drop); 378e9f207f0SJiri Benc DEBUGFS_STATS_FILE(tx_handlers_queued, 20, "%u", 379e9f207f0SJiri Benc local->tx_handlers_queued); 380e9f207f0SJiri Benc DEBUGFS_STATS_FILE(tx_handlers_drop_unencrypted, 20, "%u", 381e9f207f0SJiri Benc local->tx_handlers_drop_unencrypted); 382e9f207f0SJiri Benc DEBUGFS_STATS_FILE(tx_handlers_drop_fragment, 20, "%u", 383e9f207f0SJiri Benc local->tx_handlers_drop_fragment); 384e9f207f0SJiri Benc DEBUGFS_STATS_FILE(tx_handlers_drop_wep, 20, "%u", 385e9f207f0SJiri Benc local->tx_handlers_drop_wep); 386e9f207f0SJiri Benc DEBUGFS_STATS_FILE(tx_handlers_drop_not_assoc, 20, "%u", 387e9f207f0SJiri Benc local->tx_handlers_drop_not_assoc); 388e9f207f0SJiri Benc DEBUGFS_STATS_FILE(tx_handlers_drop_unauth_port, 20, "%u", 389e9f207f0SJiri Benc local->tx_handlers_drop_unauth_port); 390e9f207f0SJiri Benc DEBUGFS_STATS_FILE(rx_handlers_drop, 20, "%u", 391e9f207f0SJiri Benc local->rx_handlers_drop); 392e9f207f0SJiri Benc DEBUGFS_STATS_FILE(rx_handlers_queued, 20, "%u", 393e9f207f0SJiri Benc local->rx_handlers_queued); 394e9f207f0SJiri Benc DEBUGFS_STATS_FILE(rx_handlers_drop_nullfunc, 20, "%u", 395e9f207f0SJiri Benc local->rx_handlers_drop_nullfunc); 396e9f207f0SJiri Benc DEBUGFS_STATS_FILE(rx_handlers_drop_defrag, 20, "%u", 397e9f207f0SJiri Benc local->rx_handlers_drop_defrag); 398e9f207f0SJiri Benc DEBUGFS_STATS_FILE(rx_handlers_drop_short, 20, "%u", 399e9f207f0SJiri Benc local->rx_handlers_drop_short); 400e9f207f0SJiri Benc DEBUGFS_STATS_FILE(rx_handlers_drop_passive_scan, 20, "%u", 401e9f207f0SJiri Benc local->rx_handlers_drop_passive_scan); 402e9f207f0SJiri Benc DEBUGFS_STATS_FILE(tx_expand_skb_head, 20, "%u", 403e9f207f0SJiri Benc local->tx_expand_skb_head); 404e9f207f0SJiri Benc DEBUGFS_STATS_FILE(tx_expand_skb_head_cloned, 20, "%u", 405e9f207f0SJiri Benc local->tx_expand_skb_head_cloned); 406e9f207f0SJiri Benc DEBUGFS_STATS_FILE(rx_expand_skb_head, 20, "%u", 407e9f207f0SJiri Benc local->rx_expand_skb_head); 408e9f207f0SJiri Benc DEBUGFS_STATS_FILE(rx_expand_skb_head2, 20, "%u", 409e9f207f0SJiri Benc local->rx_expand_skb_head2); 410e9f207f0SJiri Benc DEBUGFS_STATS_FILE(rx_handlers_fragments, 20, "%u", 411e9f207f0SJiri Benc local->rx_handlers_fragments); 412e9f207f0SJiri Benc DEBUGFS_STATS_FILE(tx_status_drop, 20, "%u", 413e9f207f0SJiri Benc local->tx_status_drop); 414e9f207f0SJiri Benc 415e9f207f0SJiri Benc #endif 416e9f207f0SJiri Benc 417e9f207f0SJiri Benc DEBUGFS_DEVSTATS_FILE(dot11ACKFailureCount); 418e9f207f0SJiri Benc DEBUGFS_DEVSTATS_FILE(dot11RTSFailureCount); 419e9f207f0SJiri Benc DEBUGFS_DEVSTATS_FILE(dot11FCSErrorCount); 420e9f207f0SJiri Benc DEBUGFS_DEVSTATS_FILE(dot11RTSSuccessCount); 421e9f207f0SJiri Benc 422e9f207f0SJiri Benc 423e9f207f0SJiri Benc void debugfs_hw_add(struct ieee80211_local *local) 424e9f207f0SJiri Benc { 425e9f207f0SJiri Benc struct dentry *phyd = local->hw.wiphy->debugfsdir; 426e9f207f0SJiri Benc struct dentry *statsd; 427e9f207f0SJiri Benc 428e9f207f0SJiri Benc if (!phyd) 429e9f207f0SJiri Benc return; 430e9f207f0SJiri Benc 431e9f207f0SJiri Benc local->debugfs.stations = debugfs_create_dir("stations", phyd); 432e9f207f0SJiri Benc local->debugfs.keys = debugfs_create_dir("keys", phyd); 433e9f207f0SJiri Benc 434e9f207f0SJiri Benc DEBUGFS_ADD(frequency); 435e9f207f0SJiri Benc DEBUGFS_ADD(total_ps_buffered); 436e9f207f0SJiri Benc DEBUGFS_ADD(wep_iv); 437ae54c985SAlina Friedrichsen DEBUGFS_ADD(tsf); 438db2e6bd4SJohannes Berg DEBUGFS_ADD(queues); 439827b1fb4SJohannes Berg DEBUGFS_ADD_MODE(reset, 0200); 440d3707d99SJohannes Berg DEBUGFS_ADD(noack); 44150ae0cf1SKalle Valo DEBUGFS_ADD(uapsd_queues); 44250ae0cf1SKalle Valo DEBUGFS_ADD(uapsd_max_sp_len); 443*199d69f2SBenoit Papillault DEBUGFS_ADD(channel_type); 444e9f207f0SJiri Benc 445e9f207f0SJiri Benc statsd = debugfs_create_dir("statistics", phyd); 446e9f207f0SJiri Benc 447e9f207f0SJiri Benc /* if the dir failed, don't put all the other things into the root! */ 448e9f207f0SJiri Benc if (!statsd) 449e9f207f0SJiri Benc return; 450e9f207f0SJiri Benc 451e9f207f0SJiri Benc DEBUGFS_STATS_ADD(transmitted_fragment_count); 452e9f207f0SJiri Benc DEBUGFS_STATS_ADD(multicast_transmitted_frame_count); 453e9f207f0SJiri Benc DEBUGFS_STATS_ADD(failed_count); 454e9f207f0SJiri Benc DEBUGFS_STATS_ADD(retry_count); 455e9f207f0SJiri Benc DEBUGFS_STATS_ADD(multiple_retry_count); 456e9f207f0SJiri Benc DEBUGFS_STATS_ADD(frame_duplicate_count); 457e9f207f0SJiri Benc DEBUGFS_STATS_ADD(received_fragment_count); 458e9f207f0SJiri Benc DEBUGFS_STATS_ADD(multicast_received_frame_count); 459e9f207f0SJiri Benc DEBUGFS_STATS_ADD(transmitted_frame_count); 460e9f207f0SJiri Benc #ifdef CONFIG_MAC80211_DEBUG_COUNTERS 461e9f207f0SJiri Benc DEBUGFS_STATS_ADD(tx_handlers_drop); 462e9f207f0SJiri Benc DEBUGFS_STATS_ADD(tx_handlers_queued); 463e9f207f0SJiri Benc DEBUGFS_STATS_ADD(tx_handlers_drop_unencrypted); 464e9f207f0SJiri Benc DEBUGFS_STATS_ADD(tx_handlers_drop_fragment); 465e9f207f0SJiri Benc DEBUGFS_STATS_ADD(tx_handlers_drop_wep); 466e9f207f0SJiri Benc DEBUGFS_STATS_ADD(tx_handlers_drop_not_assoc); 467e9f207f0SJiri Benc DEBUGFS_STATS_ADD(tx_handlers_drop_unauth_port); 468e9f207f0SJiri Benc DEBUGFS_STATS_ADD(rx_handlers_drop); 469e9f207f0SJiri Benc DEBUGFS_STATS_ADD(rx_handlers_queued); 470e9f207f0SJiri Benc DEBUGFS_STATS_ADD(rx_handlers_drop_nullfunc); 471e9f207f0SJiri Benc DEBUGFS_STATS_ADD(rx_handlers_drop_defrag); 472e9f207f0SJiri Benc DEBUGFS_STATS_ADD(rx_handlers_drop_short); 473e9f207f0SJiri Benc DEBUGFS_STATS_ADD(rx_handlers_drop_passive_scan); 474e9f207f0SJiri Benc DEBUGFS_STATS_ADD(tx_expand_skb_head); 475e9f207f0SJiri Benc DEBUGFS_STATS_ADD(tx_expand_skb_head_cloned); 476e9f207f0SJiri Benc DEBUGFS_STATS_ADD(rx_expand_skb_head); 477e9f207f0SJiri Benc DEBUGFS_STATS_ADD(rx_expand_skb_head2); 478e9f207f0SJiri Benc DEBUGFS_STATS_ADD(rx_handlers_fragments); 479e9f207f0SJiri Benc DEBUGFS_STATS_ADD(tx_status_drop); 480e9f207f0SJiri Benc #endif 481e9f207f0SJiri Benc DEBUGFS_STATS_ADD(dot11ACKFailureCount); 482e9f207f0SJiri Benc DEBUGFS_STATS_ADD(dot11RTSFailureCount); 483e9f207f0SJiri Benc DEBUGFS_STATS_ADD(dot11FCSErrorCount); 484e9f207f0SJiri Benc DEBUGFS_STATS_ADD(dot11RTSSuccessCount); 485e9f207f0SJiri Benc } 486