root/drivers/net/wimax/i2400m/debugfs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. debugfs_netdev_queue_stopped_get
  2. i2400m_rx_stats_read
  3. i2400m_rx_stats_write
  4. i2400m_tx_stats_read
  5. i2400m_tx_stats_write
  6. debugfs_i2400m_suspend_set
  7. debugfs_i2400m_reset_set
  8. i2400m_debugfs_add
  9. i2400m_debugfs_rm

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Intel Wireless WiMAX Connection 2400m
   4  * Debugfs interfaces to manipulate driver and device information
   5  *
   6  * Copyright (C) 2007 Intel Corporation <linux-wimax@intel.com>
   7  * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
   8  */
   9 
  10 #include <linux/debugfs.h>
  11 #include <linux/netdevice.h>
  12 #include <linux/etherdevice.h>
  13 #include <linux/spinlock.h>
  14 #include <linux/device.h>
  15 #include <linux/export.h>
  16 #include "i2400m.h"
  17 
  18 
  19 #define D_SUBMODULE debugfs
  20 #include "debug-levels.h"
  21 
  22 static
  23 int debugfs_netdev_queue_stopped_get(void *data, u64 *val)
  24 {
  25         struct i2400m *i2400m = data;
  26         *val = netif_queue_stopped(i2400m->wimax_dev.net_dev);
  27         return 0;
  28 }
  29 DEFINE_SIMPLE_ATTRIBUTE(fops_netdev_queue_stopped,
  30                         debugfs_netdev_queue_stopped_get,
  31                         NULL, "%llu\n");
  32 
  33 /*
  34  * We don't allow partial reads of this file, as then the reader would
  35  * get weirdly confused data as it is updated.
  36  *
  37  * So or you read it all or nothing; if you try to read with an offset
  38  * != 0, we consider you are done reading.
  39  */
  40 static
  41 ssize_t i2400m_rx_stats_read(struct file *filp, char __user *buffer,
  42                              size_t count, loff_t *ppos)
  43 {
  44         struct i2400m *i2400m = filp->private_data;
  45         char buf[128];
  46         unsigned long flags;
  47 
  48         if (*ppos != 0)
  49                 return 0;
  50         if (count < sizeof(buf))
  51                 return -ENOSPC;
  52         spin_lock_irqsave(&i2400m->rx_lock, flags);
  53         snprintf(buf, sizeof(buf), "%u %u %u %u %u %u %u\n",
  54                  i2400m->rx_pl_num, i2400m->rx_pl_min,
  55                  i2400m->rx_pl_max, i2400m->rx_num,
  56                  i2400m->rx_size_acc,
  57                  i2400m->rx_size_min, i2400m->rx_size_max);
  58         spin_unlock_irqrestore(&i2400m->rx_lock, flags);
  59         return simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf));
  60 }
  61 
  62 
  63 /* Any write clears the stats */
  64 static
  65 ssize_t i2400m_rx_stats_write(struct file *filp, const char __user *buffer,
  66                               size_t count, loff_t *ppos)
  67 {
  68         struct i2400m *i2400m = filp->private_data;
  69         unsigned long flags;
  70 
  71         spin_lock_irqsave(&i2400m->rx_lock, flags);
  72         i2400m->rx_pl_num = 0;
  73         i2400m->rx_pl_max = 0;
  74         i2400m->rx_pl_min = UINT_MAX;
  75         i2400m->rx_num = 0;
  76         i2400m->rx_size_acc = 0;
  77         i2400m->rx_size_min = UINT_MAX;
  78         i2400m->rx_size_max = 0;
  79         spin_unlock_irqrestore(&i2400m->rx_lock, flags);
  80         return count;
  81 }
  82 
  83 static
  84 const struct file_operations i2400m_rx_stats_fops = {
  85         .owner =        THIS_MODULE,
  86         .open =         simple_open,
  87         .read =         i2400m_rx_stats_read,
  88         .write =        i2400m_rx_stats_write,
  89         .llseek =       default_llseek,
  90 };
  91 
  92 
  93 /* See i2400m_rx_stats_read() */
  94 static
  95 ssize_t i2400m_tx_stats_read(struct file *filp, char __user *buffer,
  96                              size_t count, loff_t *ppos)
  97 {
  98         struct i2400m *i2400m = filp->private_data;
  99         char buf[128];
 100         unsigned long flags;
 101 
 102         if (*ppos != 0)
 103                 return 0;
 104         if (count < sizeof(buf))
 105                 return -ENOSPC;
 106         spin_lock_irqsave(&i2400m->tx_lock, flags);
 107         snprintf(buf, sizeof(buf), "%u %u %u %u %u %u %u\n",
 108                  i2400m->tx_pl_num, i2400m->tx_pl_min,
 109                  i2400m->tx_pl_max, i2400m->tx_num,
 110                  i2400m->tx_size_acc,
 111                  i2400m->tx_size_min, i2400m->tx_size_max);
 112         spin_unlock_irqrestore(&i2400m->tx_lock, flags);
 113         return simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf));
 114 }
 115 
 116 /* Any write clears the stats */
 117 static
 118 ssize_t i2400m_tx_stats_write(struct file *filp, const char __user *buffer,
 119                               size_t count, loff_t *ppos)
 120 {
 121         struct i2400m *i2400m = filp->private_data;
 122         unsigned long flags;
 123 
 124         spin_lock_irqsave(&i2400m->tx_lock, flags);
 125         i2400m->tx_pl_num = 0;
 126         i2400m->tx_pl_max = 0;
 127         i2400m->tx_pl_min = UINT_MAX;
 128         i2400m->tx_num = 0;
 129         i2400m->tx_size_acc = 0;
 130         i2400m->tx_size_min = UINT_MAX;
 131         i2400m->tx_size_max = 0;
 132         spin_unlock_irqrestore(&i2400m->tx_lock, flags);
 133         return count;
 134 }
 135 
 136 static
 137 const struct file_operations i2400m_tx_stats_fops = {
 138         .owner =        THIS_MODULE,
 139         .open =         simple_open,
 140         .read =         i2400m_tx_stats_read,
 141         .write =        i2400m_tx_stats_write,
 142         .llseek =       default_llseek,
 143 };
 144 
 145 
 146 /* Write 1 to ask the device to go into suspend */
 147 static
 148 int debugfs_i2400m_suspend_set(void *data, u64 val)
 149 {
 150         int result;
 151         struct i2400m *i2400m = data;
 152         result = i2400m_cmd_enter_powersave(i2400m);
 153         if (result >= 0)
 154                 result = 0;
 155         return result;
 156 }
 157 DEFINE_SIMPLE_ATTRIBUTE(fops_i2400m_suspend,
 158                         NULL, debugfs_i2400m_suspend_set,
 159                         "%llu\n");
 160 
 161 /*
 162  * Reset the device
 163  *
 164  * Write 0 to ask the device to soft reset, 1 to cold reset, 2 to bus
 165  * reset (as defined by enum i2400m_reset_type).
 166  */
 167 static
 168 int debugfs_i2400m_reset_set(void *data, u64 val)
 169 {
 170         int result;
 171         struct i2400m *i2400m = data;
 172         enum i2400m_reset_type rt = val;
 173         switch(rt) {
 174         case I2400M_RT_WARM:
 175         case I2400M_RT_COLD:
 176         case I2400M_RT_BUS:
 177                 result = i2400m_reset(i2400m, rt);
 178                 if (result >= 0)
 179                         result = 0;
 180                 break;
 181         default:
 182                 result = -EINVAL;
 183         }
 184         return result;
 185 }
 186 DEFINE_SIMPLE_ATTRIBUTE(fops_i2400m_reset,
 187                         NULL, debugfs_i2400m_reset_set,
 188                         "%llu\n");
 189 
 190 void i2400m_debugfs_add(struct i2400m *i2400m)
 191 {
 192         struct dentry *dentry = i2400m->wimax_dev.debugfs_dentry;
 193 
 194         dentry = debugfs_create_dir("i2400m", dentry);
 195         i2400m->debugfs_dentry = dentry;
 196 
 197         d_level_register_debugfs("dl_", control, dentry);
 198         d_level_register_debugfs("dl_", driver, dentry);
 199         d_level_register_debugfs("dl_", debugfs, dentry);
 200         d_level_register_debugfs("dl_", fw, dentry);
 201         d_level_register_debugfs("dl_", netdev, dentry);
 202         d_level_register_debugfs("dl_", rfkill, dentry);
 203         d_level_register_debugfs("dl_", rx, dentry);
 204         d_level_register_debugfs("dl_", tx, dentry);
 205 
 206         debugfs_create_size_t("tx_in", 0400, dentry, &i2400m->tx_in);
 207         debugfs_create_size_t("tx_out", 0400, dentry, &i2400m->tx_out);
 208         debugfs_create_u32("state", 0600, dentry, &i2400m->state);
 209 
 210         /*
 211          * Trace received messages from user space
 212          *
 213          * In order to tap the bidirectional message stream in the
 214          * 'msg' pipe, user space can read from the 'msg' pipe;
 215          * however, due to limitations in libnl, we can't know what
 216          * the different applications are sending down to the kernel.
 217          *
 218          * So we have this hack where the driver will echo any message
 219          * received on the msg pipe from user space [through a call to
 220          * wimax_dev->op_msg_from_user() into
 221          * i2400m_op_msg_from_user()] into the 'trace' pipe that this
 222          * driver creates.
 223          *
 224          * So then, reading from both the 'trace' and 'msg' pipes in
 225          * user space will provide a full dump of the traffic.
 226          *
 227          * Write 1 to activate, 0 to clear.
 228          *
 229          * It is not really very atomic, but it is also not too
 230          * critical.
 231          */
 232         debugfs_create_u8("trace_msg_from_user", 0600, dentry,
 233                           &i2400m->trace_msg_from_user);
 234 
 235         debugfs_create_file("netdev_queue_stopped", 0400, dentry, i2400m,
 236                             &fops_netdev_queue_stopped);
 237 
 238         debugfs_create_file("rx_stats", 0600, dentry, i2400m,
 239                             &i2400m_rx_stats_fops);
 240 
 241         debugfs_create_file("tx_stats", 0600, dentry, i2400m,
 242                             &i2400m_tx_stats_fops);
 243 
 244         debugfs_create_file("suspend", 0200, dentry, i2400m,
 245                             &fops_i2400m_suspend);
 246 
 247         debugfs_create_file("reset", 0200, dentry, i2400m, &fops_i2400m_reset);
 248 }
 249 
 250 void i2400m_debugfs_rm(struct i2400m *i2400m)
 251 {
 252         debugfs_remove_recursive(i2400m->debugfs_dentry);
 253 }

/* [<][>][^][v][top][bottom][index][help] */