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 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 = kzalloc_objs(*fw_modules, LIBIE_NR_FW_LOG_MODULES); 842 if (!fw_modules) 843 return; 844 845 fwlog->debugfs = debugfs_create_dir("fwlog", root); 846 if (IS_ERR(fwlog->debugfs)) 847 goto err_create_module_files; 848 849 fw_modules_dir = debugfs_create_dir("modules", fwlog->debugfs); 850 if (IS_ERR(fw_modules_dir)) 851 goto err_create_module_files; 852 853 for (i = 0; i < LIBIE_NR_FW_LOG_MODULES; i++) { 854 fw_modules[i] = debugfs_create_file(libie_fwlog_module_string[i], 855 0600, fw_modules_dir, fwlog, 856 &libie_debugfs_module_fops); 857 if (IS_ERR(fw_modules[i])) 858 goto err_create_module_files; 859 } 860 861 debugfs_create_file("nr_messages", 0600, fwlog->debugfs, fwlog, 862 &libie_debugfs_nr_messages_fops); 863 864 fwlog->debugfs_modules = fw_modules; 865 866 debugfs_create_file("enable", 0600, fwlog->debugfs, fwlog, 867 &libie_debugfs_enable_fops); 868 869 debugfs_create_file("log_size", 0600, fwlog->debugfs, fwlog, 870 &libie_debugfs_log_size_fops); 871 872 debugfs_create_file("data", 0600, fwlog->debugfs, fwlog, 873 &libie_debugfs_data_fops); 874 875 return; 876 877 err_create_module_files: 878 debugfs_remove_recursive(fwlog->debugfs); 879 kfree(fw_modules); 880 } 881 882 static bool libie_fwlog_ring_full(struct libie_fwlog_ring *rings) 883 { 884 u16 head, tail; 885 886 head = rings->head; 887 tail = rings->tail; 888 889 if (head < tail && (tail - head == (rings->size - 1))) 890 return true; 891 else if (head > tail && (tail == (head - 1))) 892 return true; 893 894 return false; 895 } 896 897 /** 898 * libie_aq_fwlog_get - Get the current firmware logging configuration (0xFF32) 899 * @fwlog: pointer to the fwlog structure 900 * @cfg: firmware logging configuration to populate 901 */ 902 static int libie_aq_fwlog_get(struct libie_fwlog *fwlog, 903 struct libie_fwlog_cfg *cfg) 904 { 905 struct libie_aqc_fw_log_cfg_resp *fw_modules; 906 struct libie_aq_desc desc = {0}; 907 struct libie_aqc_fw_log *cmd; 908 u16 module_id_cnt; 909 int status; 910 void *buf; 911 int i; 912 913 memset(cfg, 0, sizeof(*cfg)); 914 915 buf = kzalloc(LIBIE_AQ_MAX_BUF_LEN, GFP_KERNEL); 916 if (!buf) 917 return -ENOMEM; 918 919 desc.opcode = cpu_to_le16(libie_aqc_opc_fw_logs_query); 920 desc.flags = cpu_to_le16(LIBIE_AQ_FLAG_SI); 921 cmd = libie_aq_raw(&desc); 922 923 cmd->cmd_flags = LIBIE_AQC_FW_LOG_AQ_QUERY; 924 925 status = fwlog->send_cmd(fwlog->priv, &desc, buf, LIBIE_AQ_MAX_BUF_LEN); 926 if (status) { 927 dev_dbg(&fwlog->pdev->dev, "Failed to get FW log configuration\n"); 928 goto status_out; 929 } 930 931 module_id_cnt = le16_to_cpu(cmd->ops.cfg.mdl_cnt); 932 if (module_id_cnt < LIBIE_AQC_FW_LOG_ID_MAX) { 933 dev_dbg(&fwlog->pdev->dev, "FW returned less than the expected number of FW log module IDs\n"); 934 } else if (module_id_cnt > LIBIE_AQC_FW_LOG_ID_MAX) { 935 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", 936 LIBIE_AQC_FW_LOG_ID_MAX); 937 module_id_cnt = LIBIE_AQC_FW_LOG_ID_MAX; 938 } 939 940 cfg->log_resolution = le16_to_cpu(cmd->ops.cfg.log_resolution); 941 if (cmd->cmd_flags & LIBIE_AQC_FW_LOG_CONF_AQ_EN) 942 cfg->options |= LIBIE_FWLOG_OPTION_ARQ_ENA; 943 if (cmd->cmd_flags & LIBIE_AQC_FW_LOG_CONF_UART_EN) 944 cfg->options |= LIBIE_FWLOG_OPTION_UART_ENA; 945 if (cmd->cmd_flags & LIBIE_AQC_FW_LOG_QUERY_REGISTERED) 946 cfg->options |= LIBIE_FWLOG_OPTION_IS_REGISTERED; 947 948 fw_modules = (struct libie_aqc_fw_log_cfg_resp *)buf; 949 950 for (i = 0; i < module_id_cnt; i++) { 951 struct libie_aqc_fw_log_cfg_resp *fw_module = &fw_modules[i]; 952 953 cfg->module_entries[i].module_id = 954 le16_to_cpu(fw_module->module_identifier); 955 cfg->module_entries[i].log_level = fw_module->log_level; 956 } 957 958 status_out: 959 kfree(buf); 960 return status; 961 } 962 963 /** 964 * libie_fwlog_set_supported - Set if FW logging is supported by FW 965 * @fwlog: pointer to the fwlog structure 966 * 967 * If FW returns success to the libie_aq_fwlog_get call then it supports FW 968 * logging, else it doesn't. Set the fwlog_supported flag accordingly. 969 * 970 * This function is only meant to be called during driver init to determine if 971 * the FW support FW logging. 972 */ 973 static void libie_fwlog_set_supported(struct libie_fwlog *fwlog) 974 { 975 struct libie_fwlog_cfg *cfg; 976 int status; 977 978 fwlog->supported = false; 979 980 cfg = kzalloc_obj(*cfg); 981 if (!cfg) 982 return; 983 984 status = libie_aq_fwlog_get(fwlog, cfg); 985 if (status) 986 dev_dbg(&fwlog->pdev->dev, "libie_aq_fwlog_get failed, FW logging is not supported on this version of FW, status %d\n", 987 status); 988 else 989 fwlog->supported = true; 990 991 kfree(cfg); 992 } 993 994 /** 995 * libie_fwlog_init - Initialize FW logging configuration 996 * @fwlog: pointer to the fwlog structure 997 * @api: api structure to init fwlog 998 * 999 * This function should be called on driver initialization during 1000 * libie_init_hw(). 1001 */ 1002 int libie_fwlog_init(struct libie_fwlog *fwlog, struct libie_fwlog_api *api) 1003 { 1004 fwlog->api = *api; 1005 libie_fwlog_set_supported(fwlog); 1006 1007 if (libie_fwlog_supported(fwlog)) { 1008 int status; 1009 1010 /* read the current config from the FW and store it */ 1011 status = libie_aq_fwlog_get(fwlog, &fwlog->cfg); 1012 if (status) 1013 return status; 1014 1015 fwlog->ring.rings = kzalloc_objs(*fwlog->ring.rings, 1016 LIBIE_FWLOG_RING_SIZE_DFLT); 1017 if (!fwlog->ring.rings) { 1018 dev_warn(&fwlog->pdev->dev, "Unable to allocate memory for FW log rings\n"); 1019 return -ENOMEM; 1020 } 1021 1022 fwlog->ring.size = LIBIE_FWLOG_RING_SIZE_DFLT; 1023 fwlog->ring.index = LIBIE_FWLOG_RING_SIZE_INDEX_DFLT; 1024 1025 status = libie_fwlog_alloc_ring_buffs(&fwlog->ring); 1026 if (status) { 1027 dev_warn(&fwlog->pdev->dev, "Unable to allocate memory for FW log ring data buffers\n"); 1028 libie_fwlog_free_ring_buffs(&fwlog->ring); 1029 kfree(fwlog->ring.rings); 1030 return status; 1031 } 1032 1033 libie_debugfs_fwlog_init(fwlog, api->debugfs_root); 1034 } else { 1035 dev_warn(&fwlog->pdev->dev, "FW logging is not supported in this NVM image. Please update the NVM to get FW log support\n"); 1036 } 1037 1038 return 0; 1039 } 1040 EXPORT_SYMBOL_GPL(libie_fwlog_init); 1041 1042 /** 1043 * libie_fwlog_deinit - unroll FW logging configuration 1044 * @fwlog: pointer to the fwlog structure 1045 * 1046 * This function should be called in libie_deinit_hw(). 1047 */ 1048 void libie_fwlog_deinit(struct libie_fwlog *fwlog) 1049 { 1050 int status; 1051 1052 /* if FW logging isn't supported it means no configuration was done */ 1053 if (!libie_fwlog_supported(fwlog)) 1054 return; 1055 1056 /* make sure FW logging is disabled to not put the FW in a weird state 1057 * for the next driver load 1058 */ 1059 fwlog->cfg.options &= ~LIBIE_FWLOG_OPTION_ARQ_ENA; 1060 status = libie_fwlog_set(fwlog, &fwlog->cfg); 1061 if (status) 1062 dev_warn(&fwlog->pdev->dev, "Unable to turn off FW logging, status: %d\n", 1063 status); 1064 1065 kfree(fwlog->debugfs_modules); 1066 1067 fwlog->debugfs_modules = NULL; 1068 1069 status = libie_fwlog_unregister(fwlog); 1070 if (status) 1071 dev_warn(&fwlog->pdev->dev, "Unable to unregister FW logging, status: %d\n", 1072 status); 1073 1074 if (fwlog->ring.rings) { 1075 libie_fwlog_free_ring_buffs(&fwlog->ring); 1076 kfree(fwlog->ring.rings); 1077 } 1078 } 1079 EXPORT_SYMBOL_GPL(libie_fwlog_deinit); 1080 1081 /** 1082 * libie_get_fwlog_data - copy the FW log data from ARQ event 1083 * @fwlog: fwlog that the FW log event is associated with 1084 * @buf: event buffer pointer 1085 * @len: len of event descriptor 1086 */ 1087 void libie_get_fwlog_data(struct libie_fwlog *fwlog, u8 *buf, u16 len) 1088 { 1089 struct libie_fwlog_data *log; 1090 1091 log = &fwlog->ring.rings[fwlog->ring.tail]; 1092 1093 memset(log->data, 0, PAGE_SIZE); 1094 log->data_size = len; 1095 1096 memcpy(log->data, buf, log->data_size); 1097 libie_fwlog_ring_increment(&fwlog->ring.tail, fwlog->ring.size); 1098 1099 if (libie_fwlog_ring_full(&fwlog->ring)) { 1100 /* the rings are full so bump the head to create room */ 1101 libie_fwlog_ring_increment(&fwlog->ring.head, fwlog->ring.size); 1102 } 1103 } 1104 EXPORT_SYMBOL_GPL(libie_get_fwlog_data); 1105 1106 void libie_fwlog_reregister(struct libie_fwlog *fwlog) 1107 { 1108 if (!(fwlog->cfg.options & LIBIE_FWLOG_OPTION_IS_REGISTERED)) 1109 return; 1110 1111 if (libie_fwlog_register(fwlog)) 1112 fwlog->cfg.options &= ~LIBIE_FWLOG_OPTION_IS_REGISTERED; 1113 } 1114 EXPORT_SYMBOL_GPL(libie_fwlog_reregister); 1115 1116 MODULE_DESCRIPTION("Intel(R) Ethernet common library"); 1117 MODULE_LICENSE("GPL"); 1118