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