Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ice: move debugfs code to fwlog

This code is only used in fwlog. Moved it there for easier lib creation.
There is a circular dependency between debugfs and fwlog. Moving to one
file is fixing it.

Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>

authored by

Michal Swiatkowski and committed by
Tony Nguyen
2ab5eb4b 413cf5db

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