1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2022, Intel Corporation. */ 3 4 #include <linux/fs.h> 5 #include <linux/debugfs.h> 6 #include <linux/random.h> 7 #include <linux/vmalloc.h> 8 #include "ice.h" 9 10 static struct dentry *ice_debugfs_root; 11 12 /* create a define that has an extra module that doesn't really exist. this 13 * is so we can add a module 'all' to easily enable/disable all the modules 14 */ 15 #define ICE_NR_FW_LOG_MODULES (ICE_AQC_FW_LOG_ID_MAX + 1) 16 17 /* the ordering in this array is important. it matches the ordering of the 18 * values in the FW so the index is the same value as in ice_aqc_fw_logging_mod 19 */ 20 static const char * const ice_fwlog_module_string[] = { 21 "general", 22 "ctrl", 23 "link", 24 "link_topo", 25 "dnl", 26 "i2c", 27 "sdp", 28 "mdio", 29 "adminq", 30 "hdma", 31 "lldp", 32 "dcbx", 33 "dcb", 34 "xlr", 35 "nvm", 36 "auth", 37 "vpd", 38 "iosf", 39 "parser", 40 "sw", 41 "scheduler", 42 "txq", 43 "rsvd", 44 "post", 45 "watchdog", 46 "task_dispatch", 47 "mng", 48 "synce", 49 "health", 50 "tsdrv", 51 "pfreg", 52 "mdlver", 53 "all", 54 }; 55 56 /* the ordering in this array is important. it matches the ordering of the 57 * values in the FW so the index is the same value as in ice_fwlog_level 58 */ 59 static const char * const ice_fwlog_level_string[] = { 60 "none", 61 "error", 62 "warning", 63 "normal", 64 "verbose", 65 }; 66 67 static const char * const ice_fwlog_log_size[] = { 68 "128K", 69 "256K", 70 "512K", 71 "1M", 72 "2M", 73 }; 74 75 /** 76 * ice_fwlog_print_module_cfg - print current FW logging module configuration 77 * @hw: pointer to the HW structure 78 * @module: module to print 79 * @s: the seq file to put data into 80 */ 81 static void 82 ice_fwlog_print_module_cfg(struct ice_hw *hw, int module, struct seq_file *s) 83 { 84 struct ice_fwlog_cfg *cfg = &hw->fwlog_cfg; 85 struct ice_fwlog_module_entry *entry; 86 87 if (module != ICE_AQC_FW_LOG_ID_MAX) { 88 entry = &cfg->module_entries[module]; 89 90 seq_printf(s, "\tModule: %s, Log Level: %s\n", 91 ice_fwlog_module_string[entry->module_id], 92 ice_fwlog_level_string[entry->log_level]); 93 } else { 94 int i; 95 96 for (i = 0; i < ICE_AQC_FW_LOG_ID_MAX; i++) { 97 entry = &cfg->module_entries[i]; 98 99 seq_printf(s, "\tModule: %s, Log Level: %s\n", 100 ice_fwlog_module_string[entry->module_id], 101 ice_fwlog_level_string[entry->log_level]); 102 } 103 } 104 } 105 106 static int ice_find_module_by_dentry(struct ice_pf *pf, struct dentry *d) 107 { 108 int i, module; 109 110 module = -1; 111 /* find the module based on the dentry */ 112 for (i = 0; i < ICE_NR_FW_LOG_MODULES; i++) { 113 if (d == pf->ice_debugfs_pf_fwlog_modules[i]) { 114 module = i; 115 break; 116 } 117 } 118 119 return module; 120 } 121 122 /** 123 * ice_debugfs_module_show - read from 'module' file 124 * @s: the opened file 125 * @v: pointer to the offset 126 */ 127 static int ice_debugfs_module_show(struct seq_file *s, void *v) 128 { 129 const struct file *filp = s->file; 130 struct dentry *dentry; 131 struct ice_pf *pf; 132 int module; 133 134 dentry = file_dentry(filp); 135 pf = s->private; 136 137 module = ice_find_module_by_dentry(pf, dentry); 138 if (module < 0) { 139 dev_info(ice_pf_to_dev(pf), "unknown module\n"); 140 return -EINVAL; 141 } 142 143 ice_fwlog_print_module_cfg(&pf->hw, module, s); 144 145 return 0; 146 } 147 148 static int ice_debugfs_module_open(struct inode *inode, struct file *filp) 149 { 150 return single_open(filp, ice_debugfs_module_show, inode->i_private); 151 } 152 153 /** 154 * ice_debugfs_module_write - write into 'module' file 155 * @filp: the opened file 156 * @buf: where to find the user's data 157 * @count: the length of the user's data 158 * @ppos: file position offset 159 */ 160 static ssize_t 161 ice_debugfs_module_write(struct file *filp, const char __user *buf, 162 size_t count, loff_t *ppos) 163 { 164 struct ice_pf *pf = file_inode(filp)->i_private; 165 struct dentry *dentry = file_dentry(filp); 166 struct device *dev = ice_pf_to_dev(pf); 167 char user_val[16], *cmd_buf; 168 int module, log_level, cnt; 169 170 /* don't allow partial writes or invalid input */ 171 if (*ppos != 0 || count > 8) 172 return -EINVAL; 173 174 cmd_buf = memdup_user_nul(buf, count); 175 if (IS_ERR(cmd_buf)) 176 return PTR_ERR(cmd_buf); 177 178 module = ice_find_module_by_dentry(pf, dentry); 179 if (module < 0) { 180 dev_info(dev, "unknown module\n"); 181 return -EINVAL; 182 } 183 184 cnt = sscanf(cmd_buf, "%s", user_val); 185 if (cnt != 1) 186 return -EINVAL; 187 188 log_level = sysfs_match_string(ice_fwlog_level_string, user_val); 189 if (log_level < 0) { 190 dev_info(dev, "unknown log level '%s'\n", user_val); 191 return -EINVAL; 192 } 193 194 if (module != ICE_AQC_FW_LOG_ID_MAX) { 195 ice_pf_fwlog_update_module(pf, log_level, module); 196 } else { 197 /* the module 'all' is a shortcut so that we can set 198 * all of the modules to the same level quickly 199 */ 200 int i; 201 202 for (i = 0; i < ICE_AQC_FW_LOG_ID_MAX; i++) 203 ice_pf_fwlog_update_module(pf, log_level, i); 204 } 205 206 return count; 207 } 208 209 static const struct file_operations ice_debugfs_module_fops = { 210 .owner = THIS_MODULE, 211 .open = ice_debugfs_module_open, 212 .read = seq_read, 213 .release = single_release, 214 .write = ice_debugfs_module_write, 215 }; 216 217 /** 218 * ice_debugfs_nr_messages_read - read from 'nr_messages' file 219 * @filp: the opened file 220 * @buffer: where to write the data for the user to read 221 * @count: the size of the user's buffer 222 * @ppos: file position offset 223 */ 224 static ssize_t ice_debugfs_nr_messages_read(struct file *filp, 225 char __user *buffer, size_t count, 226 loff_t *ppos) 227 { 228 struct ice_pf *pf = filp->private_data; 229 struct ice_hw *hw = &pf->hw; 230 char buff[32] = {}; 231 232 snprintf(buff, sizeof(buff), "%d\n", 233 hw->fwlog_cfg.log_resolution); 234 235 return simple_read_from_buffer(buffer, count, ppos, buff, strlen(buff)); 236 } 237 238 /** 239 * ice_debugfs_nr_messages_write - write into 'nr_messages' file 240 * @filp: the opened file 241 * @buf: where to find the user's data 242 * @count: the length of the user's data 243 * @ppos: file position offset 244 */ 245 static ssize_t 246 ice_debugfs_nr_messages_write(struct file *filp, const char __user *buf, 247 size_t count, loff_t *ppos) 248 { 249 struct ice_pf *pf = filp->private_data; 250 struct device *dev = ice_pf_to_dev(pf); 251 struct ice_hw *hw = &pf->hw; 252 char user_val[8], *cmd_buf; 253 s16 nr_messages; 254 ssize_t ret; 255 256 /* don't allow partial writes or invalid input */ 257 if (*ppos != 0 || count > 4) 258 return -EINVAL; 259 260 cmd_buf = memdup_user_nul(buf, count); 261 if (IS_ERR(cmd_buf)) 262 return PTR_ERR(cmd_buf); 263 264 ret = sscanf(cmd_buf, "%s", user_val); 265 if (ret != 1) 266 return -EINVAL; 267 268 ret = kstrtos16(user_val, 0, &nr_messages); 269 if (ret) 270 return ret; 271 272 if (nr_messages < ICE_AQC_FW_LOG_MIN_RESOLUTION || 273 nr_messages > ICE_AQC_FW_LOG_MAX_RESOLUTION) { 274 dev_err(dev, "Invalid FW log number of messages %d, value must be between %d - %d\n", 275 nr_messages, ICE_AQC_FW_LOG_MIN_RESOLUTION, 276 ICE_AQC_FW_LOG_MAX_RESOLUTION); 277 return -EINVAL; 278 } 279 280 hw->fwlog_cfg.log_resolution = nr_messages; 281 282 return count; 283 } 284 285 static const struct file_operations ice_debugfs_nr_messages_fops = { 286 .owner = THIS_MODULE, 287 .open = simple_open, 288 .read = ice_debugfs_nr_messages_read, 289 .write = ice_debugfs_nr_messages_write, 290 }; 291 292 /** 293 * ice_debugfs_enable_read - read from 'enable' file 294 * @filp: the opened file 295 * @buffer: where to write the data for the user to read 296 * @count: the size of the user's buffer 297 * @ppos: file position offset 298 */ 299 static ssize_t ice_debugfs_enable_read(struct file *filp, 300 char __user *buffer, size_t count, 301 loff_t *ppos) 302 { 303 struct ice_pf *pf = filp->private_data; 304 struct ice_hw *hw = &pf->hw; 305 char buff[32] = {}; 306 307 snprintf(buff, sizeof(buff), "%u\n", 308 (u16)(hw->fwlog_cfg.options & 309 ICE_FWLOG_OPTION_IS_REGISTERED) >> 3); 310 311 return simple_read_from_buffer(buffer, count, ppos, buff, strlen(buff)); 312 } 313 314 /** 315 * ice_debugfs_enable_write - write into 'enable' file 316 * @filp: the opened file 317 * @buf: where to find the user's data 318 * @count: the length of the user's data 319 * @ppos: file position offset 320 */ 321 static ssize_t 322 ice_debugfs_enable_write(struct file *filp, const char __user *buf, 323 size_t count, loff_t *ppos) 324 { 325 struct ice_pf *pf = filp->private_data; 326 struct ice_hw *hw = &pf->hw; 327 char user_val[8], *cmd_buf; 328 bool enable; 329 ssize_t ret; 330 331 /* don't allow partial writes or invalid input */ 332 if (*ppos != 0 || count > 2) 333 return -EINVAL; 334 335 cmd_buf = memdup_user_nul(buf, count); 336 if (IS_ERR(cmd_buf)) 337 return PTR_ERR(cmd_buf); 338 339 ret = sscanf(cmd_buf, "%s", user_val); 340 if (ret != 1) 341 return -EINVAL; 342 343 ret = kstrtobool(user_val, &enable); 344 if (ret) 345 goto enable_write_error; 346 347 if (enable) 348 hw->fwlog_cfg.options |= ICE_FWLOG_OPTION_ARQ_ENA; 349 else 350 hw->fwlog_cfg.options &= ~ICE_FWLOG_OPTION_ARQ_ENA; 351 352 ret = ice_fwlog_set(hw, &hw->fwlog_cfg); 353 if (ret) 354 goto enable_write_error; 355 356 if (enable) 357 ret = ice_fwlog_register(hw); 358 else 359 ret = ice_fwlog_unregister(hw); 360 361 if (ret) 362 goto enable_write_error; 363 364 /* if we get here, nothing went wrong; return count since we didn't 365 * really write anything 366 */ 367 ret = (ssize_t)count; 368 369 enable_write_error: 370 /* This function always consumes all of the written input, or produces 371 * an error. Check and enforce this. Otherwise, the write operation 372 * won't complete properly. 373 */ 374 if (WARN_ON(ret != (ssize_t)count && ret >= 0)) 375 ret = -EIO; 376 377 return ret; 378 } 379 380 static const struct file_operations ice_debugfs_enable_fops = { 381 .owner = THIS_MODULE, 382 .open = simple_open, 383 .read = ice_debugfs_enable_read, 384 .write = ice_debugfs_enable_write, 385 }; 386 387 /** 388 * ice_debugfs_log_size_read - read from 'log_size' file 389 * @filp: the opened file 390 * @buffer: where to write the data for the user to read 391 * @count: the size of the user's buffer 392 * @ppos: file position offset 393 */ 394 static ssize_t ice_debugfs_log_size_read(struct file *filp, 395 char __user *buffer, size_t count, 396 loff_t *ppos) 397 { 398 struct ice_pf *pf = filp->private_data; 399 struct ice_hw *hw = &pf->hw; 400 char buff[32] = {}; 401 int index; 402 403 index = hw->fwlog_ring.index; 404 snprintf(buff, sizeof(buff), "%s\n", ice_fwlog_log_size[index]); 405 406 return simple_read_from_buffer(buffer, count, ppos, buff, strlen(buff)); 407 } 408 409 /** 410 * ice_debugfs_log_size_write - write into 'log_size' file 411 * @filp: the opened file 412 * @buf: where to find the user's data 413 * @count: the length of the user's data 414 * @ppos: file position offset 415 */ 416 static ssize_t 417 ice_debugfs_log_size_write(struct file *filp, const char __user *buf, 418 size_t count, loff_t *ppos) 419 { 420 struct ice_pf *pf = filp->private_data; 421 struct device *dev = ice_pf_to_dev(pf); 422 struct ice_hw *hw = &pf->hw; 423 char user_val[8], *cmd_buf; 424 ssize_t ret; 425 int index; 426 427 /* don't allow partial writes or invalid input */ 428 if (*ppos != 0 || count > 5) 429 return -EINVAL; 430 431 cmd_buf = memdup_user_nul(buf, count); 432 if (IS_ERR(cmd_buf)) 433 return PTR_ERR(cmd_buf); 434 435 ret = sscanf(cmd_buf, "%s", user_val); 436 if (ret != 1) 437 return -EINVAL; 438 439 index = sysfs_match_string(ice_fwlog_log_size, user_val); 440 if (index < 0) { 441 dev_info(dev, "Invalid log size '%s'. The value must be one of 128K, 256K, 512K, 1M, 2M\n", 442 user_val); 443 ret = -EINVAL; 444 goto log_size_write_error; 445 } else if (hw->fwlog_cfg.options & ICE_FWLOG_OPTION_IS_REGISTERED) { 446 dev_info(dev, "FW logging is currently running. Please disable FW logging to change log_size\n"); 447 ret = -EINVAL; 448 goto log_size_write_error; 449 } 450 451 /* free all the buffers and the tracking info and resize */ 452 ice_fwlog_realloc_rings(hw, index); 453 454 /* if we get here, nothing went wrong; return count since we didn't 455 * really write anything 456 */ 457 ret = (ssize_t)count; 458 459 log_size_write_error: 460 /* This function always consumes all of the written input, or produces 461 * an error. Check and enforce this. Otherwise, the write operation 462 * won't complete properly. 463 */ 464 if (WARN_ON(ret != (ssize_t)count && ret >= 0)) 465 ret = -EIO; 466 467 return ret; 468 } 469 470 static const struct file_operations ice_debugfs_log_size_fops = { 471 .owner = THIS_MODULE, 472 .open = simple_open, 473 .read = ice_debugfs_log_size_read, 474 .write = ice_debugfs_log_size_write, 475 }; 476 477 /** 478 * ice_debugfs_data_read - read from 'data' file 479 * @filp: the opened file 480 * @buffer: where to write the data for the user to read 481 * @count: the size of the user's buffer 482 * @ppos: file position offset 483 */ 484 static ssize_t ice_debugfs_data_read(struct file *filp, char __user *buffer, 485 size_t count, loff_t *ppos) 486 { 487 struct ice_pf *pf = filp->private_data; 488 struct ice_hw *hw = &pf->hw; 489 int data_copied = 0; 490 bool done = false; 491 492 if (ice_fwlog_ring_empty(&hw->fwlog_ring)) 493 return 0; 494 495 while (!ice_fwlog_ring_empty(&hw->fwlog_ring) && !done) { 496 struct ice_fwlog_data *log; 497 u16 cur_buf_len; 498 499 log = &hw->fwlog_ring.rings[hw->fwlog_ring.head]; 500 cur_buf_len = log->data_size; 501 if (cur_buf_len >= count) { 502 done = true; 503 continue; 504 } 505 506 if (copy_to_user(buffer, log->data, cur_buf_len)) { 507 /* if there is an error then bail and return whatever 508 * the driver has copied so far 509 */ 510 done = true; 511 continue; 512 } 513 514 data_copied += cur_buf_len; 515 buffer += cur_buf_len; 516 count -= cur_buf_len; 517 *ppos += cur_buf_len; 518 ice_fwlog_ring_increment(&hw->fwlog_ring.head, 519 hw->fwlog_ring.size); 520 } 521 522 return data_copied; 523 } 524 525 /** 526 * ice_debugfs_data_write - write into 'data' file 527 * @filp: the opened file 528 * @buf: where to find the user's data 529 * @count: the length of the user's data 530 * @ppos: file position offset 531 */ 532 static ssize_t 533 ice_debugfs_data_write(struct file *filp, const char __user *buf, size_t count, 534 loff_t *ppos) 535 { 536 struct ice_pf *pf = filp->private_data; 537 struct device *dev = ice_pf_to_dev(pf); 538 struct ice_hw *hw = &pf->hw; 539 ssize_t ret; 540 541 /* don't allow partial writes */ 542 if (*ppos != 0) 543 return 0; 544 545 /* any value is allowed to clear the buffer so no need to even look at 546 * what the value is 547 */ 548 if (!(hw->fwlog_cfg.options & ICE_FWLOG_OPTION_IS_REGISTERED)) { 549 hw->fwlog_ring.head = 0; 550 hw->fwlog_ring.tail = 0; 551 } else { 552 dev_info(dev, "Can't clear FW log data while FW log running\n"); 553 ret = -EINVAL; 554 goto nr_buffs_write_error; 555 } 556 557 /* if we get here, nothing went wrong; return count since we didn't 558 * really write anything 559 */ 560 ret = (ssize_t)count; 561 562 nr_buffs_write_error: 563 /* This function always consumes all of the written input, or produces 564 * an error. Check and enforce this. Otherwise, the write operation 565 * won't complete properly. 566 */ 567 if (WARN_ON(ret != (ssize_t)count && ret >= 0)) 568 ret = -EIO; 569 570 return ret; 571 } 572 573 static const struct file_operations ice_debugfs_data_fops = { 574 .owner = THIS_MODULE, 575 .open = simple_open, 576 .read = ice_debugfs_data_read, 577 .write = ice_debugfs_data_write, 578 }; 579 580 /** 581 * ice_debugfs_fwlog_init - setup the debugfs directory 582 * @pf: the ice that is starting up 583 */ 584 void ice_debugfs_fwlog_init(struct ice_pf *pf) 585 { 586 const char *name = pci_name(pf->pdev); 587 struct dentry *fw_modules_dir; 588 struct dentry **fw_modules; 589 int i; 590 591 /* only support fw log commands on PF 0 */ 592 if (pf->hw.bus.func) 593 return; 594 595 /* allocate space for this first because if it fails then we don't 596 * need to unwind 597 */ 598 fw_modules = kcalloc(ICE_NR_FW_LOG_MODULES, sizeof(*fw_modules), 599 GFP_KERNEL); 600 if (!fw_modules) 601 return; 602 603 pf->ice_debugfs_pf = debugfs_create_dir(name, ice_debugfs_root); 604 if (IS_ERR(pf->ice_debugfs_pf)) 605 goto err_create_module_files; 606 607 pf->ice_debugfs_pf_fwlog = debugfs_create_dir("fwlog", 608 pf->ice_debugfs_pf); 609 if (IS_ERR(pf->ice_debugfs_pf)) 610 goto err_create_module_files; 611 612 fw_modules_dir = debugfs_create_dir("modules", 613 pf->ice_debugfs_pf_fwlog); 614 if (IS_ERR(fw_modules_dir)) 615 goto err_create_module_files; 616 617 for (i = 0; i < ICE_NR_FW_LOG_MODULES; i++) { 618 fw_modules[i] = debugfs_create_file(ice_fwlog_module_string[i], 619 0600, fw_modules_dir, pf, 620 &ice_debugfs_module_fops); 621 if (IS_ERR(fw_modules[i])) 622 goto err_create_module_files; 623 } 624 625 debugfs_create_file("nr_messages", 0600, 626 pf->ice_debugfs_pf_fwlog, pf, 627 &ice_debugfs_nr_messages_fops); 628 629 pf->ice_debugfs_pf_fwlog_modules = fw_modules; 630 631 debugfs_create_file("enable", 0600, pf->ice_debugfs_pf_fwlog, 632 pf, &ice_debugfs_enable_fops); 633 634 debugfs_create_file("log_size", 0600, pf->ice_debugfs_pf_fwlog, 635 pf, &ice_debugfs_log_size_fops); 636 637 debugfs_create_file("data", 0600, pf->ice_debugfs_pf_fwlog, 638 pf, &ice_debugfs_data_fops); 639 640 return; 641 642 err_create_module_files: 643 debugfs_remove_recursive(pf->ice_debugfs_pf_fwlog); 644 kfree(fw_modules); 645 } 646 647 /** 648 * ice_debugfs_pf_deinit - cleanup PF's debugfs 649 * @pf: pointer to the PF struct 650 */ 651 void ice_debugfs_pf_deinit(struct ice_pf *pf) 652 { 653 debugfs_remove_recursive(pf->ice_debugfs_pf); 654 pf->ice_debugfs_pf = NULL; 655 } 656 657 /** 658 * ice_debugfs_init - create root directory for debugfs entries 659 */ 660 void ice_debugfs_init(void) 661 { 662 ice_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); 663 if (IS_ERR(ice_debugfs_root)) 664 pr_info("init of debugfs failed\n"); 665 } 666 667 /** 668 * ice_debugfs_exit - remove debugfs entries 669 */ 670 void ice_debugfs_exit(void) 671 { 672 debugfs_remove_recursive(ice_debugfs_root); 673 ice_debugfs_root = NULL; 674 } 675