1 /******************************************************************************* 2 3 Intel 10 Gigabit PCI Express Linux driver 4 Copyright(c) 1999 - 2012 Intel Corporation. 5 6 This program is free software; you can redistribute it and/or modify it 7 under the terms and conditions of the GNU General Public License, 8 version 2, as published by the Free Software Foundation. 9 10 This program is distributed in the hope it will be useful, but WITHOUT 11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 more details. 14 15 You should have received a copy of the GNU General Public License along with 16 this program; if not, write to the Free Software Foundation, Inc., 17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 18 19 The full GNU General Public License is included in this distribution in 20 the file called "COPYING". 21 22 Contact Information: 23 e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> 24 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 25 26 *******************************************************************************/ 27 28 #ifdef CONFIG_DEBUG_FS 29 30 #include <linux/debugfs.h> 31 #include <linux/module.h> 32 33 #include "ixgbe.h" 34 35 static struct dentry *ixgbe_dbg_root; 36 37 static char ixgbe_dbg_reg_ops_buf[256] = ""; 38 39 /** 40 * ixgbe_dbg_reg_ops_open - prep the debugfs pokee data item when opened 41 * @inode: inode that was opened 42 * @filp: file info 43 * 44 * Stash the adapter pointer hiding in the inode into the file pointer where 45 * we can find it later in the read and write calls 46 **/ 47 static int ixgbe_dbg_reg_ops_open(struct inode *inode, struct file *filp) 48 { 49 filp->private_data = inode->i_private; 50 return 0; 51 } 52 53 /** 54 * ixgbe_dbg_reg_ops_read - read for reg_ops datum 55 * @filp: the opened file 56 * @buffer: where to write the data for the user to read 57 * @count: the size of the user's buffer 58 * @ppos: file position offset 59 **/ 60 static ssize_t ixgbe_dbg_reg_ops_read(struct file *filp, char __user *buffer, 61 size_t count, loff_t *ppos) 62 { 63 struct ixgbe_adapter *adapter = filp->private_data; 64 char buf[256]; 65 int bytes_not_copied; 66 int len; 67 68 /* don't allow partial reads */ 69 if (*ppos != 0) 70 return 0; 71 72 len = snprintf(buf, sizeof(buf), "%s: %s\n", 73 adapter->netdev->name, ixgbe_dbg_reg_ops_buf); 74 if (count < len) 75 return -ENOSPC; 76 bytes_not_copied = copy_to_user(buffer, buf, len); 77 if (bytes_not_copied < 0) 78 return bytes_not_copied; 79 80 *ppos = len; 81 return len; 82 } 83 84 /** 85 * ixgbe_dbg_reg_ops_write - write into reg_ops datum 86 * @filp: the opened file 87 * @buffer: where to find the user's data 88 * @count: the length of the user's data 89 * @ppos: file position offset 90 **/ 91 static ssize_t ixgbe_dbg_reg_ops_write(struct file *filp, 92 const char __user *buffer, 93 size_t count, loff_t *ppos) 94 { 95 struct ixgbe_adapter *adapter = filp->private_data; 96 int bytes_not_copied; 97 98 /* don't allow partial writes */ 99 if (*ppos != 0) 100 return 0; 101 if (count >= sizeof(ixgbe_dbg_reg_ops_buf)) 102 return -ENOSPC; 103 104 bytes_not_copied = copy_from_user(ixgbe_dbg_reg_ops_buf, buffer, count); 105 if (bytes_not_copied < 0) 106 return bytes_not_copied; 107 else if (bytes_not_copied < count) 108 count -= bytes_not_copied; 109 else 110 return -ENOSPC; 111 ixgbe_dbg_reg_ops_buf[count] = '\0'; 112 113 if (strncmp(ixgbe_dbg_reg_ops_buf, "write", 5) == 0) { 114 u32 reg, value; 115 int cnt; 116 cnt = sscanf(&ixgbe_dbg_reg_ops_buf[5], "%x %x", ®, &value); 117 if (cnt == 2) { 118 IXGBE_WRITE_REG(&adapter->hw, reg, value); 119 value = IXGBE_READ_REG(&adapter->hw, reg); 120 e_dev_info("write: 0x%08x = 0x%08x\n", reg, value); 121 } else { 122 e_dev_info("write <reg> <value>\n"); 123 } 124 } else if (strncmp(ixgbe_dbg_reg_ops_buf, "read", 4) == 0) { 125 u32 reg, value; 126 int cnt; 127 cnt = sscanf(&ixgbe_dbg_reg_ops_buf[4], "%x", ®); 128 if (cnt == 1) { 129 value = IXGBE_READ_REG(&adapter->hw, reg); 130 e_dev_info("read 0x%08x = 0x%08x\n", reg, value); 131 } else { 132 e_dev_info("read <reg>\n"); 133 } 134 } else { 135 e_dev_info("Unknown command %s\n", ixgbe_dbg_reg_ops_buf); 136 e_dev_info("Available commands:\n"); 137 e_dev_info(" read <reg>\n"); 138 e_dev_info(" write <reg> <value>\n"); 139 } 140 return count; 141 } 142 143 static const struct file_operations ixgbe_dbg_reg_ops_fops = { 144 .owner = THIS_MODULE, 145 .open = ixgbe_dbg_reg_ops_open, 146 .read = ixgbe_dbg_reg_ops_read, 147 .write = ixgbe_dbg_reg_ops_write, 148 }; 149 150 static char ixgbe_dbg_netdev_ops_buf[256] = ""; 151 152 /** 153 * ixgbe_dbg_netdev_ops_open - prep the debugfs netdev_ops data item 154 * @inode: inode that was opened 155 * @filp: file info 156 * 157 * Stash the adapter pointer hiding in the inode into the file pointer 158 * where we can find it later in the read and write calls 159 **/ 160 static int ixgbe_dbg_netdev_ops_open(struct inode *inode, struct file *filp) 161 { 162 filp->private_data = inode->i_private; 163 return 0; 164 } 165 166 /** 167 * ixgbe_dbg_netdev_ops_read - read for netdev_ops datum 168 * @filp: the opened file 169 * @buffer: where to write the data for the user to read 170 * @count: the size of the user's buffer 171 * @ppos: file position offset 172 **/ 173 static ssize_t ixgbe_dbg_netdev_ops_read(struct file *filp, 174 char __user *buffer, 175 size_t count, loff_t *ppos) 176 { 177 struct ixgbe_adapter *adapter = filp->private_data; 178 char buf[256]; 179 int bytes_not_copied; 180 int len; 181 182 /* don't allow partial reads */ 183 if (*ppos != 0) 184 return 0; 185 186 len = snprintf(buf, sizeof(buf), "%s: %s\n", 187 adapter->netdev->name, ixgbe_dbg_netdev_ops_buf); 188 if (count < len) 189 return -ENOSPC; 190 bytes_not_copied = copy_to_user(buffer, buf, len); 191 if (bytes_not_copied < 0) 192 return bytes_not_copied; 193 194 *ppos = len; 195 return len; 196 } 197 198 /** 199 * ixgbe_dbg_netdev_ops_write - write into netdev_ops datum 200 * @filp: the opened file 201 * @buffer: where to find the user's data 202 * @count: the length of the user's data 203 * @ppos: file position offset 204 **/ 205 static ssize_t ixgbe_dbg_netdev_ops_write(struct file *filp, 206 const char __user *buffer, 207 size_t count, loff_t *ppos) 208 { 209 struct ixgbe_adapter *adapter = filp->private_data; 210 int bytes_not_copied; 211 212 /* don't allow partial writes */ 213 if (*ppos != 0) 214 return 0; 215 if (count >= sizeof(ixgbe_dbg_netdev_ops_buf)) 216 return -ENOSPC; 217 218 bytes_not_copied = copy_from_user(ixgbe_dbg_netdev_ops_buf, 219 buffer, count); 220 if (bytes_not_copied < 0) 221 return bytes_not_copied; 222 else if (bytes_not_copied < count) 223 count -= bytes_not_copied; 224 else 225 return -ENOSPC; 226 ixgbe_dbg_netdev_ops_buf[count] = '\0'; 227 228 if (strncmp(ixgbe_dbg_netdev_ops_buf, "tx_timeout", 10) == 0) { 229 adapter->netdev->netdev_ops->ndo_tx_timeout(adapter->netdev); 230 e_dev_info("tx_timeout called\n"); 231 } else { 232 e_dev_info("Unknown command: %s\n", ixgbe_dbg_netdev_ops_buf); 233 e_dev_info("Available commands:\n"); 234 e_dev_info(" tx_timeout\n"); 235 } 236 return count; 237 } 238 239 static const struct file_operations ixgbe_dbg_netdev_ops_fops = { 240 .owner = THIS_MODULE, 241 .open = ixgbe_dbg_netdev_ops_open, 242 .read = ixgbe_dbg_netdev_ops_read, 243 .write = ixgbe_dbg_netdev_ops_write, 244 }; 245 246 /** 247 * ixgbe_dbg_adapter_init - setup the debugfs directory for the adapter 248 * @adapter: the adapter that is starting up 249 **/ 250 void ixgbe_dbg_adapter_init(struct ixgbe_adapter *adapter) 251 { 252 const char *name = pci_name(adapter->pdev); 253 struct dentry *pfile; 254 adapter->ixgbe_dbg_adapter = debugfs_create_dir(name, ixgbe_dbg_root); 255 if (adapter->ixgbe_dbg_adapter) { 256 pfile = debugfs_create_file("reg_ops", 0600, 257 adapter->ixgbe_dbg_adapter, adapter, 258 &ixgbe_dbg_reg_ops_fops); 259 if (!pfile) 260 e_dev_err("debugfs reg_ops for %s failed\n", name); 261 pfile = debugfs_create_file("netdev_ops", 0600, 262 adapter->ixgbe_dbg_adapter, adapter, 263 &ixgbe_dbg_netdev_ops_fops); 264 if (!pfile) 265 e_dev_err("debugfs netdev_ops for %s failed\n", name); 266 } else { 267 e_dev_err("debugfs entry for %s failed\n", name); 268 } 269 } 270 271 /** 272 * ixgbe_dbg_adapter_exit - clear out the adapter's debugfs entries 273 * @pf: the pf that is stopping 274 **/ 275 void ixgbe_dbg_adapter_exit(struct ixgbe_adapter *adapter) 276 { 277 if (adapter->ixgbe_dbg_adapter) 278 debugfs_remove_recursive(adapter->ixgbe_dbg_adapter); 279 adapter->ixgbe_dbg_adapter = NULL; 280 } 281 282 /** 283 * ixgbe_dbg_init - start up debugfs for the driver 284 **/ 285 void ixgbe_dbg_init(void) 286 { 287 ixgbe_dbg_root = debugfs_create_dir(ixgbe_driver_name, NULL); 288 if (ixgbe_dbg_root == NULL) 289 pr_err("init of debugfs failed\n"); 290 } 291 292 /** 293 * ixgbe_dbg_exit - clean out the driver's debugfs entries 294 **/ 295 void ixgbe_dbg_exit(void) 296 { 297 debugfs_remove_recursive(ixgbe_dbg_root); 298 } 299 300 #endif /* CONFIG_DEBUG_FS */ 301