Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) }