17bcfaf2f431c09c51fe776fc06638b25d3b421c5Johannes Berg 2e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc/* 3e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc * mac80211 debugfs for wireless PHYs 4e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc * 5e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> 6d98ad83ee86e523cc00cbf425f456fbd14b4fdc4Johannes Berg * Copyright 2013-2014 Intel Mobile Communications GmbH 7e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc * 8e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc * GPLv2 9e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc * 10e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc */ 11e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc 12e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc#include <linux/debugfs.h> 13e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc#include <linux/rtnetlink.h> 14e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc#include "ieee80211_i.h" 152448798133d747ad339e57099e32a1d1e68aca1cJohannes Berg#include "driver-ops.h" 162c8dccc77420fb7433da5674818959d3499d35beJohannes Berg#include "rate.h" 17e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc#include "debugfs.h" 18e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc 1907caf9d6c9135ae25a760867f37aab90c1008380Eliad Peller#define DEBUGFS_FORMAT_BUFFER_SIZE 100 2007caf9d6c9135ae25a760867f37aab90c1008380Eliad Peller 21ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb#define TX_LATENCY_BIN_DELIMTER_C ',' 22ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb#define TX_LATENCY_BIN_DELIMTER_S "," 23ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb#define TX_LATENCY_BINS_DISABLED "enable(bins disabled)\n" 24ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb#define TX_LATENCY_DISABLED "disable\n" 25ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 26ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 27ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb/* 28ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb * Display if Tx latency statistics & bins are enabled/disabled 29ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb */ 30ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottliebstatic ssize_t sta_tx_latency_stat_read(struct file *file, 31ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb char __user *userbuf, 32ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb size_t count, loff_t *ppos) 33ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb{ 34ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb struct ieee80211_local *local = file->private_data; 35ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb struct ieee80211_tx_latency_bin_ranges *tx_latency; 36ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb char *buf; 37ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb int bufsz, i, ret; 38ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb int pos = 0; 39ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 40ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb rcu_read_lock(); 41ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 42ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb tx_latency = rcu_dereference(local->tx_latency); 43ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 44ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb if (tx_latency && tx_latency->n_ranges) { 45ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb bufsz = tx_latency->n_ranges * 15; 46ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb buf = kzalloc(bufsz, GFP_ATOMIC); 47ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb if (!buf) 48ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb goto err; 49ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 50ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb for (i = 0; i < tx_latency->n_ranges; i++) 51ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb pos += scnprintf(buf + pos, bufsz - pos, "%d,", 52ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb tx_latency->ranges[i]); 53ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb pos += scnprintf(buf + pos, bufsz - pos, "\n"); 54ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb } else if (tx_latency) { 55ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb bufsz = sizeof(TX_LATENCY_BINS_DISABLED) + 1; 56ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb buf = kzalloc(bufsz, GFP_ATOMIC); 57ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb if (!buf) 58ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb goto err; 59ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 60ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb pos += scnprintf(buf + pos, bufsz - pos, "%s\n", 61ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb TX_LATENCY_BINS_DISABLED); 62ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb } else { 63ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb bufsz = sizeof(TX_LATENCY_DISABLED) + 1; 64ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb buf = kzalloc(bufsz, GFP_ATOMIC); 65ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb if (!buf) 66ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb goto err; 67ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 68ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb pos += scnprintf(buf + pos, bufsz - pos, "%s\n", 69ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb TX_LATENCY_DISABLED); 70ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb } 71ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 72ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb rcu_read_unlock(); 73ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 74ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos); 75ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb kfree(buf); 76ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 77ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb return ret; 78ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieberr: 79ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb rcu_read_unlock(); 80ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb return -ENOMEM; 81ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb} 82ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 83ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb/* 84ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb * Receive input from user regarding Tx latency statistics 85ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb * The input should indicate if Tx latency statistics and bins are 86ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb * enabled/disabled. 87ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb * If bins are enabled input should indicate the amount of different bins and 88ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb * their ranges. Each bin will count how many Tx frames transmitted within the 89ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb * appropriate latency. 90ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb * Legal input is: 91ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb * a) "enable(bins disabled)" - to enable only general statistics 92ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb * b) "a,b,c,d,...z" - to enable general statistics and bins, where all are 93ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb * numbers and a < b < c < d.. < z 94ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb * c) "disable" - disable all statistics 95ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb * NOTE: must configure Tx latency statistics bins before stations connected. 96ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb */ 97ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 98ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottliebstatic ssize_t sta_tx_latency_stat_write(struct file *file, 99ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb const char __user *userbuf, 100ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb size_t count, loff_t *ppos) 101ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb{ 102ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb struct ieee80211_local *local = file->private_data; 103ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb char buf[128] = {}; 104ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb char *bins = buf; 105ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb char *token; 106ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb int buf_size, i, alloc_size; 107ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb int prev_bin = 0; 108ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb int n_ranges = 0; 109ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb int ret = count; 110ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb struct ieee80211_tx_latency_bin_ranges *tx_latency; 111ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 112ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb if (sizeof(buf) <= count) 113ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb return -EINVAL; 114ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb buf_size = count; 115ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb if (copy_from_user(buf, userbuf, buf_size)) 116ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb return -EFAULT; 117ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 118ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb mutex_lock(&local->sta_mtx); 119ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 120ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb /* cannot change config once we have stations */ 121ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb if (local->num_sta) 122ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb goto unlock; 123ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 124ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb tx_latency = 125ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb rcu_dereference_protected(local->tx_latency, 126ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb lockdep_is_held(&local->sta_mtx)); 127ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 128ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb /* disable Tx statistics */ 129ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb if (!strcmp(buf, TX_LATENCY_DISABLED)) { 130ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb if (!tx_latency) 131ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb goto unlock; 1320c2bef4621c5feb5bda9068c9964b2e9acf57017Monam Agarwal RCU_INIT_POINTER(local->tx_latency, NULL); 133ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb synchronize_rcu(); 134ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb kfree(tx_latency); 135ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb goto unlock; 136ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb } 137ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 138ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb /* Tx latency already enabled */ 139ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb if (tx_latency) 140ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb goto unlock; 141ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 142ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb if (strcmp(TX_LATENCY_BINS_DISABLED, buf)) { 143ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb /* check how many bins and between what ranges user requested */ 144ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb token = buf; 145ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb while (*token != '\0') { 146ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb if (*token == TX_LATENCY_BIN_DELIMTER_C) 147ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb n_ranges++; 148ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb token++; 149ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb } 150ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb n_ranges++; 151ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb } 152ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 153ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb alloc_size = sizeof(struct ieee80211_tx_latency_bin_ranges) + 154ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb n_ranges * sizeof(u32); 155ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb tx_latency = kzalloc(alloc_size, GFP_ATOMIC); 156ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb if (!tx_latency) { 157ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb ret = -ENOMEM; 158ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb goto unlock; 159ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb } 160ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb tx_latency->n_ranges = n_ranges; 161ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb for (i = 0; i < n_ranges; i++) { /* setting bin ranges */ 162ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb token = strsep(&bins, TX_LATENCY_BIN_DELIMTER_S); 163ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb sscanf(token, "%d", &tx_latency->ranges[i]); 164ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb /* bins values should be in ascending order */ 165ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb if (prev_bin >= tx_latency->ranges[i]) { 166ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb ret = -EINVAL; 167ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb kfree(tx_latency); 168ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb goto unlock; 169ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb } 170ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb prev_bin = tx_latency->ranges[i]; 171ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb } 172ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb rcu_assign_pointer(local->tx_latency, tx_latency); 173ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 174ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottliebunlock: 175ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb mutex_unlock(&local->sta_mtx); 176ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 177ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb return ret; 178ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb} 179ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 180ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottliebstatic const struct file_operations stats_tx_latency_ops = { 181ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb .write = sta_tx_latency_stat_write, 182ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb .read = sta_tx_latency_stat_read, 183ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb .open = simple_open, 184ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb .llseek = generic_file_llseek, 185ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb}; 186ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 18707caf9d6c9135ae25a760867f37aab90c1008380Eliad Pellerint mac80211_format_buffer(char __user *userbuf, size_t count, 18807caf9d6c9135ae25a760867f37aab90c1008380Eliad Peller loff_t *ppos, char *fmt, ...) 18907caf9d6c9135ae25a760867f37aab90c1008380Eliad Peller{ 19007caf9d6c9135ae25a760867f37aab90c1008380Eliad Peller va_list args; 19107caf9d6c9135ae25a760867f37aab90c1008380Eliad Peller char buf[DEBUGFS_FORMAT_BUFFER_SIZE]; 19207caf9d6c9135ae25a760867f37aab90c1008380Eliad Peller int res; 19307caf9d6c9135ae25a760867f37aab90c1008380Eliad Peller 19407caf9d6c9135ae25a760867f37aab90c1008380Eliad Peller va_start(args, fmt); 19507caf9d6c9135ae25a760867f37aab90c1008380Eliad Peller res = vscnprintf(buf, sizeof(buf), fmt, args); 19607caf9d6c9135ae25a760867f37aab90c1008380Eliad Peller va_end(args); 19707caf9d6c9135ae25a760867f37aab90c1008380Eliad Peller 19807caf9d6c9135ae25a760867f37aab90c1008380Eliad Peller return simple_read_from_buffer(userbuf, count, ppos, buf, res); 19907caf9d6c9135ae25a760867f37aab90c1008380Eliad Peller} 20007caf9d6c9135ae25a760867f37aab90c1008380Eliad Peller 201279daf64c01e391379060a6d30e9827cc0c56612Ben Greear#define DEBUGFS_READONLY_FILE_FN(name, fmt, value...) \ 202e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Bencstatic ssize_t name## _read(struct file *file, char __user *userbuf, \ 203e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc size_t count, loff_t *ppos) \ 204e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc{ \ 205e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc struct ieee80211_local *local = file->private_data; \ 206e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc \ 20707caf9d6c9135ae25a760867f37aab90c1008380Eliad Peller return mac80211_format_buffer(userbuf, count, ppos, \ 20807caf9d6c9135ae25a760867f37aab90c1008380Eliad Peller fmt "\n", ##value); \ 209279daf64c01e391379060a6d30e9827cc0c56612Ben Greear} 210279daf64c01e391379060a6d30e9827cc0c56612Ben Greear 211279daf64c01e391379060a6d30e9827cc0c56612Ben Greear#define DEBUGFS_READONLY_FILE_OPS(name) \ 212e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Bencstatic const struct file_operations name## _ops = { \ 213e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc .read = name## _read, \ 214234e340582901211f40d8c732afc49f0630ecf05Stephen Boyd .open = simple_open, \ 2152b18ab36cf7e956fb5b5ee12847e94fc66d496f4Arnd Bergmann .llseek = generic_file_llseek, \ 216e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc}; 217e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc 218279daf64c01e391379060a6d30e9827cc0c56612Ben Greear#define DEBUGFS_READONLY_FILE(name, fmt, value...) \ 219279daf64c01e391379060a6d30e9827cc0c56612Ben Greear DEBUGFS_READONLY_FILE_FN(name, fmt, value) \ 220279daf64c01e391379060a6d30e9827cc0c56612Ben Greear DEBUGFS_READONLY_FILE_OPS(name) 221279daf64c01e391379060a6d30e9827cc0c56612Ben Greear 222e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc#define DEBUGFS_ADD(name) \ 2237bcfaf2f431c09c51fe776fc06638b25d3b421c5Johannes Berg debugfs_create_file(#name, 0400, phyd, local, &name## _ops); 224e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc 225827b1fb44b7e41377a5498b9d070a11dfae2c283Johannes Berg#define DEBUGFS_ADD_MODE(name, mode) \ 2267bcfaf2f431c09c51fe776fc06638b25d3b421c5Johannes Berg debugfs_create_file(#name, mode, phyd, local, &name## _ops); 227e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc 228e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc 22983bdf2a17279bd6ee3d0f5c0f086ebe06644109dBen GreearDEBUGFS_READONLY_FILE(user_power, "%d", 23083bdf2a17279bd6ee3d0f5c0f086ebe06644109dBen Greear local->user_power_level); 23183bdf2a17279bd6ee3d0f5c0f086ebe06644109dBen GreearDEBUGFS_READONLY_FILE(power, "%d", 23283bdf2a17279bd6ee3d0f5c0f086ebe06644109dBen Greear local->hw.conf.power_level); 23307caf9d6c9135ae25a760867f37aab90c1008380Eliad PellerDEBUGFS_READONLY_FILE(total_ps_buffered, "%d", 234e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc local->total_ps_buffered); 23507caf9d6c9135ae25a760867f37aab90c1008380Eliad PellerDEBUGFS_READONLY_FILE(wep_iv, "%#08x", 236e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc local->wep_iv & 0xffffff); 23707caf9d6c9135ae25a760867f37aab90c1008380Eliad PellerDEBUGFS_READONLY_FILE(rate_ctrl_alg, "%s", 238af65cd96dd4ea8ea5adc6ee850e61a407cd1067aJohannes Berg local->rate_ctrl ? local->rate_ctrl->ops->name : "hw/driver"); 2393b5d665b51cda73ef1a774b515afd879a38e3674Alina Friedrichsen 2402ad4814fb6ddc78ec17079b5dec9e2cd313a944cJohannes Berg#ifdef CONFIG_PM 241827b1fb44b7e41377a5498b9d070a11dfae2c283Johannes Bergstatic ssize_t reset_write(struct file *file, const char __user *user_buf, 242827b1fb44b7e41377a5498b9d070a11dfae2c283Johannes Berg size_t count, loff_t *ppos) 243827b1fb44b7e41377a5498b9d070a11dfae2c283Johannes Berg{ 244827b1fb44b7e41377a5498b9d070a11dfae2c283Johannes Berg struct ieee80211_local *local = file->private_data; 245827b1fb44b7e41377a5498b9d070a11dfae2c283Johannes Berg 246827b1fb44b7e41377a5498b9d070a11dfae2c283Johannes Berg rtnl_lock(); 247eecc48000afe2ca6da22122d553b7cad294e42fcJohannes Berg __ieee80211_suspend(&local->hw, NULL); 248827b1fb44b7e41377a5498b9d070a11dfae2c283Johannes Berg __ieee80211_resume(&local->hw); 249827b1fb44b7e41377a5498b9d070a11dfae2c283Johannes Berg rtnl_unlock(); 250827b1fb44b7e41377a5498b9d070a11dfae2c283Johannes Berg 251827b1fb44b7e41377a5498b9d070a11dfae2c283Johannes Berg return count; 252827b1fb44b7e41377a5498b9d070a11dfae2c283Johannes Berg} 253827b1fb44b7e41377a5498b9d070a11dfae2c283Johannes Berg 254827b1fb44b7e41377a5498b9d070a11dfae2c283Johannes Bergstatic const struct file_operations reset_ops = { 255827b1fb44b7e41377a5498b9d070a11dfae2c283Johannes Berg .write = reset_write, 256234e340582901211f40d8c732afc49f0630ecf05Stephen Boyd .open = simple_open, 2576038f373a3dc1f1c26496e60b6c40b164716f07eArnd Bergmann .llseek = noop_llseek, 258827b1fb44b7e41377a5498b9d070a11dfae2c283Johannes Berg}; 2592ad4814fb6ddc78ec17079b5dec9e2cd313a944cJohannes Berg#endif 260827b1fb44b7e41377a5498b9d070a11dfae2c283Johannes Berg 261279daf64c01e391379060a6d30e9827cc0c56612Ben Greearstatic ssize_t hwflags_read(struct file *file, char __user *user_buf, 262279daf64c01e391379060a6d30e9827cc0c56612Ben Greear size_t count, loff_t *ppos) 263279daf64c01e391379060a6d30e9827cc0c56612Ben Greear{ 264279daf64c01e391379060a6d30e9827cc0c56612Ben Greear struct ieee80211_local *local = file->private_data; 265279daf64c01e391379060a6d30e9827cc0c56612Ben Greear int mxln = 500; 266279daf64c01e391379060a6d30e9827cc0c56612Ben Greear ssize_t rv; 267279daf64c01e391379060a6d30e9827cc0c56612Ben Greear char *buf = kzalloc(mxln, GFP_KERNEL); 268279daf64c01e391379060a6d30e9827cc0c56612Ben Greear int sf = 0; /* how many written so far */ 269279daf64c01e391379060a6d30e9827cc0c56612Ben Greear 270d15b84590a1d2ec021ada00a0e67ee5851a0ea2bJoe Perches if (!buf) 271d15b84590a1d2ec021ada00a0e67ee5851a0ea2bJoe Perches return 0; 272d15b84590a1d2ec021ada00a0e67ee5851a0ea2bJoe Perches 273f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller sf += scnprintf(buf, mxln - sf, "0x%x\n", local->hw.flags); 274279daf64c01e391379060a6d30e9827cc0c56612Ben Greear if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) 275f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller sf += scnprintf(buf + sf, mxln - sf, "HAS_RATE_CONTROL\n"); 276279daf64c01e391379060a6d30e9827cc0c56612Ben Greear if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) 277f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller sf += scnprintf(buf + sf, mxln - sf, "RX_INCLUDES_FCS\n"); 278279daf64c01e391379060a6d30e9827cc0c56612Ben Greear if (local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING) 279f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller sf += scnprintf(buf + sf, mxln - sf, 280f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller "HOST_BCAST_PS_BUFFERING\n"); 281279daf64c01e391379060a6d30e9827cc0c56612Ben Greear if (local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE) 282f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller sf += scnprintf(buf + sf, mxln - sf, 283f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller "2GHZ_SHORT_SLOT_INCAPABLE\n"); 284279daf64c01e391379060a6d30e9827cc0c56612Ben Greear if (local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE) 285f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller sf += scnprintf(buf + sf, mxln - sf, 286f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller "2GHZ_SHORT_PREAMBLE_INCAPABLE\n"); 287279daf64c01e391379060a6d30e9827cc0c56612Ben Greear if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) 288f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller sf += scnprintf(buf + sf, mxln - sf, "SIGNAL_UNSPEC\n"); 289279daf64c01e391379060a6d30e9827cc0c56612Ben Greear if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) 290f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller sf += scnprintf(buf + sf, mxln - sf, "SIGNAL_DBM\n"); 291c65dd1477b6fe5971489dd8b6e28a07ec277fdd6Emmanuel Grumbach if (local->hw.flags & IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC) 292f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller sf += scnprintf(buf + sf, mxln - sf, 293f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller "NEED_DTIM_BEFORE_ASSOC\n"); 294279daf64c01e391379060a6d30e9827cc0c56612Ben Greear if (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT) 295f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller sf += scnprintf(buf + sf, mxln - sf, "SPECTRUM_MGMT\n"); 296279daf64c01e391379060a6d30e9827cc0c56612Ben Greear if (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION) 297f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller sf += scnprintf(buf + sf, mxln - sf, "AMPDU_AGGREGATION\n"); 298279daf64c01e391379060a6d30e9827cc0c56612Ben Greear if (local->hw.flags & IEEE80211_HW_SUPPORTS_PS) 299f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller sf += scnprintf(buf + sf, mxln - sf, "SUPPORTS_PS\n"); 300279daf64c01e391379060a6d30e9827cc0c56612Ben Greear if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) 301f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller sf += scnprintf(buf + sf, mxln - sf, "PS_NULLFUNC_STACK\n"); 302279daf64c01e391379060a6d30e9827cc0c56612Ben Greear if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) 303f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller sf += scnprintf(buf + sf, mxln - sf, "SUPPORTS_DYNAMIC_PS\n"); 304279daf64c01e391379060a6d30e9827cc0c56612Ben Greear if (local->hw.flags & IEEE80211_HW_MFP_CAPABLE) 305f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller sf += scnprintf(buf + sf, mxln - sf, "MFP_CAPABLE\n"); 306279daf64c01e391379060a6d30e9827cc0c56612Ben Greear if (local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD) 307f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller sf += scnprintf(buf + sf, mxln - sf, "SUPPORTS_UAPSD\n"); 308279daf64c01e391379060a6d30e9827cc0c56612Ben Greear if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) 309f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller sf += scnprintf(buf + sf, mxln - sf, 310f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller "REPORTS_TX_ACK_STATUS\n"); 311279daf64c01e391379060a6d30e9827cc0c56612Ben Greear if (local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) 312f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller sf += scnprintf(buf + sf, mxln - sf, "CONNECTION_MONITOR\n"); 313279daf64c01e391379060a6d30e9827cc0c56612Ben Greear if (local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK) 314f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller sf += scnprintf(buf + sf, mxln - sf, "SUPPORTS_PER_STA_GTK\n"); 315279daf64c01e391379060a6d30e9827cc0c56612Ben Greear if (local->hw.flags & IEEE80211_HW_AP_LINK_PS) 316f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller sf += scnprintf(buf + sf, mxln - sf, "AP_LINK_PS\n"); 317edf6b784c0e574696915e7b04fe42158f3112d0dArik Nemtsov if (local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW) 318f364ef99a8e82ee27933d6a0cf5cc1f27e9f0df9Eliad Peller sf += scnprintf(buf + sf, mxln - sf, "TX_AMPDU_SETUP_IN_HW\n"); 319279daf64c01e391379060a6d30e9827cc0c56612Ben Greear 320279daf64c01e391379060a6d30e9827cc0c56612Ben Greear rv = simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); 321279daf64c01e391379060a6d30e9827cc0c56612Ben Greear kfree(buf); 322279daf64c01e391379060a6d30e9827cc0c56612Ben Greear return rv; 323279daf64c01e391379060a6d30e9827cc0c56612Ben Greear} 324199d69f27326858b16449eb1cc1623299db64415Benoit Papillault 325db2e6bd4e966a36c6b2f1921feb3537e8254415cJohannes Bergstatic ssize_t queues_read(struct file *file, char __user *user_buf, 326db2e6bd4e966a36c6b2f1921feb3537e8254415cJohannes Berg size_t count, loff_t *ppos) 327db2e6bd4e966a36c6b2f1921feb3537e8254415cJohannes Berg{ 328db2e6bd4e966a36c6b2f1921feb3537e8254415cJohannes Berg struct ieee80211_local *local = file->private_data; 329db2e6bd4e966a36c6b2f1921feb3537e8254415cJohannes Berg unsigned long flags; 330db2e6bd4e966a36c6b2f1921feb3537e8254415cJohannes Berg char buf[IEEE80211_MAX_QUEUES * 20]; 331db2e6bd4e966a36c6b2f1921feb3537e8254415cJohannes Berg int q, res = 0; 332db2e6bd4e966a36c6b2f1921feb3537e8254415cJohannes Berg 333db2e6bd4e966a36c6b2f1921feb3537e8254415cJohannes Berg spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 334db2e6bd4e966a36c6b2f1921feb3537e8254415cJohannes Berg for (q = 0; q < local->hw.queues; q++) 335db2e6bd4e966a36c6b2f1921feb3537e8254415cJohannes Berg res += sprintf(buf + res, "%02d: %#.8lx/%d\n", q, 336db2e6bd4e966a36c6b2f1921feb3537e8254415cJohannes Berg local->queue_stop_reasons[q], 3373b8d81e020f77c9da8b85b0685c8cd2ca7c7b150Johannes Berg skb_queue_len(&local->pending[q])); 338db2e6bd4e966a36c6b2f1921feb3537e8254415cJohannes Berg spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 339db2e6bd4e966a36c6b2f1921feb3537e8254415cJohannes Berg 340db2e6bd4e966a36c6b2f1921feb3537e8254415cJohannes Berg return simple_read_from_buffer(user_buf, count, ppos, buf, res); 341db2e6bd4e966a36c6b2f1921feb3537e8254415cJohannes Berg} 342db2e6bd4e966a36c6b2f1921feb3537e8254415cJohannes Berg 343279daf64c01e391379060a6d30e9827cc0c56612Ben GreearDEBUGFS_READONLY_FILE_OPS(hwflags); 344279daf64c01e391379060a6d30e9827cc0c56612Ben GreearDEBUGFS_READONLY_FILE_OPS(queues); 345db2e6bd4e966a36c6b2f1921feb3537e8254415cJohannes Berg 346e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc/* statistics stuff */ 347e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc 348e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Bencstatic ssize_t format_devstat_counter(struct ieee80211_local *local, 349e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc char __user *userbuf, 350e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc size_t count, loff_t *ppos, 351e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc int (*printvalue)(struct ieee80211_low_level_stats *stats, char *buf, 352e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc int buflen)) 353e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc{ 354e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc struct ieee80211_low_level_stats stats; 355e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc char buf[20]; 356e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc int res; 357e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc 35875636525fbfa78fa33fd754c89785cfde750acd3Johannes Berg rtnl_lock(); 3592448798133d747ad339e57099e32a1d1e68aca1cJohannes Berg res = drv_get_stats(local, &stats); 360e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc rtnl_unlock(); 3612448798133d747ad339e57099e32a1d1e68aca1cJohannes Berg if (res) 3622448798133d747ad339e57099e32a1d1e68aca1cJohannes Berg return res; 3632448798133d747ad339e57099e32a1d1e68aca1cJohannes Berg res = printvalue(&stats, buf, sizeof(buf)); 364e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc return simple_read_from_buffer(userbuf, count, ppos, buf, res); 365e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc} 366e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc 367e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc#define DEBUGFS_DEVSTATS_FILE(name) \ 368e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Bencstatic int print_devstats_##name(struct ieee80211_low_level_stats *stats,\ 369e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc char *buf, int buflen) \ 370e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc{ \ 371e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc return scnprintf(buf, buflen, "%u\n", stats->name); \ 372e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc} \ 373e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Bencstatic ssize_t stats_ ##name## _read(struct file *file, \ 374e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc char __user *userbuf, \ 375e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc size_t count, loff_t *ppos) \ 376e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc{ \ 377e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc return format_devstat_counter(file->private_data, \ 378e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc userbuf, \ 379e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc count, \ 380e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc ppos, \ 381e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc print_devstats_##name); \ 382e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc} \ 383e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc \ 384e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Bencstatic const struct file_operations stats_ ##name## _ops = { \ 385e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc .read = stats_ ##name## _read, \ 386234e340582901211f40d8c732afc49f0630ecf05Stephen Boyd .open = simple_open, \ 3872b18ab36cf7e956fb5b5ee12847e94fc66d496f4Arnd Bergmann .llseek = generic_file_llseek, \ 388e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc}; 389e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc 3902826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau#define DEBUGFS_STATS_ADD(name, field) \ 3912826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau debugfs_create_u32(#name, 0400, statsd, (u32 *) &field); 3922826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau#define DEBUGFS_DEVSTATS_ADD(name) \ 3937bcfaf2f431c09c51fe776fc06638b25d3b421c5Johannes Berg debugfs_create_file(#name, 0400, statsd, local, &stats_ ##name## _ops); 394e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc 395e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri BencDEBUGFS_DEVSTATS_FILE(dot11ACKFailureCount); 396e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri BencDEBUGFS_DEVSTATS_FILE(dot11RTSFailureCount); 397e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri BencDEBUGFS_DEVSTATS_FILE(dot11FCSErrorCount); 398e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri BencDEBUGFS_DEVSTATS_FILE(dot11RTSSuccessCount); 399e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc 400e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Bencvoid debugfs_hw_add(struct ieee80211_local *local) 401e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc{ 402e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc struct dentry *phyd = local->hw.wiphy->debugfsdir; 403e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc struct dentry *statsd; 404e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc 405e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc if (!phyd) 406e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc return; 407e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc 408e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc local->debugfs.keys = debugfs_create_dir("keys", phyd); 409e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc 410e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc DEBUGFS_ADD(total_ps_buffered); 411e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc DEBUGFS_ADD(wep_iv); 412db2e6bd4e966a36c6b2f1921feb3537e8254415cJohannes Berg DEBUGFS_ADD(queues); 4132ad4814fb6ddc78ec17079b5dec9e2cd313a944cJohannes Berg#ifdef CONFIG_PM 414827b1fb44b7e41377a5498b9d070a11dfae2c283Johannes Berg DEBUGFS_ADD_MODE(reset, 0200); 4152ad4814fb6ddc78ec17079b5dec9e2cd313a944cJohannes Berg#endif 416279daf64c01e391379060a6d30e9827cc0c56612Ben Greear DEBUGFS_ADD(hwflags); 41783bdf2a17279bd6ee3d0f5c0f086ebe06644109dBen Greear DEBUGFS_ADD(user_power); 41883bdf2a17279bd6ee3d0f5c0f086ebe06644109dBen Greear DEBUGFS_ADD(power); 419e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc 420e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc statsd = debugfs_create_dir("statistics", phyd); 421e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc 422e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc /* if the dir failed, don't put all the other things into the root! */ 423e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc if (!statsd) 424e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc return; 425e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc 4262826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(transmitted_fragment_count, 4272826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau local->dot11TransmittedFragmentCount); 4282826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(multicast_transmitted_frame_count, 4292826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau local->dot11MulticastTransmittedFrameCount); 4302826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(failed_count, local->dot11FailedCount); 4312826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(retry_count, local->dot11RetryCount); 4322826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(multiple_retry_count, 4332826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau local->dot11MultipleRetryCount); 4342826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(frame_duplicate_count, 4352826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau local->dot11FrameDuplicateCount); 4362826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(received_fragment_count, 4372826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau local->dot11ReceivedFragmentCount); 4382826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(multicast_received_frame_count, 4392826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau local->dot11MulticastReceivedFrameCount); 4402826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(transmitted_frame_count, 4412826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau local->dot11TransmittedFrameCount); 442e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc#ifdef CONFIG_MAC80211_DEBUG_COUNTERS 4432826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(tx_handlers_drop, local->tx_handlers_drop); 4442826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(tx_handlers_queued, local->tx_handlers_queued); 4452826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(tx_handlers_drop_unencrypted, 4462826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau local->tx_handlers_drop_unencrypted); 4472826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(tx_handlers_drop_fragment, 4482826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau local->tx_handlers_drop_fragment); 4492826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(tx_handlers_drop_wep, 4502826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau local->tx_handlers_drop_wep); 4512826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(tx_handlers_drop_not_assoc, 4522826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau local->tx_handlers_drop_not_assoc); 4532826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(tx_handlers_drop_unauth_port, 4542826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau local->tx_handlers_drop_unauth_port); 4552826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(rx_handlers_drop, local->rx_handlers_drop); 4562826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(rx_handlers_queued, local->rx_handlers_queued); 4572826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(rx_handlers_drop_nullfunc, 4582826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau local->rx_handlers_drop_nullfunc); 4592826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(rx_handlers_drop_defrag, 4602826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau local->rx_handlers_drop_defrag); 4612826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(rx_handlers_drop_short, 4622826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau local->rx_handlers_drop_short); 4632826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(tx_expand_skb_head, 4642826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau local->tx_expand_skb_head); 4652826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(tx_expand_skb_head_cloned, 4662826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau local->tx_expand_skb_head_cloned); 4672826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(rx_expand_skb_head, 4682826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau local->rx_expand_skb_head); 4692826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(rx_expand_skb_head2, 4702826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau local->rx_expand_skb_head2); 4712826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(rx_handlers_fragments, 4722826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau local->rx_handlers_fragments); 4732826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_STATS_ADD(tx_status_drop, 4742826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau local->tx_status_drop); 475e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc#endif 4762826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_DEVSTATS_ADD(dot11ACKFailureCount); 4772826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_DEVSTATS_ADD(dot11RTSFailureCount); 4782826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_DEVSTATS_ADD(dot11FCSErrorCount); 4792826bcd844e05dcbef9b9284bddb7fe88e8d314fFelix Fietkau DEBUGFS_DEVSTATS_ADD(dot11RTSSuccessCount); 480ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb 481ad38bfc916da6aee9160bfa5335aed8d6c190e39Matti Gottlieb DEBUGFS_DEVSTATS_ADD(tx_latency); 482e9f207f0ff90bf60b825800d7450e6f2ff2eab88Jiri Benc} 483