1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2022, Intel Corporation. */ 3 4 #include <linux/debugfs.h> 5 #include <linux/export.h> 6 #include <linux/fs.h> 7 #include <linux/net/intel/libie/fwlog.h> 8 #include <linux/pci.h> 9 #include <linux/random.h> 10 #include <linux/vmalloc.h> 11 12 #define DEFAULT_SYMBOL_NAMESPACE "LIBIE_FWLOG" 13 14 /* create a define that has an extra module that doesn't really exist. this 15 * is so we can add a module 'all' to easily enable/disable all the modules 16 */ 17 #define LIBIE_NR_FW_LOG_MODULES (LIBIE_AQC_FW_LOG_ID_MAX + 1) 18 19 /* the ordering in this array is important. it matches the ordering of the 20 * values in the FW so the index is the same value as in 21 * libie_aqc_fw_logging_mod 22 */ 23 static const char * const libie_fwlog_module_string[] = { 24 "general", 25 "ctrl", 26 "link", 27 "link_topo", 28 "dnl", 29 "i2c", 30 "sdp", 31 "mdio", 32 "adminq", 33 "hdma", 34 "lldp", 35 "dcbx", 36 "dcb", 37 "xlr", 38 "nvm", 39 "auth", 40 "vpd", 41 "iosf", 42 "parser", 43 "sw", 44 "scheduler", 45 "txq", 46 "rsvd", 47 "post", 48 "watchdog", 49 "task_dispatch", 50 "mng", 51 "synce", 52 "health", 53 "tsdrv", 54 "pfreg", 55 "mdlver", 56 "all", 57 }; 58 59 /* the ordering in this array is important. it matches the ordering of the 60 * values in the FW so the index is the same value as in libie_fwlog_level 61 */ 62 static const char * const libie_fwlog_level_string[] = { 63 "none", 64 "error", 65 "warning", 66 "normal", 67 "verbose", 68 }; 69 70 static const char * const libie_fwlog_log_size[] = { 71 "128K", 72 "256K", 73 "512K", 74 "1M", 75 "2M", 76 }; 77 78 static bool libie_fwlog_ring_empty(struct libie_fwlog_ring *rings) 79 { 80 return rings->head == rings->tail; 81 } 82 83 static void libie_fwlog_ring_increment(u16 *item, u16 size) 84 { 85 *item = (*item + 1) & (size - 1); 86 } 87 88 static int libie_fwlog_alloc_ring_buffs(struct libie_fwlog_ring *rings) 89 { 90 int i, nr_bytes; 91 u8 *mem; 92 93 nr_bytes = rings->size * LIBIE_AQ_MAX_BUF_LEN; 94 mem = vzalloc(nr_bytes); 95 if (!mem) 96 return -ENOMEM; 97 98 for (i = 0; i < rings->size; i++) { 99 struct libie_fwlog_data *ring = &rings->rings[i]; 100 101 ring->data_size = LIBIE_AQ_MAX_BUF_LEN; 102 ring->data = mem; 103 mem += LIBIE_AQ_MAX_BUF_LEN; 104 } 105 106 return 0; 107 } 108 109 static void libie_fwlog_free_ring_buffs(struct libie_fwlog_ring *rings) 110 { 111 int i; 112 113 for (i = 0; i < rings->size; i++) { 114 struct libie_fwlog_data *ring = &rings->rings[i]; 115 116 /* the first ring is the base memory for the whole range so 117 * free it 118 */ 119 if (!i) 120 vfree(ring->data); 121 122 ring->data = NULL; 123 ring->data_size = 0; 124 } 125 } 126 127 #define LIBIE_FWLOG_INDEX_TO_BYTES(n) ((128 * 1024) << (n)) 128 /** 129 * libie_fwlog_realloc_rings - reallocate the FW log rings 130 * @fwlog: pointer to the fwlog structure 131 * @index: the new index to use to allocate memory for the log data 132 * 133 */ 134 static void libie_fwlog_realloc_rings(struct libie_fwlog *fwlog, int index) 135 { 136 struct libie_fwlog_ring ring; 137 int status, ring_size; 138 139 /* convert the number of bytes into a number of 4K buffers. externally 140 * the driver presents the interface to the FW log data as a number of 141 * bytes because that's easy for users to understand. internally the 142 * driver uses a ring of buffers because the driver doesn't know where 143 * the beginning and end of any line of log data is so the driver has 144 * to overwrite data as complete blocks. when the data is returned to 145 * the user the driver knows that the data is correct and the FW log 146 * can be correctly parsed by the tools 147 */ 148 ring_size = LIBIE_FWLOG_INDEX_TO_BYTES(index) / LIBIE_AQ_MAX_BUF_LEN; 149 if (ring_size == fwlog->ring.size) 150 return; 151 152 /* allocate space for the new rings and buffers then release the 153 * old rings and buffers. that way if we don't have enough 154 * memory then we at least have what we had before 155 */ 156 ring.rings = kcalloc(ring_size, sizeof(*ring.rings), GFP_KERNEL); 157 if (!ring.rings) 158 return; 159 160 ring.size = ring_size; 161 162 status = libie_fwlog_alloc_ring_buffs(&ring); 163 if (status) { 164 dev_warn(&fwlog->pdev->dev, "Unable to allocate memory for FW log ring data buffers\n"); 165 libie_fwlog_free_ring_buffs(&ring); 166 kfree(ring.rings); 167 return; 168 } 169 170 libie_fwlog_free_ring_buffs(&fwlog->ring); 171 kfree(fwlog->ring.rings); 172 173 fwlog->ring.rings = ring.rings; 174 fwlog->ring.size = ring.size; 175 fwlog->ring.index = index; 176 fwlog->ring.head = 0; 177 fwlog->ring.tail = 0; 178 } 179 180 /** 181 * libie_fwlog_supported - Cached for whether FW supports FW logging or not 182 * @fwlog: pointer to the fwlog structure 183 * 184 * This will always return false if called before libie_init_hw(), so it must be 185 * called after libie_init_hw(). 186 */ 187 static bool libie_fwlog_supported(struct libie_fwlog *fwlog) 188 { 189 return fwlog->supported; 190 } 191 192 /** 193 * libie_aq_fwlog_set - Set FW logging configuration AQ command (0xFF30) 194 * @fwlog: pointer to the fwlog structure 195 * @entries: entries to configure 196 * @num_entries: number of @entries 197 * @options: options from libie_fwlog_cfg->options structure 198 * @log_resolution: logging resolution 199 */ 200 static int 201 libie_aq_fwlog_set(struct libie_fwlog *fwlog, 202 struct libie_fwlog_module_entry *entries, u16 num_entries, 203 u16 options, u16 log_resolution) 204 { 205 struct libie_aqc_fw_log_cfg_resp *fw_modules; 206 struct libie_aq_desc desc = {0}; 207 struct libie_aqc_fw_log *cmd; 208 int status; 209 int i; 210 211 fw_modules = kcalloc(num_entries, sizeof(*fw_modules), GFP_KERNEL); 212 if (!fw_modules) 213 return -ENOMEM; 214 215 for (i = 0; i < num_entries; i++) { 216 fw_modules[i].module_identifier = 217 cpu_to_le16(entries[i].module_id); 218 fw_modules[i].log_level = entries[i].log_level; 219 } 220 221 desc.opcode = cpu_to_le16(libie_aqc_opc_fw_logs_config); 222 desc.flags = cpu_to_le16(LIBIE_AQ_FLAG_SI) | 223 cpu_to_le16(LIBIE_AQ_FLAG_RD); 224 225 cmd = libie_aq_raw(&desc); 226 227 cmd->cmd_flags = LIBIE_AQC_FW_LOG_CONF_SET_VALID; 228 cmd->ops.cfg.log_resolution = cpu_to_le16(log_resolution); 229 cmd->ops.cfg.mdl_cnt = cpu_to_le16(num_entries); 230 231 if (options & LIBIE_FWLOG_OPTION_ARQ_ENA) 232 cmd->cmd_flags |= LIBIE_AQC_FW_LOG_CONF_AQ_EN; 233 if (options & LIBIE_FWLOG_OPTION_UART_ENA) 234 cmd->cmd_flags |= LIBIE_AQC_FW_LOG_CONF_UART_EN; 235 236 status = fwlog->send_cmd(fwlog->priv, &desc, fw_modules, 237 sizeof(*fw_modules) * num_entries); 238 239 kfree(fw_modules); 240 241 return status; 242 } 243 244 /** 245 * libie_fwlog_set - Set the firmware logging settings 246 * @fwlog: pointer to the fwlog structure 247 * @cfg: config used to set firmware logging 248 * 249 * This function should be called whenever the driver needs to set the firmware 250 * logging configuration. It can be called on initialization, reset, or during 251 * runtime. 252 * 253 * If the PF wishes to receive FW logging then it must register via 254 * libie_fwlog_register. Note, that libie_fwlog_register does not need to be called 255 * for init. 256 */ 257 static int libie_fwlog_set(struct libie_fwlog *fwlog, 258 struct libie_fwlog_cfg *cfg) 259 { 260 if (!libie_fwlog_supported(fwlog)) 261 return -EOPNOTSUPP; 262 263 return libie_aq_fwlog_set(fwlog, cfg->module_entries, 264 LIBIE_AQC_FW_LOG_ID_MAX, cfg->options, 265 cfg->log_resolution); 266 } 267 268 /** 269 * libie_aq_fwlog_register - Register PF for firmware logging events (0xFF31) 270 * @fwlog: pointer to the fwlog structure 271 * @reg: true to register and false to unregister 272 */ 273 static int libie_aq_fwlog_register(struct libie_fwlog *fwlog, bool reg) 274 { 275 struct libie_aq_desc desc = {0}; 276 struct libie_aqc_fw_log *cmd; 277 278 desc.opcode = cpu_to_le16(libie_aqc_opc_fw_logs_register); 279 desc.flags = cpu_to_le16(LIBIE_AQ_FLAG_SI); 280 cmd = libie_aq_raw(&desc); 281 282 if (reg) 283 cmd->cmd_flags = LIBIE_AQC_FW_LOG_AQ_REGISTER; 284 285 return fwlog->send_cmd(fwlog->priv, &desc, NULL, 0); 286 } 287 288 /** 289 * libie_fwlog_register - Register the PF for firmware logging 290 * @fwlog: pointer to the fwlog structure 291 * 292 * After this call the PF will start to receive firmware logging based on the 293 * configuration set in libie_fwlog_set. 294 */ 295 static int libie_fwlog_register(struct libie_fwlog *fwlog) 296 { 297 int status; 298 299 if (!libie_fwlog_supported(fwlog)) 300 return -EOPNOTSUPP; 301 302 status = libie_aq_fwlog_register(fwlog, true); 303 if (status) 304 dev_dbg(&fwlog->pdev->dev, "Failed to register for firmware logging events over ARQ\n"); 305 else 306 fwlog->cfg.options |= LIBIE_FWLOG_OPTION_IS_REGISTERED; 307 308 return status; 309 } 310 311 /** 312 * libie_fwlog_unregister - Unregister the PF from firmware logging 313 * @fwlog: pointer to the fwlog structure 314 */ 315 static int libie_fwlog_unregister(struct libie_fwlog *fwlog) 316 { 317 int status; 318 319 if (!libie_fwlog_supported(fwlog)) 320 return -EOPNOTSUPP; 321 322 status = libie_aq_fwlog_register(fwlog, false); 323 if (status) 324 dev_dbg(&fwlog->pdev->dev, "Failed to unregister from firmware logging events over ARQ\n"); 325 else 326 fwlog->cfg.options &= ~LIBIE_FWLOG_OPTION_IS_REGISTERED; 327 328 return status; 329 } 330 331 /** 332 * libie_fwlog_print_module_cfg - print current FW logging module configuration 333 * @cfg: pointer to the fwlog cfg structure 334 * @module: module to print 335 * @s: the seq file to put data into 336 */ 337 static void 338 libie_fwlog_print_module_cfg(struct libie_fwlog_cfg *cfg, int module, 339 struct seq_file *s) 340 { 341 struct libie_fwlog_module_entry *entry; 342 343 if (module != LIBIE_AQC_FW_LOG_ID_MAX) { 344 entry = &cfg->module_entries[module]; 345 346 seq_printf(s, "\tModule: %s, Log Level: %s\n", 347 libie_fwlog_module_string[entry->module_id], 348 libie_fwlog_level_string[entry->log_level]); 349 } else { 350 int i; 351 352 for (i = 0; i < LIBIE_AQC_FW_LOG_ID_MAX; i++) { 353 entry = &cfg->module_entries[i]; 354 355 seq_printf(s, "\tModule: %s, Log Level: %s\n", 356 libie_fwlog_module_string[entry->module_id], 357 libie_fwlog_level_string[entry->log_level]); 358 } 359 } 360 } 361 362 static int libie_find_module_by_dentry(struct dentry **modules, struct dentry *d) 363 { 364 int i, module; 365 366 module = -1; 367 /* find the module based on the dentry */ 368 for (i = 0; i < LIBIE_NR_FW_LOG_MODULES; i++) { 369 if (d == modules[i]) { 370 module = i; 371 break; 372 } 373 } 374 375 return module; 376 } 377 378 /** 379 * libie_debugfs_module_show - read from 'module' file 380 * @s: the opened file 381 * @v: pointer to the offset 382 */ 383 static int libie_debugfs_module_show(struct seq_file *s, void *v) 384 { 385 struct libie_fwlog *fwlog = s->private; 386 const struct file *filp = s->file; 387 struct dentry *dentry; 388 int module; 389 390 dentry = file_dentry(filp); 391 392 module = libie_find_module_by_dentry(fwlog->debugfs_modules, dentry); 393 if (module < 0) { 394 dev_info(&fwlog->pdev->dev, "unknown module\n"); 395 return -EINVAL; 396 } 397 398 libie_fwlog_print_module_cfg(&fwlog->cfg, module, s); 399 400 return 0; 401 } 402 403 static int libie_debugfs_module_open(struct inode *inode, struct file *filp) 404 { 405 return single_open(filp, libie_debugfs_module_show, inode->i_private); 406 } 407 408 /** 409 * libie_debugfs_module_write - write into 'module' file 410 * @filp: the opened file 411 * @buf: where to find the user's data 412 * @count: the length of the user's data 413 * @ppos: file position offset 414 */ 415 static ssize_t 416 libie_debugfs_module_write(struct file *filp, const char __user *buf, 417 size_t count, loff_t *ppos) 418 { 419 struct libie_fwlog *fwlog = file_inode(filp)->i_private; 420 struct dentry *dentry = file_dentry(filp); 421 struct device *dev = &fwlog->pdev->dev; 422 char user_val[16], *cmd_buf; 423 int module, log_level, cnt; 424 425 /* don't allow partial writes or invalid input */ 426 if (*ppos != 0 || count > 8) 427 return -EINVAL; 428 429 cmd_buf = memdup_user_nul(buf, count); 430 if (IS_ERR(cmd_buf)) 431 return PTR_ERR(cmd_buf); 432 433 module = libie_find_module_by_dentry(fwlog->debugfs_modules, dentry); 434 if (module < 0) { 435 dev_info(dev, "unknown module\n"); 436 return -EINVAL; 437 } 438 439 cnt = sscanf(cmd_buf, "%s", user_val); 440 if (cnt != 1) 441 return -EINVAL; 442 443 log_level = sysfs_match_string(libie_fwlog_level_string, user_val); 444 if (log_level < 0) { 445 dev_info(dev, "unknown log level '%s'\n", user_val); 446 return -EINVAL; 447 } 448 449 if (module != LIBIE_AQC_FW_LOG_ID_MAX) { 450 fwlog->cfg.module_entries[module].log_level = log_level; 451 } else { 452 /* the module 'all' is a shortcut so that we can set 453 * all of the modules to the same level quickly 454 */ 455 int i; 456 457 for (i = 0; i < LIBIE_AQC_FW_LOG_ID_MAX; i++) 458 fwlog->cfg.module_entries[i].log_level = log_level; 459 } 460 461 return count; 462 } 463 464 static const struct file_operations libie_debugfs_module_fops = { 465 .owner = THIS_MODULE, 466 .open = libie_debugfs_module_open, 467 .read = seq_read, 468 .release = single_release, 469 .write = libie_debugfs_module_write, 470 }; 471 472 /** 473 * libie_debugfs_nr_messages_read - read from 'nr_messages' file 474 * @filp: the opened file 475 * @buffer: where to write the data for the user to read 476 * @count: the size of the user's buffer 477 * @ppos: file position offset 478 */ 479 static ssize_t libie_debugfs_nr_messages_read(struct file *filp, 480 char __user *buffer, size_t count, 481 loff_t *ppos) 482 { 483 struct libie_fwlog *fwlog = filp->private_data; 484 char buff[32] = {}; 485 486 snprintf(buff, sizeof(buff), "%d\n", 487 fwlog->cfg.log_resolution); 488 489 return simple_read_from_buffer(buffer, count, ppos, buff, strlen(buff)); 490 } 491 492 /** 493 * libie_debugfs_nr_messages_write - write into 'nr_messages' file 494 * @filp: the opened file 495 * @buf: where to find the user's data 496 * @count: the length of the user's data 497 * @ppos: file position offset 498 */ 499 static ssize_t 500 libie_debugfs_nr_messages_write(struct file *filp, const char __user *buf, 501 size_t count, loff_t *ppos) 502 { 503 struct libie_fwlog *fwlog = filp->private_data; 504 struct device *dev = &fwlog->pdev->dev; 505 char user_val[8], *cmd_buf; 506 s16 nr_messages; 507 ssize_t ret; 508 509 /* don't allow partial writes or invalid input */ 510 if (*ppos != 0 || count > 4) 511 return -EINVAL; 512 513 cmd_buf = memdup_user_nul(buf, count); 514 if (IS_ERR(cmd_buf)) 515 return PTR_ERR(cmd_buf); 516 517 ret = sscanf(cmd_buf, "%s", user_val); 518 if (ret != 1) 519 return -EINVAL; 520 521 ret = kstrtos16(user_val, 0, &nr_messages); 522 if (ret) 523 return ret; 524 525 if (nr_messages < LIBIE_AQC_FW_LOG_MIN_RESOLUTION || 526 nr_messages > LIBIE_AQC_FW_LOG_MAX_RESOLUTION) { 527 dev_err(dev, "Invalid FW log number of messages %d, value must be between %d - %d\n", 528 nr_messages, LIBIE_AQC_FW_LOG_MIN_RESOLUTION, 529 LIBIE_AQC_FW_LOG_MAX_RESOLUTION); 530 return -EINVAL; 531 } 532 533 fwlog->cfg.log_resolution = nr_messages; 534 535 return count; 536 } 537 538 static const struct file_operations libie_debugfs_nr_messages_fops = { 539 .owner = THIS_MODULE, 540 .open = simple_open, 541 .read = libie_debugfs_nr_messages_read, 542 .write = libie_debugfs_nr_messages_write, 543 }; 544 545 /** 546 * libie_debugfs_enable_read - read from 'enable' file 547 * @filp: the opened file 548 * @buffer: where to write the data for the user to read 549 * @count: the size of the user's buffer 550 * @ppos: file position offset 551 */ 552 static ssize_t libie_debugfs_enable_read(struct file *filp, 553 char __user *buffer, size_t count, 554 loff_t *ppos) 555 { 556 struct libie_fwlog *fwlog = filp->private_data; 557 char buff[32] = {}; 558 559 snprintf(buff, sizeof(buff), "%u\n", 560 (u16)(fwlog->cfg.options & 561 LIBIE_FWLOG_OPTION_IS_REGISTERED) >> 3); 562 563 return simple_read_from_buffer(buffer, count, ppos, buff, strlen(buff)); 564 } 565 566 /** 567 * libie_debugfs_enable_write - write into 'enable' file 568 * @filp: the opened file 569 * @buf: where to find the user's data 570 * @count: the length of the user's data 571 * @ppos: file position offset 572 */ 573 static ssize_t 574 libie_debugfs_enable_write(struct file *filp, const char __user *buf, 575 size_t count, loff_t *ppos) 576 { 577 struct libie_fwlog *fwlog = filp->private_data; 578 char user_val[8], *cmd_buf; 579 bool enable; 580 ssize_t ret; 581 582 /* don't allow partial writes or invalid input */ 583 if (*ppos != 0 || count > 2) 584 return -EINVAL; 585 586 cmd_buf = memdup_user_nul(buf, count); 587 if (IS_ERR(cmd_buf)) 588 return PTR_ERR(cmd_buf); 589 590 ret = sscanf(cmd_buf, "%s", user_val); 591 if (ret != 1) 592 return -EINVAL; 593 594 ret = kstrtobool(user_val, &enable); 595 if (ret) 596 goto enable_write_error; 597 598 if (enable) 599 fwlog->cfg.options |= LIBIE_FWLOG_OPTION_ARQ_ENA; 600 else 601 fwlog->cfg.options &= ~LIBIE_FWLOG_OPTION_ARQ_ENA; 602 603 ret = libie_fwlog_set(fwlog, &fwlog->cfg); 604 if (ret) 605 goto enable_write_error; 606 607 if (enable) 608 ret = libie_fwlog_register(fwlog); 609 else 610 ret = libie_fwlog_unregister(fwlog); 611 612 if (ret) 613 goto enable_write_error; 614 615 /* if we get here, nothing went wrong; return count since we didn't 616 * really write anything 617 */ 618 ret = (ssize_t)count; 619 620 enable_write_error: 621 /* This function always consumes all of the written input, or produces 622 * an error. Check and enforce this. Otherwise, the write operation 623 * won't complete properly. 624 */ 625 if (WARN_ON(ret != (ssize_t)count && ret >= 0)) 626 ret = -EIO; 627 628 return ret; 629 } 630 631 static const struct file_operations libie_debugfs_enable_fops = { 632 .owner = THIS_MODULE, 633 .open = simple_open, 634 .read = libie_debugfs_enable_read, 635 .write = libie_debugfs_enable_write, 636 }; 637 638 /** 639 * libie_debugfs_log_size_read - read from 'log_size' file 640 * @filp: the opened file 641 * @buffer: where to write the data for the user to read 642 * @count: the size of the user's buffer 643 * @ppos: file position offset 644 */ 645 static ssize_t libie_debugfs_log_size_read(struct file *filp, 646 char __user *buffer, size_t count, 647 loff_t *ppos) 648 { 649 struct libie_fwlog *fwlog = filp->private_data; 650 char buff[32] = {}; 651 int index; 652 653 index = fwlog->ring.index; 654 snprintf(buff, sizeof(buff), "%s\n", libie_fwlog_log_size[index]); 655 656 return simple_read_from_buffer(buffer, count, ppos, buff, strlen(buff)); 657 } 658 659 /** 660 * libie_debugfs_log_size_write - write into 'log_size' file 661 * @filp: the opened file 662 * @buf: where to find the user's data 663 * @count: the length of the user's data 664 * @ppos: file position offset 665 */ 666 static ssize_t 667 libie_debugfs_log_size_write(struct file *filp, const char __user *buf, 668 size_t count, loff_t *ppos) 669 { 670 struct libie_fwlog *fwlog = filp->private_data; 671 struct device *dev = &fwlog->pdev->dev; 672 char user_val[8], *cmd_buf; 673 ssize_t ret; 674 int index; 675 676 /* don't allow partial writes or invalid input */ 677 if (*ppos != 0 || count > 5) 678 return -EINVAL; 679 680 cmd_buf = memdup_user_nul(buf, count); 681 if (IS_ERR(cmd_buf)) 682 return PTR_ERR(cmd_buf); 683 684 ret = sscanf(cmd_buf, "%s", user_val); 685 if (ret != 1) 686 return -EINVAL; 687 688 index = sysfs_match_string(libie_fwlog_log_size, user_val); 689 if (index < 0) { 690 dev_info(dev, "Invalid log size '%s'. The value must be one of 128K, 256K, 512K, 1M, 2M\n", 691 user_val); 692 ret = -EINVAL; 693 goto log_size_write_error; 694 } else if (fwlog->cfg.options & LIBIE_FWLOG_OPTION_IS_REGISTERED) { 695 dev_info(dev, "FW logging is currently running. Please disable FW logging to change log_size\n"); 696 ret = -EINVAL; 697 goto log_size_write_error; 698 } 699 700 /* free all the buffers and the tracking info and resize */ 701 libie_fwlog_realloc_rings(fwlog, index); 702 703 /* if we get here, nothing went wrong; return count since we didn't 704 * really write anything 705 */ 706 ret = (ssize_t)count; 707 708 log_size_write_error: 709 /* This function always consumes all of the written input, or produces 710 * an error. Check and enforce this. Otherwise, the write operation 711 * won't complete properly. 712 */ 713 if (WARN_ON(ret != (ssize_t)count && ret >= 0)) 714 ret = -EIO; 715 716 return ret; 717 } 718 719 static const struct file_operations libie_debugfs_log_size_fops = { 720 .owner = THIS_MODULE, 721 .open = simple_open, 722 .read = libie_debugfs_log_size_read, 723 .write = libie_debugfs_log_size_write, 724 }; 725 726 /** 727 * libie_debugfs_data_read - read from 'data' file 728 * @filp: the opened file 729 * @buffer: where to write the data for the user to read 730 * @count: the size of the user's buffer 731 * @ppos: file position offset 732 */ 733 static ssize_t libie_debugfs_data_read(struct file *filp, char __user *buffer, 734 size_t count, loff_t *ppos) 735 { 736 struct libie_fwlog *fwlog = filp->private_data; 737 int data_copied = 0; 738 bool done = false; 739 740 if (libie_fwlog_ring_empty(&fwlog->ring)) 741 return 0; 742 743 while (!libie_fwlog_ring_empty(&fwlog->ring) && !done) { 744 struct libie_fwlog_data *log; 745 u16 cur_buf_len; 746 747 log = &fwlog->ring.rings[fwlog->ring.head]; 748 cur_buf_len = log->data_size; 749 if (cur_buf_len >= count) { 750 done = true; 751 continue; 752 } 753 754 if (copy_to_user(buffer, log->data, cur_buf_len)) { 755 /* if there is an error then bail and return whatever 756 * the driver has copied so far 757 */ 758 done = true; 759 continue; 760 } 761 762 data_copied += cur_buf_len; 763 buffer += cur_buf_len; 764 count -= cur_buf_len; 765 *ppos += cur_buf_len; 766 libie_fwlog_ring_increment(&fwlog->ring.head, fwlog->ring.size); 767 } 768 769 return data_copied; 770 } 771 772 /** 773 * libie_debugfs_data_write - write into 'data' file 774 * @filp: the opened file 775 * @buf: where to find the user's data 776 * @count: the length of the user's data 777 * @ppos: file position offset 778 */ 779 static ssize_t 780 libie_debugfs_data_write(struct file *filp, const char __user *buf, size_t count, 781 loff_t *ppos) 782 { 783 struct libie_fwlog *fwlog = filp->private_data; 784 struct device *dev = &fwlog->pdev->dev; 785 ssize_t ret; 786 787 /* don't allow partial writes */ 788 if (*ppos != 0) 789 return 0; 790 791 /* any value is allowed to clear the buffer so no need to even look at 792 * what the value is 793 */ 794 if (!(fwlog->cfg.options & LIBIE_FWLOG_OPTION_IS_REGISTERED)) { 795 fwlog->ring.head = 0; 796 fwlog->ring.tail = 0; 797 } else { 798 dev_info(dev, "Can't clear FW log data while FW log running\n"); 799 ret = -EINVAL; 800 goto nr_buffs_write_error; 801 } 802 803 /* if we get here, nothing went wrong; return count since we didn't 804 * really write anything 805 */ 806 ret = (ssize_t)count; 807 808 nr_buffs_write_error: 809 /* This function always consumes all of the written input, or produces 810 * an error. Check and enforce this. Otherwise, the write operation 811 * won't complete properly. 812 */ 813 if (WARN_ON(ret != (ssize_t)count && ret >= 0)) 814 ret = -EIO; 815 816 return ret; 817 } 818 819 static const struct file_operations libie_debugfs_data_fops = { 820 .owner = THIS_MODULE, 821 .open = simple_open, 822 .read = libie_debugfs_data_read, 823 .write = libie_debugfs_data_write, 824 }; 825 826 /** 827 * libie_debugfs_fwlog_init - setup the debugfs directory 828 * @fwlog: pointer to the fwlog structure 829 * @root: debugfs root entry on which fwlog director will be registered 830 */ 831 static void libie_debugfs_fwlog_init(struct libie_fwlog *fwlog, 832 struct dentry *root) 833 { 834 struct dentry *fw_modules_dir; 835 struct dentry **fw_modules; 836 int i; 837 838 /* allocate space for this first because if it fails then we don't 839 * need to unwind 840 */ 841 fw_modules = kcalloc(LIBIE_NR_FW_LOG_MODULES, sizeof(*fw_modules), 842 GFP_KERNEL); 843 if (!fw_modules) 844 return; 845 846 fwlog->debugfs = debugfs_create_dir("fwlog", root); 847 if (IS_ERR(fwlog->debugfs)) 848 goto err_create_module_files; 849 850 fw_modules_dir = debugfs_create_dir("modules", fwlog->debugfs); 851 if (IS_ERR(fw_modules_dir)) 852 goto err_create_module_files; 853 854 for (i = 0; i < LIBIE_NR_FW_LOG_MODULES; i++) { 855 fw_modules[i] = debugfs_create_file(libie_fwlog_module_string[i], 856 0600, fw_modules_dir, fwlog, 857 &libie_debugfs_module_fops); 858 if (IS_ERR(fw_modules[i])) 859 goto err_create_module_files; 860 } 861 862 debugfs_create_file("nr_messages", 0600, fwlog->debugfs, fwlog, 863 &libie_debugfs_nr_messages_fops); 864 865 fwlog->debugfs_modules = fw_modules; 866 867 debugfs_create_file("enable", 0600, fwlog->debugfs, fwlog, 868 &libie_debugfs_enable_fops); 869 870 debugfs_create_file("log_size", 0600, fwlog->debugfs, fwlog, 871 &libie_debugfs_log_size_fops); 872 873 debugfs_create_file("data", 0600, fwlog->debugfs, fwlog, 874 &libie_debugfs_data_fops); 875 876 return; 877 878 err_create_module_files: 879 debugfs_remove_recursive(fwlog->debugfs); 880 kfree(fw_modules); 881 } 882 883 static bool libie_fwlog_ring_full(struct libie_fwlog_ring *rings) 884 { 885 u16 head, tail; 886 887 head = rings->head; 888 tail = rings->tail; 889 890 if (head < tail && (tail - head == (rings->size - 1))) 891 return true; 892 else if (head > tail && (tail == (head - 1))) 893 return true; 894 895 return false; 896 } 897 898 /** 899 * libie_aq_fwlog_get - Get the current firmware logging configuration (0xFF32) 900 * @fwlog: pointer to the fwlog structure 901 * @cfg: firmware logging configuration to populate 902 */ 903 static int libie_aq_fwlog_get(struct libie_fwlog *fwlog, 904 struct libie_fwlog_cfg *cfg) 905 { 906 struct libie_aqc_fw_log_cfg_resp *fw_modules; 907 struct libie_aq_desc desc = {0}; 908 struct libie_aqc_fw_log *cmd; 909 u16 module_id_cnt; 910 int status; 911 void *buf; 912 int i; 913 914 memset(cfg, 0, sizeof(*cfg)); 915 916 buf = kzalloc(LIBIE_AQ_MAX_BUF_LEN, GFP_KERNEL); 917 if (!buf) 918 return -ENOMEM; 919 920 desc.opcode = cpu_to_le16(libie_aqc_opc_fw_logs_query); 921 desc.flags = cpu_to_le16(LIBIE_AQ_FLAG_SI); 922 cmd = libie_aq_raw(&desc); 923 924 cmd->cmd_flags = LIBIE_AQC_FW_LOG_AQ_QUERY; 925 926 status = fwlog->send_cmd(fwlog->priv, &desc, buf, LIBIE_AQ_MAX_BUF_LEN); 927 if (status) { 928 dev_dbg(&fwlog->pdev->dev, "Failed to get FW log configuration\n"); 929 goto status_out; 930 } 931 932 module_id_cnt = le16_to_cpu(cmd->ops.cfg.mdl_cnt); 933 if (module_id_cnt < LIBIE_AQC_FW_LOG_ID_MAX) { 934 dev_dbg(&fwlog->pdev->dev, "FW returned less than the expected number of FW log module IDs\n"); 935 } else if (module_id_cnt > LIBIE_AQC_FW_LOG_ID_MAX) { 936 dev_dbg(&fwlog->pdev->dev, "FW returned more than expected number of FW log module IDs, setting module_id_cnt to software expected max %u\n", 937 LIBIE_AQC_FW_LOG_ID_MAX); 938 module_id_cnt = LIBIE_AQC_FW_LOG_ID_MAX; 939 } 940 941 cfg->log_resolution = le16_to_cpu(cmd->ops.cfg.log_resolution); 942 if (cmd->cmd_flags & LIBIE_AQC_FW_LOG_CONF_AQ_EN) 943 cfg->options |= LIBIE_FWLOG_OPTION_ARQ_ENA; 944 if (cmd->cmd_flags & LIBIE_AQC_FW_LOG_CONF_UART_EN) 945 cfg->options |= LIBIE_FWLOG_OPTION_UART_ENA; 946 if (cmd->cmd_flags & LIBIE_AQC_FW_LOG_QUERY_REGISTERED) 947 cfg->options |= LIBIE_FWLOG_OPTION_IS_REGISTERED; 948 949 fw_modules = (struct libie_aqc_fw_log_cfg_resp *)buf; 950 951 for (i = 0; i < module_id_cnt; i++) { 952 struct libie_aqc_fw_log_cfg_resp *fw_module = &fw_modules[i]; 953 954 cfg->module_entries[i].module_id = 955 le16_to_cpu(fw_module->module_identifier); 956 cfg->module_entries[i].log_level = fw_module->log_level; 957 } 958 959 status_out: 960 kfree(buf); 961 return status; 962 } 963 964 /** 965 * libie_fwlog_set_supported - Set if FW logging is supported by FW 966 * @fwlog: pointer to the fwlog structure 967 * 968 * If FW returns success to the libie_aq_fwlog_get call then it supports FW 969 * logging, else it doesn't. Set the fwlog_supported flag accordingly. 970 * 971 * This function is only meant to be called during driver init to determine if 972 * the FW support FW logging. 973 */ 974 static void libie_fwlog_set_supported(struct libie_fwlog *fwlog) 975 { 976 struct libie_fwlog_cfg *cfg; 977 int status; 978 979 fwlog->supported = false; 980 981 cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); 982 if (!cfg) 983 return; 984 985 status = libie_aq_fwlog_get(fwlog, cfg); 986 if (status) 987 dev_dbg(&fwlog->pdev->dev, "libie_aq_fwlog_get failed, FW logging is not supported on this version of FW, status %d\n", 988 status); 989 else 990 fwlog->supported = true; 991 992 kfree(cfg); 993 } 994 995 /** 996 * libie_fwlog_init - Initialize FW logging configuration 997 * @fwlog: pointer to the fwlog structure 998 * @api: api structure to init fwlog 999 * 1000 * This function should be called on driver initialization during 1001 * libie_init_hw(). 1002 */ 1003 int libie_fwlog_init(struct libie_fwlog *fwlog, struct libie_fwlog_api *api) 1004 { 1005 fwlog->api = *api; 1006 libie_fwlog_set_supported(fwlog); 1007 1008 if (libie_fwlog_supported(fwlog)) { 1009 int status; 1010 1011 /* read the current config from the FW and store it */ 1012 status = libie_aq_fwlog_get(fwlog, &fwlog->cfg); 1013 if (status) 1014 return status; 1015 1016 fwlog->ring.rings = kcalloc(LIBIE_FWLOG_RING_SIZE_DFLT, 1017 sizeof(*fwlog->ring.rings), 1018 GFP_KERNEL); 1019 if (!fwlog->ring.rings) { 1020 dev_warn(&fwlog->pdev->dev, "Unable to allocate memory for FW log rings\n"); 1021 return -ENOMEM; 1022 } 1023 1024 fwlog->ring.size = LIBIE_FWLOG_RING_SIZE_DFLT; 1025 fwlog->ring.index = LIBIE_FWLOG_RING_SIZE_INDEX_DFLT; 1026 1027 status = libie_fwlog_alloc_ring_buffs(&fwlog->ring); 1028 if (status) { 1029 dev_warn(&fwlog->pdev->dev, "Unable to allocate memory for FW log ring data buffers\n"); 1030 libie_fwlog_free_ring_buffs(&fwlog->ring); 1031 kfree(fwlog->ring.rings); 1032 return status; 1033 } 1034 1035 libie_debugfs_fwlog_init(fwlog, api->debugfs_root); 1036 } else { 1037 dev_warn(&fwlog->pdev->dev, "FW logging is not supported in this NVM image. Please update the NVM to get FW log support\n"); 1038 } 1039 1040 return 0; 1041 } 1042 EXPORT_SYMBOL_GPL(libie_fwlog_init); 1043 1044 /** 1045 * libie_fwlog_deinit - unroll FW logging configuration 1046 * @fwlog: pointer to the fwlog structure 1047 * 1048 * This function should be called in libie_deinit_hw(). 1049 */ 1050 void libie_fwlog_deinit(struct libie_fwlog *fwlog) 1051 { 1052 int status; 1053 1054 /* make sure FW logging is disabled to not put the FW in a weird state 1055 * for the next driver load 1056 */ 1057 fwlog->cfg.options &= ~LIBIE_FWLOG_OPTION_ARQ_ENA; 1058 status = libie_fwlog_set(fwlog, &fwlog->cfg); 1059 if (status) 1060 dev_warn(&fwlog->pdev->dev, "Unable to turn off FW logging, status: %d\n", 1061 status); 1062 1063 kfree(fwlog->debugfs_modules); 1064 1065 fwlog->debugfs_modules = NULL; 1066 1067 status = libie_fwlog_unregister(fwlog); 1068 if (status) 1069 dev_warn(&fwlog->pdev->dev, "Unable to unregister FW logging, status: %d\n", 1070 status); 1071 1072 if (fwlog->ring.rings) { 1073 libie_fwlog_free_ring_buffs(&fwlog->ring); 1074 kfree(fwlog->ring.rings); 1075 } 1076 } 1077 EXPORT_SYMBOL_GPL(libie_fwlog_deinit); 1078 1079 /** 1080 * libie_get_fwlog_data - copy the FW log data from ARQ event 1081 * @fwlog: fwlog that the FW log event is associated with 1082 * @buf: event buffer pointer 1083 * @len: len of event descriptor 1084 */ 1085 void libie_get_fwlog_data(struct libie_fwlog *fwlog, u8 *buf, u16 len) 1086 { 1087 struct libie_fwlog_data *log; 1088 1089 log = &fwlog->ring.rings[fwlog->ring.tail]; 1090 1091 memset(log->data, 0, PAGE_SIZE); 1092 log->data_size = len; 1093 1094 memcpy(log->data, buf, log->data_size); 1095 libie_fwlog_ring_increment(&fwlog->ring.tail, fwlog->ring.size); 1096 1097 if (libie_fwlog_ring_full(&fwlog->ring)) { 1098 /* the rings are full so bump the head to create room */ 1099 libie_fwlog_ring_increment(&fwlog->ring.head, fwlog->ring.size); 1100 } 1101 } 1102 EXPORT_SYMBOL_GPL(libie_get_fwlog_data); 1103 1104 void libie_fwlog_reregister(struct libie_fwlog *fwlog) 1105 { 1106 if (!(fwlog->cfg.options & LIBIE_FWLOG_OPTION_IS_REGISTERED)) 1107 return; 1108 1109 if (libie_fwlog_register(fwlog)) 1110 fwlog->cfg.options &= ~LIBIE_FWLOG_OPTION_IS_REGISTERED; 1111 } 1112 EXPORT_SYMBOL_GPL(libie_fwlog_reregister); 1113 1114 MODULE_DESCRIPTION("Intel(R) Ethernet common library"); 1115 MODULE_LICENSE("GPL"); 1116