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 = kzalloc_objs(*ring.rings, ring_size); 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 = kzalloc_objs(*fw_modules, num_entries); 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 count = -EINVAL; 437 goto free_cmd_buf; 438 } 439 440 cnt = sscanf(cmd_buf, "%s", user_val); 441 if (cnt != 1) { 442 count = -EINVAL; 443 goto free_cmd_buf; 444 } 445 446 log_level = sysfs_match_string(libie_fwlog_level_string, user_val); 447 if (log_level < 0) { 448 dev_info(dev, "unknown log level '%s'\n", user_val); 449 count = -EINVAL; 450 goto free_cmd_buf; 451 } 452 453 if (module != LIBIE_AQC_FW_LOG_ID_MAX) { 454 fwlog->cfg.module_entries[module].log_level = log_level; 455 } else { 456 /* the module 'all' is a shortcut so that we can set 457 * all of the modules to the same level quickly 458 */ 459 int i; 460 461 for (i = 0; i < LIBIE_AQC_FW_LOG_ID_MAX; i++) 462 fwlog->cfg.module_entries[i].log_level = log_level; 463 } 464 465 free_cmd_buf: 466 kfree(cmd_buf); 467 468 return count; 469 } 470 471 static const struct file_operations libie_debugfs_module_fops = { 472 .owner = THIS_MODULE, 473 .open = libie_debugfs_module_open, 474 .read = seq_read, 475 .release = single_release, 476 .write = libie_debugfs_module_write, 477 }; 478 479 /** 480 * libie_debugfs_nr_messages_read - read from 'nr_messages' file 481 * @filp: the opened file 482 * @buffer: where to write the data for the user to read 483 * @count: the size of the user's buffer 484 * @ppos: file position offset 485 */ 486 static ssize_t libie_debugfs_nr_messages_read(struct file *filp, 487 char __user *buffer, size_t count, 488 loff_t *ppos) 489 { 490 struct libie_fwlog *fwlog = filp->private_data; 491 char buff[32] = {}; 492 493 snprintf(buff, sizeof(buff), "%d\n", 494 fwlog->cfg.log_resolution); 495 496 return simple_read_from_buffer(buffer, count, ppos, buff, strlen(buff)); 497 } 498 499 /** 500 * libie_debugfs_nr_messages_write - write into 'nr_messages' file 501 * @filp: the opened file 502 * @buf: where to find the user's data 503 * @count: the length of the user's data 504 * @ppos: file position offset 505 */ 506 static ssize_t 507 libie_debugfs_nr_messages_write(struct file *filp, const char __user *buf, 508 size_t count, loff_t *ppos) 509 { 510 struct libie_fwlog *fwlog = filp->private_data; 511 struct device *dev = &fwlog->pdev->dev; 512 char user_val[8], *cmd_buf; 513 s16 nr_messages; 514 ssize_t ret; 515 516 /* don't allow partial writes or invalid input */ 517 if (*ppos != 0 || count > 4) 518 return -EINVAL; 519 520 cmd_buf = memdup_user_nul(buf, count); 521 if (IS_ERR(cmd_buf)) 522 return PTR_ERR(cmd_buf); 523 524 ret = sscanf(cmd_buf, "%s", user_val); 525 if (ret != 1) { 526 count = -EINVAL; 527 goto free_cmd_buf; 528 } 529 530 ret = kstrtos16(user_val, 0, &nr_messages); 531 if (ret) { 532 count = ret; 533 goto free_cmd_buf; 534 } 535 536 if (nr_messages < LIBIE_AQC_FW_LOG_MIN_RESOLUTION || 537 nr_messages > LIBIE_AQC_FW_LOG_MAX_RESOLUTION) { 538 dev_err(dev, "Invalid FW log number of messages %d, value must be between %d - %d\n", 539 nr_messages, LIBIE_AQC_FW_LOG_MIN_RESOLUTION, 540 LIBIE_AQC_FW_LOG_MAX_RESOLUTION); 541 count = -EINVAL; 542 goto free_cmd_buf; 543 } 544 545 fwlog->cfg.log_resolution = nr_messages; 546 547 free_cmd_buf: 548 kfree(cmd_buf); 549 550 return count; 551 } 552 553 static const struct file_operations libie_debugfs_nr_messages_fops = { 554 .owner = THIS_MODULE, 555 .open = simple_open, 556 .read = libie_debugfs_nr_messages_read, 557 .write = libie_debugfs_nr_messages_write, 558 }; 559 560 /** 561 * libie_debugfs_enable_read - read from 'enable' file 562 * @filp: the opened file 563 * @buffer: where to write the data for the user to read 564 * @count: the size of the user's buffer 565 * @ppos: file position offset 566 */ 567 static ssize_t libie_debugfs_enable_read(struct file *filp, 568 char __user *buffer, size_t count, 569 loff_t *ppos) 570 { 571 struct libie_fwlog *fwlog = filp->private_data; 572 char buff[32] = {}; 573 574 snprintf(buff, sizeof(buff), "%u\n", 575 (u16)(fwlog->cfg.options & 576 LIBIE_FWLOG_OPTION_IS_REGISTERED) >> 3); 577 578 return simple_read_from_buffer(buffer, count, ppos, buff, strlen(buff)); 579 } 580 581 /** 582 * libie_debugfs_enable_write - write into 'enable' file 583 * @filp: the opened file 584 * @buf: where to find the user's data 585 * @count: the length of the user's data 586 * @ppos: file position offset 587 */ 588 static ssize_t 589 libie_debugfs_enable_write(struct file *filp, const char __user *buf, 590 size_t count, loff_t *ppos) 591 { 592 struct libie_fwlog *fwlog = filp->private_data; 593 char user_val[8], *cmd_buf; 594 bool enable; 595 ssize_t ret; 596 597 /* don't allow partial writes or invalid input */ 598 if (*ppos != 0 || count > 2) 599 return -EINVAL; 600 601 cmd_buf = memdup_user_nul(buf, count); 602 if (IS_ERR(cmd_buf)) 603 return PTR_ERR(cmd_buf); 604 605 ret = sscanf(cmd_buf, "%s", user_val); 606 if (ret != 1) { 607 ret = -EINVAL; 608 goto free_cmd_buf; 609 } 610 611 ret = kstrtobool(user_val, &enable); 612 if (ret) 613 goto enable_write_error; 614 615 if (enable) 616 fwlog->cfg.options |= LIBIE_FWLOG_OPTION_ARQ_ENA; 617 else 618 fwlog->cfg.options &= ~LIBIE_FWLOG_OPTION_ARQ_ENA; 619 620 ret = libie_fwlog_set(fwlog, &fwlog->cfg); 621 if (ret) 622 goto enable_write_error; 623 624 if (enable) 625 ret = libie_fwlog_register(fwlog); 626 else 627 ret = libie_fwlog_unregister(fwlog); 628 629 if (ret) 630 goto enable_write_error; 631 632 /* if we get here, nothing went wrong; return count since we didn't 633 * really write anything 634 */ 635 ret = (ssize_t)count; 636 637 enable_write_error: 638 /* This function always consumes all of the written input, or produces 639 * an error. Check and enforce this. Otherwise, the write operation 640 * won't complete properly. 641 */ 642 if (WARN_ON(ret != (ssize_t)count && ret >= 0)) 643 ret = -EIO; 644 free_cmd_buf: 645 kfree(cmd_buf); 646 647 return ret; 648 } 649 650 static const struct file_operations libie_debugfs_enable_fops = { 651 .owner = THIS_MODULE, 652 .open = simple_open, 653 .read = libie_debugfs_enable_read, 654 .write = libie_debugfs_enable_write, 655 }; 656 657 /** 658 * libie_debugfs_log_size_read - read from 'log_size' file 659 * @filp: the opened file 660 * @buffer: where to write the data for the user to read 661 * @count: the size of the user's buffer 662 * @ppos: file position offset 663 */ 664 static ssize_t libie_debugfs_log_size_read(struct file *filp, 665 char __user *buffer, size_t count, 666 loff_t *ppos) 667 { 668 struct libie_fwlog *fwlog = filp->private_data; 669 char buff[32] = {}; 670 int index; 671 672 index = fwlog->ring.index; 673 snprintf(buff, sizeof(buff), "%s\n", libie_fwlog_log_size[index]); 674 675 return simple_read_from_buffer(buffer, count, ppos, buff, strlen(buff)); 676 } 677 678 /** 679 * libie_debugfs_log_size_write - write into 'log_size' file 680 * @filp: the opened file 681 * @buf: where to find the user's data 682 * @count: the length of the user's data 683 * @ppos: file position offset 684 */ 685 static ssize_t 686 libie_debugfs_log_size_write(struct file *filp, const char __user *buf, 687 size_t count, loff_t *ppos) 688 { 689 struct libie_fwlog *fwlog = filp->private_data; 690 struct device *dev = &fwlog->pdev->dev; 691 char user_val[8], *cmd_buf; 692 ssize_t ret; 693 int index; 694 695 /* don't allow partial writes or invalid input */ 696 if (*ppos != 0 || count > 5) 697 return -EINVAL; 698 699 cmd_buf = memdup_user_nul(buf, count); 700 if (IS_ERR(cmd_buf)) 701 return PTR_ERR(cmd_buf); 702 703 ret = sscanf(cmd_buf, "%s", user_val); 704 if (ret != 1) { 705 ret = -EINVAL; 706 goto free_cmd_buf; 707 } 708 709 index = sysfs_match_string(libie_fwlog_log_size, user_val); 710 if (index < 0) { 711 dev_info(dev, "Invalid log size '%s'. The value must be one of 128K, 256K, 512K, 1M, 2M\n", 712 user_val); 713 ret = -EINVAL; 714 goto log_size_write_error; 715 } else if (fwlog->cfg.options & LIBIE_FWLOG_OPTION_IS_REGISTERED) { 716 dev_info(dev, "FW logging is currently running. Please disable FW logging to change log_size\n"); 717 ret = -EINVAL; 718 goto log_size_write_error; 719 } 720 721 /* free all the buffers and the tracking info and resize */ 722 libie_fwlog_realloc_rings(fwlog, index); 723 724 /* if we get here, nothing went wrong; return count since we didn't 725 * really write anything 726 */ 727 ret = (ssize_t)count; 728 729 log_size_write_error: 730 /* This function always consumes all of the written input, or produces 731 * an error. Check and enforce this. Otherwise, the write operation 732 * won't complete properly. 733 */ 734 if (WARN_ON(ret != (ssize_t)count && ret >= 0)) 735 ret = -EIO; 736 free_cmd_buf: 737 kfree(cmd_buf); 738 739 return ret; 740 } 741 742 static const struct file_operations libie_debugfs_log_size_fops = { 743 .owner = THIS_MODULE, 744 .open = simple_open, 745 .read = libie_debugfs_log_size_read, 746 .write = libie_debugfs_log_size_write, 747 }; 748 749 /** 750 * libie_debugfs_data_read - read from 'data' file 751 * @filp: the opened file 752 * @buffer: where to write the data for the user to read 753 * @count: the size of the user's buffer 754 * @ppos: file position offset 755 */ 756 static ssize_t libie_debugfs_data_read(struct file *filp, char __user *buffer, 757 size_t count, loff_t *ppos) 758 { 759 struct libie_fwlog *fwlog = filp->private_data; 760 int data_copied = 0; 761 bool done = false; 762 763 if (libie_fwlog_ring_empty(&fwlog->ring)) 764 return 0; 765 766 while (!libie_fwlog_ring_empty(&fwlog->ring) && !done) { 767 struct libie_fwlog_data *log; 768 u16 cur_buf_len; 769 770 log = &fwlog->ring.rings[fwlog->ring.head]; 771 cur_buf_len = log->data_size; 772 if (cur_buf_len >= count) { 773 done = true; 774 continue; 775 } 776 777 if (copy_to_user(buffer, log->data, cur_buf_len)) { 778 /* if there is an error then bail and return whatever 779 * the driver has copied so far 780 */ 781 done = true; 782 continue; 783 } 784 785 data_copied += cur_buf_len; 786 buffer += cur_buf_len; 787 count -= cur_buf_len; 788 *ppos += cur_buf_len; 789 libie_fwlog_ring_increment(&fwlog->ring.head, fwlog->ring.size); 790 } 791 792 return data_copied; 793 } 794 795 /** 796 * libie_debugfs_data_write - write into 'data' file 797 * @filp: the opened file 798 * @buf: where to find the user's data 799 * @count: the length of the user's data 800 * @ppos: file position offset 801 */ 802 static ssize_t 803 libie_debugfs_data_write(struct file *filp, const char __user *buf, size_t count, 804 loff_t *ppos) 805 { 806 struct libie_fwlog *fwlog = filp->private_data; 807 struct device *dev = &fwlog->pdev->dev; 808 ssize_t ret; 809 810 /* don't allow partial writes */ 811 if (*ppos != 0) 812 return 0; 813 814 /* any value is allowed to clear the buffer so no need to even look at 815 * what the value is 816 */ 817 if (!(fwlog->cfg.options & LIBIE_FWLOG_OPTION_IS_REGISTERED)) { 818 fwlog->ring.head = 0; 819 fwlog->ring.tail = 0; 820 } else { 821 dev_info(dev, "Can't clear FW log data while FW log running\n"); 822 ret = -EINVAL; 823 goto nr_buffs_write_error; 824 } 825 826 /* if we get here, nothing went wrong; return count since we didn't 827 * really write anything 828 */ 829 ret = (ssize_t)count; 830 831 nr_buffs_write_error: 832 /* This function always consumes all of the written input, or produces 833 * an error. Check and enforce this. Otherwise, the write operation 834 * won't complete properly. 835 */ 836 if (WARN_ON(ret != (ssize_t)count && ret >= 0)) 837 ret = -EIO; 838 839 return ret; 840 } 841 842 static const struct file_operations libie_debugfs_data_fops = { 843 .owner = THIS_MODULE, 844 .open = simple_open, 845 .read = libie_debugfs_data_read, 846 .write = libie_debugfs_data_write, 847 }; 848 849 /** 850 * libie_debugfs_fwlog_init - setup the debugfs directory 851 * @fwlog: pointer to the fwlog structure 852 * @root: debugfs root entry on which fwlog director will be registered 853 */ 854 static void libie_debugfs_fwlog_init(struct libie_fwlog *fwlog, 855 struct dentry *root) 856 { 857 struct dentry *fw_modules_dir; 858 struct dentry **fw_modules; 859 int i; 860 861 /* allocate space for this first because if it fails then we don't 862 * need to unwind 863 */ 864 fw_modules = kzalloc_objs(*fw_modules, LIBIE_NR_FW_LOG_MODULES); 865 if (!fw_modules) 866 return; 867 868 fwlog->debugfs = debugfs_create_dir("fwlog", root); 869 if (IS_ERR(fwlog->debugfs)) 870 goto err_create_module_files; 871 872 fw_modules_dir = debugfs_create_dir("modules", fwlog->debugfs); 873 if (IS_ERR(fw_modules_dir)) 874 goto err_create_module_files; 875 876 for (i = 0; i < LIBIE_NR_FW_LOG_MODULES; i++) { 877 fw_modules[i] = debugfs_create_file(libie_fwlog_module_string[i], 878 0600, fw_modules_dir, fwlog, 879 &libie_debugfs_module_fops); 880 if (IS_ERR(fw_modules[i])) 881 goto err_create_module_files; 882 } 883 884 debugfs_create_file("nr_messages", 0600, fwlog->debugfs, fwlog, 885 &libie_debugfs_nr_messages_fops); 886 887 fwlog->debugfs_modules = fw_modules; 888 889 debugfs_create_file("enable", 0600, fwlog->debugfs, fwlog, 890 &libie_debugfs_enable_fops); 891 892 debugfs_create_file("log_size", 0600, fwlog->debugfs, fwlog, 893 &libie_debugfs_log_size_fops); 894 895 debugfs_create_file("data", 0600, fwlog->debugfs, fwlog, 896 &libie_debugfs_data_fops); 897 898 return; 899 900 err_create_module_files: 901 debugfs_remove_recursive(fwlog->debugfs); 902 kfree(fw_modules); 903 } 904 905 static bool libie_fwlog_ring_full(struct libie_fwlog_ring *rings) 906 { 907 u16 head, tail; 908 909 head = rings->head; 910 tail = rings->tail; 911 912 if (head < tail && (tail - head == (rings->size - 1))) 913 return true; 914 else if (head > tail && (tail == (head - 1))) 915 return true; 916 917 return false; 918 } 919 920 /** 921 * libie_aq_fwlog_get - Get the current firmware logging configuration (0xFF32) 922 * @fwlog: pointer to the fwlog structure 923 * @cfg: firmware logging configuration to populate 924 */ 925 static int libie_aq_fwlog_get(struct libie_fwlog *fwlog, 926 struct libie_fwlog_cfg *cfg) 927 { 928 struct libie_aqc_fw_log_cfg_resp *fw_modules; 929 struct libie_aq_desc desc = {0}; 930 struct libie_aqc_fw_log *cmd; 931 u16 module_id_cnt; 932 int status; 933 void *buf; 934 int i; 935 936 memset(cfg, 0, sizeof(*cfg)); 937 938 buf = kzalloc(LIBIE_AQ_MAX_BUF_LEN, GFP_KERNEL); 939 if (!buf) 940 return -ENOMEM; 941 942 desc.opcode = cpu_to_le16(libie_aqc_opc_fw_logs_query); 943 desc.flags = cpu_to_le16(LIBIE_AQ_FLAG_SI); 944 cmd = libie_aq_raw(&desc); 945 946 cmd->cmd_flags = LIBIE_AQC_FW_LOG_AQ_QUERY; 947 948 status = fwlog->send_cmd(fwlog->priv, &desc, buf, LIBIE_AQ_MAX_BUF_LEN); 949 if (status) { 950 dev_dbg(&fwlog->pdev->dev, "Failed to get FW log configuration\n"); 951 goto status_out; 952 } 953 954 module_id_cnt = le16_to_cpu(cmd->ops.cfg.mdl_cnt); 955 if (module_id_cnt < LIBIE_AQC_FW_LOG_ID_MAX) { 956 dev_dbg(&fwlog->pdev->dev, "FW returned less than the expected number of FW log module IDs\n"); 957 } else if (module_id_cnt > LIBIE_AQC_FW_LOG_ID_MAX) { 958 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", 959 LIBIE_AQC_FW_LOG_ID_MAX); 960 module_id_cnt = LIBIE_AQC_FW_LOG_ID_MAX; 961 } 962 963 cfg->log_resolution = le16_to_cpu(cmd->ops.cfg.log_resolution); 964 if (cmd->cmd_flags & LIBIE_AQC_FW_LOG_CONF_AQ_EN) 965 cfg->options |= LIBIE_FWLOG_OPTION_ARQ_ENA; 966 if (cmd->cmd_flags & LIBIE_AQC_FW_LOG_CONF_UART_EN) 967 cfg->options |= LIBIE_FWLOG_OPTION_UART_ENA; 968 if (cmd->cmd_flags & LIBIE_AQC_FW_LOG_QUERY_REGISTERED) 969 cfg->options |= LIBIE_FWLOG_OPTION_IS_REGISTERED; 970 971 fw_modules = (struct libie_aqc_fw_log_cfg_resp *)buf; 972 973 for (i = 0; i < module_id_cnt; i++) { 974 struct libie_aqc_fw_log_cfg_resp *fw_module = &fw_modules[i]; 975 976 cfg->module_entries[i].module_id = 977 le16_to_cpu(fw_module->module_identifier); 978 cfg->module_entries[i].log_level = fw_module->log_level; 979 } 980 981 status_out: 982 kfree(buf); 983 return status; 984 } 985 986 /** 987 * libie_fwlog_set_supported - Set if FW logging is supported by FW 988 * @fwlog: pointer to the fwlog structure 989 * 990 * If FW returns success to the libie_aq_fwlog_get call then it supports FW 991 * logging, else it doesn't. Set the fwlog_supported flag accordingly. 992 * 993 * This function is only meant to be called during driver init to determine if 994 * the FW support FW logging. 995 */ 996 static void libie_fwlog_set_supported(struct libie_fwlog *fwlog) 997 { 998 struct libie_fwlog_cfg *cfg; 999 int status; 1000 1001 fwlog->supported = false; 1002 1003 cfg = kzalloc_obj(*cfg); 1004 if (!cfg) 1005 return; 1006 1007 status = libie_aq_fwlog_get(fwlog, cfg); 1008 if (status) 1009 dev_dbg(&fwlog->pdev->dev, "libie_aq_fwlog_get failed, FW logging is not supported on this version of FW, status %d\n", 1010 status); 1011 else 1012 fwlog->supported = true; 1013 1014 kfree(cfg); 1015 } 1016 1017 /** 1018 * libie_fwlog_init - Initialize FW logging configuration 1019 * @fwlog: pointer to the fwlog structure 1020 * @api: api structure to init fwlog 1021 * 1022 * This function should be called on driver initialization during 1023 * libie_init_hw(). 1024 */ 1025 int libie_fwlog_init(struct libie_fwlog *fwlog, struct libie_fwlog_api *api) 1026 { 1027 fwlog->api = *api; 1028 libie_fwlog_set_supported(fwlog); 1029 1030 if (libie_fwlog_supported(fwlog)) { 1031 int status; 1032 1033 /* read the current config from the FW and store it */ 1034 status = libie_aq_fwlog_get(fwlog, &fwlog->cfg); 1035 if (status) 1036 return status; 1037 1038 fwlog->ring.rings = kzalloc_objs(*fwlog->ring.rings, 1039 LIBIE_FWLOG_RING_SIZE_DFLT); 1040 if (!fwlog->ring.rings) { 1041 dev_warn(&fwlog->pdev->dev, "Unable to allocate memory for FW log rings\n"); 1042 return -ENOMEM; 1043 } 1044 1045 fwlog->ring.size = LIBIE_FWLOG_RING_SIZE_DFLT; 1046 fwlog->ring.index = LIBIE_FWLOG_RING_SIZE_INDEX_DFLT; 1047 1048 status = libie_fwlog_alloc_ring_buffs(&fwlog->ring); 1049 if (status) { 1050 dev_warn(&fwlog->pdev->dev, "Unable to allocate memory for FW log ring data buffers\n"); 1051 libie_fwlog_free_ring_buffs(&fwlog->ring); 1052 kfree(fwlog->ring.rings); 1053 return status; 1054 } 1055 1056 libie_debugfs_fwlog_init(fwlog, api->debugfs_root); 1057 } else { 1058 dev_warn(&fwlog->pdev->dev, "FW logging is not supported in this NVM image. Please update the NVM to get FW log support\n"); 1059 } 1060 1061 return 0; 1062 } 1063 EXPORT_SYMBOL_GPL(libie_fwlog_init); 1064 1065 /** 1066 * libie_fwlog_deinit - unroll FW logging configuration 1067 * @fwlog: pointer to the fwlog structure 1068 * 1069 * This function should be called in libie_deinit_hw(). 1070 */ 1071 void libie_fwlog_deinit(struct libie_fwlog *fwlog) 1072 { 1073 int status; 1074 1075 /* if FW logging isn't supported it means no configuration was done */ 1076 if (!libie_fwlog_supported(fwlog)) 1077 return; 1078 1079 /* make sure FW logging is disabled to not put the FW in a weird state 1080 * for the next driver load 1081 */ 1082 fwlog->cfg.options &= ~LIBIE_FWLOG_OPTION_ARQ_ENA; 1083 status = libie_fwlog_set(fwlog, &fwlog->cfg); 1084 if (status) 1085 dev_warn(&fwlog->pdev->dev, "Unable to turn off FW logging, status: %d\n", 1086 status); 1087 1088 kfree(fwlog->debugfs_modules); 1089 1090 fwlog->debugfs_modules = NULL; 1091 1092 status = libie_fwlog_unregister(fwlog); 1093 if (status) 1094 dev_warn(&fwlog->pdev->dev, "Unable to unregister FW logging, status: %d\n", 1095 status); 1096 1097 if (fwlog->ring.rings) { 1098 libie_fwlog_free_ring_buffs(&fwlog->ring); 1099 kfree(fwlog->ring.rings); 1100 } 1101 } 1102 EXPORT_SYMBOL_GPL(libie_fwlog_deinit); 1103 1104 /** 1105 * libie_get_fwlog_data - copy the FW log data from ARQ event 1106 * @fwlog: fwlog that the FW log event is associated with 1107 * @buf: event buffer pointer 1108 * @len: len of event descriptor 1109 */ 1110 void libie_get_fwlog_data(struct libie_fwlog *fwlog, u8 *buf, u16 len) 1111 { 1112 struct libie_fwlog_data *log; 1113 1114 log = &fwlog->ring.rings[fwlog->ring.tail]; 1115 1116 memset(log->data, 0, PAGE_SIZE); 1117 log->data_size = len; 1118 1119 memcpy(log->data, buf, log->data_size); 1120 libie_fwlog_ring_increment(&fwlog->ring.tail, fwlog->ring.size); 1121 1122 if (libie_fwlog_ring_full(&fwlog->ring)) { 1123 /* the rings are full so bump the head to create room */ 1124 libie_fwlog_ring_increment(&fwlog->ring.head, fwlog->ring.size); 1125 } 1126 } 1127 EXPORT_SYMBOL_GPL(libie_get_fwlog_data); 1128 1129 void libie_fwlog_reregister(struct libie_fwlog *fwlog) 1130 { 1131 if (!(fwlog->cfg.options & LIBIE_FWLOG_OPTION_IS_REGISTERED)) 1132 return; 1133 1134 if (libie_fwlog_register(fwlog)) 1135 fwlog->cfg.options &= ~LIBIE_FWLOG_OPTION_IS_REGISTERED; 1136 } 1137 EXPORT_SYMBOL_GPL(libie_fwlog_reregister); 1138 1139 MODULE_DESCRIPTION("Intel(R) Ethernet common library"); 1140 MODULE_LICENSE("GPL"); 1141