Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright(c) 1999 - 2018 Intel Corporation. */
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     /* don't allow partial reads */
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  * ixgbe_dbg_reg_ops_read - read for reg_ops datum
0043  * @filp: the opened file
0044  * @buffer: where to write the data for the user to read
0045  * @count: the size of the user's buffer
0046  * @ppos: file position offset
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  * ixgbe_dbg_reg_ops_write - write into reg_ops datum
0057  * @filp: the opened file
0058  * @buffer: where to find the user's data
0059  * @count: the length of the user's data
0060  * @ppos: file position offset
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     /* don't allow partial writes */
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", &reg, &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", &reg);
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  * ixgbe_dbg_netdev_ops_read - read for netdev_ops datum
0126  * @filp: the opened file
0127  * @buffer: where to write the data for the user to read
0128  * @count: the size of the user's buffer
0129  * @ppos: file position offset
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  * ixgbe_dbg_netdev_ops_write - write into netdev_ops datum
0140  * @filp: the opened file
0141  * @buffer: where to find the user's data
0142  * @count: the length of the user's data
0143  * @ppos: file position offset
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     /* don't allow partial writes */
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         /* TX Queue number below is wrong, but ixgbe does not use it */
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  * ixgbe_dbg_adapter_init - setup the debugfs directory for the adapter
0190  * @adapter: the adapter that is starting up
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  * ixgbe_dbg_adapter_exit - clear out the adapter's debugfs entries
0205  * @adapter: the adapter that is exiting
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  * ixgbe_dbg_init - start up debugfs for the driver
0215  **/
0216 void ixgbe_dbg_init(void)
0217 {
0218     ixgbe_dbg_root = debugfs_create_dir(ixgbe_driver_name, NULL);
0219 }
0220 
0221 /**
0222  * ixgbe_dbg_exit - clean out the driver's debugfs entries
0223  **/
0224 void ixgbe_dbg_exit(void)
0225 {
0226     debugfs_remove_recursive(ixgbe_dbg_root);
0227 }