linux/net/mac80211/debugfs_sta.c
<<
>>
Prefs
   1/*
   2 * Copyright 2003-2005  Devicescape Software, Inc.
   3 * Copyright (c) 2006   Jiri Benc <jbenc@suse.cz>
   4 * Copyright 2007       Johannes Berg <johannes@sipsolutions.net>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 */
  10
  11#include <linux/debugfs.h>
  12#include <linux/ieee80211.h>
  13#include "ieee80211_i.h"
  14#include "debugfs.h"
  15#include "debugfs_sta.h"
  16#include "sta_info.h"
  17
  18/* sta attributtes */
  19
  20#define STA_READ(name, buflen, field, format_string)                    \
  21static ssize_t sta_ ##name## _read(struct file *file,                   \
  22                                   char __user *userbuf,                \
  23                                   size_t count, loff_t *ppos)          \
  24{                                                                       \
  25        int res;                                                        \
  26        struct sta_info *sta = file->private_data;                      \
  27        char buf[buflen];                                               \
  28        res = scnprintf(buf, buflen, format_string, sta->field);        \
  29        return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
  30}
  31#define STA_READ_D(name, field) STA_READ(name, 20, field, "%d\n")
  32#define STA_READ_U(name, field) STA_READ(name, 20, field, "%u\n")
  33#define STA_READ_LU(name, field) STA_READ(name, 20, field, "%lu\n")
  34#define STA_READ_S(name, field) STA_READ(name, 20, field, "%s\n")
  35
  36#define STA_READ_RATE(name, field)                                      \
  37static ssize_t sta_##name##_read(struct file *file,                     \
  38                                 char __user *userbuf,                  \
  39                                 size_t count, loff_t *ppos)            \
  40{                                                                       \
  41        struct sta_info *sta = file->private_data;                      \
  42        struct ieee80211_local *local = wdev_priv(sta->dev->ieee80211_ptr);\
  43        struct ieee80211_hw_mode *mode = local->oper_hw_mode;           \
  44        char buf[20];                                                   \
  45        int res = scnprintf(buf, sizeof(buf), "%d\n",                   \
  46                            (sta->field >= 0 &&                         \
  47                            sta->field < mode->num_rates) ?             \
  48                            mode->rates[sta->field].rate : -1);         \
  49        return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
  50}
  51
  52#define STA_OPS(name)                                                   \
  53static const struct file_operations sta_ ##name## _ops = {              \
  54        .read = sta_##name##_read,                                      \
  55        .open = mac80211_open_file_generic,                             \
  56}
  57
  58#define STA_FILE(name, field, format)                                   \
  59                STA_READ_##format(name, field)                          \
  60                STA_OPS(name)
  61
  62STA_FILE(aid, aid, D);
  63STA_FILE(dev, dev->name, S);
  64STA_FILE(rx_packets, rx_packets, LU);
  65STA_FILE(tx_packets, tx_packets, LU);
  66STA_FILE(rx_bytes, rx_bytes, LU);
  67STA_FILE(tx_bytes, tx_bytes, LU);
  68STA_FILE(rx_duplicates, num_duplicates, LU);
  69STA_FILE(rx_fragments, rx_fragments, LU);
  70STA_FILE(rx_dropped, rx_dropped, LU);
  71STA_FILE(tx_fragments, tx_fragments, LU);
  72STA_FILE(tx_filtered, tx_filtered_count, LU);
  73STA_FILE(txrate, txrate, RATE);
  74STA_FILE(last_txrate, last_txrate, RATE);
  75STA_FILE(tx_retry_failed, tx_retry_failed, LU);
  76STA_FILE(tx_retry_count, tx_retry_count, LU);
  77STA_FILE(last_rssi, last_rssi, D);
  78STA_FILE(last_signal, last_signal, D);
  79STA_FILE(last_noise, last_noise, D);
  80STA_FILE(channel_use, channel_use, D);
  81STA_FILE(wep_weak_iv_count, wep_weak_iv_count, D);
  82
  83static ssize_t sta_flags_read(struct file *file, char __user *userbuf,
  84                              size_t count, loff_t *ppos)
  85{
  86        char buf[100];
  87        struct sta_info *sta = file->private_data;
  88        int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s",
  89                sta->flags & WLAN_STA_AUTH ? "AUTH\n" : "",
  90                sta->flags & WLAN_STA_ASSOC ? "ASSOC\n" : "",
  91                sta->flags & WLAN_STA_PS ? "PS\n" : "",
  92                sta->flags & WLAN_STA_TIM ? "TIM\n" : "",
  93                sta->flags & WLAN_STA_PERM ? "PERM\n" : "",
  94                sta->flags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "",
  95                sta->flags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "",
  96                sta->flags & WLAN_STA_WME ? "WME\n" : "",
  97                sta->flags & WLAN_STA_WDS ? "WDS\n" : "");
  98        return simple_read_from_buffer(userbuf, count, ppos, buf, res);
  99}
 100STA_OPS(flags);
 101
 102static ssize_t sta_num_ps_buf_frames_read(struct file *file,
 103                                          char __user *userbuf,
 104                                          size_t count, loff_t *ppos)
 105{
 106        char buf[20];
 107        struct sta_info *sta = file->private_data;
 108        int res = scnprintf(buf, sizeof(buf), "%u\n",
 109                            skb_queue_len(&sta->ps_tx_buf));
 110        return simple_read_from_buffer(userbuf, count, ppos, buf, res);
 111}
 112STA_OPS(num_ps_buf_frames);
 113
 114static ssize_t sta_last_ack_rssi_read(struct file *file, char __user *userbuf,
 115                                      size_t count, loff_t *ppos)
 116{
 117        char buf[100];
 118        struct sta_info *sta = file->private_data;
 119        int res = scnprintf(buf, sizeof(buf), "%d %d %d\n",
 120                            sta->last_ack_rssi[0],
 121                            sta->last_ack_rssi[1],
 122                            sta->last_ack_rssi[2]);
 123        return simple_read_from_buffer(userbuf, count, ppos, buf, res);
 124}
 125STA_OPS(last_ack_rssi);
 126
 127static ssize_t sta_last_ack_ms_read(struct file *file, char __user *userbuf,
 128                                    size_t count, loff_t *ppos)
 129{
 130        char buf[20];
 131        struct sta_info *sta = file->private_data;
 132        int res = scnprintf(buf, sizeof(buf), "%d\n",
 133                            sta->last_ack ?
 134                            jiffies_to_msecs(jiffies - sta->last_ack) : -1);
 135        return simple_read_from_buffer(userbuf, count, ppos, buf, res);
 136}
 137STA_OPS(last_ack_ms);
 138
 139static ssize_t sta_inactive_ms_read(struct file *file, char __user *userbuf,
 140                                    size_t count, loff_t *ppos)
 141{
 142        char buf[20];
 143        struct sta_info *sta = file->private_data;
 144        int res = scnprintf(buf, sizeof(buf), "%d\n",
 145                            jiffies_to_msecs(jiffies - sta->last_rx));
 146        return simple_read_from_buffer(userbuf, count, ppos, buf, res);
 147}
 148STA_OPS(inactive_ms);
 149
 150static ssize_t sta_last_seq_ctrl_read(struct file *file, char __user *userbuf,
 151                                      size_t count, loff_t *ppos)
 152{
 153        char buf[15*NUM_RX_DATA_QUEUES], *p = buf;
 154        int i;
 155        struct sta_info *sta = file->private_data;
 156        for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
 157                p += scnprintf(p, sizeof(buf)+buf-p, "%x ",
 158                               le16_to_cpu(sta->last_seq_ctrl[i]));
 159        p += scnprintf(p, sizeof(buf)+buf-p, "\n");
 160        return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
 161}
 162STA_OPS(last_seq_ctrl);
 163
 164#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
 165static ssize_t sta_wme_rx_queue_read(struct file *file, char __user *userbuf,
 166                                     size_t count, loff_t *ppos)
 167{
 168        char buf[15*NUM_RX_DATA_QUEUES], *p = buf;
 169        int i;
 170        struct sta_info *sta = file->private_data;
 171        for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
 172                p += scnprintf(p, sizeof(buf)+buf-p, "%u ",
 173                               sta->wme_rx_queue[i]);
 174        p += scnprintf(p, sizeof(buf)+buf-p, "\n");
 175        return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
 176}
 177STA_OPS(wme_rx_queue);
 178
 179static ssize_t sta_wme_tx_queue_read(struct file *file, char __user *userbuf,
 180                                     size_t count, loff_t *ppos)
 181{
 182        char buf[15*NUM_TX_DATA_QUEUES], *p = buf;
 183        int i;
 184        struct sta_info *sta = file->private_data;
 185        for (i = 0; i < NUM_TX_DATA_QUEUES; i++)
 186                p += scnprintf(p, sizeof(buf)+buf-p, "%u ",
 187                               sta->wme_tx_queue[i]);
 188        p += scnprintf(p, sizeof(buf)+buf-p, "\n");
 189        return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
 190}
 191STA_OPS(wme_tx_queue);
 192#endif
 193
 194#define DEBUGFS_ADD(name) \
 195        sta->debugfs.name = debugfs_create_file(#name, 0444, \
 196                sta->debugfs.dir, sta, &sta_ ##name## _ops);
 197
 198#define DEBUGFS_DEL(name) \
 199        debugfs_remove(sta->debugfs.name);\
 200        sta->debugfs.name = NULL;
 201
 202
 203void ieee80211_sta_debugfs_add(struct sta_info *sta)
 204{
 205        struct dentry *stations_dir = sta->local->debugfs.stations;
 206        DECLARE_MAC_BUF(mac);
 207
 208        if (!stations_dir)
 209                return;
 210
 211        print_mac(mac, sta->addr);
 212
 213        sta->debugfs.dir = debugfs_create_dir(mac, stations_dir);
 214        if (!sta->debugfs.dir)
 215                return;
 216
 217        DEBUGFS_ADD(flags);
 218        DEBUGFS_ADD(num_ps_buf_frames);
 219        DEBUGFS_ADD(last_ack_rssi);
 220        DEBUGFS_ADD(last_ack_ms);
 221        DEBUGFS_ADD(inactive_ms);
 222        DEBUGFS_ADD(last_seq_ctrl);
 223#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
 224        DEBUGFS_ADD(wme_rx_queue);
 225        DEBUGFS_ADD(wme_tx_queue);
 226#endif
 227}
 228
 229void ieee80211_sta_debugfs_remove(struct sta_info *sta)
 230{
 231        DEBUGFS_DEL(flags);
 232        DEBUGFS_DEL(num_ps_buf_frames);
 233        DEBUGFS_DEL(last_ack_rssi);
 234        DEBUGFS_DEL(last_ack_ms);
 235        DEBUGFS_DEL(inactive_ms);
 236        DEBUGFS_DEL(last_seq_ctrl);
 237#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
 238        DEBUGFS_DEL(wme_rx_queue);
 239        DEBUGFS_DEL(wme_tx_queue);
 240#endif
 241
 242        debugfs_remove(sta->debugfs.dir);
 243        sta->debugfs.dir = NULL;
 244}
 245