0001
0002
0003
0004 #include <linux/debugfs.h>
0005 #include <linux/module.h>
0006
0007 #include "ixgbe.h"
0008
0009 static struct dentry *ixgbe_dbg_root;
0010
0011 static char ixgbe_dbg_reg_ops_buf[256] = "";
0012
0013 static ssize_t ixgbe_dbg_common_ops_read(struct file *filp, char __user *buffer,
0014 size_t count, loff_t *ppos,
0015 char *dbg_buf)
0016 {
0017 struct ixgbe_adapter *adapter = filp->private_data;
0018 char *buf;
0019 int len;
0020
0021
0022 if (*ppos != 0)
0023 return 0;
0024
0025 buf = kasprintf(GFP_KERNEL, "%s: %s\n",
0026 adapter->netdev->name, dbg_buf);
0027 if (!buf)
0028 return -ENOMEM;
0029
0030 if (count < strlen(buf)) {
0031 kfree(buf);
0032 return -ENOSPC;
0033 }
0034
0035 len = simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf));
0036
0037 kfree(buf);
0038 return len;
0039 }
0040
0041
0042
0043
0044
0045
0046
0047
0048 static ssize_t ixgbe_dbg_reg_ops_read(struct file *filp, char __user *buffer,
0049 size_t count, loff_t *ppos)
0050 {
0051 return ixgbe_dbg_common_ops_read(filp, buffer, count, ppos,
0052 ixgbe_dbg_reg_ops_buf);
0053 }
0054
0055
0056
0057
0058
0059
0060
0061
0062 static ssize_t ixgbe_dbg_reg_ops_write(struct file *filp,
0063 const char __user *buffer,
0064 size_t count, loff_t *ppos)
0065 {
0066 struct ixgbe_adapter *adapter = filp->private_data;
0067 int len;
0068
0069
0070 if (*ppos != 0)
0071 return 0;
0072 if (count >= sizeof(ixgbe_dbg_reg_ops_buf))
0073 return -ENOSPC;
0074
0075 len = simple_write_to_buffer(ixgbe_dbg_reg_ops_buf,
0076 sizeof(ixgbe_dbg_reg_ops_buf)-1,
0077 ppos,
0078 buffer,
0079 count);
0080 if (len < 0)
0081 return len;
0082
0083 ixgbe_dbg_reg_ops_buf[len] = '\0';
0084
0085 if (strncmp(ixgbe_dbg_reg_ops_buf, "write", 5) == 0) {
0086 u32 reg, value;
0087 int cnt;
0088 cnt = sscanf(&ixgbe_dbg_reg_ops_buf[5], "%x %x", ®, &value);
0089 if (cnt == 2) {
0090 IXGBE_WRITE_REG(&adapter->hw, reg, value);
0091 value = IXGBE_READ_REG(&adapter->hw, reg);
0092 e_dev_info("write: 0x%08x = 0x%08x\n", reg, value);
0093 } else {
0094 e_dev_info("write <reg> <value>\n");
0095 }
0096 } else if (strncmp(ixgbe_dbg_reg_ops_buf, "read", 4) == 0) {
0097 u32 reg, value;
0098 int cnt;
0099 cnt = sscanf(&ixgbe_dbg_reg_ops_buf[4], "%x", ®);
0100 if (cnt == 1) {
0101 value = IXGBE_READ_REG(&adapter->hw, reg);
0102 e_dev_info("read 0x%08x = 0x%08x\n", reg, value);
0103 } else {
0104 e_dev_info("read <reg>\n");
0105 }
0106 } else {
0107 e_dev_info("Unknown command %s\n", ixgbe_dbg_reg_ops_buf);
0108 e_dev_info("Available commands:\n");
0109 e_dev_info(" read <reg>\n");
0110 e_dev_info(" write <reg> <value>\n");
0111 }
0112 return count;
0113 }
0114
0115 static const struct file_operations ixgbe_dbg_reg_ops_fops = {
0116 .owner = THIS_MODULE,
0117 .open = simple_open,
0118 .read = ixgbe_dbg_reg_ops_read,
0119 .write = ixgbe_dbg_reg_ops_write,
0120 };
0121
0122 static char ixgbe_dbg_netdev_ops_buf[256] = "";
0123
0124
0125
0126
0127
0128
0129
0130
0131 static ssize_t ixgbe_dbg_netdev_ops_read(struct file *filp, char __user *buffer,
0132 size_t count, loff_t *ppos)
0133 {
0134 return ixgbe_dbg_common_ops_read(filp, buffer, count, ppos,
0135 ixgbe_dbg_netdev_ops_buf);
0136 }
0137
0138
0139
0140
0141
0142
0143
0144
0145 static ssize_t ixgbe_dbg_netdev_ops_write(struct file *filp,
0146 const char __user *buffer,
0147 size_t count, loff_t *ppos)
0148 {
0149 struct ixgbe_adapter *adapter = filp->private_data;
0150 int len;
0151
0152
0153 if (*ppos != 0)
0154 return 0;
0155 if (count >= sizeof(ixgbe_dbg_netdev_ops_buf))
0156 return -ENOSPC;
0157
0158 len = simple_write_to_buffer(ixgbe_dbg_netdev_ops_buf,
0159 sizeof(ixgbe_dbg_netdev_ops_buf)-1,
0160 ppos,
0161 buffer,
0162 count);
0163 if (len < 0)
0164 return len;
0165
0166 ixgbe_dbg_netdev_ops_buf[len] = '\0';
0167
0168 if (strncmp(ixgbe_dbg_netdev_ops_buf, "tx_timeout", 10) == 0) {
0169
0170 adapter->netdev->netdev_ops->ndo_tx_timeout(adapter->netdev,
0171 UINT_MAX);
0172 e_dev_info("tx_timeout called\n");
0173 } else {
0174 e_dev_info("Unknown command: %s\n", ixgbe_dbg_netdev_ops_buf);
0175 e_dev_info("Available commands:\n");
0176 e_dev_info(" tx_timeout\n");
0177 }
0178 return count;
0179 }
0180
0181 static const struct file_operations ixgbe_dbg_netdev_ops_fops = {
0182 .owner = THIS_MODULE,
0183 .open = simple_open,
0184 .read = ixgbe_dbg_netdev_ops_read,
0185 .write = ixgbe_dbg_netdev_ops_write,
0186 };
0187
0188
0189
0190
0191
0192 void ixgbe_dbg_adapter_init(struct ixgbe_adapter *adapter)
0193 {
0194 const char *name = pci_name(adapter->pdev);
0195
0196 adapter->ixgbe_dbg_adapter = debugfs_create_dir(name, ixgbe_dbg_root);
0197 debugfs_create_file("reg_ops", 0600, adapter->ixgbe_dbg_adapter,
0198 adapter, &ixgbe_dbg_reg_ops_fops);
0199 debugfs_create_file("netdev_ops", 0600, adapter->ixgbe_dbg_adapter,
0200 adapter, &ixgbe_dbg_netdev_ops_fops);
0201 }
0202
0203
0204
0205
0206
0207 void ixgbe_dbg_adapter_exit(struct ixgbe_adapter *adapter)
0208 {
0209 debugfs_remove_recursive(adapter->ixgbe_dbg_adapter);
0210 adapter->ixgbe_dbg_adapter = NULL;
0211 }
0212
0213
0214
0215
0216 void ixgbe_dbg_init(void)
0217 {
0218 ixgbe_dbg_root = debugfs_create_dir(ixgbe_driver_name, NULL);
0219 }
0220
0221
0222
0223
0224 void ixgbe_dbg_exit(void)
0225 {
0226 debugfs_remove_recursive(ixgbe_dbg_root);
0227 }